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

📄 ip_intf.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    // What would we do here?

    return;
}

int
QueryInfo
    (   void        *IFContext,
        TDIObjectID *ID,
        PNDIS_BUFFER Buffer,
        uint        *Size,
        void        *Context )
{
    PPP_CONTEXT     *pCurContext = (PPP_CONTEXT *)IFContext;
	pppSession_t    *s_p = pCurContext->Session;
	PLCPContext		lcp_p  = (PLCPContext)s_p->lcpCntxt;
    uint            Offset       = 0;
    uint            BufferSize   = *Size;
    uchar           InfoBuff[ sizeof( IFEntry ) ];
    uint            Entity;
    uint            Instance;

    DEBUGMSG (ZONE_PPP, (
    TEXT( "PPP QueryInfo( %08X, %08X, %08X, %08X, %08X )\r\n"),
           IFContext, ID, Buffer, Size ) );

    Entity = ID->toi_entity.tei_entity;
    Instance = ID->toi_entity.tei_instance;

    // We support only Interface MIBs - no address xlation -
    // pretty much like a loopback i/f (per Henry circa 1994).

    if( (Entity != IF_ENTITY) || (Instance != pCurContext->ifinst) )
    {
        return( TDI_INVALID_REQUEST );
    }

    if( ID->toi_type != INFO_TYPE_PROVIDER )
    {
        return( TDI_INVALID_PARAMETER );
    }

    *Size = 0 ;                                     // a safe initialization.

    if( ID->toi_class == INFO_CLASS_GENERIC )
    {
        if( ID->toi_id == ENTITY_TYPE_ID )
        {
            // Identify what type we are.

            if( BufferSize >= sizeof( uint ) )
            {
                *(uint *)&InfoBuff[ 0 ] =
                (Entity == AT_ENTITY) ? AT_ARP : IF_MIB;

                (void )CopyFlatToNdis(Buffer, InfoBuff, sizeof(uint), &Offset);
                *Size = sizeof(uint);
                return( TDI_SUCCESS );
            }
            else
            {
                return( TDI_BUFFER_TOO_SMALL );
            }
        }

        // That's the only generic request supported.

        return( TDI_INVALID_PARAMETER );
    }

    if( ID->toi_class != INFO_CLASS_PROTOCOL )
    {
        return( TDI_INVALID_PARAMETER );
    }

    // Asking for interface level information.
    // Do we support what he's asking for.

    if( ID->toi_id == IF_MIB_STATS_ID )
    {
        // We should probably fill get some statistics for it.

        IFEntry  *IFE = (IFEntry *)InfoBuff;

        if( BufferSize < IFE_FIXED_SIZE )
        {
            return( TDI_BUFFER_TOO_SMALL );
        }

        // Buffer can hold the fixeded part. Build
        // the IFEntry structure, and copy it in.

        IFE->if_index       = pCurContext->index;
        IFE->if_type        = IF_TYPE_PPP;
        IFE->if_physaddrlen = ARP_802_ADDR_LENGTH;
		switch( s_p->Mode )
		{
		case PPPMODE_PPP:
			// Use the negotiated peer MRU
			IFE->if_mtu         = lcp_p->peer.MRU;
			break;

		case PPPMODE_SLIP:
		case PPPMODE_CSLIP:
			IFE->if_mtu         = SLIP_DEFAULT_MTU;
			break;

		default: ASSERT( 0 );
		}
		DEBUGMSG (ZONE_PPP, ( TEXT( "PPP QueryInfo +pppMac_GetCallSpeed\n")));
		pppMac_GetCallSpeed(s_p->macCntxt, &IFE->if_speed);
		DEBUGMSG (ZONE_PPP, ( TEXT( "PPP QueryInfo -pppMac_GetCallSpeed\n")));

        CTEMemSet( IFE->if_physaddr, 0, ARP_802_ADDR_LENGTH );

		//
		//	Since PPP dynamically registers/deregisters adapters,
		//	it can only be queried by TCP/IP when it is "UP".
		//
		IFE->if_adminstatus = IF_STATUS_UP;
		IFE->if_operstatus  = IF_STATUS_UP;

		        IFE->if_lastchange = 0;

        // Get the MAC layers stats

        // Rx Statistics

        IFE->if_inoctets        = s_p->Stats.BytesRcvd;
        IFE->if_inucastpkts     = s_p->Stats.FramesRcvd;
        IFE->if_innucastpkts    = 0;
        IFE->if_indiscards      = s_p->Stats.CRCErrors;
        IFE->if_inerrors        = s_p->Stats.TimeoutErrors +
                                  s_p->Stats.AlignmentErrors +
                                  s_p->Stats.SerialOverrunErrors +
                                  s_p->Stats.FramingErrors +
                                  s_p->Stats.BufferOverrunErrors;
        IFE->if_inunknownprotos = 0;

        // Tx Statistics

        IFE->if_outoctets       = s_p->Stats.BytesSent;
        IFE->if_outucastpkts    = s_p->Stats.FramesRcvd;
        IFE->if_outnucastpkts   = 0;
        IFE->if_outdiscards     = 0;
        IFE->if_outerrors       = 0;
        IFE->if_outqlen         = 0;    // no queue

        IFE->if_descrlen        = 0;

        Buffer = CopyFlatToNdis( Buffer, (uchar *)IFE, IFE_FIXED_SIZE, &Offset);

        // We should copy a description over....

        *Size = IFE_FIXED_SIZE;
		DEBUGMSG (ZONE_PPP, ( TEXT( "PPP -QueryInfo SUCCESS\n")));
        return TDI_SUCCESS;
    }

    return( TDI_INVALID_PARAMETER );
}

int

SetInfo( void *Context, TDIObjectID *ID, void *Buffer, uint Size )
{
    DEBUGMSG (ZONE_PPP, (TEXT("PPP SetInfo(%08X, %08X, %08X, %d)\r\n"),
                  Context, ID, Buffer, Size));

    return( TRUE );
}

int

GetEList(void *Context, TDIEntityID *EntityList, uint *Count)
{
    PPP_CONTEXT     *pCurContext = (PPP_CONTEXT *)Context;
    uint            ECount;
    uint            MyIFBase;
    uint            i;
    TDIEntityID		*pEntity = NULL;
    int				Status = TRUE;

#ifndef MAX
#define MAX(x,y)    ((x) > (y) ? (x) : (y))
#endif

    DEBUGMSG (ZONE_PPP, (TEXT("PPP GetEList(%08X,%08X,%08X)\r\n"),
                  Context, EntityList, Count));

    ECount = *Count;

    // Walk down the list, looking for existing AT or IF entities, and
    // adjust our base instance accordingly.

    MyIFBase = 0;
    for (i = 0; i < ECount; i++, EntityList++)
    {
        if (EntityList->tei_entity == IF_ENTITY)
        {
	        if ( EntityList->tei_instance == pCurContext->ifinst &&
	             EntityList->tei_instance != INVALID_ENTITY_INSTANCE ) {
	            pEntity    = EntityList;
	            break;
	        } else {
	            MyIFBase = MAX(MyIFBase, EntityList->tei_instance + 1);
	        }
        }
    }

	if (pEntity) {

		if (! pCurContext->fOpen)
			pEntity->tei_instance = (DWORD)INVALID_ENTITY_INSTANCE;

	} else {

		if (pCurContext->fOpen) {
		    // EntityList points to the start of where we want to begin filling in.
		    // Make sure we have enough room. We need one for the ICMP instance,
		    // and one for the CL_NL instance.

		    if ((ECount + 1) > MAX_TDI_ENTITIES)
		    {
		        Status = FALSE;

		    } else {

			    // At this point we've figure out our base instance. Save for later use.

			    pCurContext->ifinst = MyIFBase;

			    // Now fill it in.
			    EntityList->tei_entity = IF_ENTITY;
			    EntityList->tei_instance = MyIFBase;
			    *Count += 1;
			}
		}
	}

    return( Status );
}

LONG
RegSetIPAddrMultiSzValue(
	HKEY	 hKey,
	PTCHAR	 tszValueName,
	...)
//
//	Set a registry value which is a MULTI_SZ list of IP addresses.
//
//	The variable parameters to this function are a NULL terminated list of
//	pdwIPAddrs to convert to strings to build the multi_sz.
//
//	NOTE: Does not set addresses with a value of 0.  If not addresses are
//	      set, the registry value is deleted.
//
//	@alert: if memory allocation fails, registry value is not deleted
//
{
	TCHAR	*ptszMultiIpAddr = NULL, *tszCur = NULL;
	DWORD	dwIPAddr, *pdwIPAddr;
	va_list ArgList;
	LONG	lResult;
	HLOCAL hMem = NULL;

	#ifndef BLOCK_LENGTH
	#undef	BLOCK_LENGTH
	#endif /* BLOCK_LENGTH */
	#define	BLOCK_LENGTH	(0x100)

	INT nContentLength = 0;
	INT nAllocatedLength = BLOCK_LENGTH;

	va_start (ArgList, tszValueName);

	hMem = LocalAlloc(LMEM_ZEROINIT, nAllocatedLength * sizeof(TCHAR));			// ref: +alloc

	if (!hMem)
	{
		return ERROR_NOT_ENOUGH_MEMORY;
	}

	ptszMultiIpAddr = LocalLock(hMem);											// ref: +lock
	tszCur = ptszMultiIpAddr;

	// Build the multi_sz
	while (pdwIPAddr = va_arg(ArgList, PDWORD))
	{
		dwIPAddr = *pdwIPAddr;

		if (dwIPAddr)
		{
			/* since the function accepts variable list of pdwIPAddrs, it's
			necessary to reallocate the memory holding the string. BLOCK_LENGTH
			is basically (max IP adddress length (string) + safe length) and it
			can be fine tuned to the exact specifications */

			if ((nContentLength > 0) && ((nAllocatedLength - nContentLength) > BLOCK_LENGTH))
			{
				HLOCAL hTmp = NULL;

				LocalUnlock(hMem);												// ref: -lock

				hTmp = LocalReAlloc(hMem, (nAllocatedLength + BLOCK_LENGTH) *
					sizeof(TCHAR), (LMEM_MODIFY | LMEM_MOVEABLE));				// ref: *alloc

				if (!hTmp)
				{
					LocalFree(hMem);											// ref: -alloc
					return ERROR_NOT_ENOUGH_MEMORY;
				}
				else
				{
					nAllocatedLength += BLOCK_LENGTH;
				}

				hMem = hTmp;
				ptszMultiIpAddr = LocalLock(hMem);								// ref: +lock
				tszCur = (ptszMultiIpAddr + nContentLength);	// set tszCur to current location
			}

			tszCur += _stprintf (tszCur, TEXT("%d.%d.%d.%d\0"),
							(dwIPAddr >> 24) & 0xFF, (dwIPAddr >> 16) & 0xFF,
							(dwIPAddr >>  8) & 0xFF,  dwIPAddr        & 0xFF) + 1;

			nContentLength = (tszCur - ptszMultiIpAddr);
		}
	}
	va_end(ArgList);

	if (tszCur > ptszMultiIpAddr)
	{
		// We have 1 or more nonzero IP addresses
		//
		// Add the extra terminator to denote end of the multi_sz
		*tszCur++ = TEXT('\0');

		DEBUGMSG (ZONE_PPP, (TEXT("PPP: Setting multi_sz list for %s - 1=%s\n"), tszValueName, ptszMultiIpAddr));

		lResult = RegSetValueEx (hKey, tszValueName, 0, REG_MULTI_SZ, (char *)ptszMultiIpAddr, (tszCur - ptszMultiIpAddr) * sizeof(TCHAR));
	}
	else
	{
		DEBUGMSG (ZONE_PPP, (TEXT("PPP: Deleting registry value %s - all IP addresses for it are 0\n"), tszValueName));

		lResult = RegDeleteValue(hKey, tszValueName);
	}

	if (hMem)
	{
		LocalUnlock(hMem);														// ref: -lock
		LocalFree(hMem);														// ref: -alloc
	}

	#ifndef BLOCK_LENGTH
	#undef	BLOCK_LENGTH
	#endif /* BLOCK_LENGTH */

	return lResult;
}

const WCHAR TcpipParametersKey[] =  L"Comm\\Tcpip\\Parms";


BOOL
PPPSetAdapterIPRegistrySettings(
	IN		PPP_CONTEXT    *pContext,
	IN	OUT	PNDIS_STRING	pConfigName,
		OUT	PDWORD		    pdwDefaultGateway)
//
//	Set the adapter's IP registry values based upon the IPCP negotiated values.
//
	/*
		[HKEY_LOCAL_MACHINE\Comm\<adapter name/#>\Parms\TcpIp]
	   "EnableDHCP"       = dword:0
	   "DefaultGateway"   = multi_sz:"<IPCP peer ip addr>"
	   "UseZeroBroadcast" = dword:0
	   "IpAddress"        = multi_sz:"<IPCP negotiated ip address>"
	   "Subnetmask"       = multi_sz:"<derived from IP address>"
	   "DNS"              = multi_sz:"<IPCP assigned primary DNS server address>","<DNS secondary>"
	   "WINS"             = multi_sz:"<IPCP assigned primary WINS>","<WINS secondary>"
	*/
{
	pppSession_t    *s_p    = pContext->Session;
	ncpCntxt_t      *ncp_p  = s_p->ncpCntxt;
	ipcpCntxt_t     *ipcp_p = (ipcpCntxt_t *)ncp_p->protocol[ 1 ].context;
	HKEY			hKey;
	LONG			hRes;
	DWORD			zero = 0;
	DWORD			dwSubNetMask, dwIPAddr, dwDefaultGatewayIPAddr,
		            dwAddDefaultGateway, dwDontAddDefaultGateway;
    WCHAR Buffer[MAX_PATH];

    if (s_p->szDomain[0] != 0)
    {
        memset(Buffer, 0, sizeof(Buffer));
        MultiByteToWideChar(CP_OEMCP, 0, &s_p->szDomain[0], -1, Buffer, MAX_PATH);
        //
        // Set system-wide DNSDomain name
        //
        hRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TcpipParametersKey, 0, 0, &hKey);
        if (ERROR_SUCCESS == hRes)
        {
            RegSetValueEx (hKey, TEXT("DNSDomain"), 0, REG_SZ, (PBYTE)&Buffer[0], (wcslen(Buffer) + 1) * sizeof(WCHAR));
            RegCloseKey(hKey);
        }
    }
    
    
    //
	// Set the per adapter TcpIp parameters.
	//
	_stprintf(pConfigName->Buffer, TEXT("Comm\\%s\\Parms\\TcpIp"), &pContext->AdapterName[0]);

	pConfigName->Length = wcslen(pConfigName->Buffer) * sizeof(WCHAR);
	ASSERT(pConfigName->Length < pConfigName->MaximumLength);
	hRes = RegCreateKeyEx (HKEY_LOCAL_MACHINE, pConfigName->Buffer, 0, NULL,
								   REG_OPTION_NON_VOLATILE, 0, NULL,
								   &hKey, NULL);
	if (hRes != ERROR_SUCCESS)
	{
		DEBUGMSG (ZONE_ERROR, (TEXT("PPP: Unable to create reg key '%s'\n"), pConfigName->Buffer));
		return FALSE;
	}

	//
	// Set the TCP/IP domain for this adapter if we obtained a domain
	// via DHCP over PPP.
	//
	if (s_p->szDomain[0] != 0)
	{
        RegSetValueEx (hKey, TEXT("Domain"), 0, REG_SZ, (PBYTE)&Buffer[0], (wcslen(Buffer) + 1) * sizeof(WCHAR));
	} else {
        RegDeleteValue (hKey, TEXT("Domain"));
    }

	// Don't run DHCP over the PPP link, the IP address is set by the IPCP negotiation
	RegSetValueEx (hKey, TEXT("EnableDHCP"), 0, REG_DWORD, (char *)&(zero), sizeof(DWORD));
	RegSetValueEx (hKey, TEXT("UseZeroBroadcast"), 0, REG_DWORD, (char *)&(zero), sizeof(DWORD));

	//
	//	Only want to set up default routes (gateways) if we are a RAS client
	//  and the RASENTRY option is set.
	//
	dwAddDefaultGateway = !s_p->bIsServer && (s_p->dwAlwaysAddDefaultRoute || (s_p->rasEntry.dwfOptions & RASEO_RemoteDefaultGateway));
	dwDontAddDefaultGateway =  !dwAddDefaultGateway;
	RegSetValueEx (hKey, TEXT("DontAddDefaultGateway"), 0, REG_DWORD, (char *)&dwDontAddDefaultGateway, sizeof(DWORD));

    switch( s_p->Mode )
    {
    case PPPMODE_PPP:
		dwIPAddr = ipcp_p->local.ipAddress;
		dwDefaultGatewayIPAddr = ipcp_p->peer.ipAddress;

		//
		// If the server did not tell us its IP address, generate
		// a default gateway address based upon our address.
		//
		// If the server told us that its address is the same as
		// our address, that's strange and really confuses our routing
		// tables, so replace it with a fake address instead.
		//
		if (dwDefaultGatewayIPAddr == 0 || dwDefaultGatewayIPAddr == dwIPAddr)
		{
			dwDefaultGatewayIPAddr = dwIPAddr;
			DEBUGMSG(ZONE_WARN, (TEXT("PPP: Server did not tell us its IP address, using own IP as default gateway\n")));
		}
		break;

	case PPPMODE_SLIP:
    case PPPMODE_CSLIP:
		dwIPAddr = *(PDWORD)&s_p->rasEntry.ipaddr;

		//
		// We need to have a default gateway assigned so that IP will add a default route to the route
		// table.  The IP address of the default gateway doesn't matter so long as it is on the same
		// subnet as the SLIP adapter's IP address.  Since SLIP has no mechanism to tell us what our
		// SLIP peer's IP address is, we just fudge an address on the same subnet.  The gateway's IP
		// address will get passed into our send handler by IP when the default route kicks in, but
		// PPP just ignores this address as PPP only has one place to send IP packets to.  On a LAN
		// adapter, the gateway's MAC address would get put into the LAN packet.
		//
		dwDefaultGatewayIPAddr = dwIPAddr;
		break;
	}

	if (s_p->bIsServer)
	{
		dwSubNetMask = PPPServerGetSessionIPMask(s_p);
	}
	else
	{
		// Just derive the subnet from the IP address (class A, B, or C)
		dwSubNetMask = IPGetNetMask( dwIPAddr );
	}

	//
	// If we are adding a default route, make sure that the peer's IP address is
	// within the same subnet as our IP address. Otherwise, with the peer IP outside
	// the subnet, the routing table will be configured such that PPP interface may
	// not be used to send packets matching the PPP default route!
	//
	if ((dwIPAddr & dwSubNetMask) != (dwDefaultGatewayIPAddr & dwSubNetMask))
	{
		DEBUGMSG(ZONE_WARN, (L"PPP: Peer IP addr %x outside our subnet %x/%x, using own IP as gateway\n", dwDefaultGatewayIPAddr, dwIPAddr, dwSubNetMask));
		dwDefaultGatewayIPAddr = dwIPAddr;
	}

	if ((s_p->rasEntry.dwfOptions & RASEO_RemoteDefaultGateway)
	&&  !(s_p->dwAlwaysAddSubnetRoute))
	{
		//
		// We are adding a default route for this PPP interface, and don't
		// want a subnet route as well.

⌨️ 快捷键说明

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