mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 12:33:44 +02:00
Remove a lot of code that we don't need from tap-windows, further winnowing down this fork of OpenVPN's tap-windows to a more minimal version that does only basic Ethernet tap functionality.
This commit is contained in:
parent
45c5b66e9e
commit
a365a0e3ba
14 changed files with 2542 additions and 4462 deletions
|
@ -261,20 +261,6 @@
|
||||||
<FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
|
<FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="dhcp.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Win8 Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Vista Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Win8 Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Vista Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Win7 Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Win7 Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Vista Debug|x64'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Win8 Debug|x64'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Vista Release|x64'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Win7 Debug|x64'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Win7 Release|x64'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Win8 Release|x64'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="error.c">
|
<ClCompile Include="error.c">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Win8 Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Win8 Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Vista Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Vista Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
@ -336,7 +322,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="config.h" />
|
<ClInclude Include="config.h" />
|
||||||
<ClInclude Include="constants.h" />
|
<ClInclude Include="constants.h" />
|
||||||
<ClInclude Include="dhcp.h" />
|
|
||||||
<ClInclude Include="endian.h" />
|
<ClInclude Include="endian.h" />
|
||||||
<ClInclude Include="error.h" />
|
<ClInclude Include="error.h" />
|
||||||
<ClInclude Include="lock.h" />
|
<ClInclude Include="lock.h" />
|
||||||
|
|
|
@ -19,9 +19,6 @@
|
||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="dhcp.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="error.c">
|
<ClCompile Include="error.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -42,9 +39,6 @@
|
||||||
<ClInclude Include="constants.h">
|
<ClInclude Include="constants.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="dhcp.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="endian.h">
|
<ClInclude Include="endian.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -1,603 +0,0 @@
|
||||||
/*
|
|
||||||
* TAP-Windows -- A kernel driver to provide virtual tap
|
|
||||||
* device functionality on Windows.
|
|
||||||
*
|
|
||||||
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
|
||||||
*
|
|
||||||
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
|
||||||
* and is released under the GPL version 2 (see below).
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2
|
|
||||||
* as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program (see the file COPYING included with this
|
|
||||||
* distribution); if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
//=========================
|
|
||||||
// Code to set DHCP options
|
|
||||||
//=========================
|
|
||||||
|
|
||||||
VOID
|
|
||||||
SetDHCPOpt (DHCPMsg *m, void *data, unsigned int len)
|
|
||||||
{
|
|
||||||
if (!m->overflow)
|
|
||||||
{
|
|
||||||
if (m->optlen + len <= DHCP_OPTIONS_BUFFER_SIZE)
|
|
||||||
{
|
|
||||||
if (len)
|
|
||||||
{
|
|
||||||
NdisMoveMemory (m->msg.options + m->optlen, data, len);
|
|
||||||
m->optlen += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m->overflow = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
SetDHCPOpt0 (DHCPMsg *msg, int type)
|
|
||||||
{
|
|
||||||
DHCPOPT0 opt;
|
|
||||||
opt.type = (UCHAR) type;
|
|
||||||
SetDHCPOpt (msg, &opt, sizeof (opt));
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
SetDHCPOpt8 (DHCPMsg *msg, int type, ULONG data)
|
|
||||||
{
|
|
||||||
DHCPOPT8 opt;
|
|
||||||
opt.type = (UCHAR) type;
|
|
||||||
opt.len = sizeof (opt.data);
|
|
||||||
opt.data = (UCHAR) data;
|
|
||||||
SetDHCPOpt (msg, &opt, sizeof (opt));
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
SetDHCPOpt32 (DHCPMsg *msg, int type, ULONG data)
|
|
||||||
{
|
|
||||||
DHCPOPT32 opt;
|
|
||||||
opt.type = (UCHAR) type;
|
|
||||||
opt.len = sizeof (opt.data);
|
|
||||||
opt.data = data;
|
|
||||||
SetDHCPOpt (msg, &opt, sizeof (opt));
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============
|
|
||||||
// Checksum code
|
|
||||||
//==============
|
|
||||||
|
|
||||||
USHORT
|
|
||||||
ip_checksum (const UCHAR *buf, const int len_ip_header)
|
|
||||||
{
|
|
||||||
USHORT word16;
|
|
||||||
ULONG sum = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// make 16 bit words out of every two adjacent 8 bit words in the packet
|
|
||||||
// and add them up
|
|
||||||
for (i = 0; i < len_ip_header - 1; i += 2) {
|
|
||||||
word16 = ((buf[i] << 8) & 0xFF00) + (buf[i+1] & 0xFF);
|
|
||||||
sum += (ULONG) word16;
|
|
||||||
}
|
|
||||||
|
|
||||||
// take only 16 bits out of the 32 bit sum and add up the carries
|
|
||||||
while (sum >> 16)
|
|
||||||
sum = (sum & 0xFFFF) + (sum >> 16);
|
|
||||||
|
|
||||||
// one's complement the result
|
|
||||||
return ((USHORT) ~sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
USHORT
|
|
||||||
udp_checksum (const UCHAR *buf,
|
|
||||||
const int len_udp,
|
|
||||||
const UCHAR *src_addr,
|
|
||||||
const UCHAR *dest_addr)
|
|
||||||
{
|
|
||||||
USHORT word16;
|
|
||||||
ULONG sum = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// make 16 bit words out of every two adjacent 8 bit words and
|
|
||||||
// calculate the sum of all 16 bit words
|
|
||||||
for (i = 0; i < len_udp; i += 2){
|
|
||||||
word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_udp) ? (buf[i+1] & 0xFF) : 0);
|
|
||||||
sum += word16;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the UDP pseudo header which contains the IP source and destination addresses
|
|
||||||
for (i = 0; i < 4; i += 2){
|
|
||||||
word16 =((src_addr[i] << 8) & 0xFF00) + (src_addr[i+1] & 0xFF);
|
|
||||||
sum += word16;
|
|
||||||
}
|
|
||||||
for (i = 0; i < 4; i += 2){
|
|
||||||
word16 =((dest_addr[i] << 8) & 0xFF00) + (dest_addr[i+1] & 0xFF);
|
|
||||||
sum += word16;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the protocol number and the length of the UDP packet
|
|
||||||
sum += (USHORT) IPPROTO_UDP + (USHORT) len_udp;
|
|
||||||
|
|
||||||
// keep only the last 16 bits of the 32 bit calculated sum and add the carries
|
|
||||||
while (sum >> 16)
|
|
||||||
sum = (sum & 0xFFFF) + (sum >> 16);
|
|
||||||
|
|
||||||
// Take the one's complement of sum
|
|
||||||
return ((USHORT) ~sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================
|
|
||||||
// Set IP and UDP packet checksums
|
|
||||||
//================================
|
|
||||||
|
|
||||||
VOID
|
|
||||||
SetChecksumDHCPMsg (DHCPMsg *m)
|
|
||||||
{
|
|
||||||
// Set IP checksum
|
|
||||||
m->msg.pre.ip.check = htons (ip_checksum ((UCHAR *) &m->msg.pre.ip, sizeof (IPHDR)));
|
|
||||||
|
|
||||||
// Set UDP Checksum
|
|
||||||
m->msg.pre.udp.check = htons (udp_checksum ((UCHAR *) &m->msg.pre.udp,
|
|
||||||
sizeof (UDPHDR) + sizeof (DHCP) + m->optlen,
|
|
||||||
(UCHAR *)&m->msg.pre.ip.saddr,
|
|
||||||
(UCHAR *)&m->msg.pre.ip.daddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
//===================
|
|
||||||
// DHCP message tests
|
|
||||||
//===================
|
|
||||||
|
|
||||||
int
|
|
||||||
GetDHCPMessageType (const DHCP *dhcp, const int optlen)
|
|
||||||
{
|
|
||||||
const UCHAR *p = (UCHAR *) (dhcp + 1);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < optlen; ++i)
|
|
||||||
{
|
|
||||||
const UCHAR type = p[i];
|
|
||||||
const int room = optlen - i - 1;
|
|
||||||
if (type == DHCP_END) // didn't find what we were looking for
|
|
||||||
return -1;
|
|
||||||
else if (type == DHCP_PAD) // no-operation
|
|
||||||
;
|
|
||||||
else if (type == DHCP_MSG_TYPE) // what we are looking for
|
|
||||||
{
|
|
||||||
if (room >= 2)
|
|
||||||
{
|
|
||||||
if (p[i+1] == 1) // message length should be 1
|
|
||||||
return p[i+2]; // return message type
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else // some other message
|
|
||||||
{
|
|
||||||
if (room >= 1)
|
|
||||||
{
|
|
||||||
const int len = p[i+1]; // get message length
|
|
||||||
i += (len + 1); // advance to next message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
DHCPMessageOurs (const TapAdapterPointer p_Adapter,
|
|
||||||
const ETH_HEADER *eth,
|
|
||||||
const IPHDR *ip,
|
|
||||||
const UDPHDR *udp,
|
|
||||||
const DHCP *dhcp)
|
|
||||||
{
|
|
||||||
// Must be UDPv4 protocol
|
|
||||||
if (!(eth->proto == htons (ETH_P_IP) && ip->protocol == IPPROTO_UDP))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
// Source MAC must be our adapter
|
|
||||||
if (!MAC_EQUAL (eth->src, p_Adapter->m_MAC))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
// Dest MAC must be either broadcast or our virtual DHCP server
|
|
||||||
if (!(MAC_EQUAL (eth->dest, p_Adapter->m_MAC_Broadcast)
|
|
||||||
|| MAC_EQUAL (eth->dest, p_Adapter->m_dhcp_server_mac)))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
// Port numbers must be correct
|
|
||||||
if (!(udp->dest == htons (BOOTPS_PORT)
|
|
||||||
&& udp->source == htons (BOOTPC_PORT)))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
// Hardware address must be MAC addr sized
|
|
||||||
if (!(dhcp->hlen == sizeof (MACADDR)))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
// Hardware address must match our adapter
|
|
||||||
if (!MAC_EQUAL (eth->src, dhcp->chaddr))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//=====================================================
|
|
||||||
// Build all of DHCP packet except for DHCP options.
|
|
||||||
// Assume that *p has been zeroed before we are called.
|
|
||||||
//=====================================================
|
|
||||||
|
|
||||||
VOID
|
|
||||||
BuildDHCPPre (const TapAdapterPointer a,
|
|
||||||
DHCPPre *p,
|
|
||||||
const ETH_HEADER *eth,
|
|
||||||
const IPHDR *ip,
|
|
||||||
const UDPHDR *udp,
|
|
||||||
const DHCP *dhcp,
|
|
||||||
const int optlen,
|
|
||||||
const int type)
|
|
||||||
{
|
|
||||||
// Should we broadcast or direct to a specific MAC / IP address?
|
|
||||||
const BOOLEAN broadcast = (type == DHCPNAK
|
|
||||||
|| MAC_EQUAL (eth->dest, a->m_MAC_Broadcast));
|
|
||||||
// Build ethernet header
|
|
||||||
|
|
||||||
COPY_MAC (p->eth.src, a->m_dhcp_server_mac);
|
|
||||||
|
|
||||||
if (broadcast)
|
|
||||||
COPY_MAC (p->eth.dest, a->m_MAC_Broadcast);
|
|
||||||
else
|
|
||||||
COPY_MAC (p->eth.dest, eth->src);
|
|
||||||
|
|
||||||
p->eth.proto = htons (ETH_P_IP);
|
|
||||||
|
|
||||||
// Build IP header
|
|
||||||
|
|
||||||
p->ip.version_len = (4 << 4) | (sizeof (IPHDR) >> 2);
|
|
||||||
p->ip.tos = 0;
|
|
||||||
p->ip.tot_len = htons (sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen);
|
|
||||||
p->ip.id = 0;
|
|
||||||
p->ip.frag_off = 0;
|
|
||||||
p->ip.ttl = 16;
|
|
||||||
p->ip.protocol = IPPROTO_UDP;
|
|
||||||
p->ip.check = 0;
|
|
||||||
p->ip.saddr = a->m_dhcp_server_ip;
|
|
||||||
|
|
||||||
if (broadcast)
|
|
||||||
p->ip.daddr = ~0;
|
|
||||||
else
|
|
||||||
p->ip.daddr = a->m_dhcp_addr;
|
|
||||||
|
|
||||||
// Build UDP header
|
|
||||||
|
|
||||||
p->udp.source = htons (BOOTPS_PORT);
|
|
||||||
p->udp.dest = htons (BOOTPC_PORT);
|
|
||||||
p->udp.len = htons (sizeof (UDPHDR) + sizeof (DHCP) + optlen);
|
|
||||||
p->udp.check = 0;
|
|
||||||
|
|
||||||
// Build DHCP response
|
|
||||||
|
|
||||||
p->dhcp.op = BOOTREPLY;
|
|
||||||
p->dhcp.htype = 1;
|
|
||||||
p->dhcp.hlen = sizeof (MACADDR);
|
|
||||||
p->dhcp.hops = 0;
|
|
||||||
p->dhcp.xid = dhcp->xid;
|
|
||||||
p->dhcp.secs = 0;
|
|
||||||
p->dhcp.flags = 0;
|
|
||||||
p->dhcp.ciaddr = 0;
|
|
||||||
|
|
||||||
if (type == DHCPNAK)
|
|
||||||
p->dhcp.yiaddr = 0;
|
|
||||||
else
|
|
||||||
p->dhcp.yiaddr = a->m_dhcp_addr;
|
|
||||||
|
|
||||||
p->dhcp.siaddr = a->m_dhcp_server_ip;
|
|
||||||
p->dhcp.giaddr = 0;
|
|
||||||
COPY_MAC (p->dhcp.chaddr, eth->src);
|
|
||||||
p->dhcp.magic = htonl (0x63825363);
|
|
||||||
}
|
|
||||||
//=============================
|
|
||||||
// Build specific DHCP messages
|
|
||||||
//=============================
|
|
||||||
|
|
||||||
VOID
|
|
||||||
SendDHCPMsg (const TapAdapterPointer a,
|
|
||||||
const int type,
|
|
||||||
const ETH_HEADER *eth,
|
|
||||||
const IPHDR *ip,
|
|
||||||
const UDPHDR *udp,
|
|
||||||
const DHCP *dhcp)
|
|
||||||
{
|
|
||||||
DHCPMsg *pkt;
|
|
||||||
|
|
||||||
if (!(type == DHCPOFFER || type == DHCPACK || type == DHCPNAK))
|
|
||||||
{
|
|
||||||
DEBUGP (("[TAP] SendDHCPMsg: Bad DHCP type: %d\n", type));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkt = (DHCPMsg *) MemAlloc (sizeof (DHCPMsg), TRUE);
|
|
||||||
|
|
||||||
if (pkt)
|
|
||||||
{
|
|
||||||
//-----------------------
|
|
||||||
// Build DHCP options
|
|
||||||
//-----------------------
|
|
||||||
|
|
||||||
// Message Type
|
|
||||||
SetDHCPOpt8 (pkt, DHCP_MSG_TYPE, type);
|
|
||||||
|
|
||||||
// Server ID
|
|
||||||
SetDHCPOpt32 (pkt, DHCP_SERVER_ID, a->m_dhcp_server_ip);
|
|
||||||
|
|
||||||
if (type == DHCPOFFER || type == DHCPACK)
|
|
||||||
{
|
|
||||||
// Lease Time
|
|
||||||
SetDHCPOpt32 (pkt, DHCP_LEASE_TIME, htonl (a->m_dhcp_lease_time));
|
|
||||||
|
|
||||||
// Netmask
|
|
||||||
SetDHCPOpt32 (pkt, DHCP_NETMASK, a->m_dhcp_netmask);
|
|
||||||
|
|
||||||
// Other user-defined options
|
|
||||||
SetDHCPOpt (pkt,
|
|
||||||
a->m_dhcp_user_supplied_options_buffer,
|
|
||||||
a->m_dhcp_user_supplied_options_buffer_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
// End
|
|
||||||
SetDHCPOpt0 (pkt, DHCP_END);
|
|
||||||
|
|
||||||
if (!DHCPMSG_OVERFLOW (pkt))
|
|
||||||
{
|
|
||||||
// The initial part of the DHCP message (not including options) gets built here
|
|
||||||
BuildDHCPPre (a,
|
|
||||||
&pkt->msg.pre,
|
|
||||||
eth,
|
|
||||||
ip,
|
|
||||||
udp,
|
|
||||||
dhcp,
|
|
||||||
DHCPMSG_LEN_OPT (pkt),
|
|
||||||
type);
|
|
||||||
|
|
||||||
SetChecksumDHCPMsg (pkt);
|
|
||||||
|
|
||||||
DUMP_PACKET ("DHCPMsg",
|
|
||||||
DHCPMSG_BUF (pkt),
|
|
||||||
DHCPMSG_LEN_FULL (pkt));
|
|
||||||
|
|
||||||
// Return DHCP response to kernel
|
|
||||||
InjectPacketDeferred (a,
|
|
||||||
DHCPMSG_BUF (pkt),
|
|
||||||
DHCPMSG_LEN_FULL (pkt));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUGP (("[TAP] SendDHCPMsg: DHCP buffer overflow\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
MemFree (pkt, sizeof (DHCPMsg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//===================================================================
|
|
||||||
// Handle a BOOTPS packet produced by the local system to
|
|
||||||
// resolve the address/netmask of this adapter.
|
|
||||||
// If we are in TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode, reply
|
|
||||||
// to the message. Return TRUE if we processed the passed
|
|
||||||
// message, so that downstream stages can ignore it.
|
|
||||||
//===================================================================
|
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
ProcessDHCP (TapAdapterPointer p_Adapter,
|
|
||||||
const ETH_HEADER *eth,
|
|
||||||
const IPHDR *ip,
|
|
||||||
const UDPHDR *udp,
|
|
||||||
const DHCP *dhcp,
|
|
||||||
int optlen)
|
|
||||||
{
|
|
||||||
int msg_type;
|
|
||||||
|
|
||||||
// Sanity check IP header
|
|
||||||
if (!(ntohs (ip->tot_len) == sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen
|
|
||||||
&& (ntohs (ip->frag_off) & IP_OFFMASK) == 0))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
// Does this message belong to us?
|
|
||||||
if (!DHCPMessageOurs (p_Adapter, eth, ip, udp, dhcp))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
msg_type = GetDHCPMessageType (dhcp, optlen);
|
|
||||||
|
|
||||||
// Drop non-BOOTREQUEST messages
|
|
||||||
if (dhcp->op != BOOTREQUEST)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
// Drop any messages except DHCPDISCOVER or DHCPREQUEST
|
|
||||||
if (!(msg_type == DHCPDISCOVER || msg_type == DHCPREQUEST))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
// Should we reply with DHCPOFFER, DHCPACK, or DHCPNAK?
|
|
||||||
if (msg_type == DHCPREQUEST
|
|
||||||
&& ((dhcp->ciaddr && dhcp->ciaddr != p_Adapter->m_dhcp_addr)
|
|
||||||
|| !p_Adapter->m_dhcp_received_discover
|
|
||||||
|| p_Adapter->m_dhcp_bad_requests >= BAD_DHCPREQUEST_NAK_THRESHOLD))
|
|
||||||
SendDHCPMsg (p_Adapter,
|
|
||||||
DHCPNAK,
|
|
||||||
eth, ip, udp, dhcp);
|
|
||||||
else
|
|
||||||
SendDHCPMsg (p_Adapter,
|
|
||||||
(msg_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK),
|
|
||||||
eth, ip, udp, dhcp);
|
|
||||||
|
|
||||||
// Remember if we received a DHCPDISCOVER
|
|
||||||
if (msg_type == DHCPDISCOVER)
|
|
||||||
p_Adapter->m_dhcp_received_discover = TRUE;
|
|
||||||
|
|
||||||
// Is this a bad DHCPREQUEST?
|
|
||||||
if (msg_type == DHCPREQUEST && dhcp->ciaddr && dhcp->ciaddr != p_Adapter->m_dhcp_addr)
|
|
||||||
++p_Adapter->m_dhcp_bad_requests;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DBG
|
|
||||||
|
|
||||||
const char *
|
|
||||||
message_op_text (int op)
|
|
||||||
{
|
|
||||||
switch (op)
|
|
||||||
{
|
|
||||||
case BOOTREQUEST:
|
|
||||||
return "BOOTREQUEST";
|
|
||||||
case BOOTREPLY:
|
|
||||||
return "BOOTREPLY";
|
|
||||||
default:
|
|
||||||
return "???";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
message_type_text (int type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case DHCPDISCOVER:
|
|
||||||
return "DHCPDISCOVER";
|
|
||||||
case DHCPOFFER:
|
|
||||||
return "DHCPOFFER";
|
|
||||||
case DHCPREQUEST:
|
|
||||||
return "DHCPREQUEST";
|
|
||||||
case DHCPDECLINE:
|
|
||||||
return "DHCPDECLINE";
|
|
||||||
case DHCPACK:
|
|
||||||
return "DHCPACK";
|
|
||||||
case DHCPNAK:
|
|
||||||
return "DHCPNAK";
|
|
||||||
case DHCPRELEASE:
|
|
||||||
return "DHCPRELEASE";
|
|
||||||
case DHCPINFORM:
|
|
||||||
return "DHCPINFORM";
|
|
||||||
default:
|
|
||||||
return "???";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
port_name (int port)
|
|
||||||
{
|
|
||||||
switch (port)
|
|
||||||
{
|
|
||||||
case BOOTPS_PORT:
|
|
||||||
return "BOOTPS";
|
|
||||||
case BOOTPC_PORT:
|
|
||||||
return "BOOTPC";
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
DumpDHCP (const ETH_HEADER *eth,
|
|
||||||
const IPHDR *ip,
|
|
||||||
const UDPHDR *udp,
|
|
||||||
const DHCP *dhcp,
|
|
||||||
const int optlen)
|
|
||||||
{
|
|
||||||
DEBUGP ((" %s", message_op_text (dhcp->op)));
|
|
||||||
DEBUGP ((" %s ", message_type_text (GetDHCPMessageType (dhcp, optlen))));
|
|
||||||
PrIP (ip->saddr);
|
|
||||||
DEBUGP ((":%s[", port_name (ntohs (udp->source))));
|
|
||||||
PrMac (eth->src);
|
|
||||||
DEBUGP (("] -> "));
|
|
||||||
PrIP (ip->daddr);
|
|
||||||
DEBUGP ((":%s[", port_name (ntohs (udp->dest))));
|
|
||||||
PrMac (eth->dest);
|
|
||||||
DEBUGP (("]"));
|
|
||||||
if (dhcp->ciaddr)
|
|
||||||
{
|
|
||||||
DEBUGP ((" ci="));
|
|
||||||
PrIP (dhcp->ciaddr);
|
|
||||||
}
|
|
||||||
if (dhcp->yiaddr)
|
|
||||||
{
|
|
||||||
DEBUGP ((" yi="));
|
|
||||||
PrIP (dhcp->yiaddr);
|
|
||||||
}
|
|
||||||
if (dhcp->siaddr)
|
|
||||||
{
|
|
||||||
DEBUGP ((" si="));
|
|
||||||
PrIP (dhcp->siaddr);
|
|
||||||
}
|
|
||||||
if (dhcp->hlen == sizeof (MACADDR))
|
|
||||||
{
|
|
||||||
DEBUGP ((" ch="));
|
|
||||||
PrMac (dhcp->chaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGP ((" xid=0x%08x", ntohl (dhcp->xid)));
|
|
||||||
|
|
||||||
if (ntohl (dhcp->magic) != 0x63825363)
|
|
||||||
DEBUGP ((" ma=0x%08x", ntohl (dhcp->magic)));
|
|
||||||
if (dhcp->htype != 1)
|
|
||||||
DEBUGP ((" htype=%d", dhcp->htype));
|
|
||||||
if (dhcp->hops)
|
|
||||||
DEBUGP ((" hops=%d", dhcp->hops));
|
|
||||||
if (ntohs (dhcp->secs))
|
|
||||||
DEBUGP ((" secs=%d", ntohs (dhcp->secs)));
|
|
||||||
if (ntohs (dhcp->flags))
|
|
||||||
DEBUGP ((" flags=0x%04x", ntohs (dhcp->flags)));
|
|
||||||
|
|
||||||
// extra stuff
|
|
||||||
|
|
||||||
if (ip->version_len != 0x45)
|
|
||||||
DEBUGP ((" vl=0x%02x", ip->version_len));
|
|
||||||
if (ntohs (ip->tot_len) != sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen)
|
|
||||||
DEBUGP ((" tl=%d", ntohs (ip->tot_len)));
|
|
||||||
if (ntohs (udp->len) != sizeof (UDPHDR) + sizeof (DHCP) + optlen)
|
|
||||||
DEBUGP ((" ul=%d", ntohs (udp->len)));
|
|
||||||
|
|
||||||
if (ip->tos)
|
|
||||||
DEBUGP ((" tos=0x%02x", ip->tos));
|
|
||||||
if (ntohs (ip->id))
|
|
||||||
DEBUGP ((" id=0x%04x", ntohs (ip->id)));
|
|
||||||
if (ntohs (ip->frag_off))
|
|
||||||
DEBUGP ((" frag_off=0x%04x", ntohs (ip->frag_off)));
|
|
||||||
|
|
||||||
DEBUGP ((" ttl=%d", ip->ttl));
|
|
||||||
DEBUGP ((" ic=0x%04x [0x%04x]", ntohs (ip->check),
|
|
||||||
ip_checksum ((UCHAR*)ip, sizeof (IPHDR))));
|
|
||||||
DEBUGP ((" uc=0x%04x [0x%04x/%d]", ntohs (udp->check),
|
|
||||||
udp_checksum ((UCHAR *) udp,
|
|
||||||
sizeof (UDPHDR) + sizeof (DHCP) + optlen,
|
|
||||||
(UCHAR *) &ip->saddr,
|
|
||||||
(UCHAR *) &ip->daddr),
|
|
||||||
optlen));
|
|
||||||
|
|
||||||
// Options
|
|
||||||
{
|
|
||||||
const UCHAR *opt = (UCHAR *) (dhcp + 1);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
DEBUGP ((" OPT"));
|
|
||||||
for (i = 0; i < optlen; ++i)
|
|
||||||
{
|
|
||||||
const UCHAR data = opt[i];
|
|
||||||
DEBUGP ((".%d", data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* DBG */
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,168 +0,0 @@
|
||||||
/*
|
|
||||||
* TAP-Windows -- A kernel driver to provide virtual tap
|
|
||||||
* device functionality on Windows.
|
|
||||||
*
|
|
||||||
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
|
||||||
*
|
|
||||||
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
|
||||||
* and is released under the GPL version 2 (see below).
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2
|
|
||||||
* as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program (see the file COPYING included with this
|
|
||||||
* distribution); if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
//===================================================
|
|
||||||
// How many bad DHCPREQUESTs do we receive before we
|
|
||||||
// return a NAK?
|
|
||||||
//
|
|
||||||
// A bad DHCPREQUEST is defined to be one where the
|
|
||||||
// requestor doesn't know its IP address.
|
|
||||||
//===================================================
|
|
||||||
|
|
||||||
#define BAD_DHCPREQUEST_NAK_THRESHOLD 3
|
|
||||||
|
|
||||||
//==============================================
|
|
||||||
// Maximum number of DHCP options bytes supplied
|
|
||||||
//==============================================
|
|
||||||
|
|
||||||
#define DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE 256
|
|
||||||
#define DHCP_OPTIONS_BUFFER_SIZE 256
|
|
||||||
|
|
||||||
//===================================
|
|
||||||
// UDP port numbers of DHCP messages.
|
|
||||||
//===================================
|
|
||||||
|
|
||||||
#define BOOTPS_PORT 67
|
|
||||||
#define BOOTPC_PORT 68
|
|
||||||
|
|
||||||
//===========================
|
|
||||||
// The DHCP message structure
|
|
||||||
//===========================
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
# define BOOTREQUEST 1
|
|
||||||
# define BOOTREPLY 2
|
|
||||||
UCHAR op; /* message op */
|
|
||||||
|
|
||||||
UCHAR htype; /* hardware address type (e.g. '1' = 10Mb Ethernet) */
|
|
||||||
UCHAR hlen; /* hardware address length (e.g. '6' for 10Mb Ethernet) */
|
|
||||||
UCHAR hops; /* client sets to 0, may be used by relay agents */
|
|
||||||
ULONG xid; /* transaction ID, chosen by client */
|
|
||||||
USHORT secs; /* seconds since request process began, set by client */
|
|
||||||
USHORT flags;
|
|
||||||
ULONG ciaddr; /* client IP address, client sets if known */
|
|
||||||
ULONG yiaddr; /* 'your' IP address -- server's response to client */
|
|
||||||
ULONG siaddr; /* server IP address */
|
|
||||||
ULONG giaddr; /* relay agent IP address */
|
|
||||||
UCHAR chaddr[16]; /* client hardware address */
|
|
||||||
UCHAR sname[64]; /* optional server host name */
|
|
||||||
UCHAR file[128]; /* boot file name */
|
|
||||||
ULONG magic; /* must be 0x63825363 (network order) */
|
|
||||||
} DHCP;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ETH_HEADER eth;
|
|
||||||
IPHDR ip;
|
|
||||||
UDPHDR udp;
|
|
||||||
DHCP dhcp;
|
|
||||||
} DHCPPre;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DHCPPre pre;
|
|
||||||
UCHAR options[DHCP_OPTIONS_BUFFER_SIZE];
|
|
||||||
} DHCPFull;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned int optlen;
|
|
||||||
BOOLEAN overflow;
|
|
||||||
DHCPFull msg;
|
|
||||||
} DHCPMsg;
|
|
||||||
|
|
||||||
//===================
|
|
||||||
// Macros for DHCPMSG
|
|
||||||
//===================
|
|
||||||
|
|
||||||
#define DHCPMSG_LEN_BASE(p) (sizeof (DHCPPre))
|
|
||||||
#define DHCPMSG_LEN_OPT(p) ((p)->optlen)
|
|
||||||
#define DHCPMSG_LEN_FULL(p) (DHCPMSG_LEN_BASE(p) + DHCPMSG_LEN_OPT(p))
|
|
||||||
#define DHCPMSG_BUF(p) ((UCHAR*) &(p)->msg)
|
|
||||||
#define DHCPMSG_OVERFLOW(p) ((p)->overflow)
|
|
||||||
|
|
||||||
//========================================
|
|
||||||
// structs to hold individual DHCP options
|
|
||||||
//========================================
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
UCHAR type;
|
|
||||||
} DHCPOPT0;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
UCHAR type;
|
|
||||||
UCHAR len;
|
|
||||||
UCHAR data;
|
|
||||||
} DHCPOPT8;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
UCHAR type;
|
|
||||||
UCHAR len;
|
|
||||||
ULONG data;
|
|
||||||
} DHCPOPT32;
|
|
||||||
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
//==================
|
|
||||||
// DHCP Option types
|
|
||||||
//==================
|
|
||||||
|
|
||||||
#define DHCP_MSG_TYPE 53 /* message type (u8) */
|
|
||||||
#define DHCP_PARM_REQ 55 /* parameter request list: c1 (u8), ... */
|
|
||||||
#define DHCP_CLIENT_ID 61 /* client ID: type (u8), i1 (u8), ... */
|
|
||||||
#define DHCP_IP 50 /* requested IP addr (u32) */
|
|
||||||
#define DHCP_NETMASK 1 /* subnet mask (u32) */
|
|
||||||
#define DHCP_LEASE_TIME 51 /* lease time sec (u32) */
|
|
||||||
#define DHCP_RENEW_TIME 58 /* renewal time sec (u32) */
|
|
||||||
#define DHCP_REBIND_TIME 59 /* rebind time sec (u32) */
|
|
||||||
#define DHCP_SERVER_ID 54 /* server ID: IP addr (u32) */
|
|
||||||
#define DHCP_PAD 0
|
|
||||||
#define DHCP_END 255
|
|
||||||
|
|
||||||
//====================
|
|
||||||
// DHCP Messages types
|
|
||||||
//====================
|
|
||||||
|
|
||||||
#define DHCPDISCOVER 1
|
|
||||||
#define DHCPOFFER 2
|
|
||||||
#define DHCPREQUEST 3
|
|
||||||
#define DHCPDECLINE 4
|
|
||||||
#define DHCPACK 5
|
|
||||||
#define DHCPNAK 6
|
|
||||||
#define DHCPRELEASE 7
|
|
||||||
#define DHCPINFORM 8
|
|
||||||
|
|
||||||
#if DBG
|
|
||||||
|
|
||||||
VOID
|
|
||||||
DumpDHCP (const ETH_HEADER *eth,
|
|
||||||
const IPHDR *ip,
|
|
||||||
const UDPHDR *udp,
|
|
||||||
const DHCP *dhcp,
|
|
||||||
const int optlen);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,26 +1,26 @@
|
||||||
/*
|
/*
|
||||||
* TAP-Windows -- A kernel driver to provide virtual tap
|
* TAP-Windows -- A kernel driver to provide virtual tap
|
||||||
* device functionality on Windows.
|
* device functionality on Windows.
|
||||||
*
|
*
|
||||||
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
||||||
*
|
*
|
||||||
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
||||||
* and is released under the GPL version 2 (see below).
|
* and is released under the GPL version 2 (see below).
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2
|
* it under the terms of the GNU General Public License version 2
|
||||||
* as published by the Free Software Foundation.
|
* as published by the Free Software Foundation.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program (see the file COPYING included with this
|
* along with this program (see the file COPYING included with this
|
||||||
* distribution); if not, write to the Free Software Foundation, Inc.,
|
* distribution); if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//-----------------
|
//-----------------
|
||||||
// DEBUGGING OUTPUT
|
// DEBUGGING OUTPUT
|
||||||
|
@ -34,354 +34,354 @@ int g_LastErrorLineNumber;
|
||||||
DebugOutput g_Debug;
|
DebugOutput g_Debug;
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NewlineExists (const char *str, int len)
|
NewlineExists (const char *str, int len)
|
||||||
{
|
{
|
||||||
while (len-- > 0)
|
while (len-- > 0)
|
||||||
{
|
|
||||||
const char c = *str++;
|
|
||||||
if (c == '\n')
|
|
||||||
return TRUE;
|
|
||||||
else if (c == '\0')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
MyDebugInit (unsigned int bufsiz)
|
|
||||||
{
|
|
||||||
NdisZeroMemory (&g_Debug, sizeof (g_Debug));
|
|
||||||
g_Debug.text = (char *) MemAlloc (bufsiz, FALSE);
|
|
||||||
if (g_Debug.text)
|
|
||||||
g_Debug.capacity = bufsiz;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
MyDebugFree ()
|
|
||||||
{
|
|
||||||
if (g_Debug.text)
|
|
||||||
MemFree (g_Debug.text, g_Debug.capacity);
|
|
||||||
NdisZeroMemory (&g_Debug, sizeof (g_Debug));
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
MyDebugPrint (const unsigned char* format, ...)
|
|
||||||
{
|
|
||||||
if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT)
|
|
||||||
{
|
|
||||||
BOOLEAN owned;
|
|
||||||
ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
|
|
||||||
if (owned)
|
|
||||||
{
|
{
|
||||||
const int remaining = (int)g_Debug.capacity - (int)g_Debug.out;
|
const char c = *str++;
|
||||||
|
if (c == '\n')
|
||||||
|
return TRUE;
|
||||||
|
else if (c == '\0')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (remaining > 0)
|
VOID
|
||||||
{
|
MyDebugInit (unsigned int bufsiz)
|
||||||
va_list args;
|
{
|
||||||
NTSTATUS status;
|
NdisZeroMemory (&g_Debug, sizeof (g_Debug));
|
||||||
char *end;
|
g_Debug.text = (char *) MemAlloc (bufsiz, FALSE);
|
||||||
|
if (g_Debug.text)
|
||||||
|
g_Debug.capacity = bufsiz;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MyDebugFree ()
|
||||||
|
{
|
||||||
|
if (g_Debug.text)
|
||||||
|
MemFree (g_Debug.text, g_Debug.capacity);
|
||||||
|
NdisZeroMemory (&g_Debug, sizeof (g_Debug));
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MyDebugPrint (const unsigned char* format, ...)
|
||||||
|
{
|
||||||
|
if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT)
|
||||||
|
{
|
||||||
|
BOOLEAN owned;
|
||||||
|
ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
|
||||||
|
if (owned)
|
||||||
|
{
|
||||||
|
const int remaining = (int)g_Debug.capacity - (int)g_Debug.out;
|
||||||
|
|
||||||
|
if (remaining > 0)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
NTSTATUS status;
|
||||||
|
char *end;
|
||||||
|
|
||||||
#ifdef DBG_PRINT
|
#ifdef DBG_PRINT
|
||||||
va_start (args, format);
|
va_start (args, format);
|
||||||
vDbgPrintEx (DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, format, args);
|
vDbgPrintEx (DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, format, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
#endif
|
#endif
|
||||||
va_start (args, format);
|
va_start (args, format);
|
||||||
status = RtlStringCchVPrintfExA (g_Debug.text + g_Debug.out,
|
status = RtlStringCchVPrintfExA (g_Debug.text + g_Debug.out,
|
||||||
remaining,
|
remaining,
|
||||||
&end,
|
&end,
|
||||||
NULL,
|
NULL,
|
||||||
STRSAFE_NO_TRUNCATION | STRSAFE_IGNORE_NULLS,
|
STRSAFE_NO_TRUNCATION | STRSAFE_IGNORE_NULLS,
|
||||||
format,
|
format,
|
||||||
args);
|
args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
va_start (args, format);
|
va_start (args, format);
|
||||||
vDbgPrintEx(DPFLTR_IHVDRIVER_ID , 1, format, args);
|
vDbgPrintEx(DPFLTR_IHVDRIVER_ID , 1, format, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
g_Debug.out = (unsigned int) (end - g_Debug.text);
|
g_Debug.out = (unsigned int) (end - g_Debug.text);
|
||||||
else
|
else
|
||||||
g_Debug.error = TRUE;
|
g_Debug.error = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g_Debug.error = TRUE;
|
g_Debug.error = TRUE;
|
||||||
|
|
||||||
RELEASE_MUTEX (&g_Debug.lock);
|
RELEASE_MUTEX (&g_Debug.lock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_Debug.error = TRUE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
g_Debug.error = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
GetDebugLine (char *buf, const int len)
|
GetDebugLine (char *buf, const int len)
|
||||||
{
|
{
|
||||||
static const char *truncated = "[OUTPUT TRUNCATED]\n";
|
static const char *truncated = "[OUTPUT TRUNCATED]\n";
|
||||||
BOOLEAN ret = FALSE;
|
BOOLEAN ret = FALSE;
|
||||||
|
|
||||||
NdisZeroMemory (buf, len);
|
NdisZeroMemory (buf, len);
|
||||||
|
|
||||||
if (g_Debug.text && g_Debug.capacity > 0)
|
if (g_Debug.text && g_Debug.capacity > 0)
|
||||||
{
|
|
||||||
BOOLEAN owned;
|
|
||||||
ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
|
|
||||||
if (owned)
|
|
||||||
{
|
{
|
||||||
int i = 0;
|
BOOLEAN owned;
|
||||||
|
ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
|
||||||
if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in))
|
if (owned)
|
||||||
{
|
|
||||||
while (i < (len - 1) && g_Debug.in < g_Debug.out)
|
|
||||||
{
|
{
|
||||||
const char c = g_Debug.text[g_Debug.in++];
|
int i = 0;
|
||||||
if (c == '\n')
|
|
||||||
break;
|
|
||||||
buf[i++] = c;
|
|
||||||
}
|
|
||||||
if (i < len)
|
|
||||||
buf[i] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!i)
|
if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in))
|
||||||
{
|
|
||||||
if (g_Debug.in == g_Debug.out)
|
|
||||||
{
|
|
||||||
g_Debug.in = g_Debug.out = 0;
|
|
||||||
if (g_Debug.error)
|
|
||||||
{
|
|
||||||
const unsigned int tlen = strlen (truncated);
|
|
||||||
if (tlen < g_Debug.capacity)
|
|
||||||
{
|
{
|
||||||
NdisMoveMemory (g_Debug.text, truncated, tlen+1);
|
while (i < (len - 1) && g_Debug.in < g_Debug.out)
|
||||||
g_Debug.out = tlen;
|
{
|
||||||
|
const char c = g_Debug.text[g_Debug.in++];
|
||||||
|
if (c == '\n')
|
||||||
|
break;
|
||||||
|
buf[i++] = c;
|
||||||
|
}
|
||||||
|
if (i < len)
|
||||||
|
buf[i] = '\0';
|
||||||
}
|
}
|
||||||
g_Debug.error = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret = TRUE;
|
|
||||||
|
|
||||||
RELEASE_MUTEX (&g_Debug.lock);
|
if (!i)
|
||||||
}
|
{
|
||||||
}
|
if (g_Debug.in == g_Debug.out)
|
||||||
return ret;
|
{
|
||||||
|
g_Debug.in = g_Debug.out = 0;
|
||||||
|
if (g_Debug.error)
|
||||||
|
{
|
||||||
|
const unsigned int tlen = strlen (truncated);
|
||||||
|
if (tlen < g_Debug.capacity)
|
||||||
|
{
|
||||||
|
NdisMoveMemory (g_Debug.text, truncated, tlen+1);
|
||||||
|
g_Debug.out = tlen;
|
||||||
|
}
|
||||||
|
g_Debug.error = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
|
RELEASE_MUTEX (&g_Debug.lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MyAssert (const unsigned char *file, int line)
|
MyAssert (const unsigned char *file, int line)
|
||||||
{
|
{
|
||||||
DEBUGP (("MYASSERT failed %s/%d\n", file, line));
|
DEBUGP (("MYASSERT failed %s/%d\n", file, line));
|
||||||
KeBugCheckEx (0x0F00BABA,
|
KeBugCheckEx (0x0F00BABA,
|
||||||
(ULONG_PTR) line,
|
(ULONG_PTR) line,
|
||||||
(ULONG_PTR) 0,
|
(ULONG_PTR) 0,
|
||||||
(ULONG_PTR) 0,
|
(ULONG_PTR) 0,
|
||||||
(ULONG_PTR) 0);
|
(ULONG_PTR) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
PrMac (const MACADDR mac)
|
PrMac (const MACADDR mac)
|
||||||
{
|
{
|
||||||
DEBUGP (("%x:%x:%x:%x:%x:%x",
|
DEBUGP (("%x:%x:%x:%x:%x:%x",
|
||||||
mac[0], mac[1], mac[2],
|
mac[0], mac[1], mac[2],
|
||||||
mac[3], mac[4], mac[5]));
|
mac[3], mac[4], mac[5]));
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
PrIP (IPADDR ip_addr)
|
PrIP (IPADDR ip_addr)
|
||||||
{
|
{
|
||||||
const unsigned char *ip = (const unsigned char *) &ip_addr;
|
const unsigned char *ip = (const unsigned char *) &ip_addr;
|
||||||
|
|
||||||
DEBUGP (("%d.%d.%d.%d",
|
DEBUGP (("%d.%d.%d.%d",
|
||||||
ip[0], ip[1], ip[2], ip[3]));
|
ip[0], ip[1], ip[2], ip[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
PrIPProto (int proto)
|
PrIPProto (int proto)
|
||||||
{
|
{
|
||||||
switch (proto)
|
switch (proto)
|
||||||
{
|
{
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
return "UDP";
|
return "UDP";
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
return "TCP";
|
return "TCP";
|
||||||
case IPPROTO_ICMP:
|
case IPPROTO_ICMP:
|
||||||
return "ICMP";
|
return "ICMP";
|
||||||
case IPPROTO_IGMP:
|
case IPPROTO_IGMP:
|
||||||
return "IGMP";
|
return "IGMP";
|
||||||
default:
|
default:
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
DumpARP (const char *prefix, const ARP_PACKET *arp)
|
DumpARP (const char *prefix, const ARP_PACKET *arp)
|
||||||
{
|
{
|
||||||
DEBUGP (("%s ARP src=", prefix));
|
DEBUGP (("%s ARP src=", prefix));
|
||||||
PrMac (arp->m_MAC_Source);
|
PrMac (arp->m_MAC_Source);
|
||||||
DEBUGP ((" dest="));
|
DEBUGP ((" dest="));
|
||||||
PrMac (arp->m_MAC_Destination);
|
PrMac (arp->m_MAC_Destination);
|
||||||
DEBUGP ((" OP=0x%04x",
|
DEBUGP ((" OP=0x%04x",
|
||||||
(int)ntohs(arp->m_ARP_Operation)));
|
(int)ntohs(arp->m_ARP_Operation)));
|
||||||
DEBUGP ((" M=0x%04x(%d)",
|
DEBUGP ((" M=0x%04x(%d)",
|
||||||
(int)ntohs(arp->m_MAC_AddressType),
|
(int)ntohs(arp->m_MAC_AddressType),
|
||||||
(int)arp->m_MAC_AddressSize));
|
(int)arp->m_MAC_AddressSize));
|
||||||
DEBUGP ((" P=0x%04x(%d)",
|
DEBUGP ((" P=0x%04x(%d)",
|
||||||
(int)ntohs(arp->m_PROTO_AddressType),
|
(int)ntohs(arp->m_PROTO_AddressType),
|
||||||
(int)arp->m_PROTO_AddressSize));
|
(int)arp->m_PROTO_AddressSize));
|
||||||
|
|
||||||
DEBUGP ((" MacSrc="));
|
DEBUGP ((" MacSrc="));
|
||||||
PrMac (arp->m_ARP_MAC_Source);
|
PrMac (arp->m_ARP_MAC_Source);
|
||||||
DEBUGP ((" MacDest="));
|
DEBUGP ((" MacDest="));
|
||||||
PrMac (arp->m_ARP_MAC_Destination);
|
PrMac (arp->m_ARP_MAC_Destination);
|
||||||
|
|
||||||
DEBUGP ((" IPSrc="));
|
DEBUGP ((" IPSrc="));
|
||||||
PrIP (arp->m_ARP_IP_Source);
|
PrIP (arp->m_ARP_IP_Source);
|
||||||
DEBUGP ((" IPDest="));
|
DEBUGP ((" IPDest="));
|
||||||
PrIP (arp->m_ARP_IP_Destination);
|
PrIP (arp->m_ARP_IP_Destination);
|
||||||
|
|
||||||
DEBUGP (("\n"));
|
DEBUGP (("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ethpayload {
|
struct ethpayload {
|
||||||
ETH_HEADER eth;
|
ETH_HEADER eth;
|
||||||
UCHAR payload[DEFAULT_PACKET_LOOKAHEAD];
|
UCHAR payload[DEFAULT_PACKET_LOOKAHEAD];
|
||||||
};
|
};
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
DumpPacket2 (const char *prefix,
|
DumpPacket2 (const char *prefix,
|
||||||
const ETH_HEADER *eth,
|
const ETH_HEADER *eth,
|
||||||
const unsigned char *data,
|
const unsigned char *data,
|
||||||
unsigned int len)
|
unsigned int len)
|
||||||
{
|
{
|
||||||
struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE);
|
struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE);
|
||||||
if (ep)
|
if (ep)
|
||||||
{
|
{
|
||||||
if (len > DEFAULT_PACKET_LOOKAHEAD)
|
if (len > DEFAULT_PACKET_LOOKAHEAD)
|
||||||
len = DEFAULT_PACKET_LOOKAHEAD;
|
len = DEFAULT_PACKET_LOOKAHEAD;
|
||||||
ep->eth = *eth;
|
ep->eth = *eth;
|
||||||
NdisMoveMemory (ep->payload, data, len);
|
NdisMoveMemory (ep->payload, data, len);
|
||||||
DumpPacket (prefix, (unsigned char *) ep, sizeof (ETH_HEADER) + len);
|
DumpPacket (prefix, (unsigned char *) ep, sizeof (ETH_HEADER) + len);
|
||||||
MemFree (ep, sizeof (struct ethpayload));
|
MemFree (ep, sizeof (struct ethpayload));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
DumpPacket (const char *prefix,
|
DumpPacket (const char *prefix,
|
||||||
const unsigned char *data,
|
const unsigned char *data,
|
||||||
unsigned int len)
|
unsigned int len)
|
||||||
{
|
{
|
||||||
const ETH_HEADER *eth = (const ETH_HEADER *) data;
|
const ETH_HEADER *eth = (const ETH_HEADER *) data;
|
||||||
const IPHDR *ip = (const IPHDR *) (data + sizeof (ETH_HEADER));
|
const IPHDR *ip = (const IPHDR *) (data + sizeof (ETH_HEADER));
|
||||||
|
|
||||||
if (len < sizeof (ETH_HEADER))
|
if (len < sizeof (ETH_HEADER))
|
||||||
{
|
|
||||||
DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix, len));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ARP Packet?
|
|
||||||
if (len >= sizeof (ARP_PACKET) && eth->proto == htons (ETH_P_ARP))
|
|
||||||
{
|
|
||||||
DumpARP (prefix, (const ARP_PACKET *) data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// IPv4 packet?
|
|
||||||
if (len >= (sizeof (IPHDR) + sizeof (ETH_HEADER))
|
|
||||||
&& eth->proto == htons (ETH_P_IP)
|
|
||||||
&& IPH_GET_VER (ip->version_len) == 4)
|
|
||||||
{
|
|
||||||
const int hlen = IPH_GET_LEN (ip->version_len);
|
|
||||||
const int blen = len - sizeof (ETH_HEADER);
|
|
||||||
BOOLEAN did = FALSE;
|
|
||||||
|
|
||||||
DEBUGP (("%s IPv4 %s[%d]", prefix, PrIPProto (ip->protocol), len));
|
|
||||||
|
|
||||||
if (!(ntohs (ip->tot_len) == blen && hlen <= blen))
|
|
||||||
{
|
{
|
||||||
DEBUGP ((" XXX"));
|
DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix, len));
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// TCP packet?
|
|
||||||
if (ip->protocol == IPPROTO_TCP
|
|
||||||
&& blen - hlen >= (sizeof (TCPHDR)))
|
|
||||||
{
|
|
||||||
const TCPHDR *tcp = (TCPHDR *) (data + sizeof (ETH_HEADER) + hlen);
|
|
||||||
DEBUGP ((" "));
|
|
||||||
PrIP (ip->saddr);
|
|
||||||
DEBUGP ((":%d", ntohs (tcp->source)));
|
|
||||||
DEBUGP ((" -> "));
|
|
||||||
PrIP (ip->daddr);
|
|
||||||
DEBUGP ((":%d", ntohs (tcp->dest)));
|
|
||||||
did = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDP packet?
|
// ARP Packet?
|
||||||
else if ((ntohs (ip->frag_off) & IP_OFFMASK) == 0
|
if (len >= sizeof (ARP_PACKET) && eth->proto == htons (ETH_P_ARP))
|
||||||
&& ip->protocol == IPPROTO_UDP
|
|
||||||
&& blen - hlen >= (sizeof (UDPHDR)))
|
|
||||||
{
|
{
|
||||||
const UDPHDR *udp = (UDPHDR *) (data + sizeof (ETH_HEADER) + hlen);
|
DumpARP (prefix, (const ARP_PACKET *) data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv4 packet?
|
||||||
|
if (len >= (sizeof (IPHDR) + sizeof (ETH_HEADER))
|
||||||
|
&& eth->proto == htons (ETH_P_IP)
|
||||||
|
&& IPH_GET_VER (ip->version_len) == 4)
|
||||||
|
{
|
||||||
|
const int hlen = IPH_GET_LEN (ip->version_len);
|
||||||
|
const int blen = len - sizeof (ETH_HEADER);
|
||||||
|
BOOLEAN did = FALSE;
|
||||||
|
|
||||||
|
DEBUGP (("%s IPv4 %s[%d]", prefix, PrIPProto (ip->protocol), len));
|
||||||
|
|
||||||
|
if (!(ntohs (ip->tot_len) == blen && hlen <= blen))
|
||||||
|
{
|
||||||
|
DEBUGP ((" XXX"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TCP packet?
|
||||||
|
if (ip->protocol == IPPROTO_TCP
|
||||||
|
&& blen - hlen >= (sizeof (TCPHDR)))
|
||||||
|
{
|
||||||
|
const TCPHDR *tcp = (TCPHDR *) (data + sizeof (ETH_HEADER) + hlen);
|
||||||
|
DEBUGP ((" "));
|
||||||
|
PrIP (ip->saddr);
|
||||||
|
DEBUGP ((":%d", ntohs (tcp->source)));
|
||||||
|
DEBUGP ((" -> "));
|
||||||
|
PrIP (ip->daddr);
|
||||||
|
DEBUGP ((":%d", ntohs (tcp->dest)));
|
||||||
|
did = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UDP packet?
|
||||||
|
else if ((ntohs (ip->frag_off) & IP_OFFMASK) == 0
|
||||||
|
&& ip->protocol == IPPROTO_UDP
|
||||||
|
&& blen - hlen >= (sizeof (UDPHDR)))
|
||||||
|
{
|
||||||
|
const UDPHDR *udp = (UDPHDR *) (data + sizeof (ETH_HEADER) + hlen);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// DHCP packet?
|
// DHCP packet?
|
||||||
if ((udp->dest == htons (BOOTPC_PORT) || udp->dest == htons (BOOTPS_PORT))
|
if ((udp->dest == htons (BOOTPC_PORT) || udp->dest == htons (BOOTPS_PORT))
|
||||||
&& blen - hlen >= (sizeof (UDPHDR) + sizeof (DHCP)))
|
&& blen - hlen >= (sizeof (UDPHDR) + sizeof (DHCP)))
|
||||||
{
|
{
|
||||||
const DHCP *dhcp = (DHCP *) (data
|
const DHCP *dhcp = (DHCP *) (data
|
||||||
+ hlen
|
+ hlen
|
||||||
+ sizeof (ETH_HEADER)
|
+ sizeof (ETH_HEADER)
|
||||||
+ sizeof (UDPHDR));
|
+ sizeof (UDPHDR));
|
||||||
|
|
||||||
int optlen = len
|
|
||||||
- sizeof (ETH_HEADER)
|
|
||||||
- hlen
|
|
||||||
- sizeof (UDPHDR)
|
|
||||||
- sizeof (DHCP);
|
|
||||||
|
|
||||||
if (optlen < 0)
|
int optlen = len
|
||||||
optlen = 0;
|
- sizeof (ETH_HEADER)
|
||||||
|
- hlen
|
||||||
|
- sizeof (UDPHDR)
|
||||||
|
- sizeof (DHCP);
|
||||||
|
|
||||||
DumpDHCP (eth, ip, udp, dhcp, optlen);
|
if (optlen < 0)
|
||||||
did = TRUE;
|
optlen = 0;
|
||||||
}
|
|
||||||
|
DumpDHCP (eth, ip, udp, dhcp, optlen);
|
||||||
|
did = TRUE;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!did)
|
if (!did)
|
||||||
{
|
{
|
||||||
DEBUGP ((" "));
|
DEBUGP ((" "));
|
||||||
PrIP (ip->saddr);
|
PrIP (ip->saddr);
|
||||||
DEBUGP ((":%d", ntohs (udp->source)));
|
DEBUGP ((":%d", ntohs (udp->source)));
|
||||||
DEBUGP ((" -> "));
|
DEBUGP ((" -> "));
|
||||||
PrIP (ip->daddr);
|
PrIP (ip->daddr);
|
||||||
DEBUGP ((":%d", ntohs (udp->dest)));
|
DEBUGP ((":%d", ntohs (udp->dest)));
|
||||||
did = TRUE;
|
did = TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!did)
|
||||||
|
{
|
||||||
|
DEBUGP ((" ipproto=%d ", ip->protocol));
|
||||||
|
PrIP (ip->saddr);
|
||||||
|
DEBUGP ((" -> "));
|
||||||
|
PrIP (ip->daddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGP (("\n"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!did)
|
|
||||||
{
|
{
|
||||||
DEBUGP ((" ipproto=%d ", ip->protocol));
|
DEBUGP (("%s ??? src=", prefix));
|
||||||
PrIP (ip->saddr);
|
PrMac (eth->src);
|
||||||
DEBUGP ((" -> "));
|
DEBUGP ((" dest="));
|
||||||
PrIP (ip->daddr);
|
PrMac (eth->dest);
|
||||||
|
DEBUGP ((" proto=0x%04x len=%d\n",
|
||||||
|
(int) ntohs(eth->proto),
|
||||||
|
len));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGP (("\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
DEBUGP (("%s ??? src=", prefix));
|
|
||||||
PrMac (eth->src);
|
|
||||||
DEBUGP ((" dest="));
|
|
||||||
PrMac (eth->dest);
|
|
||||||
DEBUGP ((" proto=0x%04x len=%d\n",
|
|
||||||
(int) ntohs(eth->proto),
|
|
||||||
len));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,241 +1,241 @@
|
||||||
/*
|
/*
|
||||||
* TAP-Windows -- A kernel driver to provide virtual tap
|
* TAP-Windows -- A kernel driver to provide virtual tap
|
||||||
* device functionality on Windows.
|
* device functionality on Windows.
|
||||||
*
|
*
|
||||||
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
||||||
*
|
*
|
||||||
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
||||||
* and is released under the GPL version 2 (see below).
|
* and is released under the GPL version 2 (see below).
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2
|
* it under the terms of the GNU General Public License version 2
|
||||||
* as published by the Free Software Foundation.
|
* as published by the Free Software Foundation.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program (see the file COPYING included with this
|
* along with this program (see the file COPYING included with this
|
||||||
* distribution); if not, write to the Free Software Foundation, Inc.,
|
* distribution); if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INSTANCE_KEY(a) ((PVOID)((a)->m_Extension.m_TapDevice))
|
#define INSTANCE_KEY(a) ((PVOID)((a)->m_Extension.m_TapDevice))
|
||||||
|
|
||||||
#define N_INSTANCE_BUCKETS 256
|
#define N_INSTANCE_BUCKETS 256
|
||||||
|
|
||||||
typedef struct _INSTANCE {
|
typedef struct _INSTANCE {
|
||||||
struct _INSTANCE *next;
|
struct _INSTANCE *next;
|
||||||
TapAdapterPointer m_Adapter;
|
TapAdapterPointer m_Adapter;
|
||||||
} INSTANCE;
|
} INSTANCE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
INSTANCE *list;
|
INSTANCE *list;
|
||||||
MUTEX lock;
|
MUTEX lock;
|
||||||
} INSTANCE_BUCKET;
|
} INSTANCE_BUCKET;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
INSTANCE_BUCKET buckets[N_INSTANCE_BUCKETS];
|
INSTANCE_BUCKET buckets[N_INSTANCE_BUCKETS];
|
||||||
} INSTANCE_HASH;
|
} INSTANCE_HASH;
|
||||||
|
|
||||||
INSTANCE_HASH *g_InstanceHash = NULL;
|
INSTANCE_HASH *g_InstanceHash = NULL;
|
||||||
|
|
||||||
// must return a hash >= 0 and < N_INSTANCE_BUCKETS
|
// must return a hash >= 0 and < N_INSTANCE_BUCKETS
|
||||||
int
|
int
|
||||||
InstanceHashValue (PVOID addr)
|
InstanceHashValue (PVOID addr)
|
||||||
{
|
{
|
||||||
UCHAR *p = (UCHAR *) &addr;
|
UCHAR *p = (UCHAR *) &addr;
|
||||||
|
|
||||||
if (sizeof (addr) == 4)
|
if (sizeof (addr) == 4)
|
||||||
return p[0] ^ p[1] ^ p[2] ^ p[3];
|
return p[0] ^ p[1] ^ p[2] ^ p[3];
|
||||||
else if (sizeof (addr) == 8)
|
else if (sizeof (addr) == 8)
|
||||||
return p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4] ^ p[5] ^ p[6] ^ p[7];
|
return p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4] ^ p[5] ^ p[6] ^ p[7];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MYASSERT (0);
|
MYASSERT (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
InitInstanceList (VOID)
|
InitInstanceList (VOID)
|
||||||
{
|
{
|
||||||
MYASSERT (g_InstanceHash == NULL);
|
MYASSERT (g_InstanceHash == NULL);
|
||||||
g_InstanceHash = MemAlloc (sizeof (INSTANCE_HASH), TRUE);
|
g_InstanceHash = MemAlloc (sizeof (INSTANCE_HASH), TRUE);
|
||||||
if (g_InstanceHash)
|
if (g_InstanceHash)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < N_INSTANCE_BUCKETS; ++i)
|
for (i = 0; i < N_INSTANCE_BUCKETS; ++i)
|
||||||
INIT_MUTEX (&g_InstanceHash->buckets[i].lock);
|
INIT_MUTEX (&g_InstanceHash->buckets[i].lock);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
NInstances (VOID)
|
NInstances (VOID)
|
||||||
{
|
{
|
||||||
int i, n = 0;
|
int i, n = 0;
|
||||||
|
|
||||||
if (g_InstanceHash)
|
if (g_InstanceHash)
|
||||||
{
|
|
||||||
for (i = 0; i < N_INSTANCE_BUCKETS; ++i)
|
|
||||||
{
|
{
|
||||||
BOOLEAN got_lock;
|
for (i = 0; i < N_INSTANCE_BUCKETS; ++i)
|
||||||
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i];
|
{
|
||||||
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
|
BOOLEAN got_lock;
|
||||||
|
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i];
|
||||||
|
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
|
||||||
|
|
||||||
if (got_lock)
|
if (got_lock)
|
||||||
{
|
{
|
||||||
INSTANCE *current;
|
INSTANCE *current;
|
||||||
for (current = ib->list; current != NULL; current = current->next)
|
for (current = ib->list; current != NULL; current = current->next)
|
||||||
++n;
|
++n;
|
||||||
RELEASE_MUTEX (&ib->lock);
|
RELEASE_MUTEX (&ib->lock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
InstanceMaxBucketSize (VOID)
|
InstanceMaxBucketSize (VOID)
|
||||||
{
|
{
|
||||||
int i, n = 0;
|
int i, n = 0;
|
||||||
|
|
||||||
if (g_InstanceHash)
|
if (g_InstanceHash)
|
||||||
{
|
|
||||||
for (i = 0; i < N_INSTANCE_BUCKETS; ++i)
|
|
||||||
{
|
{
|
||||||
BOOLEAN got_lock;
|
for (i = 0; i < N_INSTANCE_BUCKETS; ++i)
|
||||||
int bucket_size = 0;
|
{
|
||||||
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i];
|
BOOLEAN got_lock;
|
||||||
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
|
int bucket_size = 0;
|
||||||
|
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i];
|
||||||
|
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
|
||||||
|
|
||||||
if (got_lock)
|
if (got_lock)
|
||||||
{
|
{
|
||||||
INSTANCE *current;
|
INSTANCE *current;
|
||||||
for (current = ib->list; current != NULL; current = current->next)
|
for (current = ib->list; current != NULL; current = current->next)
|
||||||
++bucket_size;
|
++bucket_size;
|
||||||
if (bucket_size > n)
|
if (bucket_size > n)
|
||||||
n = bucket_size;
|
n = bucket_size;
|
||||||
RELEASE_MUTEX (&ib->lock);
|
RELEASE_MUTEX (&ib->lock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FreeInstanceList (VOID)
|
FreeInstanceList (VOID)
|
||||||
{
|
{
|
||||||
if (g_InstanceHash)
|
if (g_InstanceHash)
|
||||||
{
|
{
|
||||||
MYASSERT (NInstances() == 0);
|
MYASSERT (NInstances() == 0);
|
||||||
MemFree (g_InstanceHash, sizeof (INSTANCE_HASH));
|
MemFree (g_InstanceHash, sizeof (INSTANCE_HASH));
|
||||||
g_InstanceHash = NULL;
|
g_InstanceHash = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
AddAdapterToInstanceList (TapAdapterPointer p_Adapter)
|
AddAdapterToInstanceList (TapAdapterPointer p_Adapter)
|
||||||
{
|
{
|
||||||
BOOLEAN got_lock;
|
BOOLEAN got_lock;
|
||||||
BOOLEAN ret = FALSE;
|
BOOLEAN ret = FALSE;
|
||||||
const int hash = InstanceHashValue(INSTANCE_KEY(p_Adapter));
|
const int hash = InstanceHashValue(INSTANCE_KEY(p_Adapter));
|
||||||
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[hash];
|
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[hash];
|
||||||
|
|
||||||
DEBUGP (("[TAP] AddAdapterToInstanceList hash=%d\n", hash));
|
DEBUGP (("[TAP] AddAdapterToInstanceList hash=%d\n", hash));
|
||||||
|
|
||||||
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
|
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
|
||||||
|
|
||||||
if (got_lock)
|
if (got_lock)
|
||||||
{
|
|
||||||
INSTANCE *i = MemAlloc (sizeof (INSTANCE), FALSE);
|
|
||||||
if (i)
|
|
||||||
{
|
{
|
||||||
MYASSERT (p_Adapter);
|
INSTANCE *i = MemAlloc (sizeof (INSTANCE), FALSE);
|
||||||
i->m_Adapter = p_Adapter;
|
if (i)
|
||||||
i->next = ib->list;
|
{
|
||||||
ib->list = i;
|
MYASSERT (p_Adapter);
|
||||||
ret = TRUE;
|
i->m_Adapter = p_Adapter;
|
||||||
|
i->next = ib->list;
|
||||||
|
ib->list = i;
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
RELEASE_MUTEX (&ib->lock);
|
||||||
}
|
}
|
||||||
RELEASE_MUTEX (&ib->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
RemoveAdapterFromInstanceList (TapAdapterPointer p_Adapter)
|
RemoveAdapterFromInstanceList (TapAdapterPointer p_Adapter)
|
||||||
{
|
{
|
||||||
BOOLEAN got_lock;
|
BOOLEAN got_lock;
|
||||||
BOOLEAN ret = FALSE;
|
BOOLEAN ret = FALSE;
|
||||||
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue(INSTANCE_KEY(p_Adapter))];
|
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue(INSTANCE_KEY(p_Adapter))];
|
||||||
|
|
||||||
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
|
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
|
||||||
|
|
||||||
if (got_lock)
|
if (got_lock)
|
||||||
{
|
|
||||||
INSTANCE *current, *prev=NULL;
|
|
||||||
for (current = ib->list; current != NULL; current = current->next)
|
|
||||||
{
|
{
|
||||||
if (current->m_Adapter == p_Adapter) // found match
|
INSTANCE *current, *prev=NULL;
|
||||||
{
|
for (current = ib->list; current != NULL; current = current->next)
|
||||||
if (prev)
|
{
|
||||||
prev->next = current->next;
|
if (current->m_Adapter == p_Adapter) // found match
|
||||||
else
|
{
|
||||||
ib->list = current->next;
|
if (prev)
|
||||||
MemFree (current->m_Adapter, sizeof (TapAdapter));
|
prev->next = current->next;
|
||||||
MemFree (current, sizeof (INSTANCE));
|
else
|
||||||
ret = TRUE;
|
ib->list = current->next;
|
||||||
break;
|
MemFree (current->m_Adapter, sizeof (TapAdapter));
|
||||||
}
|
MemFree (current, sizeof (INSTANCE));
|
||||||
prev = current;
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev = current;
|
||||||
|
}
|
||||||
|
RELEASE_MUTEX (&ib->lock);
|
||||||
}
|
}
|
||||||
RELEASE_MUTEX (&ib->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
TapAdapterPointer
|
TapAdapterPointer
|
||||||
LookupAdapterInInstanceList (PDEVICE_OBJECT p_DeviceObject)
|
LookupAdapterInInstanceList (PDEVICE_OBJECT p_DeviceObject)
|
||||||
{
|
{
|
||||||
BOOLEAN got_lock;
|
BOOLEAN got_lock;
|
||||||
TapAdapterPointer ret = NULL;
|
TapAdapterPointer ret = NULL;
|
||||||
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue((PVOID)p_DeviceObject)];
|
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue((PVOID)p_DeviceObject)];
|
||||||
|
|
||||||
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
|
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
|
||||||
|
|
||||||
if (got_lock)
|
if (got_lock)
|
||||||
{
|
|
||||||
INSTANCE *current, *prev=NULL;
|
|
||||||
for (current = ib->list; current != NULL; current = current->next)
|
|
||||||
{
|
{
|
||||||
if (p_DeviceObject == INSTANCE_KEY (current->m_Adapter)) // found match
|
INSTANCE *current, *prev=NULL;
|
||||||
{
|
for (current = ib->list; current != NULL; current = current->next)
|
||||||
// move it to head of list
|
|
||||||
if (prev)
|
|
||||||
{
|
{
|
||||||
prev->next = current->next;
|
if (p_DeviceObject == INSTANCE_KEY (current->m_Adapter)) // found match
|
||||||
current->next = ib->list;
|
{
|
||||||
ib->list = current;
|
// move it to head of list
|
||||||
|
if (prev)
|
||||||
|
{
|
||||||
|
prev->next = current->next;
|
||||||
|
current->next = ib->list;
|
||||||
|
ib->list = current;
|
||||||
|
}
|
||||||
|
ret = ib->list->m_Adapter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev = current;
|
||||||
}
|
}
|
||||||
ret = ib->list->m_Adapter;
|
RELEASE_MUTEX (&ib->lock);
|
||||||
break;
|
|
||||||
}
|
|
||||||
prev = current;
|
|
||||||
}
|
}
|
||||||
RELEASE_MUTEX (&ib->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,154 +1,154 @@
|
||||||
/*
|
/*
|
||||||
* TAP-Windows -- A kernel driver to provide virtual tap
|
* TAP-Windows -- A kernel driver to provide virtual tap
|
||||||
* device functionality on Windows.
|
* device functionality on Windows.
|
||||||
*
|
*
|
||||||
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
||||||
*
|
*
|
||||||
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
||||||
* and is released under the GPL version 2 (see below).
|
* and is released under the GPL version 2 (see below).
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2
|
* it under the terms of the GNU General Public License version 2
|
||||||
* as published by the Free Software Foundation.
|
* as published by the Free Software Foundation.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program (see the file COPYING included with this
|
* along with this program (see the file COPYING included with this
|
||||||
* distribution); if not, write to the Free Software Foundation, Inc.,
|
* distribution); if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "macinfo.h"
|
#include "macinfo.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
HexStringToDecimalInt (const int p_Character)
|
HexStringToDecimalInt (const int p_Character)
|
||||||
{
|
{
|
||||||
int l_Value = 0;
|
int l_Value = 0;
|
||||||
|
|
||||||
if (p_Character >= 'A' && p_Character <= 'F')
|
if (p_Character >= 'A' && p_Character <= 'F')
|
||||||
l_Value = (p_Character - 'A') + 10;
|
l_Value = (p_Character - 'A') + 10;
|
||||||
else if (p_Character >= 'a' && p_Character <= 'f')
|
else if (p_Character >= 'a' && p_Character <= 'f')
|
||||||
l_Value = (p_Character - 'a') + 10;
|
l_Value = (p_Character - 'a') + 10;
|
||||||
else if (p_Character >= '0' && p_Character <= '9')
|
else if (p_Character >= '0' && p_Character <= '9')
|
||||||
l_Value = p_Character - '0';
|
l_Value = p_Character - '0';
|
||||||
|
|
||||||
return l_Value;
|
return l_Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
ParseMAC (MACADDR dest, const char *src)
|
ParseMAC (MACADDR dest, const char *src)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int mac_index = 0;
|
int mac_index = 0;
|
||||||
BOOLEAN high_digit = FALSE;
|
BOOLEAN high_digit = FALSE;
|
||||||
int delim_action = 1;
|
int delim_action = 1;
|
||||||
|
|
||||||
MYASSERT (src);
|
MYASSERT (src);
|
||||||
MYASSERT (dest);
|
MYASSERT (dest);
|
||||||
|
|
||||||
CLEAR_MAC (dest);
|
CLEAR_MAC (dest);
|
||||||
|
|
||||||
while (c = *src++)
|
while (c = *src++)
|
||||||
{
|
|
||||||
if (IsMacDelimiter (c))
|
|
||||||
{
|
{
|
||||||
mac_index += delim_action;
|
if (IsMacDelimiter (c))
|
||||||
high_digit = FALSE;
|
|
||||||
delim_action = 1;
|
|
||||||
}
|
|
||||||
else if (IsHexDigit (c))
|
|
||||||
{
|
|
||||||
const int digit = HexStringToDecimalInt (c);
|
|
||||||
if (mac_index < sizeof (MACADDR))
|
|
||||||
{
|
|
||||||
if (!high_digit)
|
|
||||||
{
|
{
|
||||||
dest[mac_index] = (char)(digit);
|
mac_index += delim_action;
|
||||||
high_digit = TRUE;
|
high_digit = FALSE;
|
||||||
delim_action = 1;
|
delim_action = 1;
|
||||||
}
|
}
|
||||||
else
|
else if (IsHexDigit (c))
|
||||||
{
|
{
|
||||||
dest[mac_index] = (char)(dest[mac_index] * 16 + digit);
|
const int digit = HexStringToDecimalInt (c);
|
||||||
++mac_index;
|
if (mac_index < sizeof (MACADDR))
|
||||||
high_digit = FALSE;
|
{
|
||||||
delim_action = 0;
|
if (!high_digit)
|
||||||
|
{
|
||||||
|
dest[mac_index] = (char)(digit);
|
||||||
|
high_digit = TRUE;
|
||||||
|
delim_action = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dest[mac_index] = (char)(dest[mac_index] * 16 + digit);
|
||||||
|
++mac_index;
|
||||||
|
high_digit = FALSE;
|
||||||
|
delim_action = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
return FALSE;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (mac_index + delim_action) >= sizeof (MACADDR);
|
return (mac_index + delim_action) >= sizeof (MACADDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate a MAC using the GUID in the adapter name.
|
* Generate a MAC using the GUID in the adapter name.
|
||||||
*
|
*
|
||||||
* The mac is constructed as 00:FF:xx:xx:xx:xx where
|
* The mac is constructed as 00:FF:xx:xx:xx:xx where
|
||||||
* the Xs are taken from the first 32 bits of the GUID in the
|
* the Xs are taken from the first 32 bits of the GUID in the
|
||||||
* adapter name. This is similar to the Linux 2.4 tap MAC
|
* adapter name. This is similar to the Linux 2.4 tap MAC
|
||||||
* generator, except linux uses 32 random bits for the Xs.
|
* generator, except linux uses 32 random bits for the Xs.
|
||||||
*
|
*
|
||||||
* In general, this solution is reasonable for most
|
* In general, this solution is reasonable for most
|
||||||
* applications except for very large bridged TAP networks,
|
* applications except for very large bridged TAP networks,
|
||||||
* where the probability of address collisions becomes more
|
* where the probability of address collisions becomes more
|
||||||
* than infintesimal.
|
* than infintesimal.
|
||||||
*
|
*
|
||||||
* Using the well-known "birthday paradox", on a 1000 node
|
* Using the well-known "birthday paradox", on a 1000 node
|
||||||
* network the probability of collision would be
|
* network the probability of collision would be
|
||||||
* 0.000116292153. On a 10,000 node network, the probability
|
* 0.000116292153. On a 10,000 node network, the probability
|
||||||
* of collision would be 0.01157288998621678766.
|
* of collision would be 0.01157288998621678766.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
VOID GenerateRandomMac (MACADDR mac, const unsigned char *adapter_name)
|
VOID GenerateRandomMac (MACADDR mac, const unsigned char *adapter_name)
|
||||||
{
|
{
|
||||||
unsigned const char *cp = adapter_name;
|
unsigned const char *cp = adapter_name;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
unsigned int i = 2;
|
unsigned int i = 2;
|
||||||
unsigned int byte = 0;
|
unsigned int byte = 0;
|
||||||
int brace = 0;
|
int brace = 0;
|
||||||
int state = 0;
|
int state = 0;
|
||||||
|
|
||||||
CLEAR_MAC (mac);
|
CLEAR_MAC (mac);
|
||||||
|
|
||||||
mac[0] = 0x00;
|
mac[0] = 0x00;
|
||||||
mac[1] = 0xFF;
|
mac[1] = 0xFF;
|
||||||
|
|
||||||
while (c = *cp++)
|
while (c = *cp++)
|
||||||
{
|
|
||||||
if (i >= sizeof (MACADDR))
|
|
||||||
break;
|
|
||||||
if (c == '{')
|
|
||||||
brace = 1;
|
|
||||||
if (IsHexDigit (c) && brace)
|
|
||||||
{
|
{
|
||||||
const unsigned int digit = HexStringToDecimalInt (c);
|
if (i >= sizeof (MACADDR))
|
||||||
if (state)
|
break;
|
||||||
{
|
if (c == '{')
|
||||||
byte <<= 4;
|
brace = 1;
|
||||||
byte |= digit;
|
if (IsHexDigit (c) && brace)
|
||||||
mac[i++] = (unsigned char) byte;
|
{
|
||||||
state = 0;
|
const unsigned int digit = HexStringToDecimalInt (c);
|
||||||
}
|
if (state)
|
||||||
else
|
{
|
||||||
{
|
byte <<= 4;
|
||||||
byte = digit;
|
byte |= digit;
|
||||||
state = 1;
|
mac[i++] = (unsigned char) byte;
|
||||||
}
|
state = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte = digit;
|
||||||
|
state = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID GenerateRelatedMAC (MACADDR dest, const MACADDR src, const int delta)
|
VOID GenerateRelatedMAC (MACADDR dest, const MACADDR src, const int delta)
|
||||||
{
|
{
|
||||||
COPY_MAC (dest, src);
|
COPY_MAC (dest, src);
|
||||||
dest[2] += (UCHAR) delta;
|
dest[2] += (UCHAR) delta;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,183 +1,183 @@
|
||||||
/*
|
/*
|
||||||
* TAP-Windows -- A kernel driver to provide virtual tap
|
* TAP-Windows -- A kernel driver to provide virtual tap
|
||||||
* device functionality on Windows.
|
* device functionality on Windows.
|
||||||
*
|
*
|
||||||
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
||||||
*
|
*
|
||||||
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
||||||
* and is released under the GPL version 2 (see below).
|
* and is released under the GPL version 2 (see below).
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2
|
* it under the terms of the GNU General Public License version 2
|
||||||
* as published by the Free Software Foundation.
|
* as published by the Free Software Foundation.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program (see the file COPYING included with this
|
* along with this program (see the file COPYING included with this
|
||||||
* distribution); if not, write to the Free Software Foundation, Inc.,
|
* distribution); if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//------------------
|
//------------------
|
||||||
// Memory Management
|
// Memory Management
|
||||||
//------------------
|
//------------------
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
MemAlloc (ULONG p_Size, BOOLEAN zero)
|
MemAlloc (ULONG p_Size, BOOLEAN zero)
|
||||||
{
|
{
|
||||||
PVOID l_Return = NULL;
|
PVOID l_Return = NULL;
|
||||||
|
|
||||||
if (p_Size)
|
if (p_Size)
|
||||||
{
|
{
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
if (NdisAllocateMemoryWithTag (&l_Return, p_Size, 'APAT')
|
if (NdisAllocateMemoryWithTag (&l_Return, p_Size, 'APAT')
|
||||||
== NDIS_STATUS_SUCCESS)
|
== NDIS_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
if (zero)
|
if (zero)
|
||||||
NdisZeroMemory (l_Return, p_Size);
|
NdisZeroMemory (l_Return, p_Size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
l_Return = NULL;
|
l_Return = NULL;
|
||||||
}
|
}
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
l_Return = NULL;
|
l_Return = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return l_Return;
|
return l_Return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MemFree (PVOID p_Addr, ULONG p_Size)
|
MemFree (PVOID p_Addr, ULONG p_Size)
|
||||||
{
|
{
|
||||||
if (p_Addr && p_Size)
|
if (p_Addr && p_Size)
|
||||||
{
|
{
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
#if DBG
|
#if DBG
|
||||||
NdisZeroMemory (p_Addr, p_Size);
|
NdisZeroMemory (p_Addr, p_Size);
|
||||||
#endif
|
#endif
|
||||||
NdisFreeMemory (p_Addr, p_Size, 0);
|
NdisFreeMemory (p_Addr, p_Size, 0);
|
||||||
}
|
}
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Circular queue management routines.
|
* Circular queue management routines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define QUEUE_BYTE_ALLOCATION(size) \
|
#define QUEUE_BYTE_ALLOCATION(size) \
|
||||||
(sizeof (Queue) + (size * sizeof (PVOID)))
|
(sizeof (Queue) + (size * sizeof (PVOID)))
|
||||||
|
|
||||||
#define QUEUE_ADD_INDEX(var, inc) \
|
#define QUEUE_ADD_INDEX(var, inc) \
|
||||||
{ \
|
{ \
|
||||||
var += inc; \
|
var += inc; \
|
||||||
if (var >= q->capacity) \
|
if (var >= q->capacity) \
|
||||||
var -= q->capacity; \
|
var -= q->capacity; \
|
||||||
MYASSERT (var < q->capacity); \
|
MYASSERT (var < q->capacity); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define QUEUE_SANITY_CHECK() \
|
#define QUEUE_SANITY_CHECK() \
|
||||||
MYASSERT (q != NULL && q->base < q->capacity && q->size <= q->capacity)
|
MYASSERT (q != NULL && q->base < q->capacity && q->size <= q->capacity)
|
||||||
|
|
||||||
#define QueueCount(q) (q->size)
|
#define QueueCount(q) (q->size)
|
||||||
|
|
||||||
#define UPDATE_MAX_SIZE() \
|
#define UPDATE_MAX_SIZE() \
|
||||||
{ \
|
{ \
|
||||||
if (q->size > q->max_size) \
|
if (q->size > q->max_size) \
|
||||||
q->max_size = q->size; \
|
q->max_size = q->size; \
|
||||||
}
|
}
|
||||||
|
|
||||||
Queue *
|
Queue *
|
||||||
QueueInit (ULONG capacity)
|
QueueInit (ULONG capacity)
|
||||||
{
|
{
|
||||||
Queue *q;
|
Queue *q;
|
||||||
|
|
||||||
MYASSERT (capacity > 0);
|
MYASSERT (capacity > 0);
|
||||||
q = (Queue *) MemAlloc (QUEUE_BYTE_ALLOCATION (capacity), TRUE);
|
q = (Queue *) MemAlloc (QUEUE_BYTE_ALLOCATION (capacity), TRUE);
|
||||||
if (!q)
|
if (!q)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
q->base = q->size = 0;
|
q->base = q->size = 0;
|
||||||
q->capacity = capacity;
|
q->capacity = capacity;
|
||||||
q->max_size = 0;
|
q->max_size = 0;
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
QueueFree (Queue *q)
|
QueueFree (Queue *q)
|
||||||
{
|
{
|
||||||
if (q)
|
if (q)
|
||||||
{
|
|
||||||
QUEUE_SANITY_CHECK ();
|
|
||||||
MemFree (q, QUEUE_BYTE_ALLOCATION (q->capacity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID
|
|
||||||
QueuePush (Queue *q, PVOID item)
|
|
||||||
{
|
|
||||||
ULONG dest;
|
|
||||||
QUEUE_SANITY_CHECK ();
|
|
||||||
if (q->size == q->capacity)
|
|
||||||
return NULL;
|
|
||||||
dest = q->base;
|
|
||||||
QUEUE_ADD_INDEX (dest, q->size);
|
|
||||||
q->data[dest] = item;
|
|
||||||
++q->size;
|
|
||||||
UPDATE_MAX_SIZE();
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID
|
|
||||||
QueuePop (Queue *q)
|
|
||||||
{
|
|
||||||
ULONG oldbase;
|
|
||||||
QUEUE_SANITY_CHECK ();
|
|
||||||
if (!q->size)
|
|
||||||
return NULL;
|
|
||||||
oldbase = q->base;
|
|
||||||
QUEUE_ADD_INDEX (q->base, 1);
|
|
||||||
--q->size;
|
|
||||||
UPDATE_MAX_SIZE();
|
|
||||||
return q->data[oldbase];
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID
|
|
||||||
QueueExtract (Queue *q, PVOID item)
|
|
||||||
{
|
|
||||||
ULONG src, dest, count, n;
|
|
||||||
QUEUE_SANITY_CHECK ();
|
|
||||||
n = 0;
|
|
||||||
src = dest = q->base;
|
|
||||||
count = q->size;
|
|
||||||
while (count--)
|
|
||||||
{
|
|
||||||
if (item == q->data[src])
|
|
||||||
{
|
{
|
||||||
++n;
|
QUEUE_SANITY_CHECK ();
|
||||||
--q->size;
|
MemFree (q, QUEUE_BYTE_ALLOCATION (q->capacity));
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
QueuePush (Queue *q, PVOID item)
|
||||||
|
{
|
||||||
|
ULONG dest;
|
||||||
|
QUEUE_SANITY_CHECK ();
|
||||||
|
if (q->size == q->capacity)
|
||||||
|
return NULL;
|
||||||
|
dest = q->base;
|
||||||
|
QUEUE_ADD_INDEX (dest, q->size);
|
||||||
|
q->data[dest] = item;
|
||||||
|
++q->size;
|
||||||
|
UPDATE_MAX_SIZE();
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
QueuePop (Queue *q)
|
||||||
|
{
|
||||||
|
ULONG oldbase;
|
||||||
|
QUEUE_SANITY_CHECK ();
|
||||||
|
if (!q->size)
|
||||||
|
return NULL;
|
||||||
|
oldbase = q->base;
|
||||||
|
QUEUE_ADD_INDEX (q->base, 1);
|
||||||
|
--q->size;
|
||||||
|
UPDATE_MAX_SIZE();
|
||||||
|
return q->data[oldbase];
|
||||||
|
}
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
QueueExtract (Queue *q, PVOID item)
|
||||||
|
{
|
||||||
|
ULONG src, dest, count, n;
|
||||||
|
QUEUE_SANITY_CHECK ();
|
||||||
|
n = 0;
|
||||||
|
src = dest = q->base;
|
||||||
|
count = q->size;
|
||||||
|
while (count--)
|
||||||
{
|
{
|
||||||
q->data[dest] = q->data[src];
|
if (item == q->data[src])
|
||||||
QUEUE_ADD_INDEX (dest, 1);
|
{
|
||||||
|
++n;
|
||||||
|
--q->size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
q->data[dest] = q->data[src];
|
||||||
|
QUEUE_ADD_INDEX (dest, 1);
|
||||||
|
}
|
||||||
|
QUEUE_ADD_INDEX (src, 1);
|
||||||
}
|
}
|
||||||
QUEUE_ADD_INDEX (src, 1);
|
if (n)
|
||||||
}
|
return item;
|
||||||
if (n)
|
else
|
||||||
return item;
|
return NULL;
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef QUEUE_BYTE_ALLOCATION
|
#undef QUEUE_BYTE_ALLOCATION
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
/*
|
/*
|
||||||
* TAP-Windows -- A kernel driver to provide virtual tap
|
* TAP-Windows -- A kernel driver to provide virtual tap
|
||||||
* device functionality on Windows.
|
* device functionality on Windows.
|
||||||
*
|
*
|
||||||
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
|
||||||
*
|
*
|
||||||
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
|
||||||
* and is released under the GPL version 2 (see below).
|
* and is released under the GPL version 2 (see below).
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2
|
* it under the terms of the GNU General Public License version 2
|
||||||
* as published by the Free Software Foundation.
|
* as published by the Free Software Foundation.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program (see the file COPYING included with this
|
* along with this program (see the file COPYING included with this
|
||||||
* distribution); if not, write to the Free Software Foundation, Inc.,
|
* distribution); if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
// MAC address, Ethernet header, and ARP
|
// MAC address, Ethernet header, and ARP
|
||||||
|
@ -40,11 +40,11 @@ typedef unsigned char IPV6ADDR [16];
|
||||||
//-----------------
|
//-----------------
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
MACADDR addr;
|
MACADDR addr;
|
||||||
} ETH_ADDR;
|
} ETH_ADDR;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ETH_ADDR list[NIC_MAX_MCAST_LIST];
|
ETH_ADDR list[NIC_MAX_MCAST_LIST];
|
||||||
} MC_LIST;
|
} MC_LIST;
|
||||||
|
|
||||||
//----------------
|
//----------------
|
||||||
|
@ -53,13 +53,13 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
MACADDR dest; /* destination eth addr */
|
MACADDR dest; /* destination eth addr */
|
||||||
MACADDR src; /* source ether addr */
|
MACADDR src; /* source ether addr */
|
||||||
|
|
||||||
# define ETH_P_IP 0x0800 /* IPv4 protocol */
|
# define ETH_P_IP 0x0800 /* IPv4 protocol */
|
||||||
# define ETH_P_IPV6 0x86DD /* IPv6 protocol */
|
# define ETH_P_IPV6 0x86DD /* IPv6 protocol */
|
||||||
# define ETH_P_ARP 0x0806 /* ARP protocol */
|
# define ETH_P_ARP 0x0806 /* ARP protocol */
|
||||||
USHORT proto; /* packet type ID field */
|
USHORT proto; /* packet type ID field */
|
||||||
} ETH_HEADER, *PETH_HEADER;
|
} ETH_HEADER, *PETH_HEADER;
|
||||||
|
|
||||||
//----------------
|
//----------------
|
||||||
|
@ -67,27 +67,27 @@ typedef struct
|
||||||
//----------------
|
//----------------
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
MACADDR m_MAC_Destination; // Reverse these two
|
MACADDR m_MAC_Destination; // Reverse these two
|
||||||
MACADDR m_MAC_Source; // to answer ARP requests
|
MACADDR m_MAC_Source; // to answer ARP requests
|
||||||
USHORT m_Proto; // 0x0806
|
USHORT m_Proto; // 0x0806
|
||||||
|
|
||||||
# define MAC_ADDR_TYPE 0x0001
|
# define MAC_ADDR_TYPE 0x0001
|
||||||
USHORT m_MAC_AddressType; // 0x0001
|
USHORT m_MAC_AddressType; // 0x0001
|
||||||
|
|
||||||
USHORT m_PROTO_AddressType; // 0x0800
|
USHORT m_PROTO_AddressType; // 0x0800
|
||||||
UCHAR m_MAC_AddressSize; // 0x06
|
UCHAR m_MAC_AddressSize; // 0x06
|
||||||
UCHAR m_PROTO_AddressSize; // 0x04
|
UCHAR m_PROTO_AddressSize; // 0x04
|
||||||
|
|
||||||
# define ARP_REQUEST 0x0001
|
# define ARP_REQUEST 0x0001
|
||||||
# define ARP_REPLY 0x0002
|
# define ARP_REPLY 0x0002
|
||||||
USHORT m_ARP_Operation; // 0x0001 for ARP request, 0x0002 for ARP reply
|
USHORT m_ARP_Operation; // 0x0001 for ARP request, 0x0002 for ARP reply
|
||||||
|
|
||||||
MACADDR m_ARP_MAC_Source;
|
MACADDR m_ARP_MAC_Source;
|
||||||
IPADDR m_ARP_IP_Source;
|
IPADDR m_ARP_IP_Source;
|
||||||
MACADDR m_ARP_MAC_Destination;
|
MACADDR m_ARP_MAC_Destination;
|
||||||
IPADDR m_ARP_IP_Destination;
|
IPADDR m_ARP_IP_Destination;
|
||||||
}
|
}
|
||||||
ARP_PACKET, *PARP_PACKET;
|
ARP_PACKET, *PARP_PACKET;
|
||||||
|
|
||||||
//----------
|
//----------
|
||||||
|
@ -97,27 +97,27 @@ ARP_PACKET, *PARP_PACKET;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
# define IPH_GET_VER(v) (((v) >> 4) & 0x0F)
|
# define IPH_GET_VER(v) (((v) >> 4) & 0x0F)
|
||||||
# define IPH_GET_LEN(v) (((v) & 0x0F) << 2)
|
# define IPH_GET_LEN(v) (((v) & 0x0F) << 2)
|
||||||
UCHAR version_len;
|
UCHAR version_len;
|
||||||
|
|
||||||
UCHAR tos;
|
UCHAR tos;
|
||||||
USHORT tot_len;
|
USHORT tot_len;
|
||||||
USHORT id;
|
USHORT id;
|
||||||
|
|
||||||
# define IP_OFFMASK 0x1fff
|
# define IP_OFFMASK 0x1fff
|
||||||
USHORT frag_off;
|
USHORT frag_off;
|
||||||
|
|
||||||
UCHAR ttl;
|
UCHAR ttl;
|
||||||
|
|
||||||
# define IPPROTO_UDP 17 /* UDP protocol */
|
# define IPPROTO_UDP 17 /* UDP protocol */
|
||||||
# define IPPROTO_TCP 6 /* TCP protocol */
|
# define IPPROTO_TCP 6 /* TCP protocol */
|
||||||
# define IPPROTO_ICMP 1 /* ICMP protocol */
|
# define IPPROTO_ICMP 1 /* ICMP protocol */
|
||||||
# define IPPROTO_IGMP 2 /* IGMP protocol */
|
# define IPPROTO_IGMP 2 /* IGMP protocol */
|
||||||
UCHAR protocol;
|
UCHAR protocol;
|
||||||
|
|
||||||
USHORT check;
|
USHORT check;
|
||||||
ULONG saddr;
|
ULONG saddr;
|
||||||
ULONG daddr;
|
ULONG daddr;
|
||||||
/* The options start here. */
|
/* The options start here. */
|
||||||
} IPHDR;
|
} IPHDR;
|
||||||
|
|
||||||
//-----------
|
//-----------
|
||||||
|
@ -125,10 +125,10 @@ typedef struct {
|
||||||
//-----------
|
//-----------
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
USHORT source;
|
USHORT source;
|
||||||
USHORT dest;
|
USHORT dest;
|
||||||
USHORT len;
|
USHORT len;
|
||||||
USHORT check;
|
USHORT check;
|
||||||
} UDPHDR;
|
} UDPHDR;
|
||||||
|
|
||||||
//--------------------------
|
//--------------------------
|
||||||
|
@ -136,13 +136,13 @@ typedef struct {
|
||||||
//--------------------------
|
//--------------------------
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
USHORT source; /* source port */
|
USHORT source; /* source port */
|
||||||
USHORT dest; /* destination port */
|
USHORT dest; /* destination port */
|
||||||
ULONG seq; /* sequence number */
|
ULONG seq; /* sequence number */
|
||||||
ULONG ack_seq; /* acknowledgement number */
|
ULONG ack_seq; /* acknowledgement number */
|
||||||
|
|
||||||
# define TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2)
|
# define TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2)
|
||||||
UCHAR doff_res;
|
UCHAR doff_res;
|
||||||
|
|
||||||
# define TCPH_FIN_MASK (1<<0)
|
# define TCPH_FIN_MASK (1<<0)
|
||||||
# define TCPH_SYN_MASK (1<<1)
|
# define TCPH_SYN_MASK (1<<1)
|
||||||
|
@ -152,11 +152,11 @@ typedef struct {
|
||||||
# define TCPH_URG_MASK (1<<5)
|
# define TCPH_URG_MASK (1<<5)
|
||||||
# define TCPH_ECE_MASK (1<<6)
|
# define TCPH_ECE_MASK (1<<6)
|
||||||
# define TCPH_CWR_MASK (1<<7)
|
# define TCPH_CWR_MASK (1<<7)
|
||||||
UCHAR flags;
|
UCHAR flags;
|
||||||
|
|
||||||
USHORT window;
|
USHORT window;
|
||||||
USHORT check;
|
USHORT check;
|
||||||
USHORT urg_ptr;
|
USHORT urg_ptr;
|
||||||
} TCPHDR;
|
} TCPHDR;
|
||||||
|
|
||||||
#define TCPOPT_EOL 0
|
#define TCPOPT_EOL 0
|
||||||
|
@ -169,14 +169,14 @@ typedef struct {
|
||||||
//------------
|
//------------
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UCHAR version_prio;
|
UCHAR version_prio;
|
||||||
UCHAR flow_lbl[3];
|
UCHAR flow_lbl[3];
|
||||||
USHORT payload_len;
|
USHORT payload_len;
|
||||||
# define IPPROTO_ICMPV6 0x3a /* ICMP protocol v6 */
|
# define IPPROTO_ICMPV6 0x3a /* ICMP protocol v6 */
|
||||||
UCHAR nexthdr;
|
UCHAR nexthdr;
|
||||||
UCHAR hop_limit;
|
UCHAR hop_limit;
|
||||||
IPV6ADDR saddr;
|
IPV6ADDR saddr;
|
||||||
IPV6ADDR daddr;
|
IPV6ADDR daddr;
|
||||||
} IPV6HDR;
|
} IPV6HDR;
|
||||||
|
|
||||||
//--------------------------------------------
|
//--------------------------------------------
|
||||||
|
@ -186,39 +186,39 @@ typedef struct {
|
||||||
// Neighbor Solictiation - RFC 4861, 4.3
|
// Neighbor Solictiation - RFC 4861, 4.3
|
||||||
// (this is just the ICMPv6 part of the packet)
|
// (this is just the ICMPv6 part of the packet)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UCHAR type;
|
UCHAR type;
|
||||||
# define ICMPV6_TYPE_NS 135 // neighbour solicitation
|
# define ICMPV6_TYPE_NS 135 // neighbour solicitation
|
||||||
UCHAR code;
|
UCHAR code;
|
||||||
# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA
|
# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA
|
||||||
USHORT checksum;
|
USHORT checksum;
|
||||||
ULONG reserved;
|
ULONG reserved;
|
||||||
IPV6ADDR target_addr;
|
IPV6ADDR target_addr;
|
||||||
} ICMPV6_NS;
|
} ICMPV6_NS;
|
||||||
|
|
||||||
// Neighbor Advertisement - RFC 4861, 4.4 + 4.6/4.6.1
|
// Neighbor Advertisement - RFC 4861, 4.4 + 4.6/4.6.1
|
||||||
// (this is just the ICMPv6 payload)
|
// (this is just the ICMPv6 payload)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UCHAR type;
|
UCHAR type;
|
||||||
# define ICMPV6_TYPE_NA 136 // neighbour advertisement
|
# define ICMPV6_TYPE_NA 136 // neighbour advertisement
|
||||||
UCHAR code;
|
UCHAR code;
|
||||||
# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA
|
# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA
|
||||||
USHORT checksum;
|
USHORT checksum;
|
||||||
UCHAR rso_bits; // Router(0), Solicited(2), Ovrrd(4)
|
UCHAR rso_bits; // Router(0), Solicited(2), Ovrrd(4)
|
||||||
UCHAR reserved[3];
|
UCHAR reserved[3];
|
||||||
IPV6ADDR target_addr;
|
IPV6ADDR target_addr;
|
||||||
// always include "Target Link-layer Address" option (RFC 4861 4.6.1)
|
// always include "Target Link-layer Address" option (RFC 4861 4.6.1)
|
||||||
UCHAR opt_type;
|
UCHAR opt_type;
|
||||||
#define ICMPV6_OPTION_TLLA 2
|
#define ICMPV6_OPTION_TLLA 2
|
||||||
UCHAR opt_length;
|
UCHAR opt_length;
|
||||||
#define ICMPV6_LENGTH_TLLA 1 // multiplied by 8 -> 1 = 8 bytes
|
#define ICMPV6_LENGTH_TLLA 1 // multiplied by 8 -> 1 = 8 bytes
|
||||||
MACADDR target_macaddr;
|
MACADDR target_macaddr;
|
||||||
} ICMPV6_NA;
|
} ICMPV6_NA;
|
||||||
|
|
||||||
// this is the complete packet with Ethernet and IPv6 headers
|
// this is the complete packet with Ethernet and IPv6 headers
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ETH_HEADER eth;
|
ETH_HEADER eth;
|
||||||
IPV6HDR ipv6;
|
IPV6HDR ipv6;
|
||||||
ICMPV6_NA icmpv6;
|
ICMPV6_NA icmpv6;
|
||||||
} ICMPV6_NA_PKT;
|
} ICMPV6_NA_PKT;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
|
@ -200,44 +200,6 @@ VOID CheckIfDhcpAndTunMode
|
||||||
|
|
||||||
VOID HookDispatchFunctions();
|
VOID HookDispatchFunctions();
|
||||||
|
|
||||||
#if ENABLE_NONADMIN
|
|
||||||
|
|
||||||
#if defined(DDKVER_MAJOR) && DDKVER_MAJOR < 5600
|
|
||||||
/*
|
|
||||||
* Better solution for use on Vista DDK, but possibly not compatible with
|
|
||||||
* earlier DDKs:
|
|
||||||
*
|
|
||||||
* Eliminate the definition of SECURITY_DESCRIPTOR (and even ZwSetSecurityObject),
|
|
||||||
* and at the top of tapdrv.c change:
|
|
||||||
*
|
|
||||||
* #include <ndis.h>
|
|
||||||
* #include <ntstrsafe.h>
|
|
||||||
* #include <ntddk.h>
|
|
||||||
*
|
|
||||||
* To
|
|
||||||
*
|
|
||||||
* #include <ntifs.h>
|
|
||||||
* #include <ndis.h>
|
|
||||||
* #include <ntstrsafe.h>
|
|
||||||
*/
|
|
||||||
typedef struct _SECURITY_DESCRIPTOR {
|
|
||||||
unsigned char opaque[64];
|
|
||||||
} SECURITY_DESCRIPTOR;
|
|
||||||
|
|
||||||
NTSYSAPI
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
ZwSetSecurityObject (
|
|
||||||
IN HANDLE Handle,
|
|
||||||
IN SECURITY_INFORMATION SecurityInformation,
|
|
||||||
IN PSECURITY_DESCRIPTOR SecurityDescriptor);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VOID AllowNonAdmin (TapExtensionPointer p_Extension);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct WIN2K_NDIS_MINIPORT_BLOCK
|
struct WIN2K_NDIS_MINIPORT_BLOCK
|
||||||
{
|
{
|
||||||
unsigned char opaque[16];
|
unsigned char opaque[16];
|
||||||
|
|
|
@ -33,22 +33,11 @@
|
||||||
#define TAP_WIN_CONTROL_CODE(request,method) \
|
#define TAP_WIN_CONTROL_CODE(request,method) \
|
||||||
CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
|
CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
|
||||||
|
|
||||||
/* Present in 8.1 */
|
|
||||||
|
|
||||||
#define TAP_WIN_IOCTL_GET_MAC TAP_WIN_CONTROL_CODE (1, METHOD_BUFFERED)
|
#define TAP_WIN_IOCTL_GET_MAC TAP_WIN_CONTROL_CODE (1, METHOD_BUFFERED)
|
||||||
#define TAP_WIN_IOCTL_GET_VERSION TAP_WIN_CONTROL_CODE (2, METHOD_BUFFERED)
|
#define TAP_WIN_IOCTL_GET_VERSION TAP_WIN_CONTROL_CODE (2, METHOD_BUFFERED)
|
||||||
#define TAP_WIN_IOCTL_GET_MTU TAP_WIN_CONTROL_CODE (3, METHOD_BUFFERED)
|
#define TAP_WIN_IOCTL_GET_MTU TAP_WIN_CONTROL_CODE (3, METHOD_BUFFERED)
|
||||||
#define TAP_WIN_IOCTL_GET_INFO TAP_WIN_CONTROL_CODE (4, METHOD_BUFFERED)
|
|
||||||
//#define TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT TAP_WIN_CONTROL_CODE (5, METHOD_BUFFERED)
|
|
||||||
#define TAP_WIN_IOCTL_SET_MEDIA_STATUS TAP_WIN_CONTROL_CODE (6, METHOD_BUFFERED)
|
#define TAP_WIN_IOCTL_SET_MEDIA_STATUS TAP_WIN_CONTROL_CODE (6, METHOD_BUFFERED)
|
||||||
//#define TAP_WIN_IOCTL_CONFIG_DHCP_MASQ TAP_WIN_CONTROL_CODE (7, METHOD_BUFFERED)
|
|
||||||
#define TAP_WIN_IOCTL_GET_LOG_LINE TAP_WIN_CONTROL_CODE (8, METHOD_BUFFERED)
|
#define TAP_WIN_IOCTL_GET_LOG_LINE TAP_WIN_CONTROL_CODE (8, METHOD_BUFFERED)
|
||||||
//#define TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT TAP_WIN_CONTROL_CODE (9, METHOD_BUFFERED)
|
|
||||||
|
|
||||||
/* Added in 8.2 */
|
|
||||||
|
|
||||||
/* obsoletes TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT */
|
|
||||||
//#define TAP_WIN_IOCTL_CONFIG_TUN TAP_WIN_CONTROL_CODE (10, METHOD_BUFFERED)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =================
|
* =================
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -83,11 +83,13 @@ typedef struct _TapExtension
|
||||||
BOOLEAN m_TapIsRunning;
|
BOOLEAN m_TapIsRunning;
|
||||||
BOOLEAN m_CalledTapDeviceFreeResources;
|
BOOLEAN m_CalledTapDeviceFreeResources;
|
||||||
|
|
||||||
|
#if 0
|
||||||
// DPC queue for deferred packet injection
|
// DPC queue for deferred packet injection
|
||||||
BOOLEAN m_InjectDpcInitialized;
|
BOOLEAN m_InjectDpcInitialized;
|
||||||
KDPC m_InjectDpc;
|
KDPC m_InjectDpc;
|
||||||
NDIS_SPIN_LOCK m_InjectLock;
|
NDIS_SPIN_LOCK m_InjectLock;
|
||||||
Queue *m_InjectQueue;
|
Queue *m_InjectQueue;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
TapExtension, *TapExtensionPointer;
|
TapExtension, *TapExtensionPointer;
|
||||||
|
|
||||||
|
@ -101,6 +103,7 @@ typedef struct _TapPacket
|
||||||
}
|
}
|
||||||
TapPacket, *TapPacketPointer;
|
TapPacket, *TapPacketPointer;
|
||||||
|
|
||||||
|
#if 0
|
||||||
typedef struct _InjectPacket
|
typedef struct _InjectPacket
|
||||||
{
|
{
|
||||||
# define INJECT_PACKET_SIZE(data_size) (sizeof (InjectPacket) + (data_size))
|
# define INJECT_PACKET_SIZE(data_size) (sizeof (InjectPacket) + (data_size))
|
||||||
|
@ -109,6 +112,7 @@ typedef struct _InjectPacket
|
||||||
UCHAR m_Data []; // m_Data must be the last struct member
|
UCHAR m_Data []; // m_Data must be the last struct member
|
||||||
}
|
}
|
||||||
InjectPacket, *InjectPacketPointer;
|
InjectPacket, *InjectPacketPointer;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _TapAdapter
|
typedef struct _TapAdapter
|
||||||
{
|
{
|
||||||
|
@ -136,33 +140,6 @@ typedef struct _TapAdapter
|
||||||
// Adapter power state
|
// Adapter power state
|
||||||
char m_DeviceState;
|
char m_DeviceState;
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Info for point-to-point mode
|
|
||||||
BOOLEAN m_tun;
|
|
||||||
IPADDR m_localIP;
|
|
||||||
IPADDR m_remoteNetwork;
|
|
||||||
IPADDR m_remoteNetmask;
|
|
||||||
ETH_HEADER m_TapToUser;
|
|
||||||
ETH_HEADER m_UserToTap;
|
|
||||||
ETH_HEADER m_UserToTap_IPv6; // same as UserToTap but proto=ipv6
|
|
||||||
MACADDR m_MAC_Broadcast;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Used for DHCP server masquerade
|
|
||||||
BOOLEAN m_dhcp_enabled;
|
|
||||||
IPADDR m_dhcp_addr;
|
|
||||||
ULONG m_dhcp_netmask;
|
|
||||||
IPADDR m_dhcp_server_ip;
|
|
||||||
BOOLEAN m_dhcp_server_arp;
|
|
||||||
MACADDR m_dhcp_server_mac;
|
|
||||||
ULONG m_dhcp_lease_time;
|
|
||||||
UCHAR m_dhcp_user_supplied_options_buffer[DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE];
|
|
||||||
ULONG m_dhcp_user_supplied_options_buffer_len;
|
|
||||||
BOOLEAN m_dhcp_received_discover;
|
|
||||||
ULONG m_dhcp_bad_requests;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Help to tear down the adapter by keeping
|
// Help to tear down the adapter by keeping
|
||||||
// some state information on allocated
|
// some state information on allocated
|
||||||
// resources.
|
// resources.
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>wsock32.lib;ws2_32.lib;winhttp.lib;Iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win64-vs2012\libeay32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>wsock32.lib;ws2_32.lib;winhttp.lib;Iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
@ -127,7 +127,7 @@
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<AdditionalDependencies>wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>wsock32.lib;ws2_32.lib;winhttp.lib;Iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<AdditionalDependencies>wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win64-vs2012\libeay32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>wsock32.lib;ws2_32.lib;winhttp.lib;Iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
|
Loading…
Add table
Reference in a new issue