autonet.c

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

C
538
字号
/*****************************************************************************//**                   Microsoft Windows                                     **//**   Copyright (c) 1999-2000 Microsoft Corporation.  All rights reserved.  **//*****************************************************************************//*    autonet.c  DESCRIPTION:    Automatic IP configuration functions*/#include "dhcpp.h"#include "dhcp.h"#include "protocol.h"#include "icmpif.h"#define DHCP_IPAUTOCONFIGURATION_ATTEMPTS   20void ProcessAutoIP(DhcpInfo *pDhcp);extern DhcpInfo **_FindDhcp(DhcpInfo *pDhcp, PTSTR pName);  // dhcp.cextern void FreeDhcpInfo(DhcpInfo *pDhcp);          // dhcp.cextern void CloseDhcpSocket(DhcpInfo *pDhcp);       // dhcp.cextern STATUS SetDhcpConfig(DhcpInfo *pDhcp);       // dhcp.cextern STATUS PutNetUp(DhcpInfo *pDhcp);            // dhcp.cextern BOOL CanUseCachedLease(DhcpInfo * pDhcp);    // dhcp.cextern void NotifyXxxChange(HANDLE hEvent);           // dhcp.cextern HANDLE	g_hAddrChangeEvent;                 // dhcp.c#define DHCP_ICMP_WAIT_TIME     1000#define DHCP_ICMP_RCV_BUF_SIZE  0x1000#define DHCP_ICMP_SEND_MESSAGE  "DHCPC"typedef ULONG (* PFN_VXDECHOREQUEST)(void  * InBuf, ulong * InBufLen, void  * OutBuf, ulong * OutBufLen);//// Ping the specified IP address with "DHCPC".//BOOLPingDhcp(    DWORD dwIPAddr    ){    DWORD inlen;    DWORD outlen;    DWORD status;    BYTE ReqBuffer[sizeof(ICMP_ECHO_REQUEST)+8];    PICMP_ECHO_REQUEST pReq;    BYTE ReplyBuffer[DHCP_ICMP_RCV_BUF_SIZE];    PICMP_ECHO_REPLY EchoReplies;    PFN_VXDECHOREQUEST pfnEchoRequest;    HANDLE hTcpstk;    BOOL bRet;#ifdef DEBUG    TCHAR Addr[32];    TCHAR Reply[32];#endif    DEBUGMSG(ZONE_FUNCTION|ZONE_AUTOIP, (L"DHCP:+PingDhcp\n"));    hTcpstk = LoadLibrary(L"tcpstk.dll");    if (hTcpstk == NULL) {        DEBUGMSG(ZONE_FUNCTION|ZONE_AUTOIP, (L"DHCP:-PingDhcp: LoadLibrary(tcpstk.dll) failed\n"));        return FALSE;    }    bRet = FALSE;    pfnEchoRequest = (PFN_VXDECHOREQUEST)GetProcAddress(hTcpstk, L"VXDEchoRequest");    if (pfnEchoRequest == NULL) {        DEBUGMSG(ZONE_FUNCTION|ZONE_AUTOIP, (L"DHCP:PingDhcp: GetProcAddress(VXDEchoRequest) failed\n"));        goto pd_exit;    }    pReq = (PICMP_ECHO_REQUEST)ReqBuffer;    pReq->Address = dwIPAddr;    pReq->Timeout = DHCP_ICMP_WAIT_TIME;    pReq->DataOffset = sizeof(ICMP_ECHO_REQUEST);    pReq->DataSize = strlen(DHCP_ICMP_SEND_MESSAGE);    strcpy(ReqBuffer+sizeof(ICMP_ECHO_REQUEST), DHCP_ICMP_SEND_MESSAGE);    pReq->OptionsValid = 0;    pReq->Ttl = 1;    pReq->Tos = 0;    pReq->Flags = 0;    pReq->OptionsOffset = 0;    pReq->OptionsSize = 0;    inlen = sizeof(ReqBuffer);    outlen = sizeof(ReplyBuffer);    status = pfnEchoRequest(                (void *)ReqBuffer,                &inlen,                (void *)ReplyBuffer,                &outlen                );    if (status) {        DEBUGMSG(ZONE_AUTOIP, (L"DHCP:PingDhcp: VXDEchoRequest failed %d\n", status));        goto pd_exit;    }    EchoReplies = (PICMP_ECHO_REPLY)ReplyBuffer;    if (EchoReplies->Status) {        DEBUGMSG(ZONE_AUTOIP, (L"DHCP:PingDhcp: Echo status = %d\n", EchoReplies->Status));        goto pd_exit;    }    if (EchoReplies->Address != dwIPAddr) {        DEBUGMSG(ZONE_AUTOIP, (L"DHCP:PingDhcp: Echo IPAddr(%s) != Request IPAddr(%s)\n",            AddrToString(EchoReplies->Status, Reply), AddrToString(dwIPAddr, Addr)));        goto pd_exit;    }    bRet = TRUE;pd_exit:    FreeLibrary(hTcpstk);    DEBUGMSG(ZONE_FUNCTION|ZONE_AUTOIP, (L"DHCP:-PingDhcp returning %s\n", bRet ? L"TRUE" : L"FALSE"));    return bRet;}   // PingDhcp//// If there were no DHCP servers and this interface has a leased IP addr, then ping// the default gateway to make sure we are on the same subnet. This will avoid going// to auto IP prematurely.//// This function will bring up the interface and leave it up if the default gateway// could be ping'd.//BOOLCouldPingGateway(    DhcpInfo * pDhcp    ){#ifdef DEBUG    TCHAR Addr[32];    TCHAR Gateway[32];#endif    DEBUGMSG(ZONE_FUNCTION|ZONE_AUTOIP, (L"DHCP:+CouldPingGateway\n"));    if ((pDhcp->IPAddr == 0) || (pDhcp->Gateway == 0)) {        DEBUGMSG(ZONE_FUNCTION|ZONE_AUTOIP, (L"DHCP:-CouldPingGateway: IPAddr = %s, Gateway = %s\n",            AddrToString(pDhcp->IPAddr, Addr), AddrToString(pDhcp->Gateway, Gateway)));        return FALSE;    }    if (!CanUseCachedLease(pDhcp)) {        DEBUGMSG(ZONE_FUNCTION|ZONE_AUTOIP, (L"DHCP:-CouldPingGateway: In T2 stage!\n"));        return FALSE;    }    //CallNetMsgBox(NULL, NMB_FL_OK, NETUI_GETNETSTR_CACHED_LEASE);    if (PutNetUp(pDhcp) != DHCP_SUCCESS) {        DEBUGMSG(ZONE_FUNCTION|ZONE_AUTOIP, (L"DHCP:-CouldPingGateway: PutNetUp(%s) failed\n",            AddrToString(pDhcp->IPAddr, Addr)));        return FALSE;    }    if (PingDhcp(pDhcp->Gateway)) {        DEBUGMSG(ZONE_FUNCTION|ZONE_AUTOIP, (L"DHCP:-CouldPingGateway: Received response from default gateway\n"));        return TRUE;    }    DEBUGMSG(ZONE_FUNCTION|ZONE_AUTOIP, (L"DHCP:-CouldPingGateway: No response to ping\n"));        TakeNetDown(pDhcp, FALSE, TRUE);      // retain IPAddr    return FALSE;}   // CouldPingGateway//// Schedule a CTE timer so ProcessAutoIP can look for a DHCP server again.//voidStartAutoIPTimer(    DhcpInfo * pDhcp    ){    FILETIME Ft;    FILETIME CurTime;    Ft.dwLowDateTime = pDhcp->AutoInterval;    Ft.dwHighDateTime = 0;    mul64_32_64(&Ft, TEN_M, &Ft);    GetCurrentFT(&CurTime);    add64_64_64(&CurTime, &Ft, &Ft);    CTEStartFTimer(&pDhcp->Timer, Ft, (CTEEventRtn)ProcessAutoIP, pDhcp);    DEBUGMSG(ZONE_AUTOIP, (L"DHCP:StartAutoIPTimer - AutoIP event scheduled\n"));}//// When we autoconfigure our IP address we must continuously look for a DHCP server appearing on our net.// The default interval is 5 minutes.//voidProcessAutoIP(    DhcpInfo *pDhcp    ){    int		cPkt;    STATUS	Status;    DhcpPkt	Pkt;    uint	IPAddr;	DhcpInfo	**ppDhcp;    DEBUGMSG(ZONE_FUNCTION|ZONE_AUTOIP, (L"DHCP:+ProcessAutoIP\n"));    Status = DHCP_SUCCESS;	if (*(ppDhcp = _FindDhcp(pDhcp, NULL))) {        if (SetDHCPNTE(pDhcp)) {            if (DHCP_SUCCESS == (Status = DhcpInitSock(pDhcp, 0))) {                    //                // Save current auto config IP address and set dhcp IP address to 0, to follow spec.                // Neither ciaddr nor DHCP_REQ_IP_OP should reflect the auto config IP address; they                // should both be 0.                //                IPAddr = pDhcp->IPAddr;                pDhcp->IPAddr = 0;                BuildDhcpPkt(pDhcp, &Pkt, DHCPDISCOVER, NEW_PKT_FL, pDhcp->ReqOptions, &cPkt);                pDhcp->IPAddr = IPAddr;                        Status = SendDhcpPkt(pDhcp, &Pkt, cPkt, DHCPOFFER, ONCE_FL|BCAST_FL);                if (DHCP_SUCCESS == Status) {                    //                    // If the OFFER is from a DHCP allocator, then we should request our auto config IP address                    // It is a DHCP allocator if it is on the same subnet as auto config.                    //                    if ((pDhcp->IPAddr & pDhcp->SubnetMask) == pDhcp->AutoSubnet) {                        pDhcp->IPAddr = IPAddr;                        BuildDhcpPkt(pDhcp, &Pkt, DHCPREQUEST, RIP_PKT_FL, pDhcp->ReqOptions, &cPkt);                        Status = SendDhcpPkt(pDhcp, &Pkt, cPkt, DHCPACK, 							BCAST_FL | DFT_LOOP_FL);                        						if (DHCP_SUCCESS == Status) {                            DEBUGMSG(ZONE_AUTOIP, (L"DHCP:ProcessAutoIP - Leased auto cfg IP addr with ICS DHCP allocater/server.\n"));                            ClearDHCPNTE(pDhcp);                            CloseDhcpSocket(pDhcp);                            CTEFreeLock(&pDhcp->Lock, 0);                            return;                        } else {                            Status = DHCP_SUCCESS;  // Error, fall through to switch-over case                            DEBUGMSG(ZONE_AUTOIP, (L"DHCP:ProcessAutoIP - Trouble with ICS DHCP allocater/server.\n"));                        }                    }                }                ClearDHCPNTE(pDhcp);                CloseDhcpSocket(pDhcp);                        if (DHCP_SUCCESS == Status) {                    //                    // A DHCP server has appeared on the net. We need to discard the auto IP address and DHCP for one.                    //                    DEBUGMSG(ZONE_AUTOIP, (L"DHCP:ProcessAutoIP - Saw a DHCP server, discarding auto IP\n"));    					*ppDhcp = pDhcp->pNext;					CTEFreeLock(&v_GlobalListLock, 0);                        //                    // Remember what was in this DHCPOFFER so RequestDHCPAddr doesn't send another DISCOVER

⌨️ 快捷键说明

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