⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 packet.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************/
/**                                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 + -