12 changed files with 81 additions and 901 deletions
@ -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 |
||||
Loading…
Reference in new issue