summaryrefslogtreecommitdiffstats
path: root/private/ntos/nbt/vxd/wfw.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/ntos/nbt/vxd/wfw.c694
1 files changed, 694 insertions, 0 deletions
diff --git a/private/ntos/nbt/vxd/wfw.c b/private/ntos/nbt/vxd/wfw.c
new file mode 100644
index 000000000..c7f9bb7ce
--- /dev/null
+++ b/private/ntos/nbt/vxd/wfw.c
@@ -0,0 +1,694 @@
+/**********************************************************************/
+/** 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 <nbtprocs.h>
+#include <tdiinfo.h>
+#include <llinfo.h>
+#include <ipinfo.h>
+#include <dhcpinfo.h>
+#include <nbtinfo.h>
+
+//
+// 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<AdptNum; k++ )
+ {
+ CTEFreeMem( ifeAdapterInfo[k] ) ;
+ }
+ return FALSE ;
+ }
+
+ AdptNum++;
+ }
+ }
+
+ //
+ // now that we know about the adapters, get the ipaddrs
+ //
+ for (i = 0; i < NumReturned; i++)
+ {
+ if ( EList[i].tei_entity == CL_NL_ENTITY )
+ {
+ IPSNMPInfo IPStats ;
+ IPAddrEntry * pIAE ;
+ ULONG NLType ;
+ ULONG IpNameServer[COUNT_NS_ADDR];
+ ULONG IpDnsServer[COUNT_NS_ADDR];
+ UCHAR IpIndex;
+
+ //
+ // Does this entity support IP?
+ //
+
+ 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( NLType );
+ InitNDISBuff( &ndisbuff, &NLType, Size, NULL ) ;
+ memset(Context, 0, CONTEXT_SIZE);
+ tdistatus = TdiVxdQueryInformationEx( 0,
+ &ID,
+ &ndisbuff,
+ &Size,
+ Context);
+ if ( tdistatus != TDI_SUCCESS )
+ {
+ CDbgPrint( DBGFLAG_ERROR, ( "GetActiveLanasFromIP: Getting NL type failed\r\n")) ;
+ for ( k=0; k<AdptNum; k++ )
+ {
+ CTEFreeMem( ifeAdapterInfo[k] ) ;
+ }
+ return FALSE ;
+ }
+
+ if ( NLType != CL_NL_IP )
+ continue ;
+
+ //
+ // We've got an IP driver so get it's address table
+ //
+
+ ID.toi_class = INFO_CLASS_PROTOCOL ;
+ ID.toi_id = IP_MIB_STATS_ID;
+ Size = sizeof(IPStats);
+ InitNDISBuff( &ndisbuff, &IPStats, Size, NULL ) ;
+ memset(Context, 0, CONTEXT_SIZE);
+ tdistatus = TdiVxdQueryInformationEx( 0,
+ &ID,
+ &ndisbuff,
+ &Size,
+ Context);
+ if ( tdistatus != TDI_SUCCESS )
+ {
+ CDbgPrint( DBGFLAG_ERROR, ( "GetActiveLanasFromIP: Getting IPStats failed\r\n")) ;
+ continue ;
+ }
+
+ if ( IPStats.ipsi_numaddr < 1 )
+ {
+ CDbgPrint( DBGFLAG_ERROR, ( "GetActiveLanasFromIP: No IP Addresses installed\r\n")) ;
+ continue ;
+ }
+
+ Size = sizeof(IPAddrEntry) * IPStats.ipsi_numaddr ;
+ if ( !(pIAE = (IPAddrEntry*) CTEAllocInitMem( Size )) )
+ {
+ CDbgPrint( DBGFLAG_ERROR, ( "GetActiveLanasFromIP: Couldn't allocate IP table buffer\r\n")) ;
+ continue ;
+ }
+
+ ID.toi_id = IP_MIB_ADDRTABLE_ENTRY_ID ;
+ InitNDISBuff( &ndisbuff, pIAE, Size, NULL ) ;
+ memset( Context, 0, CONTEXT_SIZE ) ;
+ tdistatus = TdiVxdQueryInformationEx( 0,
+ &ID,
+ &ndisbuff,
+ &Size,
+ Context);
+ if ( tdistatus != TDI_SUCCESS )
+ {
+ CDbgPrint( DBGFLAG_ERROR, ( "GetActiveLanasFromIP: Getting IP address table failed\r\n")) ;
+ CTEFreeMem( pIAE ) ;
+ continue ;
+ }
+
+ ASSERT( Size/sizeof(IPAddrEntry) >= 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; k<AdptNum; k++ )
+ {
+ if ( ifeAdapterInfo[k]->if_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<AdptNum; k++ )
+ {
+ CTEFreeMem( ifeAdapterInfo[k] ) ;
+ }
+
+ return fAnyValidIPs ;
+}
+
+/*******************************************************************
+
+ NAME: VxdReadIniString
+
+ SYNOPSIS: Vxd stub for CTEReadIniString
+
+ ENTRY: pchKey - Key value to look for in the NBT section
+ ppchString - Pointer to buffer found string is returned in
+
+ EXIT: ppchString will point to an allocated buffer
+
+ RETURNS: STATUS_SUCCESS if found
+
+ NOTES: The client must free ppchString when done with it
+
+ HISTORY:
+ Johnl 30-Aug-1993 Created
+ Koti 30-May-194 Added 3rd parm to GetProfileString
+
+********************************************************************/
+
+CHAR * GetProfileString( LPTSTR pchKey, LPTSTR * pchDefault, PCHAR SectName ) ;
+
+NTSTATUS VxdReadIniString( LPSTR pchKey, LPSTR * ppchString )
+{
+ char * pchTmp ;
+
+ if ( pchTmp = GetProfileString( pchKey, NULL, NBTSectionName ) )
+ {
+ if ( *ppchString = CTEAllocInitMem( strlen( pchTmp ) + 1) )
+ {
+ strcpy( *ppchString, pchTmp ) ;
+ return STATUS_SUCCESS ;
+ }
+ else
+ return STATUS_INSUFFICIENT_RESOURCES ;
+ }
+ else
+ {
+ //
+ // Does DHCP have it?
+ //
+
+ if ( pchTmp = (char *) GetDhcpOption( pchKey, 0 ) )
+ {
+ *ppchString = pchTmp ;
+ return STATUS_SUCCESS ;
+ }
+ }
+
+ return STATUS_UNSUCCESSFUL ;
+}
+
+
+/*******************************************************************
+
+ NAME: GetDnsServerAddress
+
+ SYNOPSIS: Gets the DNS server ipaddrs from the DNS section of system.ini
+
+ Or, if DHCP is installed and the DNS server addresses aren't
+ found, we get them from DHCP
+
+ ENTRY: IpAddr - If we can get from DHCP, get form this address
+ pIpDnsServer - Receives addresses if found (otherwise 0)
+
+ NOTES: This routine is only used by Snowball
+
+ HISTORY:
+ Koti 30-May-1994 Created
+
+********************************************************************/
+
+void GetDnsServerAddress( ULONG IpAddr, PULONG pIpDnsServer)
+{
+ UCHAR i ;
+ PUCHAR pchDnsSrv = "DNSServers" ;
+ UINT OptId;
+ PUCHAR pchTmp;
+ PUCHAR pchCurrent, pchNext;
+ LPTSTR pchString=NULL ;
+ TDI_STATUS tdistatus ;
+ BOOL fPrimaryFound = FALSE;
+ BOOL fOneMore=TRUE;
+ ULONG Buff[COUNT_NS_ADDR] ;
+
+
+
+ //
+ // initialize all of them to worst case
+ //
+ for ( i = 0; i < COUNT_NS_ADDR; i++)
+ {
+ pIpDnsServer[i] = LOOP_BACK ;
+ }
+
+ pchTmp = GetProfileString( pchDnsSrv, NULL, DNSSectionName );
+ if ( pchTmp == NULL )
+ {
+ goto Not_In_Sysini;
+ }
+
+ if ( !(pchString = CTEAllocInitMem( strlen( pchTmp ) + 1)) )
+ {
+ DbgPrint("GetDnsServerAddress: CTEAllocInitMem failed!\r\n") ;
+ goto Not_In_Sysini;
+ }
+
+ strcpy( pchString, pchTmp ) ;
+
+ //
+ // we are generating (upto) COUNT_NS_ADDR pointers each pointing to
+ // one ipaddr. The string in system.ini looks like:
+ // DNSServers = 11.101.4.26,200.200.200.200,1.2.3.4,1.91.245.10
+ //
+ pchNext = pchCurrent = pchString;
+
+ if ( IS_IPADDR_CHAR(*pchCurrent) ) // make sure at least one ipaddr defnd
+ {
+ i = 0;
+ while( (i < COUNT_NS_ADDR) && fOneMore )
+ {
+ while( IS_IPADDR_CHAR(*pchNext) )
+ pchNext++;
+
+ if ( *pchNext == ',' ) // ',' is the separator between 2 addrs
+ {
+ *pchNext = '\0';
+ pchNext++;
+ }
+ else
+ {
+ fOneMore = FALSE; // reached end of line
+ }
+
+ //
+ // as long as at least the first one ipaddr gets converted properly,
+ // ignore errors in others
+ //
+ if ( ConvertDottedDecimalToUlong( pchCurrent, &pIpDnsServer[i] ))
+ {
+ if ( i == 0 )
+ goto Not_In_Sysini;
+ else
+ pIpDnsServer[i] = LOOP_BACK ;
+ }
+
+ fPrimaryFound = TRUE; // => 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
+
+