/**********************************************************************/ /** Microsoft Windows **/ /** Copyright(c) Microsoft Corp., 1994 **/ /**********************************************************************/ /* wfw.c Contains VxD code that is specific to WFW FILE HISTORY: Johnl 14-Mar-1994 Created */ #include #include #include #include #include #include // // any digit 0 to 9 and '.' are legal characters in an ipaddr // #define IS_IPADDR_CHAR( ch ) ( (ch >= '0' && ch <= '9') || (ch == '.') ) #define MAX_ADAPTER_DESCRIPTION_LENGTH 128 #ifndef CHICAGO #pragma BEGIN_INIT extern char NBTSectionName[]; // Section in system.ini parameters are stored extern char DNSSectionName[]; // Section where we find DNS server ipaddrs void GetDnsServerAddress( ULONG IpAddr, PULONG pIpNameServer); extern ULONG CurrentIP ; /******************************************************************* NAME: GetActiveLanasFromIP SYNOPSIS: Queries TDI for all IP drivers that have a non-zero IP address. For non-zero IP address, a DEVICE_CONTEXT is created. RETURNS: TRUE if successful, FALSE otherwise NOTES: Even if we fail to setup a particular adapter, the Lana count is maintained. This routine is only used by Snowball ********************************************************************/ BOOL GetActiveLanasFromIP( VOID ) { NTSTATUS status ; TDI_STATUS tdistatus ; int i, j, k ; uchar Context[CONTEXT_SIZE] ; TDIObjectID ID ; TDIEntityID EList[MAX_TDI_ENTITIES] ; ULONG Size ; UINT NumReturned ; NDIS_BUFFER ndisbuff ; BOOL fAnyValidIPs = FALSE ; UINT iLanaOffset = 0 ; IFEntry *ifeAdapterInfo[MAX_TDI_ENTITIES]; UINT AdptNum; UCHAR MacAddr[6]; UCHAR PreviousNodeType; // // The first thing to do is get the list of available entities, and make // sure that there are some interface entities present. // ID.toi_entity.tei_entity = GENERIC_ENTITY; ID.toi_entity.tei_instance = 0; ID.toi_class = INFO_CLASS_GENERIC; ID.toi_type = INFO_TYPE_PROVIDER; ID.toi_id = ENTITY_LIST_ID; Size = sizeof(EList); InitNDISBuff( &ndisbuff, &EList, Size, NULL ) ; memset(Context, 0, CONTEXT_SIZE); tdistatus = TdiVxdQueryInformationEx( 0, &ID, &ndisbuff, &Size, Context); if (tdistatus != TDI_SUCCESS) { CDbgPrint( DBGFLAG_ERROR, ( "GetActiveLanasFromIP: Querying entity list failed\r\n")) ; return FALSE ; } NumReturned = (uint)Size/sizeof(TDIEntityID); AdptNum = 0; // // first find out info about the adapters // for (i = 0; i < NumReturned; i++) { // // if this entity/instance describes an adapter // if ( EList[i].tei_entity == IF_ENTITY ) { DWORD isMib; ID.toi_entity.tei_entity = EList[i].tei_entity ; ID.toi_entity.tei_instance = EList[i].tei_instance; ID.toi_class = INFO_CLASS_GENERIC ; ID.toi_type = INFO_TYPE_PROVIDER; ID.toi_id = ENTITY_TYPE_ID ; Size = sizeof( isMib ); InitNDISBuff( &ndisbuff, &isMib, Size, NULL ) ; memset(Context, 0, CONTEXT_SIZE); tdistatus = TdiVxdQueryInformationEx( 0, &ID, &ndisbuff, &Size, Context); if ( tdistatus != TDI_SUCCESS ) { CDbgPrint( DBGFLAG_ERROR, ( "GetActiveLanasFromIP: Getting isMib failed\r\n")) ; return FALSE ; } // // Does this entity support MIB // if (isMib != IF_MIB) { CDbgPrint( DBGFLAG_ERROR, ( "GetActiveLanasFromIP: skipping non-MIB entity\r\n")) ; continue; } // // MIB requests supported - query the adapter info // Size = sizeof(IFEntry) + MAX_ADAPTER_DESCRIPTION_LENGTH + 1; ifeAdapterInfo[AdptNum] = (IFEntry *)CTEAllocInitMem((USHORT)Size); if ( ifeAdapterInfo[AdptNum] == NULL ) { CDbgPrint( DBGFLAG_ERROR, ( "GetActiveLanasFromIP: Couldn't allocate AdapterInfo buffer\r\n")) ; return FALSE; } ID.toi_class = INFO_CLASS_PROTOCOL;; ID.toi_id = IF_MIB_STATS_ID; Size = sizeof(IFEntry) + MAX_ADAPTER_DESCRIPTION_LENGTH + 1; InitNDISBuff( &ndisbuff, ifeAdapterInfo[AdptNum], Size, NULL ) ; memset(Context, 0, CONTEXT_SIZE); tdistatus = TdiVxdQueryInformationEx( 0, &ID, &ndisbuff, &Size, Context); if ( tdistatus != TDI_SUCCESS ) { CDbgPrint( DBGFLAG_ERROR, ( "GetActiveLanasFromIP: Getting IF type failed\r\n")) ; for ( k=0; k= IPStats.ipsi_numaddr ) ; // // We have the IP address table for this IP driver. Look for // non-zero IP addresses // for ( j = 0 ; j < IPStats.ipsi_numaddr ; j++ ) { // // Skip the loopback address // if ((pIAE[j].iae_addr & 0x000000ff) == 0x0000007f ) { continue ; } CurrentIP = pIAE[j].iae_addr ; if (!CurrentIP) { CDbgPrint( DBGFLAG_ERROR, ( "Init: ipaddr is 0, but accepting\n\r")) ; } // // now find out the mac address for this ipaddr // memset( MacAddr, 0, 6 ) ; IpIndex = -1; for ( k=0; kif_index == pIAE[j].iae_index ) { CTEMemCopy( MacAddr, ifeAdapterInfo[k]->if_physaddr, 6 ); IpIndex = ifeAdapterInfo[k]->if_index; break; } } ASSERT(IpIndex != -1); PreviousNodeType = NodeType; // // This will re-read the DHCPable parameters now that we have // a potential DHCP source // ReadParameters2( pNbtGlobConfig, NULL ); if (PreviousNodeType & PROXY) { NodeType |= PROXY; } // // Get all the NBNS servers' and DNS servers' ipaddresses // GetNameServerAddress( CurrentIP, IpNameServer); GetDnsServerAddress( CurrentIP, IpDnsServer); // // IP stores the address in network order, so we will un-network order // them because that's what NBT expects (would be nice to avoid conversion) // status = CreateDeviceObject( pNbtGlobConfig, htonl( pIAE[j].iae_addr ), htonl( pIAE[j].iae_mask ), IpNameServer[0], IpNameServer[1], IpDnsServer[0], IpDnsServer[1], MacAddr, IpIndex ) ; if ( !NT_SUCCESS( status ) ) { CDbgPrint( DBGFLAG_ERROR, ( "Init: CreateDeviceObject failed\n\r")) ; iLanaOffset++ ; continue ; } if ( !RegisterLana( LanaBase + iLanaOffset ) ) { CDbgPrint( DBGFLAG_ERROR, ( "Init: RegisterLana failed\n\r")) ; iLanaOffset++ ; continue ; } LanaTable[iLanaOffset].pDeviceContext = (tDEVICECONTEXT*)pNbtGlobConfig->DeviceContexts.Blink ; LanaTable[iLanaOffset].pDeviceContext->iLana = LanaBase + iLanaOffset; iLanaOffset++; fAnyValidIPs = TRUE ; } // addr traversal CTEFreeMem( pIAE ) ; } // if IP } // entity traversal for ( k=0; k at least one ipaddr is good i++; pchCurrent = pchNext; // go, convert the next one } } Not_In_Sysini: if( pchString != NULL ) { CTEFreeMem( pchString ) ; } // // if we didn't find in the .ini file, try getting them from DHCP // if ( !fPrimaryFound ) { ULONG Size = sizeof( Buff ) ; OptId = 6; // DNS Option tdistatus = DhcpQueryOption( IpAddr, OptId, &Buff, &Size ) ; switch ( tdistatus ) { case TDI_SUCCESS: case TDI_BUFFER_OVERFLOW: // May be more then one our buffer will hold for ( i = 0; i < COUNT_NS_ADDR; i++ ) { if ( Size >= (sizeof(ULONG)*(i+1))) pIpDnsServer[i] = htonl(Buff[i]) ; } break ; case TDI_INVALID_PARAMETER: // Option not found break ; default: ASSERT( FALSE ) ; break ; } } KdPrint(("GetDnsServerAddress: Primary: %x, backup: %x\r\n", pIpDnsServer[0], pIpDnsServer[1] )) ; } /******************************************************************* NAME: GetNameServerAddress SYNOPSIS: Gets the Win server for the specified Lana. Or, if DHCP is installed and the Name server addresses aren't found, we get them from DHCP ENTRY: IpAddr - If we can get from DHCP, get form this address pIpNameServer - Receives addresses if found (otherwise 0) NOTES: This routine is only used by Snowball HISTORY: Johnl 21-Oct-1993 Created ********************************************************************/ void GetNameServerAddress( ULONG IpAddr, PULONG pIpNameServer) { UCHAR i ; PUCHAR pchSrv = "NameServer$" ; PUCHAR pchSrvNum; UINT OptId; LPTSTR pchString ; TDI_STATUS TdiStatus ; BOOL fPrimaryFound = FALSE; ULONG Buff[COUNT_NS_ADDR] ; OptId = 44; // NBNS Option pchSrvNum = pchSrv + 10 ; // to overwrite '$' with 1,2,3 etc. for ( i = 0; i < COUNT_NS_ADDR; i++) { pIpNameServer[i] = LOOP_BACK ; *pchSrvNum = '1' + i; if ( !CTEReadIniString( NULL, pchSrv, &pchString ) ) { if ( ConvertDottedDecimalToUlong( pchString, &pIpNameServer[i] )) { // // Bad IP address format // DbgPrint("GetNameServerAddress: ConvertDottedDecimalToUlong failed!\r\n") ; pIpNameServer[i] = LOOP_BACK ; } else if ( i == 0 ) fPrimaryFound = TRUE ; CTEFreeMem( pchString ) ; } } // // Not in the .ini file, try getting them from DHCP // if ( !fPrimaryFound ) { ULONG Size = sizeof( Buff ) ; TDI_STATUS tdistatus ; tdistatus = DhcpQueryOption( IpAddr, OptId, &Buff, &Size ) ; switch ( tdistatus ) { case TDI_SUCCESS: case TDI_BUFFER_OVERFLOW: // May be more then one our buffer will hold for ( i = 0; i < COUNT_NS_ADDR; i++ ) { if ( Size >= (sizeof(ULONG)*(i+1))) pIpNameServer[i] = htonl(Buff[i]) ; } break ; case TDI_INVALID_PARAMETER: // Option not found break ; default: ASSERT( FALSE ) ; break ; } } KdPrint(("GetNameServerAddress: Primary: %x, backup: %x\r\n", pIpNameServer[0], pIpNameServer[1] )) ; } #pragma END_INIT #endif //!CHICAGO