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

📄 packet.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 2 页
字号:

        if (fLease) {
            if (NewLease < MIN_LEASE_TIME && Type == DHCPACK) {
                DEBUGMSG(ZONE_RECV, (TEXT("DHCP:TranslatePkt: Invalid lease time %d < %d\n"), NewLease, MIN_LEASE_TIME));
                goto BreakLoop;
            }
        } else {
            if (Type == DHCPACK) {
                DEBUGMSG(ZONE_RECV, (TEXT("DHCP:TranslatePkt: No lease specified in DHCPACK!\n")));
                goto BreakLoop;
            }
        }

        if (fServer) {
            if (NewServer == 0) {
                DEBUGMSG(ZONE_RECV, (TEXT("DHCP:TranslatePkt: Invalid server id %d\n"), NewServer));
                goto BreakLoop;
            }
        }

        //
        // Make sure the ipaddr and subnet mask match if this is a renewal
        //
        if (*pType == DHCPACK && pDhcp->IPAddr) {
            if (pDhcp->IPAddr != pPkt->Yiaddr) {
                DEBUGMSG(ZONE_RECV,(TEXT("DHCP:TranslatePkt: Mismatch in IP addr - rcvd 0x%X, expect 0x%X\r\n"),
                                    pPkt->Yiaddr,pDhcp->IPAddr));
                goto BreakLoop;
            }
            if (pDhcp->SubnetMask != NewSubnetMask) {
                DEBUGMSG(ZONE_RECV,(TEXT("DHCP:TranslatePkt: Mismatch in subnet - rcvd 0x%X, expect 0x%X\r\n"),
                                    NewSubnetMask,pDhcp->SubnetMask));
                goto BreakLoop;
            }
        }

        //
        // Open registry key to save new values
        //
        if (DHCPACK == Type) {
            _tcscpy (szBuf, COMM_REG_KEY);
            _tcscat (szBuf, pDhcp->Name);
            _tcscat (szBuf, TEXT("\\Parms\\TcpIp\\DhcpOptions"));
            hRes = RegOpenKeyEx (HKEY_LOCAL_MACHINE, szBuf, 0, 0, 
                &hKey);
            if (ERROR_SUCCESS == hRes) {
                DEBUGMSG(ZONE_RECV, 
                    (TEXT("DHCP:TranslatePacket: Save in registry\r\n")));
                fSaveReg = TRUE;
            }
        }

        //
        // Now run through the options again and store away results
        //
        p = &pPkt->aOptions[4];
        while (p < (char *)pPkt + cPkt) {
            switch(*p) {
            case DHCP_PAD_OP:
                p++;
                continue;
                break;
            case DHCP_END_OP:
                Status = DHCP_SUCCESS;
                goto BreakLoop;
                break;
            case DHCP_SUBNET_OP:
                pDhcp->SubnetMask = NewSubnetMask;
                break;
            case DHCP_ROUTER_OP:
                pDhcp->Gateway = NewGateway;
                break;
            case DHCP_DNS_OP:
                pDhcp->DNS[0] = NewDNS[0];
                pDhcp->DNS[1] = NewDNS[1];
                break;
            case DHCP_DOMAIN_NAME_OP:
                if (p[1] > MAX_DOMAIN_NAME)
                    p[1] = (uchar)MAX_DOMAIN_NAME;
                memcpy(pDhcp->aDomainName, p+1, p[1] + 1);
                break;
            case DHCP_NBT_SRVR_OP:
                pDhcp->WinsServer[0] = NewWins[0];
                pDhcp->WinsServer[1] = NewWins[1];
                break;
            case DHCP_IP_LEASE_OP:
                pDhcp->Lease = net_long(NewLease);
                break;
            case DHCP_SERVER_ID_OP:
                pDhcp->DhcpServer = NewServer;
                break;
            case DHCP_T1_VALUE_OP:
                pDhcp->T1 = net_long(NewT1);
                break;
            case DHCP_T2_VALUE_OP:
                pDhcp->T2 = net_long(NewT2);
                break;

            case DHCP_MSFT_AUTOCONF:
                if (p[2]) {
                    pDhcp->Flags |= AUTO_IP_ENABLED_FL;
                } else {
                    pDhcp->Flags &= ~AUTO_IP_ENABLED_FL;
                }
                break;

            case DHCP_OVERLOAD_OP:
                ASSERT(0);                 break;

            case DHCP_MSG_TYPE_OP:
            case DHCP_MESSAGE_OP:       // NYI
            case DHCP_NBT_NODE_TYPE_OP: // NYI
            case DHCP_HOST_NAME_OP:     // NYI
                break;

            default:
                DEBUGMSG(ZONE_RECV, 
                    (TEXT("DHCP:TranslatePkt: Unexpected option %d\r\n"), *p));
                break;
            }    // switch(*p)

            if (fSaveReg) {
                Tvert(*p, szBuf);
                cData = 0;
                hRes = RegQueryValueEx(hKey, szBuf, NULL, NULL, NULL, &cData);
                if (ERROR_SUCCESS == hRes && cData)
                    SetRegBinaryValue(hKey, szBuf, p, p[1] + 2);
            }

            p += p[1] + 2;

        }    // while (...)

        DEBUGMSG(ZONE_RECV, (TEXT("DHCP:TranslatePkt: No DHCP_END_OP in packet!!\n")));

BreakLoop:        
        if (Status == DHCP_SUCCESS && (Type == DHCPOFFER || Type == DHCPACK)) {
            if (fLease) {
                if (! fT1)
                    pDhcp->T1 = pDhcp->Lease >> 1;      // default half lease time
                if (! fT2)
                    pDhcp->T2 = (pDhcp->Lease * 7) >> 3;    // dft: 7/8 lease time
                memcpy(&pDhcp->IPAddr, &pPkt->Yiaddr, 4);
            }
        }

    } else {
#if DEBUG

		if (cPkt < (sizeof(*pPkt) - OPTIONS_LEN + 4))
			DEBUGMSG(ZONE_RECV, 
				(TEXT("DHCP:Translate: packet too small %d\r\n"),
				cPkt));
		// we can continue--since pPkt is a ptr to our own packet which we know is
		// larger than the minimum dhcp packet

        if (2 != pPkt->Op) 
            DEBUGMSG(ZONE_RECV, (TEXT("DHCP:TranslatePkt: Op %d != 2\n"), 
	            pPkt->Op));
        if (1 != pPkt->Htype)
            DEBUGMSG(ZONE_RECV, 
	            (TEXT("DHCP:TranslatePkt: Htype %d != 1\n"), pPkt->Htype));
        if (Xid != pPkt->Xid)
            DEBUGMSG(ZONE_RECV, 
	            (TEXT("DHCP:TranslatePkt: Xid 0x%x != 0x%x\n"), pPkt->Xid, Xid));
        if (0 != memcmp(&Cookie, pPkt->aOptions, 4))
            DEBUGMSG(ZONE_RECV, 
	            (TEXT("DHCP:TranslatePkt: Cookie %B%B%B%B != %X\n"),
	            pPkt->aOptions[3], pPkt->aOptions[2], pPkt->aOptions[1], 
	            pPkt->aOptions[0], Cookie));

#endif                                 
    }

    if (fSaveReg)
        RegCloseKey(hKey);

    if (pType)
        *pType = Type;
    
    DEBUGMSG(ZONE_RECV, (TEXT("DHCP:-TranslatePkt: pDhcp %X Type %d, Ret: %d\r\n"),
        pDhcp, Type, Status));
    return Status;

}    // TranslatePkt()


STATUS DhcpSendDown(DhcpInfo *pDhcp, DhcpPkt *pPkt, int cPkt, int DestIP) {
    SOCKADDR_IN SockAddr;
    STATUS        Status;
    int            cSent;

    if (cPkt < 300)
        cPkt = 300;

    memset(&SockAddr, 0, sizeof(SockAddr));
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_port = net_short(DHCP_SERVER_PORT);
    SockAddr.sin_addr.S_un.S_addr = DestIP;
    
    Status = CallSock(Send)(pDhcp->Socket, (char *)pPkt, cPkt,
        0, (SOCKADDR *)&SockAddr, sizeof(SockAddr), &cSent, NULL);

    DEBUGMSG(ZONE_SEND, 
        (TEXT("*DhcpSendDown: Dest %d/%x, Sent %d/%d Status %d\r\n"),
        DHCP_SERVER_PORT, pDhcp->IPAddr, cSent, 
        cPkt, Status));

    return Status;
}    // DhcpSendDown()


#define MAX_LOOP    4

STATUS SendDhcpPkt(DhcpInfo *pDhcp, DhcpPkt *pPkt, int cPkt, 
                   uchar WaitforType, int Flags) {
    STATUS        Status = DHCP_FAILURE;
    int            cLoop, cTimeLeft, cTimeout, cMultiplier;
    int            cFuzz = 0;
    DWORD        cBeginTime, cZeroTime;
    struct timeval    Timeval;
    LPSOCK_INFO    Sock;
    SOCK_LIST    ReadList;
    DhcpPkt        RcvPkt;
    int            cRcvd, cRcvPkt;
    uchar        Type;
    int            fSend = TRUE;
    int            cMaxLoop;
    int            DestIP;

    DEBUGMSG(ZONE_SEND, (TEXT("+SendDhcpPkt: pDhcp %X pPkt %X\r\n"), 
        pDhcp, pPkt));

    Sock = pDhcp->Socket;
    if (BCAST_FL & Flags)
        DestIP = INADDR_BROADCAST;
    else
        DestIP = pDhcp->DhcpServer;

    cRcvPkt = sizeof(RcvPkt);
    CTEFreeLock(&pDhcp->Lock, 0);

	cMaxLoop = Flags & LOOP_MASK_FL;

    cLoop = 0;

    if (pDhcp->Flags & AUTO_IP_ENABLED_FL) {
        cTimeout = 1500;
        cMultiplier = 1;
    } else {
        cTimeout = 4000;
        cMultiplier = 2;
    }

    cZeroTime = GetTickCount();
    // add random fuzz of +/- 1 sec.
    cFuzz = (GetTickCount() % 2000) - 1000;
    cTimeLeft = cTimeout + cFuzz;
    pDhcp->SFlags &= ~DHCPSTATE_SAW_DHCP_SRV;
    do {
        cBeginTime = GetTickCount();
        
        if (fSend) {
            pPkt->Secs = (unsigned short)((cBeginTime - cZeroTime) / 1000);
            if (Status = DhcpSendDown(pDhcp, pPkt, cPkt, DestIP))
                break;
        }

        // wait only 8 secs (2 x min time) after last packet
        if ((cLoop != 1) && ((cLoop + 1) == cMaxLoop) && (cTimeLeft > 8000))
            cTimeLeft = 8000 + cFuzz;
        
        ASSERT((cTimeLeft >= 0) && (cTimeLeft < 62000));
        if (cTimeLeft < 0)
            cTimeLeft = 0;
        if (cTimeLeft > 62000)
            cTimeLeft = 62000;

        // do select w/ timeout
        Timeval.tv_sec = cTimeLeft / 1000;
        Timeval.tv_usec = (cTimeLeft % 1000)*1000;
        
        ReadList.hSocket = 0;
        ReadList.Socket = Sock;
        ReadList.EventMask = READ_EVENTS;

        Status = CallAfd(Select)(1, &ReadList, 0, NULL, 0, NULL, &Timeval, NULL);

        if (Status)
            break;
        if (ReadList.Socket) {    // there is data
            cRcvPkt = sizeof(RcvPkt);
            
            Status = CallSock(Recv)(Sock, (char *)&RcvPkt, cRcvPkt, 0, NULL, NULL, &cRcvd, NULL);

            if (Status) {
                DEBUGMSG(ZONE_SEND, (TEXT("SendDhcpPkt: Recv() failed %d\n"), Status));
                break;
            }

            Type = WaitforType;
            Status = TranslatePkt(pDhcp, &RcvPkt, cRcvd, &Type, pPkt->Xid);

            if (DHCP_SUCCESS == Status) {
                if (Type == WaitforType)
                    break;
                else if (DHCPNACK == Type) {
                    Status = DHCP_NACK;
                    break;
                }
            }
            // this should work as long as the difference is not huge
            cTimeLeft -= GetTickCount() - cBeginTime;
        } else    {    // Select timed out
            DEBUGMSG(ZONE_SEND, (TEXT("SendDhcpPkt: Select() timed out\n")));                        
            Status = DHCP_FAILURE;
            cTimeLeft = 0;
        }

        if (cTimeLeft <= 0) {
            cFuzz = (GetTickCount() % 2000) - 1000;
            cTimeLeft = (cTimeout *= cMultiplier) + cFuzz;
            cLoop++;
            fSend = TRUE;
        } else
            fSend = FALSE;

    } while (cLoop < cMaxLoop);

    DEBUGMSG(ZONE_SEND, (TEXT("-SendDhcpPkt: pDhcp %X pPkt %X Ret: %d\r\n"), 
        pDhcp, pPkt, Status));
    
    CTEGetLock(&pDhcp->Lock, 0);

    return Status;

}    // SendDhcpPkt()



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -