Do the same modifications to the NDIS 6 code base as were done to the old 5 driver: disable all the 'tun' functionality, and add the IOCTL for querying the multicast list at Ethernet (L2) level.

This commit is contained in:
Adam Ierymenko 2015-04-25 12:21:08 -07:00
parent 1ebe2ad920
commit d4c06e924d
12 changed files with 81 additions and 901 deletions

View File

@ -213,7 +213,6 @@
<ItemGroup>
<ClCompile Include="adapter.c" />
<ClCompile Include="device.c" />
<ClCompile Include="dhcp.c" />
<ClCompile Include="error.c" />
<ClCompile Include="macinfo.c" />
<ClCompile Include="mem.c" />
@ -227,7 +226,6 @@
<ClInclude Include="config.h" />
<ClInclude Include="constants.h" />
<ClInclude Include="device.h" />
<ClInclude Include="dhcp.h" />
<ClInclude Include="endian.h" />
<ClInclude Include="error.h" />
<ClInclude Include="hexdump.h" />

View File

@ -25,9 +25,6 @@
<ClCompile Include="device.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dhcp.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="error.c">
<Filter>Source Files</Filter>
</ClCompile>
@ -63,9 +60,6 @@
<ClInclude Include="device.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="dhcp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="endian.h">
<Filter>Header Files</Filter>
</ClInclude>

View File

@ -170,6 +170,7 @@ typedef struct _TAP_ADAPTER_CONTEXT
#define TAP_WAIT_POLL_LOOP_TIMEOUT 3000 // 3 seconds
NDIS_EVENT ReceiveNblInFlightCountZeroEvent;
/*
// Info for point-to-point mode
BOOLEAN m_tun;
IPADDR m_localIP;
@ -178,8 +179,10 @@ typedef struct _TAP_ADAPTER_CONTEXT
ETH_HEADER m_TapToUser;
ETH_HEADER m_UserToTap;
ETH_HEADER m_UserToTap_IPv6; // same as UserToTap but proto=ipv6
*/
// Info for DHCP server masquerade
// Info for DHCP server masquerade
/*
BOOLEAN m_dhcp_enabled;
IPADDR m_dhcp_addr;
ULONG m_dhcp_netmask;
@ -191,6 +194,7 @@ typedef struct _TAP_ADAPTER_CONTEXT
ULONG m_dhcp_user_supplied_options_buffer_len;
BOOLEAN m_dhcp_received_discover;
ULONG m_dhcp_bad_requests;
*/
// Multicast list. Fixed size.
ULONG ulMCListSize;

View File

@ -69,7 +69,8 @@
//===========================================================
#define ETHERNET_HEADER_SIZE (sizeof (ETH_HEADER))
#define ETHERNET_MTU 1500
//#define ETHERNET_MTU 1500
#define ETHERNET_MTU 2800
#define ETHERNET_PACKET_SIZE (ETHERNET_MTU + ETHERNET_HEADER_SIZE)
#define DEFAULT_PACKET_LOOKAHEAD (ETHERNET_PACKET_SIZE)
#define VLAN_TAG_SIZE 4
@ -108,7 +109,7 @@
#define TAP_RECV_SPEED (100ULL*MEGABITS_PER_SECOND)
// Max number of multicast addresses supported in hardware
#define TAP_MAX_MCAST_LIST 32
#define TAP_MAX_MCAST_LIST 128
#define TAP_MAX_LOOKAHEAD TAP_FRAME_MAX_DATA_SIZE
#define TAP_BUFFER_SIZE TAP_MAX_FRAME_SIZE
@ -137,7 +138,7 @@
NDIS_PACKET_TYPE_PROMISCUOUS | \
NDIS_PACKET_TYPE_ALL_MULTICAST)
#define TAP_MAX_MCAST_LIST 32 // Max length of multicast address list
//#define TAP_MAX_MCAST_LIST 128 // Max length of multicast address list
//
// Specify a bitmask that defines optional properties of the NIC.

View File

@ -48,6 +48,7 @@ VOID tapResetAdapterState(
__in PTAP_ADAPTER_CONTEXT Adapter
)
{
/*
// Point-To-Point
Adapter->m_tun = FALSE;
Adapter->m_localIP = 0;
@ -56,8 +57,10 @@ VOID tapResetAdapterState(
NdisZeroMemory (&Adapter->m_TapToUser, sizeof (Adapter->m_TapToUser));
NdisZeroMemory (&Adapter->m_UserToTap, sizeof (Adapter->m_UserToTap));
NdisZeroMemory (&Adapter->m_UserToTap_IPv6, sizeof (Adapter->m_UserToTap_IPv6));
*/
// DHCP Masq
/*
Adapter->m_dhcp_enabled = FALSE;
Adapter->m_dhcp_server_arp = FALSE;
Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
@ -68,6 +71,7 @@ VOID tapResetAdapterState(
Adapter->m_dhcp_received_discover = FALSE;
Adapter->m_dhcp_bad_requests = 0;
NdisZeroMemory (Adapter->m_dhcp_server_mac, MACADDR_SIZE);
*/
}
// IRP_MJ_CREATE
@ -278,6 +282,7 @@ tapSetMediaConnectStatus(
}
}
/*
//======================================================
// If DHCP mode is used together with tun
// mode, consider the fact that the P2P remote subnet
@ -297,6 +302,7 @@ CheckIfDhcpAndTunMode (
}
}
}
*/
// IRP_MJ_DEVICE_CONTROL callback.
NTSTATUS
@ -428,6 +434,36 @@ Return Value:
}
break;
// Allow ZeroTier One to get multicast memberships at the L2 level in a
// protocol-neutral manner.
case TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS:
{
if (outBufLength < TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE) {
/* output buffer too small */
NOTE_ERROR ();
Irp->IoStatus.Status = ntStatus = STATUS_BUFFER_TOO_SMALL;
} else {
char *out = (char *)Irp->AssociatedIrp.SystemBuffer;
char *end = out + TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE;
unsigned long i,j;
for(i=0;i<adapter->ulMCListSize;++i) {
if (i >= TAP_MAX_MCAST_LIST)
break;
for(j=0;j<6;++j)
*(out++) = adapter->MCList[i][j];
if (out >= end)
break;
}
while (out < end)
*(out++) = (char)0;
Irp->IoStatus.Information = TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE;
Irp->IoStatus.Status = ntStatus = STATUS_SUCCESS;
}
break;
}
#if 0
case TAP_WIN_IOCTL_CONFIG_TUN:
{
if(inBufLength >= sizeof(IPADDR)*3)
@ -513,7 +549,9 @@ Return Value:
}
}
break;
#endif
#if 0
case TAP_WIN_IOCTL_CONFIG_DHCP_MASQ:
{
if(inBufLength >= sizeof(IPADDR)*4)
@ -586,7 +624,9 @@ Return Value:
}
}
break;
#endif
#if 0
case TAP_WIN_IOCTL_GET_INFO:
{
char state[16];
@ -657,7 +697,7 @@ Return Value:
// BUGBUG!!! Fail because this is not completely implemented.
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
}
break;
#endif
#if DBG
case TAP_WIN_IOCTL_GET_LOG_LINE:

View File

@ -1,710 +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-2014 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
*/
#include "tap.h"
//=========================
// Code to set DHCP options
//=========================
VOID
SetDHCPOpt(
__in DHCPMsg *m,
__in void *data,
__in 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(
__in DHCPMsg *msg,
__in int type
)
{
DHCPOPT0 opt;
opt.type = (UCHAR) type;
SetDHCPOpt (msg, &opt, sizeof (opt));
}
VOID
SetDHCPOpt8(
__in DHCPMsg *msg,
__in int type,
__in ULONG data
)
{
DHCPOPT8 opt;
opt.type = (UCHAR) type;
opt.len = sizeof (opt.data);
opt.data = (UCHAR) data;
SetDHCPOpt (msg, &opt, sizeof (opt));
}
VOID
SetDHCPOpt32(
__in DHCPMsg *msg,
__in int type,
__in 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(
__in const UCHAR *buf,
__in 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 (
__in const UCHAR *buf,
__in const int len_udp,
__in const UCHAR *src_addr,
__in 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(
__in 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(
__in const DHCP *dhcp,
__in 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 (
__in const PTAP_ADAPTER_CONTEXT Adapter,
__in const ETH_HEADER *eth,
__in const IPHDR *ip,
__in const UDPHDR *udp,
__in const DHCP *dhcp
)
{
// Must be UDPv4 protocol
if (!(eth->proto == htons (NDIS_ETH_TYPE_IPV4) && ip->protocol == IPPROTO_UDP))
{
return FALSE;
}
// Source MAC must be our adapter
if (!MAC_EQUAL (eth->src, Adapter->CurrentAddress))
{
return FALSE;
}
// Dest MAC must be either broadcast or our virtual DHCP server
if (!(ETH_IS_BROADCAST(eth->dest)
|| MAC_EQUAL (eth->dest, 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 (
__in const PTAP_ADAPTER_CONTEXT Adapter,
__inout DHCPPre *p,
__in const ETH_HEADER *eth,
__in const IPHDR *ip,
__in const UDPHDR *udp,
__in const DHCP *dhcp,
__in const int optlen,
__in const int type)
{
// Should we broadcast or direct to a specific MAC / IP address?
const BOOLEAN broadcast = (type == DHCPNAK
|| ETH_IS_BROADCAST(eth->dest));
//
// Build ethernet header
//
ETH_COPY_NETWORK_ADDRESS (p->eth.src, Adapter->m_dhcp_server_mac);
if (broadcast)
{
memset(p->eth.dest,0xFF,ETH_LENGTH_OF_ADDRESS);
}
else
{
ETH_COPY_NETWORK_ADDRESS (p->eth.dest, eth->src);
}
p->eth.proto = htons (NDIS_ETH_TYPE_IPV4);
//
// 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 = Adapter->m_dhcp_server_ip;
if (broadcast)
{
p->ip.daddr = ~0;
}
else
{
p->ip.daddr = Adapter->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 = Adapter->m_dhcp_addr;
}
p->dhcp.siaddr = Adapter->m_dhcp_server_ip;
p->dhcp.giaddr = 0;
ETH_COPY_NETWORK_ADDRESS (p->dhcp.chaddr, eth->src);
p->dhcp.magic = htonl (0x63825363);
}
//=============================
// Build specific DHCP messages
//=============================
VOID
SendDHCPMsg(
__in PTAP_ADAPTER_CONTEXT Adapter,
__in const int type,
__in const ETH_HEADER *eth,
__in const IPHDR *ip,
__in const UDPHDR *udp,
__in 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, Adapter->m_dhcp_server_ip);
if (type == DHCPOFFER || type == DHCPACK)
{
// Lease Time
SetDHCPOpt32 (pkt, DHCP_LEASE_TIME, htonl (Adapter->m_dhcp_lease_time));
// Netmask
SetDHCPOpt32 (pkt, DHCP_NETMASK, Adapter->m_dhcp_netmask);
// Other user-defined options
SetDHCPOpt (
pkt,
Adapter->m_dhcp_user_supplied_options_buffer,
Adapter->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 (
Adapter,
&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
IndicateReceivePacket(
Adapter,
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(
__in PTAP_ADAPTER_CONTEXT Adapter,
__in const ETH_HEADER *eth,
__in const IPHDR *ip,
__in const UDPHDR *udp,
__in const DHCP *dhcp,
__in 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 (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 != Adapter->m_dhcp_addr)
|| !Adapter->m_dhcp_received_discover
|| Adapter->m_dhcp_bad_requests >= BAD_DHCPREQUEST_NAK_THRESHOLD))
{
SendDHCPMsg(
Adapter,
DHCPNAK,
eth, ip, udp, dhcp
);
}
else
{
SendDHCPMsg(
Adapter,
(msg_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK),
eth, ip, udp, dhcp
);
}
// Remember if we received a DHCPDISCOVER
if (msg_type == DHCPDISCOVER)
{
Adapter->m_dhcp_received_discover = TRUE;
}
// Is this a bad DHCPREQUEST?
if (msg_type == DHCPREQUEST && dhcp->ciaddr && dhcp->ciaddr != Adapter->m_dhcp_addr)
{
++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 */

View File

@ -1,165 +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-2014 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
*/
#pragma once
#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

View File

@ -64,6 +64,7 @@ IndicateReceivePacket(
__in const unsigned int packetLength
);
/*
BOOLEAN
ProcessDHCP(
__in PTAP_ADAPTER_CONTEXT Adapter,
@ -73,7 +74,9 @@ ProcessDHCP(
__in const DHCP *dhcp,
__in int optlen
);
*/
/*
BOOLEAN
ProcessARP(
__in PTAP_ADAPTER_CONTEXT Adapter,
@ -83,5 +86,6 @@ ProcessARP(
__in const IPADDR ip_netmask,
__in const MACADDR mac
);
*/
#endif

View File

@ -432,7 +432,7 @@ TapDeviceWrite(
//
if(tapAdapterSendAndReceiveReady(adapter) == NDIS_STATUS_SUCCESS)
{
if (!adapter->m_tun && ((irpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE))
if (/*!adapter->m_tun &&*/ ((irpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE))
{
PNET_BUFFER_LIST netBufferList;
@ -514,6 +514,7 @@ TapDeviceWrite(
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
}
/*
else if (adapter->m_tun && ((irpSp->Parameters.Write.Length) >= IP_HEADER_SIZE))
{
PETH_HEADER p_UserToTap = &adapter->m_UserToTap;
@ -637,6 +638,7 @@ TapDeviceWrite(
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
}
*/
else
{
DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n",

View File

@ -38,17 +38,24 @@
#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_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_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_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_CONFIG_DHCP_SET_OPT TAP_WIN_CONTROL_CODE (9, 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_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)
//#define TAP_WIN_IOCTL_CONFIG_TUN TAP_WIN_CONTROL_CODE (10, METHOD_BUFFERED)
// Used by ZT1 to get multicast memberships at the L2 level -- Windows provides no native way to do this that I know of
#define TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS TAP_WIN_CONTROL_CODE (11, METHOD_BUFFERED)
// Must be the same as NIC_MAX_MCAST_LIST in constants.h
#define TAP_MAX_MCAST_LIST 128
// Amount of memory that must be provided to ioctl TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS
#define TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE (TAP_MAX_MCAST_LIST * 6)
/*
* =================

View File

@ -42,10 +42,8 @@
#include "proto.h"
#include "mem.h"
#include "macinfo.h"
#include "dhcp.h"
#include "error.h"
#include "endian.h"
#include "dhcp.h"
#include "types.h"
#include "adapter.h"
#include "device.h"

View File

@ -82,6 +82,8 @@ icmpv6_checksum(
return ((USHORT) ~sum);
}
/*
// check IPv6 packet for "is this an IPv6 Neighbor Solicitation that
// the tap driver needs to answer?"
// see RFC 4861 4.3 for the different cases
@ -267,6 +269,7 @@ ProcessARP(
else
return FALSE;
}
*/
//=============================================================
// CompleteIRP is normally called with an adapter -> userspace
@ -537,7 +540,8 @@ Return Value:
// If so, catch both DHCP requests and ARP queries
// to resolve the address of our virtual DHCP server.
//=====================================================
if (Adapter->m_dhcp_enabled)
#if 0
if (Adapter->m_dhcp_enabled)
{
const ETH_HEADER *eth = (ETH_HEADER *) tapPacket->m_Data;
const IPHDR *ip = (IPHDR *) (tapPacket->m_Data + sizeof (ETH_HEADER));
@ -594,15 +598,17 @@ Return Value:
}
}
}
#endif
//===============================================
//===============================================
// In Point-To-Point mode, check to see whether
// packet is ARP (handled) or IPv4 (sent to app).
// IPv6 packets are inspected for neighbour discovery
// (to be handled locally), and the rest is forwarded
// all other protocols are dropped
//===============================================
if (Adapter->m_tun)
#if 0
if (Adapter->m_tun)
{
ETH_HEADER *e;
@ -669,8 +675,9 @@ Return Value:
tapPacket->m_SizeFlags |= TP_TUN;
}
}
#endif
//===============================================
//===============================================
// Push packet onto queue to wait for read from
// userspace.
//===============================================