dhcp.c revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
/*
* TAP-Win32 -- A kernel driver to provide virtual tap device functionality
* on Windows. Originally derived from the CIPE-Win32
* project by Damion K. Wilson, with extensive modifications by
* James Yonan.
*
* All source code which derives from the CIPE-Win32 project is
* Copyright (C) Damion K. Wilson, 2003, and is released under the
* GPL version 2 (see below).
*
* All other source code is Copyright (C) 2002-2005 OpenVPN Solutions LLC,
* and is released under the GPL version 2 (see below).
*
* 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
*/
//=========================
// Code to set DHCP options
//=========================
{
if (!m->overflow)
{
{
if (len)
{
}
}
else
{
}
}
}
{
}
{
}
{
}
//==============
// Checksum code
//==============
{
int i;
// make 16 bit words out of every two adjacent 8 bit words in the packet
// and add them up
}
// take only 16 bits out of the 32 bit sum and add up the carries
while (sum >> 16)
// one's complement the result
}
const int len_udp,
{
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){
}
// add the UDP pseudo header which contains the IP source and destination addresses
for (i = 0; i < 4; i += 2){
}
for (i = 0; i < 4; i += 2){
}
// the protocol number and the length of the UDP packet
// keep only the last 16 bits of the 32 bit calculated sum and add the carries
while (sum >> 16)
// Take the one's complement of sum
}
//================================
// Set IP and UDP packet checksums
//================================
{
// Set IP checksum
// Set UDP Checksum
}
//===================
// DHCP message tests
//===================
int
{
int i;
for (i = 0; i < optlen; ++i)
{
return -1;
;
{
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)
{
}
}
}
return -1;
}
const ETH_HEADER *eth,
{
// Must be UDPv4 protocol
return FALSE;
// Source MAC must be our adapter
return FALSE;
// Dest MAC must be either broadcast or our virtual DHCP server
return FALSE;
// Port numbers must be correct
return FALSE;
// Hardware address must be MAC addr sized
return FALSE;
// Hardware address must match our adapter
return FALSE;
return TRUE;
}
//=====================================================
// Build all of DHCP packet except for DHCP options.
// Assume that *p has been zeroed before we are called.
//=====================================================
BuildDHCPPre (const TapAdapterPointer a,
DHCPPre *p,
const ETH_HEADER *eth,
const int optlen,
const int type)
{
// Should we broadcast or direct to a specific MAC / IP address?
// Build ethernet header
if (broadcast)
else
// Build IP header
if (broadcast)
else
// Build UDP header
// Build DHCP response
else
}
//=============================
// Build specific DHCP messages
//=============================
SendDHCPMsg (const TapAdapterPointer a,
const int type,
const ETH_HEADER *eth,
{
{
return;
}
if (pkt)
{
//-----------------------
// Build DHCP options
//-----------------------
// Message Type
// Server ID
{
// Lease Time
// Netmask
// Other user-defined options
}
// End
if (!DHCPMSG_OVERFLOW (pkt))
{
// The initial part of the DHCP message (not including options) gets built here
BuildDHCPPre (a,
eth,
ip,
udp,
dhcp,
type);
DUMP_PACKET ("DHCPMsg",
DHCPMSG_BUF (pkt),
DHCPMSG_LEN_FULL (pkt));
// Return DHCP response to kernel
InjectPacket (a,
DHCPMSG_BUF (pkt),
DHCPMSG_LEN_FULL (pkt));
}
else
{
DEBUGP (("[TAP] SendDHCPMsg: DHCP buffer overflow\n"));
}
}
}
//===================================================================
// Handle a BOOTPS packet produced by the local system to
// If we are in TAP_IOCTL_CONFIG_DHCP_MASQ mode, reply
// to the message. Return TRUE if we processed the passed
// message, so that downstream stages can ignore it.
//===================================================================
const ETH_HEADER *eth,
int optlen)
{
int msg_type;
// Sanity check IP header
return TRUE;
// Does this message belong to us?
return FALSE;
// Drop non-BOOTREQUEST messages
return TRUE;
// Drop any messages except DHCPDISCOVER or DHCPREQUEST
return TRUE;
// Should we reply with DHCPOFFER, DHCPACK, or DHCPNAK?
if (msg_type == DHCPREQUEST
else
// Remember if we received a DHCPDISCOVER
if (msg_type == DHCPDISCOVER)
// Is this a bad DHCPREQUEST?
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 *
{
switch (port)
{
case BOOTPS_PORT:
return "BOOTPS";
case BOOTPC_PORT:
return "BOOTPC";
default:
return "unknown";
}
}
const int optlen)
{
DEBUGP (("] -> "));
DEBUGP (("]"));
{
DEBUGP ((" ci="));
}
{
DEBUGP ((" yi="));
}
{
DEBUGP ((" si="));
}
{
DEBUGP ((" ch="));
}
// extra stuff
optlen));
// Options
{
int i;
DEBUGP ((" OPT"));
for (i = 0; i < optlen; ++i)
{
}
}
}
#endif /* DEBUG */