mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 20:43:44 +02:00
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:
parent
1ebe2ad920
commit
d4c06e924d
12 changed files with 81 additions and 901 deletions
|
@ -213,7 +213,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="adapter.c" />
|
<ClCompile Include="adapter.c" />
|
||||||
<ClCompile Include="device.c" />
|
<ClCompile Include="device.c" />
|
||||||
<ClCompile Include="dhcp.c" />
|
|
||||||
<ClCompile Include="error.c" />
|
<ClCompile Include="error.c" />
|
||||||
<ClCompile Include="macinfo.c" />
|
<ClCompile Include="macinfo.c" />
|
||||||
<ClCompile Include="mem.c" />
|
<ClCompile Include="mem.c" />
|
||||||
|
@ -227,7 +226,6 @@
|
||||||
<ClInclude Include="config.h" />
|
<ClInclude Include="config.h" />
|
||||||
<ClInclude Include="constants.h" />
|
<ClInclude Include="constants.h" />
|
||||||
<ClInclude Include="device.h" />
|
<ClInclude Include="device.h" />
|
||||||
<ClInclude Include="dhcp.h" />
|
|
||||||
<ClInclude Include="endian.h" />
|
<ClInclude Include="endian.h" />
|
||||||
<ClInclude Include="error.h" />
|
<ClInclude Include="error.h" />
|
||||||
<ClInclude Include="hexdump.h" />
|
<ClInclude Include="hexdump.h" />
|
||||||
|
|
|
@ -25,9 +25,6 @@
|
||||||
<ClCompile Include="device.c">
|
<ClCompile Include="device.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<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>
|
||||||
|
@ -63,9 +60,6 @@
|
||||||
<ClInclude Include="device.h">
|
<ClInclude Include="device.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>
|
||||||
|
|
|
@ -170,6 +170,7 @@ typedef struct _TAP_ADAPTER_CONTEXT
|
||||||
#define TAP_WAIT_POLL_LOOP_TIMEOUT 3000 // 3 seconds
|
#define TAP_WAIT_POLL_LOOP_TIMEOUT 3000 // 3 seconds
|
||||||
NDIS_EVENT ReceiveNblInFlightCountZeroEvent;
|
NDIS_EVENT ReceiveNblInFlightCountZeroEvent;
|
||||||
|
|
||||||
|
/*
|
||||||
// Info for point-to-point mode
|
// Info for point-to-point mode
|
||||||
BOOLEAN m_tun;
|
BOOLEAN m_tun;
|
||||||
IPADDR m_localIP;
|
IPADDR m_localIP;
|
||||||
|
@ -178,8 +179,10 @@ typedef struct _TAP_ADAPTER_CONTEXT
|
||||||
ETH_HEADER m_TapToUser;
|
ETH_HEADER m_TapToUser;
|
||||||
ETH_HEADER m_UserToTap;
|
ETH_HEADER m_UserToTap;
|
||||||
ETH_HEADER m_UserToTap_IPv6; // same as UserToTap but proto=ipv6
|
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;
|
BOOLEAN m_dhcp_enabled;
|
||||||
IPADDR m_dhcp_addr;
|
IPADDR m_dhcp_addr;
|
||||||
ULONG m_dhcp_netmask;
|
ULONG m_dhcp_netmask;
|
||||||
|
@ -191,6 +194,7 @@ typedef struct _TAP_ADAPTER_CONTEXT
|
||||||
ULONG m_dhcp_user_supplied_options_buffer_len;
|
ULONG m_dhcp_user_supplied_options_buffer_len;
|
||||||
BOOLEAN m_dhcp_received_discover;
|
BOOLEAN m_dhcp_received_discover;
|
||||||
ULONG m_dhcp_bad_requests;
|
ULONG m_dhcp_bad_requests;
|
||||||
|
*/
|
||||||
|
|
||||||
// Multicast list. Fixed size.
|
// Multicast list. Fixed size.
|
||||||
ULONG ulMCListSize;
|
ULONG ulMCListSize;
|
||||||
|
|
|
@ -69,7 +69,8 @@
|
||||||
//===========================================================
|
//===========================================================
|
||||||
|
|
||||||
#define ETHERNET_HEADER_SIZE (sizeof (ETH_HEADER))
|
#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 ETHERNET_PACKET_SIZE (ETHERNET_MTU + ETHERNET_HEADER_SIZE)
|
||||||
#define DEFAULT_PACKET_LOOKAHEAD (ETHERNET_PACKET_SIZE)
|
#define DEFAULT_PACKET_LOOKAHEAD (ETHERNET_PACKET_SIZE)
|
||||||
#define VLAN_TAG_SIZE 4
|
#define VLAN_TAG_SIZE 4
|
||||||
|
@ -108,7 +109,7 @@
|
||||||
#define TAP_RECV_SPEED (100ULL*MEGABITS_PER_SECOND)
|
#define TAP_RECV_SPEED (100ULL*MEGABITS_PER_SECOND)
|
||||||
|
|
||||||
// Max number of multicast addresses supported in hardware
|
// 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_MAX_LOOKAHEAD TAP_FRAME_MAX_DATA_SIZE
|
||||||
#define TAP_BUFFER_SIZE TAP_MAX_FRAME_SIZE
|
#define TAP_BUFFER_SIZE TAP_MAX_FRAME_SIZE
|
||||||
|
@ -137,7 +138,7 @@
|
||||||
NDIS_PACKET_TYPE_PROMISCUOUS | \
|
NDIS_PACKET_TYPE_PROMISCUOUS | \
|
||||||
NDIS_PACKET_TYPE_ALL_MULTICAST)
|
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.
|
// Specify a bitmask that defines optional properties of the NIC.
|
||||||
|
|
|
@ -48,6 +48,7 @@ VOID tapResetAdapterState(
|
||||||
__in PTAP_ADAPTER_CONTEXT Adapter
|
__in PTAP_ADAPTER_CONTEXT Adapter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
// Point-To-Point
|
// Point-To-Point
|
||||||
Adapter->m_tun = FALSE;
|
Adapter->m_tun = FALSE;
|
||||||
Adapter->m_localIP = 0;
|
Adapter->m_localIP = 0;
|
||||||
|
@ -56,8 +57,10 @@ VOID tapResetAdapterState(
|
||||||
NdisZeroMemory (&Adapter->m_TapToUser, sizeof (Adapter->m_TapToUser));
|
NdisZeroMemory (&Adapter->m_TapToUser, sizeof (Adapter->m_TapToUser));
|
||||||
NdisZeroMemory (&Adapter->m_UserToTap, sizeof (Adapter->m_UserToTap));
|
NdisZeroMemory (&Adapter->m_UserToTap, sizeof (Adapter->m_UserToTap));
|
||||||
NdisZeroMemory (&Adapter->m_UserToTap_IPv6, sizeof (Adapter->m_UserToTap_IPv6));
|
NdisZeroMemory (&Adapter->m_UserToTap_IPv6, sizeof (Adapter->m_UserToTap_IPv6));
|
||||||
|
*/
|
||||||
|
|
||||||
// DHCP Masq
|
// DHCP Masq
|
||||||
|
/*
|
||||||
Adapter->m_dhcp_enabled = FALSE;
|
Adapter->m_dhcp_enabled = FALSE;
|
||||||
Adapter->m_dhcp_server_arp = FALSE;
|
Adapter->m_dhcp_server_arp = FALSE;
|
||||||
Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
|
Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
|
||||||
|
@ -68,6 +71,7 @@ VOID tapResetAdapterState(
|
||||||
Adapter->m_dhcp_received_discover = FALSE;
|
Adapter->m_dhcp_received_discover = FALSE;
|
||||||
Adapter->m_dhcp_bad_requests = 0;
|
Adapter->m_dhcp_bad_requests = 0;
|
||||||
NdisZeroMemory (Adapter->m_dhcp_server_mac, MACADDR_SIZE);
|
NdisZeroMemory (Adapter->m_dhcp_server_mac, MACADDR_SIZE);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// IRP_MJ_CREATE
|
// IRP_MJ_CREATE
|
||||||
|
@ -278,6 +282,7 @@ tapSetMediaConnectStatus(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
//======================================================
|
//======================================================
|
||||||
// If DHCP mode is used together with tun
|
// If DHCP mode is used together with tun
|
||||||
// mode, consider the fact that the P2P remote subnet
|
// mode, consider the fact that the P2P remote subnet
|
||||||
|
@ -297,6 +302,7 @@ CheckIfDhcpAndTunMode (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// IRP_MJ_DEVICE_CONTROL callback.
|
// IRP_MJ_DEVICE_CONTROL callback.
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -428,6 +434,36 @@ Return Value:
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case TAP_WIN_IOCTL_CONFIG_TUN:
|
||||||
{
|
{
|
||||||
if(inBufLength >= sizeof(IPADDR)*3)
|
if(inBufLength >= sizeof(IPADDR)*3)
|
||||||
|
@ -513,7 +549,9 @@ Return Value:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
case TAP_WIN_IOCTL_CONFIG_DHCP_MASQ:
|
case TAP_WIN_IOCTL_CONFIG_DHCP_MASQ:
|
||||||
{
|
{
|
||||||
if(inBufLength >= sizeof(IPADDR)*4)
|
if(inBufLength >= sizeof(IPADDR)*4)
|
||||||
|
@ -586,7 +624,9 @@ Return Value:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
case TAP_WIN_IOCTL_GET_INFO:
|
case TAP_WIN_IOCTL_GET_INFO:
|
||||||
{
|
{
|
||||||
char state[16];
|
char state[16];
|
||||||
|
@ -657,7 +697,7 @@ Return Value:
|
||||||
// BUGBUG!!! Fail because this is not completely implemented.
|
// BUGBUG!!! Fail because this is not completely implemented.
|
||||||
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
|
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
}
|
}
|
||||||
break;
|
#endif
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
case TAP_WIN_IOCTL_GET_LOG_LINE:
|
case TAP_WIN_IOCTL_GET_LOG_LINE:
|
||||||
|
|
|
@ -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 */
|
|
|
@ -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
|
|
|
@ -64,6 +64,7 @@ IndicateReceivePacket(
|
||||||
__in const unsigned int packetLength
|
__in const unsigned int packetLength
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
ProcessDHCP(
|
ProcessDHCP(
|
||||||
__in PTAP_ADAPTER_CONTEXT Adapter,
|
__in PTAP_ADAPTER_CONTEXT Adapter,
|
||||||
|
@ -73,7 +74,9 @@ ProcessDHCP(
|
||||||
__in const DHCP *dhcp,
|
__in const DHCP *dhcp,
|
||||||
__in int optlen
|
__in int optlen
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
ProcessARP(
|
ProcessARP(
|
||||||
__in PTAP_ADAPTER_CONTEXT Adapter,
|
__in PTAP_ADAPTER_CONTEXT Adapter,
|
||||||
|
@ -83,5 +86,6 @@ ProcessARP(
|
||||||
__in const IPADDR ip_netmask,
|
__in const IPADDR ip_netmask,
|
||||||
__in const MACADDR mac
|
__in const MACADDR mac
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -432,7 +432,7 @@ TapDeviceWrite(
|
||||||
//
|
//
|
||||||
if(tapAdapterSendAndReceiveReady(adapter) == NDIS_STATUS_SUCCESS)
|
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;
|
PNET_BUFFER_LIST netBufferList;
|
||||||
|
|
||||||
|
@ -514,6 +514,7 @@ TapDeviceWrite(
|
||||||
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
|
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
else if (adapter->m_tun && ((irpSp->Parameters.Write.Length) >= IP_HEADER_SIZE))
|
else if (adapter->m_tun && ((irpSp->Parameters.Write.Length) >= IP_HEADER_SIZE))
|
||||||
{
|
{
|
||||||
PETH_HEADER p_UserToTap = &adapter->m_UserToTap;
|
PETH_HEADER p_UserToTap = &adapter->m_UserToTap;
|
||||||
|
@ -637,6 +638,7 @@ TapDeviceWrite(
|
||||||
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
|
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n",
|
DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n",
|
||||||
|
|
|
@ -38,17 +38,24 @@
|
||||||
#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_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_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_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)
|
//#define TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT TAP_WIN_CONTROL_CODE (9, METHOD_BUFFERED)
|
||||||
|
|
||||||
/* Added in 8.2 */
|
/* Added in 8.2 */
|
||||||
|
|
||||||
/* obsoletes TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT */
|
/* 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)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =================
|
* =================
|
||||||
|
|
|
@ -42,10 +42,8 @@
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "macinfo.h"
|
#include "macinfo.h"
|
||||||
#include "dhcp.h"
|
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "endian.h"
|
#include "endian.h"
|
||||||
#include "dhcp.h"
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "adapter.h"
|
#include "adapter.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
|
|
@ -82,6 +82,8 @@ icmpv6_checksum(
|
||||||
return ((USHORT) ~sum);
|
return ((USHORT) ~sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
// check IPv6 packet for "is this an IPv6 Neighbor Solicitation that
|
// check IPv6 packet for "is this an IPv6 Neighbor Solicitation that
|
||||||
// the tap driver needs to answer?"
|
// the tap driver needs to answer?"
|
||||||
// see RFC 4861 4.3 for the different cases
|
// see RFC 4861 4.3 for the different cases
|
||||||
|
@ -267,6 +269,7 @@ ProcessARP(
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
//=============================================================
|
//=============================================================
|
||||||
// CompleteIRP is normally called with an adapter -> userspace
|
// CompleteIRP is normally called with an adapter -> userspace
|
||||||
|
@ -537,6 +540,7 @@ Return Value:
|
||||||
// If so, catch both DHCP requests and ARP queries
|
// If so, catch both DHCP requests and ARP queries
|
||||||
// to resolve the address of our virtual DHCP server.
|
// to resolve the address of our virtual DHCP server.
|
||||||
//=====================================================
|
//=====================================================
|
||||||
|
#if 0
|
||||||
if (Adapter->m_dhcp_enabled)
|
if (Adapter->m_dhcp_enabled)
|
||||||
{
|
{
|
||||||
const ETH_HEADER *eth = (ETH_HEADER *) tapPacket->m_Data;
|
const ETH_HEADER *eth = (ETH_HEADER *) tapPacket->m_Data;
|
||||||
|
@ -594,6 +598,7 @@ Return Value:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//===============================================
|
//===============================================
|
||||||
// In Point-To-Point mode, check to see whether
|
// In Point-To-Point mode, check to see whether
|
||||||
|
@ -602,6 +607,7 @@ Return Value:
|
||||||
// (to be handled locally), and the rest is forwarded
|
// (to be handled locally), and the rest is forwarded
|
||||||
// all other protocols are dropped
|
// all other protocols are dropped
|
||||||
//===============================================
|
//===============================================
|
||||||
|
#if 0
|
||||||
if (Adapter->m_tun)
|
if (Adapter->m_tun)
|
||||||
{
|
{
|
||||||
ETH_HEADER *e;
|
ETH_HEADER *e;
|
||||||
|
@ -669,6 +675,7 @@ Return Value:
|
||||||
tapPacket->m_SizeFlags |= TP_TUN;
|
tapPacket->m_SizeFlags |= TP_TUN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//===============================================
|
//===============================================
|
||||||
// Push packet onto queue to wait for read from
|
// Push packet onto queue to wait for read from
|
||||||
|
|
Loading…
Add table
Reference in a new issue