packet.c
来自「wince下的源代码集合打包」· C语言 代码 · 共 685 行 · 第 1/2 页
C
685 行
/*****************************************************************************//** 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 DEBUGLPWSTRPacketType( 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"; }}#endifvoid 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 1STATUS 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 + =
减小字号Ctrl + -
显示快捷键?