packet.c

来自「wince下的源代码集合打包」· C语言 代码 · 共 685 行 · 第 1/2 页

C
685
字号
        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    4STATUS 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 + =
减小字号Ctrl + -
显示快捷键?