📄 packet.c
字号:
/*****************************************************************************/
/** Microsoft Windows **/
/** Copyright (c) 1997-2000 Microsoft Corporation. All rights reserved. **/
/*****************************************************************************/
/*
packet.c
DESCRIPTION:
DHCP packet routines
*/
#include "dhcpp.h"
#include "dhcp.h"
#include "protocol.h"
#ifdef DEBUG
LPWSTR
PacketType(
uchar Type
)
{
switch (Type) {
case DHCPDISCOVER: return L"DISCOVER";
case DHCPREQUEST: return L"REQUEST";
case DHCPINFORM: return L"INFORM";
case DHCPDECLINE: return L"DECLINE";
case DHCPRELEASE: return L"RELEASE";
default: return L"UNKNOWN";
}
}
#endif
void BuildDhcpPkt(DhcpInfo *pDhcp, DhcpPkt *pPkt, uchar Type, int Flags,
uchar *aOptionList, int *pcPkt) {
int Cookie = MAGIC_COOKIE;
uchar *p, *pEnd;
DEBUGMSG(ZONE_INIT, (TEXT("+BuildDhcpPkt: %s pDhcp 0x%X/0x%X\r\n"),
PacketType(Type), pDhcp, pDhcp->Socket));
pEnd = pPkt->aOptions + OPTIONS_LEN; // byte right after end of pkt
if (Flags & NEW_PKT_FL) {
pPkt->Op = 1;
pPkt->Htype = 1; // 10Mb Ethernet
pPkt->Hlen = ETH_ADDR_LEN;
pPkt->Hops = 0;
// now we getXid here - OM
pPkt->Xid = GetXid(pDhcp->PhysAddr);
pPkt->Xid = net_long(pPkt->Xid);
// Secs, Flags, Yiaddr, Siaddr, Giaddr should all be set to 0
pPkt->Secs = pPkt->Flags = pPkt->Ciaddr = pPkt->Yiaddr =
pPkt->Siaddr = pPkt->Giaddr = 0; // erase any previous value
memset(pPkt->aChaddr, 0, CHADDR_LEN + SNAME_LEN + FILE_LEN);
memcpy(pPkt->aChaddr, pDhcp->PhysAddr, ETH_ADDR_LEN);
memcpy(pPkt->aOptions, &Cookie, 4);
}
if ((Flags & RIP_PKT_FL) == 0)
pPkt->Ciaddr = pDhcp->IPAddr;
p = pPkt->aOptions + 4;
// Set the Message Type
*p++ = DHCP_MSG_TYPE_OP;
*p++ = 1; // option length
*p++ = Type;
switch(Type) {
case DHCPREQUEST:
// Server Identifier
if (Flags & SID_PKT_FL) {
*p++ = DHCP_SERVER_ID_OP;
*p++ = 4;
memcpy(p, &pDhcp->DhcpServer, 4);
p += 4;
}
// no break, fall-thru
case DHCPDISCOVER:
// Requested Addr
if (pDhcp->IPAddr && (Flags & RIP_PKT_FL)) {
*p++ = DHCP_REQ_IP_OP;
*p++ = 4;
memcpy(p, &pDhcp->IPAddr, 4);
p += 4;
}
// IP address lease should also be done before DHCPINFORM
// no break, fall-thru
case DHCPINFORM:
// Set the Client Id
*p++ = DHCP_CLIENT_ID_OP;
*p++ = 7; // op len
*p++ = 1; // Type - 10Mb Ethernet
memcpy(p, &pDhcp->PhysAddr, ETH_ADDR_LEN); p += ETH_ADDR_LEN;
/* Host Name Option
*p++ = DHCP_HOST_NAME_OP;
*p++ = 0; // len of name
memcpy();
*/
// Parameter Request List
if (aOptionList && aOptionList[0] &&
aOptionList[0] <= (pEnd - p)) {
*p++ = DHCP_PARAMETER_REQ_OP;
memcpy (p, aOptionList, aOptionList[0] + 1); // +1 for len
p += aOptionList[0] + 1; // +1 for length
}
if (pDhcp->pSendOptions) {
memcpy(p, pDhcp->pSendOptions, pDhcp->cSendOptions);
p += pDhcp->cSendOptions;
}
// End Option
*p++ = DHCP_END_OP;
break;
case DHCPDECLINE:
// Requested Addr
*p++ = DHCP_REQ_IP_OP;
*p++ = 4;
memcpy(p, &pDhcp->IPAddr, 4);
p += 4;
// no break, fall-thru
case DHCPRELEASE:
// Set the Client Id
*p++ = DHCP_CLIENT_ID_OP;
*p++ = 7; // op len
*p++ = 1; // Type - 10Mb Ethernet
memcpy(p, pDhcp->PhysAddr, ETH_ADDR_LEN);
p += ETH_ADDR_LEN;
// Server Identifier
*p++ = DHCP_SERVER_ID_OP;
*p++ = 4;
memcpy(p, &pDhcp->DhcpServer, 4);
p += 4;
// we should also do Message Option
// End Option
*p++ = DHCP_END_OP;
break;
default:
DEBUGMSG(ZONE_ERROR,
(TEXT("\t!BuildDhcpPkt: unknown packet type (%d) requested\r\n"),
Type));
break;
} // switch(Type)
if (p < pEnd)
memset(p, DHCP_PAD_OP, pEnd - p);
if (pcPkt)
*pcPkt = p - (char *)pPkt;
DEBUGMSG(ZONE_INIT, (TEXT("-BuildDhcpPkt: pDhcp 0x%X/0x%X Len %d\r\n"),
pDhcp, pDhcp->Socket, (p - (char *)pPkt)));
} // BuildDhcpPkt()
void Tvert(uchar c, TCHAR *p) {
if (c >= 100)
p++;
if (c >= 10)
p++;
*(p+1) = TEXT('\0');
do {
*p-- = TEXT('0') + (c % 10);
} while (c /= 10);
}
#define MIN_LEASE_TIME 1
STATUS TranslatePkt(DhcpInfo *pDhcp, DhcpPkt *pPkt, int cPkt, uchar *pType,
unsigned int Xid) {
STATUS Status = DHCP_FAILURE; // assume failure
int i, fSaveReg, Cookie = MAGIC_COOKIE;
uchar *p, Type = 0;
TCHAR szBuf[MAX_REG_STR];
HKEY hKey;
LONG hRes;
DWORD cData;
uint NewSubnetMask, fSubnetMask;
uint NewGateway, fGateway;
uint NewLease, fLease;
uint NewServer, fServer;
uint NewT1, fT1;
uint NewT2, fT2;
uint NewDNS[2], fDNS;
uint NewWins[2], fWins;
uchar * pnew;
DEBUGMSG(ZONE_RECV,
(TEXT("DHCP:+TranslatePkt: pDhcp %X: OP %d, Htype %d, Xid %x/%x\r\n"),
pDhcp, pPkt->Op, pPkt->Htype, pPkt->Xid, Xid));
fSubnetMask = fGateway = fLease = fServer = fT1 = fT2 = fDNS = fWins = fSaveReg = FALSE;
if (cPkt >= (sizeof(*pPkt) - OPTIONS_LEN + 4) &&
2 == pPkt->Op &&
1 == pPkt->Htype &&
Xid == pPkt->Xid &&
0 == memcmp(&Cookie, pPkt->aOptions, 4) &&
((pDhcp->Flags & NO_MAC_COMPARE_FL) || (pPkt->Hlen == 6 &&
(0 == memcmp(pDhcp->PhysAddr, pPkt->aChaddr, 6))))) {
pDhcp->SFlags |= DHCPSTATE_SAW_DHCP_SRV; // There is a DHCP server on the net.
//
// Scan through the options once without storing config options so we can
// perform some sanity checks first.
// (The number of options checked will increase as we get more input from QA and customers)
//
p = &pPkt->aOptions[4];
while (p < (char *)pPkt + cPkt) {
i = 4;
pnew = NULL;
switch (*p) {
//
// These are the 4 byte (i=4) cases
//
case DHCP_SUBNET_OP:
pnew = (uchar *) &NewSubnetMask;
fSubnetMask++;
break;
case DHCP_IP_LEASE_OP:
pnew = (uchar *) &NewLease;
fLease++;
break;
case DHCP_SERVER_ID_OP:
pnew = (uchar *) &NewServer;
fServer++;
break;
case DHCP_ROUTER_OP:
pnew = (uchar *) &NewGateway;
fGateway++;
break;
case DHCP_T1_VALUE_OP:
pnew = (uchar *) &NewT1;
fT1++;
break;
case DHCP_T2_VALUE_OP:
pnew = (uchar *) &NewT2;
fT2++;
break;
//
// Up to 8 byte options
//
case DHCP_DNS_OP:
NewDNS[0] = 0;
NewDNS[1] = 0;
if ((i = p[1]) > 8) {
i = 8;
}
pnew = (uchar *)NewDNS;
fDNS++;
break;
case DHCP_NBT_SRVR_OP:
NewWins[0] = 0;
NewWins[1] = 0;
if ((i = p[1]) > 8) {
i = 8;
}
pnew = (uchar *)NewWins;
fWins++;
break;
//
// Special cases
//
case DHCP_MSG_TYPE_OP:
Type = p[2];
if (*pType && Type != *pType) {
Status = DHCP_SUCCESS;
DEBUGMSG(ZONE_RECV, (TEXT("DHCP:TranslatePkt: Type = %d, expecting %d\n"), Type, *pType));
goto BreakLoop;
}
break;
case DHCP_MSFT_AUTOCONF:
if (p[1] != 1) {
DEBUGMSG(ZONE_RECV, (TEXT("DHCP:TranslatePkt: AutoConfig Option Len = %d, expecting 1\n"), p[1]));
goto BreakLoop;
}
break;
case DHCP_PAD_OP:
p++;
continue;
break;
case DHCP_END_OP:
goto VerifyOptions;
break;
}
if (pnew) {
// verify length
if (p + i > (char *)pPkt + cPkt) {
DEBUGMSG(ZONE_RECV, (TEXT("DHCP:TranslatePkt: Length %d too long for option %d\n"), i, *p));
goto BreakLoop;
}
memcpy(pnew, p+2, i);
}
p += p[1] + 2;
}
VerifyOptions:
//
// Make sure config options seem reasonable
//
if (fSubnetMask) {
if (NewSubnetMask == 0) {
DEBUGMSG(ZONE_RECV, (TEXT("DHCP:TranslatePkt: Invalid subnet mask %d\n"), NewSubnetMask));
goto BreakLoop;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -