Commit in reactos/drivers/net/tcpip on MAIN
datalink/lan.c+115-881.13 -> 1.14
include/address.h+41.7 -> 1.8
       /info.h+261.4 -> 1.5
       /ip.h+21.9 -> 1.10
       /tcpip.h+11.7 -> 1.8
tcpip/address.c+291.10 -> 1.11
     /info.c+131-391.4 -> 1.5
+308-127
7 modified files
Added bit counting and inverting functions to address.
Broke out some functions in info.c -- They still don't work properly but
are improving.
Added setting of netmask in datalink/lan.c from the registry, broke out
registry reading function.

reactos/drivers/net/tcpip/datalink
lan.c 1.13 -> 1.14
diff -u -r1.13 -r1.14
--- lan.c	8 Mar 2004 10:20:17 -0000	1.13
+++ lan.c	12 Mar 2004 04:21:59 -0000	1.14
@@ -15,7 +15,6 @@
 #include <receive.h>
 #include <arp.h>
 
-
 NDIS_HANDLE NdisProtocolHandle = (NDIS_HANDLE)NULL;
 BOOLEAN ProtocolRegistered     = FALSE;
 LIST_ENTRY AdapterListHead;
@@ -590,6 +589,72 @@
     }
 }
 
+static NTSTATUS 
+OpenRegistryKey( PNDIS_STRING RegistryPath, PHANDLE RegHandle ) {
+    OBJECT_ATTRIBUTES Attributes;
+    NTSTATUS Status;
+    
+    InitializeObjectAttributes(&Attributes, RegistryPath, OBJ_CASE_INSENSITIVE, 0, 0);
+    Status = ZwOpenKey(RegHandle, GENERIC_READ, &Attributes);
+    return Status;
+}
+
+static NTSTATUS ReadIPAddressFromRegistry( HANDLE RegHandle,
+					   PWCHAR RegistryValue,
+					   PIP_ADDRESS *Address ) {
+    UNICODE_STRING ValueName;
+    UNICODE_STRING UnicodeAddress; 
+    NTSTATUS Status;
+    ULONG ResultLength;
+    UCHAR buf[1024];
+    PKEY_VALUE_PARTIAL_INFORMATION Information = (PKEY_VALUE_PARTIAL_INFORMATION)buf;
+    ANSI_STRING AnsiAddress;
+    ULONG AnsiLen;
+
+    RtlInitUnicodeString(&ValueName, RegistryValue);
+    Status = 
+	ZwQueryValueKey(RegHandle, 
+			&ValueName, 
+			KeyValuePartialInformation, 
+			Information, 
+			sizeof(buf), 
+			&ResultLength);
+
+    if (!NT_SUCCESS(Status))
+	return Status;
+    /* IP address is stored as a REG_MULTI_SZ - we only pay attention to the first one though */
+    TI_DbgPrint(MIN_TRACE, ("Information DataLength: 0x%x\n", Information->DataLength));
+    
+    UnicodeAddress.Buffer = (PWCHAR)&Information->Data;
+    UnicodeAddress.Length = Information->DataLength;
+    UnicodeAddress.MaximumLength = Information->DataLength;
+    
+    AnsiLen = RtlUnicodeStringToAnsiSize(&UnicodeAddress);
+    if(!AnsiLen)
+	return STATUS_NO_MEMORY;
+    
+    AnsiAddress.Buffer = ExAllocatePoolWithTag(PagedPool, AnsiLen, 0x01020304);
+    if(!AnsiAddress.Buffer)
+	return STATUS_NO_MEMORY;
+
+    AnsiAddress.Length = AnsiLen;
+    AnsiAddress.MaximumLength = AnsiLen;
+    
+    Status = RtlUnicodeStringToAnsiString(&AnsiAddress, &UnicodeAddress, FALSE);
+    if (!NT_SUCCESS(Status)) {
+	ExFreePool(AnsiAddress.Buffer);
+	return STATUS_UNSUCCESSFUL;
+    }
+    
+    AnsiAddress.Buffer[AnsiAddress.Length] = 0;
+    *Address = AddrBuildIPv4(inet_addr(AnsiAddress.Buffer));
+    if (!Address) {
+	ExFreePool(AnsiAddress.Buffer);
+	return STATUS_UNSUCCESSFUL;
+    }
+
+    return *Address ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
+}
 
 VOID BindAdapter(
     PLAN_ADAPTER Adapter,
@@ -605,11 +670,14 @@
 {
     INT i;
     PIP_INTERFACE IF;
-    PIP_ADDRESS Address;
+    PIP_ADDRESS Address = 0;
+    PIP_ADDRESS Netmask = 0;
     PNDIS_PACKET Packet;
     NDIS_STATUS NdisStatus;
     LLIP_BIND_INFO BindInfo;
     ULONG Lookahead = LOOKAHEAD_SIZE;
+    NTSTATUS Status;
+    HANDLE RegHandle = 0;
 
     TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
 
@@ -655,100 +723,59 @@
         return;
     }
 
-			{
-				/* 
-				 * Query per-adapter configuration from the registry 
-				 * In case anyone is curious:  there *is* an Ndis configuration api
-				 * for this sort of thing, but it doesn't really support things like
-				 * REG_MULTI_SZ very well, and there is a note in the DDK that says that
-				 * protocol drivers developed for win2k and above just use the native
-				 * services (ZwOpenKey, etc).
-				 */
-
-				OBJECT_ATTRIBUTES Attributes;
-				HANDLE RegHandle;
-				NTSTATUS Status;
-				UNICODE_STRING ValueName;
-				UCHAR buf[1024];
-				PKEY_VALUE_PARTIAL_INFORMATION Information = (PKEY_VALUE_PARTIAL_INFORMATION)buf;
-				ULONG ResultLength;
-				ANSI_STRING AnsiAddress;
-				UNICODE_STRING UnicodeAddress;
-				ULONG AnsiLen;
-
-				InitializeObjectAttributes(&Attributes, RegistryPath, OBJ_CASE_INSENSITIVE, 0, 0);
-				Status = ZwOpenKey(&RegHandle, GENERIC_READ, &Attributes);
-
-				if(!NT_SUCCESS(Status))
-					{
-						TI_DbgPrint(MIN_TRACE, ("Unable to open protocol-specific registry key: 0x%x\n", Status));
-
-						/* XXX how do we proceed?  No ip address, no parameters... do we guess? */
-						FreeTDPackets(Adapter);
-						IPDestroyInterface(Adapter->Context);
-						return;
-					}
-
-				RtlInitUnicodeString(&ValueName, L"IPAddress");
-				ZwQueryValueKey(RegHandle, &ValueName, KeyValuePartialInformation, Information, sizeof(buf), &ResultLength);
-				ZwClose(RegHandle);
-
-				/* IP address is stored as a REG_MULTI_SZ - we only pay attention to the first one though */
-				TI_DbgPrint(MIN_TRACE, ("Information DataLength: 0x%x\n", Information->DataLength));
-
-				UnicodeAddress.Buffer = (PWCHAR)&Information->Data;
-				UnicodeAddress.Length = Information->DataLength;
-				UnicodeAddress.MaximumLength = Information->DataLength;
-
-				AnsiLen = RtlUnicodeStringToAnsiSize(&UnicodeAddress);
-				if(!AnsiLen)
-					{
-						TI_DbgPrint(MIN_TRACE, ("Unable to calculate address length\n"));
-						FreeTDPackets(Adapter);
-						IPDestroyInterface(Adapter->Context);
-						return;
-					}
-
-				AnsiAddress.Buffer = ExAllocatePoolWithTag(PagedPool, AnsiLen, 0x01020304);
-				if(!AnsiAddress.Buffer)
-					{
-						TI_DbgPrint(MIN_TRACE, ("ExAllocatePoolWithTag() failed.\n"));
-						FreeTDPackets(Adapter);
-						IPDestroyInterface(Adapter->Context);
-						return;
-					}
-        AnsiAddress.Length = AnsiLen;
-        AnsiAddress.MaximumLength = AnsiLen;
-
-				Status = RtlUnicodeStringToAnsiString(&AnsiAddress, &UnicodeAddress, FALSE);
-        if (!NT_SUCCESS(Status))
-					{
-						TI_DbgPrint(MIN_TRACE, ("RtlUnicodeStringToAnsiString() failed with Status 0x%lx.\n", Status));
-						FreeTDPackets(Adapter);
-						IPDestroyInterface(Adapter->Context);
-						return;
-					}
-
-				AnsiAddress.Buffer[AnsiAddress.Length] = 0;
-				Address = AddrBuildIPv4(inet_addr(AnsiAddress.Buffer));
-				if (!Address) {
-						TI_DbgPrint(MIN_TRACE, ("AddrBuildIPv4() failed.\n"));
-						FreeTDPackets(Adapter);
-						IPDestroyInterface(Adapter->Context);
-						return;
-				}
-
-        TI_DbgPrint(MID_TRACE, ("--> Our IP address on this interface: '%s'\n", A2S(Address)));
-			}
+    /* 
+     * Query per-adapter configuration from the registry 
+     * In case anyone is curious:  there *is* an Ndis configuration api
+     * for this sort of thing, but it doesn't really support things like
+     * REG_MULTI_SZ very well, and there is a note in the DDK that says that
+     * protocol drivers developed for win2k and above just use the native
+     * services (ZwOpenKey, etc).
+     */
+    
+    Status = OpenRegistryKey( RegistryPath, &RegHandle );
+	    
+    if(NT_SUCCESS(Status))
+	Status = ReadIPAddressFromRegistry( RegHandle, L"IPAddress",
+					    &Address );
+    if(NT_SUCCESS(Status)) 
+	Status = ReadIPAddressFromRegistry( RegHandle, L"SubnetMask",
+					    &Netmask );
+    
+    if(!NT_SUCCESS(Status) || !Address || !Netmask)
+    {
+	TI_DbgPrint(MIN_TRACE, ("Unable to open protocol-specific registry key: 0x%x\n", Status));
+	
+	/* XXX how do we proceed?  No ip address, no parameters... do we guess? */
+	if(RegHandle)  
+	    ZwClose(RegHandle);
+	if(Address) Address->Free(Address);
+	if(Netmask) Netmask->Free(Netmask);
+	FreeTDPackets(Adapter);
+	IPDestroyInterface(IF);
+	return;
+    }
+    
+    TI_DbgPrint
+	(MID_TRACE, 
+	 ("--> Our IP address on this interface: '%s'\n", 
+	  A2S(Address)));
+    
+    TI_DbgPrint
+	(MID_TRACE, 
+	 ("--> Our net mask on this interface: '%s'\n", 
+	  A2S(Netmask)));
 
     /* Create a net table entry for this interface */
-    if (!IPCreateNTE(IF, Address, 8)) {
+    if (!IPCreateNTE(IF, Address, AddrCountPrefixBits(Netmask))) {
+	Netmask->Free(Netmask);
         TI_DbgPrint(MIN_TRACE, ("IPCreateNTE() failed.\n"));
         FreeTDPackets(Adapter);
         IPDestroyInterface(IF);
         return;
     }
 
+    Netmask->Free(Netmask);
+
     /* Reference the interface for the NTE. The reference
        for the address is just passed on to the NTE */
     ReferenceObject(IF);

reactos/drivers/net/tcpip/include
address.h 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- address.h	4 Mar 2004 20:45:38 -0000	1.7
+++ address.h	12 Mar 2004 04:21:59 -0000	1.8
@@ -78,6 +78,10 @@
 
 unsigned long PASCAL inet_addr(const char*);
 
+ULONG IPv4NToHl( ULONG Address );
+
+UINT AddrCountPrefixBits( PIP_ADDRESS Netmask );
+
 #endif /* __ADDRESS_H */
 
 /* EOF */

reactos/drivers/net/tcpip/include
info.h 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- info.h	8 Mar 2004 10:20:17 -0000	1.4
+++ info.h	12 Mar 2004 04:21:59 -0000	1.5
@@ -7,6 +7,8 @@
 #ifndef __INFO_H
 #define __INFO_H
 
+#define MAX_PHYSADDR_LEN 8
+#define MAX_IFDESCR_LEN  256
 
 typedef struct IPSNMP_INFO {
 	ULONG Forwarding;
@@ -60,7 +62,31 @@
     ULONG Info;
 } IPROUTE_ENTRY, *PIPROUTE_ENTRY;
 
+typedef struct IFENTRY {
+    ULONG Index;
+    ULONG Type;
+    ULONG Mtu;
+    ULONG Speed;
+    ULONG PhysAddrLen;
+    UCHAR PhysAddr[MAX_PHYSADDR_LEN];
+    ULONG AdminStatus;
+    ULONG OperStatus;
+    ULONG LastChange;
+    ULONG InOctets;
+    ULONG InUcastPackets;
+    ULONG InDiscards;
+    ULONG InErrors;
+    ULONG InUnknownProtos;
+    ULONG OutOctets;
+    ULONG OutUcastPackets;
+    ULONG OutDiscards;
+    ULONG OutErrors;
+    ULONG OutQLen;
+    ULONG DescrLen;
+} IFENTRY, *PIFENTRY;
+ 
 #define	IP_MIB_STATS_ID           1
+#define IF_MIB_STATS_ID           1
 #ifndef IP_MIB_ADDRTABLE_ENTRY_ID
 #define	IP_MIB_ADDRTABLE_ENTRY_ID 0x102
 #endif

reactos/drivers/net/tcpip/include
ip.h 1.9 -> 1.10
diff -u -r1.9 -r1.10
--- ip.h	4 Mar 2004 20:45:38 -0000	1.9
+++ ip.h	12 Mar 2004 04:21:59 -0000	1.10
@@ -264,6 +264,8 @@
 NTSTATUS IPShutdown(
     VOID);
 
+
+
 #endif /* __IP_H */
 
 /* EOF */

reactos/drivers/net/tcpip/include
tcpip.h 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- tcpip.h	8 Mar 2004 10:20:17 -0000	1.7
+++ tcpip.h	12 Mar 2004 04:21:59 -0000	1.8
@@ -125,6 +125,7 @@
 extern KSPIN_LOCK EntityListLock;
 extern TDIEntityID *EntityList;
 extern ULONG EntityCount;
+extern ULONG EntityMax;
 extern UDP_STATISTICS UDPStats;
 
 #endif /* __TCPIP_H */

reactos/drivers/net/tcpip/tcpip
address.c 1.10 -> 1.11
diff -u -r1.10 -r1.11
--- address.c	4 Mar 2004 20:45:39 -0000	1.10
+++ address.c	12 Mar 2004 04:21:59 -0000	1.11
@@ -54,6 +54,35 @@
 
 #endif /* DBG */
 
+ULONG IPv4NToHl( ULONG Address ) {
+    return 
+	((Address & 0xff) << 24) |
+	((Address & 0xff00) << 8) |
+	((Address >> 8) & 0xff00) |
+	((Address >> 24) & 0xff);
+}
+
+UINT AddrCountPrefixBits( PIP_ADDRESS Netmask ) {
+    UINT Prefix = 0;
+    if( Netmask->Type == IP_ADDRESS_V4 ) {
+	ULONG BitTest = 0x80000000;
+	
+	/* The mask has been read in network order.  Put it in host order
+	 * in order to scan it. */
+
+	ULONG TestMask = IPv4NToHl(Netmask->Address.IPv4Address);
+	
+	while( (BitTest & TestMask) == BitTest ) {
+	    Prefix++;
+	    BitTest >>= 1;
+	}
+	return Prefix;
+    } else {
+	TI_DbgPrint(DEBUG_DATALINK, ("Don't know address type %d\n", 
+				     Netmask->Type));
+	return 0;
+    }
+}
 
 VOID IPAddressFree(
     PVOID Object)

reactos/drivers/net/tcpip/tcpip
info.c 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- info.c	8 Mar 2004 10:20:18 -0000	1.4
+++ info.c	12 Mar 2004 04:21:59 -0000	1.5
@@ -201,6 +201,127 @@
   return TDI_INVALID_PARAMETER;
 }
 
+TDI_STATUS InfoTdiQueryListEntities(PNDIS_BUFFER Buffer,
+				    UINT BufSize,
+				    PUINT BufferSize)
+{
+    UINT Count, Size, Temp;
+    KIRQL OldIrql;
+    PLIST_ENTRY CurrentIFEntry;
+
+    /* Count Adapters */
+    KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
+    
+    CurrentIFEntry = InterfaceListHead.Flink;
+    Count = EntityCount;
+    
+    while( CurrentIFEntry != &InterfaceListHead ) {
+	Count++;
+	CurrentIFEntry = CurrentIFEntry->Flink;
+    }
+    
+    KeReleaseSpinLock(&InterfaceListLock, OldIrql);
+    
+    Size = Count * sizeof(TDIEntityID);
+    *BufferSize = Size;
+    
+    if (BufSize < Size)
+    {
+	/* The buffer is too small to contain requested data */
+	return TDI_BUFFER_TOO_SMALL;
+    }
+    
+    DbgPrint("About to copy %d TDIEntityIDs (%d bytes) to user\n",
+	     Count, Size);
+    
+    KeAcquireSpinLock(&EntityListLock, &OldIrql);
+    
+    /* Update entity list */
+    for( Temp = EntityCount; Temp < Count; Temp++ ) {
+	EntityList[Temp].tei_entity = IF_ENTITY;
+	EntityList[Temp].tei_instance = Temp - EntityCount;
+    }
+    EntityMax = Count;
+    
+    /* Return entity list */
+    Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)EntityList, Size);
+    
+    KeReleaseSpinLock(&EntityListLock, OldIrql);
+    
+    *BufferSize = Size;
+
+    return TDI_SUCCESS;
+}
+
+TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIObjectID *ID,
+				       PNDIS_BUFFER Buffer,
+				       UINT BufSize,
+				       PUINT BufferSize) {
+    PIFENTRY OutData;
+    UINT ListedIfIndex, Count, Size;
+    PLIST_ENTRY CurrentADEEntry;
+    PADDRESS_ENTRY CurrentADE;
+    PLIST_ENTRY CurrentIFEntry;
+    PIP_INTERFACE CurrentIF;
+    PCHAR IFDescr;
+    KIRQL OldIrql;
+
+    OutData = ExAllocatePool( NonPagedPool, 
+			      sizeof(IFENTRY) + MAX_IFDESCR_LEN );
+
+    if( !OutData ) return STATUS_NO_MEMORY;
+
+    RtlZeroMemory( OutData,sizeof(IFENTRY) + MAX_IFDESCR_LEN );
+
+    KeAcquireSpinLock(&EntityListLock, &OldIrql);
+    ListedIfIndex = ID->toi_entity.tei_instance - EntityCount;
+    if( ListedIfIndex > EntityMax ) {
+	KeReleaseSpinLock(&EntityListLock,OldIrql);
+	return TDI_INVALID_REQUEST;
+    }
+    
+    CurrentIFEntry = InterfaceListHead.Flink;
+    
+    for( Count = 0; Count < ListedIfIndex; Count++ )
+	CurrentIFEntry = CurrentIFEntry->Flink;
+    
+    CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
+
+    CurrentADEEntry = CurrentIF->ADEListHead.Flink;
+    if( CurrentADEEntry == &CurrentIF->ADEListHead ) {
+	KeReleaseSpinLock( &EntityListLock, OldIrql );
+	return TDI_INVALID_REQUEST;
+    }
+
+    CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
+    
+    OutData->Index = Count + 1; /* XXX - arty What goes here?? */
+    OutData->Type = CurrentADE->Type;
+    OutData->Mtu = CurrentIF->MTU;
+    OutData->Speed = 10000000; /* XXX - arty Not sure */
+    memcpy(OutData->PhysAddr,
+	   CurrentIF->Address,CurrentIF->AddressLength);
+    OutData->PhysAddrLen = CurrentIF->AddressLength;
+    OutData->AdminStatus = TRUE;
+    OutData->OperStatus = TRUE;
+    IFDescr = (PCHAR)&OutData[1];
+    strcpy(IFDescr,"ethernet adapter");
+    OutData->DescrLen = strlen(IFDescr);
+    IFDescr = IFDescr + strlen(IFDescr);
+    Size = IFDescr - (PCHAR)OutData;
+
+    KeReleaseSpinLock(&InterfaceListLock, OldIrql);
+
+    *BufferSize = Size;
+
+    if( BufSize < Size ) {
+	return TDI_BUFFER_TOO_SMALL;
+    } else {
+	CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&OutData, Size);
+	return TDI_SUCCESS;
+    }
+}
+    
 TDI_STATUS InfoTdiQueryInformationEx(
   PTDI_REQUEST Request,
   TDIObjectID *ID,
@@ -250,47 +371,18 @@
           return TDI_INVALID_PARAMETER;
         }
 
-      /* Count Adapters */
-      KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
-
-      CurrentIFEntry = InterfaceListHead.Flink;
-      Count = EntityCount;
-
-      while( CurrentIFEntry != &InterfaceListHead ) {
-	  Count++;
-	  CurrentIFEntry = CurrentIFEntry->Flink;
-      }
-      
-      KeReleaseSpinLock(&InterfaceListLock, OldIrql);
-
-      Size = Count * sizeof(TDIEntityID);
-      *BufferSize = Size;
-
-      if (BufSize < Size)
-        {
-          /* The buffer is too small to contain requested data */
-          return TDI_BUFFER_TOO_SMALL;
-        }
-
-      DbgPrint("About to copy %d TDIEntityIDs (%d bytes) to user\n",
-	       Count, Size);
-
-      KeAcquireSpinLock(&EntityListLock, &OldIrql);
-
-      /* Update entity list */
-      for( Temp = EntityCount; Temp < Count; Temp++ ) {
-	  EntityList[Temp].tei_entity = IF_ENTITY;
-	  EntityList[Temp].tei_instance = Temp - EntityCount;
-      }
-
-      /* Return entity list */
-      Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)EntityList, Size);
-
-      KeReleaseSpinLock(&EntityListLock, OldIrql);
+      return InfoTdiQueryListEntities(Buffer, BufSize, BufferSize);
+    }
 
-      *BufferSize = Size;
+  /* Get an IFENTRY */
+  if (ID->toi_class == INFO_CLASS_PROTOCOL && 
+      ID->toi_type  == INFO_TYPE_PROVIDER &&
+      ID->toi_id    == IF_MIB_STATS_ID) 
+    {
+      if(ID->toi_entity.tei_entity != IF_ENTITY)
+	return TDI_INVALID_REQUEST;
 
-      return TDI_SUCCESS;
+      return InfoTdiQueryGetInterfaceMIB(ID, Buffer, BufSize, BufferSize);
     }
 
     if ((Entity != CL_TL_ENTITY) && (Entity != CO_TL_ENTITY))
CVSspam 0.2.8