7 modified files
reactos/drivers/net/tcpip/datalink
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
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
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
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
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
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
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