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 + -
显示快捷键?