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 + -
显示快捷键?