|
@@ -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 */
|