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

📄 autonet.c

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

void ProcessAutoIP(DhcpInfo *pDhcp);
extern DhcpInfo **_FindDhcp(DhcpInfo *pDhcp, PTSTR pName);  // dhcp.c
extern void FreeDhcpInfo(DhcpInfo *pDhcp);          // dhcp.c
extern void CloseDhcpSocket(DhcpInfo *pDhcp);       // dhcp.c
extern STATUS SetDhcpConfig(DhcpInfo *pDhcp);       // dhcp.c
extern STATUS PutNetUp(DhcpInfo *pDhcp);            // dhcp.c
extern BOOL CanUseCachedLease(DhcpInfo * pDhcp);    // dhcp.c
extern void NotifyXxxChange(HANDLE hEvent);           // dhcp.c
extern 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".
//
BOOL
PingDhcp(
    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.
//
BOOL
CouldPingGateway(
    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.
//
void
StartAutoIPTimer(
    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.
//
void
ProcessAutoIP(
    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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -