From 0ecfffa8a07a77b7a6412fe0b6bcc39120277407 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Thu, 24 Mar 2005 10:46:52 +0000 Subject: [PATCH] This is change 1 of 2. AddIPAddress and DeleteIPAddress are now implemented all the way down. Next we need the dhcp service live enough to assign the address from userland, then we can remove the IP address setting from the kernel. svn path=/trunk/; revision=14298 --- reactos/drivers/lib/ip/network/ip.c | 16 +++++ reactos/drivers/net/tcpip/include/dispatch.h | 8 +++ reactos/drivers/net/tcpip/include/ip.h | 6 ++ reactos/drivers/net/tcpip/include/ticonsts.h | 6 ++ reactos/drivers/net/tcpip/tcpip/dispatch.c | 52 ++++++++++++++ reactos/drivers/net/tcpip/tcpip/iinfo.c | 4 +- reactos/drivers/net/tcpip/tcpip/main.c | 12 +++- reactos/include/tcpioctl.h | 6 ++ reactos/lib/iphlpapi/ifenum_reactos.c | 71 ++++++++++++++++++++ reactos/lib/iphlpapi/iphlpapi_main.c | 10 +-- reactos/lib/iphlpapi/iphlpapi_private.h | 6 ++ 11 files changed, 188 insertions(+), 9 deletions(-) diff --git a/reactos/drivers/lib/ip/network/ip.c b/reactos/drivers/lib/ip/network/ip.c index 4b6871efc0c..ef23f27b5d1 100644 --- a/reactos/drivers/lib/ip/network/ip.c +++ b/reactos/drivers/lib/ip/network/ip.c @@ -244,13 +244,29 @@ BOOLEAN IPRegisterInterface( */ { KIRQL OldIrql; + UINT ChosenIndex = 1; + BOOLEAN IndexHasBeenChosen; IP_ADDRESS NetworkAddress; PNEIGHBOR_CACHE_ENTRY NCE; + IF_LIST_ITER(Interface); TI_DbgPrint(MID_TRACE, ("Called. IF (0x%X).\n", IF)); TcpipAcquireSpinLock(&IF->Lock, &OldIrql); + /* Choose an index */ + do { + IndexHasBeenChosen = TRUE; + ForEachInterface(Interface) { + if( Interface->Index == ChosenIndex ) { + ChosenIndex++; + IndexHasBeenChosen = FALSE; + } + } EndFor(Interface); + } while( !IndexHasBeenChosen ); + + IF->Index = ChosenIndex; + /* Add a permanent neighbor for this NTE */ NCE = NBAddNeighbor(IF, &IF->Unicast, IF->Address, IF->AddressLength, diff --git a/reactos/drivers/net/tcpip/include/dispatch.h b/reactos/drivers/net/tcpip/include/dispatch.h index 5108ff55695..bd559517b11 100644 --- a/reactos/drivers/net/tcpip/include/dispatch.h +++ b/reactos/drivers/net/tcpip/include/dispatch.h @@ -56,6 +56,14 @@ NTSTATUS DispTdiSetInformationEx( PIRP Irp, PIO_STACK_LOCATION IrpSp); +NTSTATUS DispTdiSetIPAddress( + PIRP Irp, + PIO_STACK_LOCATION IrpSp); + +NTSTATUS DispTdiDeleteIPAddress( + PIRP Irp, + PIO_STACK_LOCATION IrpSp); + #endif /* __DISPATCH_H */ /* EOF */ diff --git a/reactos/drivers/net/tcpip/include/ip.h b/reactos/drivers/net/tcpip/include/ip.h index 9986897fa3b..68950cebcee 100644 --- a/reactos/drivers/net/tcpip/include/ip.h +++ b/reactos/drivers/net/tcpip/include/ip.h @@ -153,10 +153,16 @@ typedef struct _IP_INTERFACE { UNICODE_STRING Name; /* Adapter name */ PUCHAR Address; /* Pointer to interface address */ UINT AddressLength; /* Length of address in bytes */ + UINT Index; /* Index of adapter (used to add ip addr) */ LL_TRANSMIT_ROUTINE Transmit; /* Pointer to transmit function */ PVOID TCPContext; /* TCP Content for this interface */ } IP_INTERFACE, *PIP_INTERFACE; +typedef struct _IP_SET_ADDRESS { + ULONG NteIndex; + IPv4_RAW_ADDRESS Address; + IPv4_RAW_ADDRESS Netmask; +} IP_SET_ADDRESS, *PIP_SET_ADDRESS; #define IP_PROTOCOL_TABLE_SIZE 0x100 diff --git a/reactos/drivers/net/tcpip/include/ticonsts.h b/reactos/drivers/net/tcpip/include/ticonsts.h index ab0b2425fb2..ca26064f111 100644 --- a/reactos/drivers/net/tcpip/include/ticonsts.h +++ b/reactos/drivers/net/tcpip/include/ticonsts.h @@ -45,6 +45,12 @@ #define IOCTL_TCP_SET_INFORMATION_EX \ _TCP_CTL_CODE(1, METHOD_BUFFERED, FILE_WRITE_ACCESS) +#define IOCTL_SET_IP_ADDRESS \ + _TCP_CTL_CODE(14, METHOD_BUFFERED, FILE_WRITE_ACCESS) + +#define IOCTL_DELETE_IP_ADDRESS \ + _TCP_CTL_CODE(16, METHOD_BUFFERED, FILE_WRITE_ACCESS) + /* Unique error values for log entries */ #define TI_ERROR_DRIVERENTRY 0 diff --git a/reactos/drivers/net/tcpip/tcpip/dispatch.c b/reactos/drivers/net/tcpip/tcpip/dispatch.c index ec417f99b36..0f25e9e41a5 100644 --- a/reactos/drivers/net/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/net/tcpip/tcpip/dispatch.c @@ -1465,4 +1465,56 @@ NTSTATUS DispTdiSetInformationEx( return Status; } +/* TODO: Support multiple addresses per interface. + * For now just set the nte context to the interface index. + * + * Later on, create an NTE context and NTE instance + */ + +NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) { + NTSTATUS Status = STATUS_DEVICE_DOES_NOT_EXIST; + PIP_SET_ADDRESS IpAddrChange = + (PIP_SET_ADDRESS)Irp->AssociatedIrp.SystemBuffer; + IF_LIST_ITER(IF); + + ForEachInterface(IF) { + if( IF->Unicast.Address.IPv4Address == IpAddrChange->Address ) { + Status = STATUS_DUPLICATE_OBJECTID; + break; + } + if( IF->Index == IpAddrChange->NteIndex ) { + IF->Unicast.Type = IP_ADDRESS_V4; + IF->Unicast.Address.IPv4Address = IpAddrChange->Address; + IF->Netmask.Type = IP_ADDRESS_V4; + IF->Netmask.Address.IPv4Address = IpAddrChange->Netmask; + IpAddrChange->Address = IF->Index; + Status = STATUS_SUCCESS; + Irp->IoStatus.Information = IF->Index; + break; + } + } EndFor(IF); + + Irp->IoStatus.Status = Status; + return Status; +} + +NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) { + NTSTATUS Status = STATUS_UNSUCCESSFUL; + PUSHORT NteIndex = Irp->AssociatedIrp.SystemBuffer; + IF_LIST_ITER(IF); + + ForEachInterface(IF) { + if( IF->Index == *NteIndex ) { + IF->Unicast.Type = IP_ADDRESS_V4; + IF->Unicast.Address.IPv4Address = 0; + IF->Netmask.Type = IP_ADDRESS_V4; + IF->Netmask.Address.IPv4Address = 0; + Status = STATUS_SUCCESS; + } + } EndFor(IF); + + Irp->IoStatus.Status = Status; + return Status; +} + /* EOF */ diff --git a/reactos/drivers/net/tcpip/tcpip/iinfo.c b/reactos/drivers/net/tcpip/tcpip/iinfo.c index 4d47b555c50..857e0a323fc 100644 --- a/reactos/drivers/net/tcpip/tcpip/iinfo.c +++ b/reactos/drivers/net/tcpip/tcpip/iinfo.c @@ -33,7 +33,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID, RtlZeroMemory( OutData, sizeof(IFENTRY) + MAX_IFDESCR_LEN ); - OutData->Index = ID->tei_instance + 1; + OutData->Index = Interface->Index; /* viz: tcpip keeps those indices */ OutData->Type = Interface == Loopback ? MIB_IF_TYPE_LOOPBACK : MIB_IF_TYPE_ETHERNET; @@ -104,5 +104,7 @@ TDI_STATUS InfoInterfaceTdiSetEx( UINT InfoClass, TDIEntityID *id, PCHAR Buffer, UINT BufferSize ) { + TI_DbgPrint("Got Request: Class %x Type %x Id %x, EntityID %x:%x\n", + InfoClass, InfoId, id->tei_entity, id->tei_instance); return TDI_INVALID_REQUEST; } diff --git a/reactos/drivers/net/tcpip/tcpip/main.c b/reactos/drivers/net/tcpip/tcpip/main.c index eb5101dd974..ca9e274ff95 100644 --- a/reactos/drivers/net/tcpip/tcpip/main.c +++ b/reactos/drivers/net/tcpip/tcpip/main.c @@ -9,7 +9,7 @@ */ #include "precomp.h" -#define NDEBUG +//#define NDEBUG #ifndef NDEBUG DWORD DebugTraceLevel = DEBUG_ULTRA & ~(DEBUG_LOCK | DEBUG_PBUFFER); @@ -578,6 +578,16 @@ TiDispatch( Status = DispTdiSetInformationEx(Irp, IrpSp); break; + case IOCTL_SET_IP_ADDRESS: + TI_DbgPrint(MIN_TRACE, ("SET_IP_ADDRESS\n")); + Status = DispTdiSetIPAddress(Irp, IrpSp); + break; + + case IOCTL_DELETE_IP_ADDRESS: + TI_DbgPrint(MIN_TRACE, ("DELETE_IP_ADDRESS\n")); + Status = DispTdiDeleteIPAddress(Irp, IrpSp); + break; + default: TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n", IrpSp->Parameters.DeviceIoControl.IoControlCode)); diff --git a/reactos/include/tcpioctl.h b/reactos/include/tcpioctl.h index b1e113daab7..49d5b794280 100644 --- a/reactos/include/tcpioctl.h +++ b/reactos/include/tcpioctl.h @@ -37,4 +37,10 @@ #define IOCTL_TCP_SET_INFORMATION_EX \ _TCP_CTL_CODE(1, METHOD_BUFFERED, FILE_WRITE_ACCESS) +#define IOCTL_SET_IP_ADDRESS \ + _TCP_CTL_CODE(14, METHOD_BUFFERED, FILE_WRITE_ACCESS) + +#define IOCTL_DELETE_IP_ADDRESS \ + _TCP_CTL_CODE(16, METHOD_BUFFERED, FILE_WRITE_ACCESS) + #endif/*_TCPIOCTL_H*/ diff --git a/reactos/lib/iphlpapi/ifenum_reactos.c b/reactos/lib/iphlpapi/ifenum_reactos.c index ac19823be84..073983d8a9a 100644 --- a/reactos/lib/iphlpapi/ifenum_reactos.c +++ b/reactos/lib/iphlpapi/ifenum_reactos.c @@ -754,6 +754,8 @@ DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry) sizeof(info.if_info) ); } + DPRINT1("entry->bDescr = %s\n", entry->bDescr); + closeTcpFile( tcpFile ); } @@ -795,3 +797,72 @@ char *toIPAddressString(unsigned int addr, char string[16]) } return string; } + +NTSTATUS addIPAddress( IPAddr Address, IPMask Mask, DWORD IfIndex, + PULONG NteContext, PULONG NteInstance ) +{ + HANDLE tcpFile; + NTSTATUS status = openTcpFile( &tcpFile ); + IP_SET_DATA Data; + IO_STATUS_BLOCK Iosb; + + DPRINT("Called.\n"); + + if( !NT_SUCCESS(status) ) return status; + + Data.NteContext = IfIndex; + Data.NewAddress = Address; + Data.NewNetmask = Mask; + + status = NtDeviceIoControlFile( tcpFile, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_SET_IP_ADDRESS, + &Data, + sizeof(Data), + &Data, + sizeof(Data) ); + + closeTcpFile( tcpFile ); + + if( NT_SUCCESS(status) ) { + *NteContext = Iosb.Information; + *NteInstance = Data.NewAddress; + } + + switch( status ) { + case STATUS_SUCCESS: return ERROR_SUCCESS; + case STATUS_DEVICE_DOES_NOT_EXIST: return ERROR_DEV_NOT_EXIST; + default: return status; + } +} + +NTSTATUS deleteIpAddress( ULONG NteContext ) +{ + HANDLE tcpFile; + NTSTATUS status = openTcpFile( &tcpFile ); + USHORT TheNteContext = NteContext; + IO_STATUS_BLOCK Iosb; + + DPRINT("Called.\n"); + + if( !NT_SUCCESS(status) ) return status; + + status = NtDeviceIoControlFile( tcpFile, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DELETE_IP_ADDRESS, + &NteContext, + sizeof(USHORT), + NULL, + 0 ); + + closeTcpFile( tcpFile ); + + if( NT_SUCCESS(status) ) return ERROR_SUCCESS; + else return ERROR_GEN_FAILURE; +} diff --git a/reactos/lib/iphlpapi/iphlpapi_main.c b/reactos/lib/iphlpapi/iphlpapi_main.c index 7cb92952e77..3baddf6074d 100644 --- a/reactos/lib/iphlpapi/iphlpapi_main.c +++ b/reactos/lib/iphlpapi/iphlpapi_main.c @@ -82,11 +82,9 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) * DWORD * */ -DWORD WINAPI AddIPAddress(IPAddr Address, IPMask IpMask, DWORD IfIndex, PULONG NTEContext, PULONG NTEInstance) +DWORD WINAPI AddIPAddress(IPAddr Address, IPMask Netmask, DWORD IfIndex, PULONG NteContext, PULONG NteInstance) { - FIXME(":stub\n"); - /* marking Win2K+ functions not supported */ - return ERROR_NOT_SUPPORTED; + return addIPAddress( Address, Netmask, IfIndex, NteContext, NteInstance ); } @@ -404,9 +402,7 @@ DWORD WINAPI CreateProxyArpEntry(DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex) DWORD WINAPI DeleteIPAddress(ULONG NTEContext) { TRACE("NTEContext %ld\n", NTEContext); - FIXME(":stub\n"); - /* marking Win2K+ functions not supported */ - return ERROR_NOT_SUPPORTED; + return deleteIpAddress( NTEContext ); } diff --git a/reactos/lib/iphlpapi/iphlpapi_private.h b/reactos/lib/iphlpapi/iphlpapi_private.h index 92b9be872b6..1d52a9f4605 100644 --- a/reactos/lib/iphlpapi/iphlpapi_private.h +++ b/reactos/lib/iphlpapi/iphlpapi_private.h @@ -82,6 +82,12 @@ typedef struct _IFInfo { IPAddrEntry ip_addr; } IFInfo; +typedef struct _IP_SET_DATA { + ULONG NteContext; + ULONG NewAddress; + ULONG NewNetmask; +} IP_SET_DATA, *PIP_SET_DATA; + typedef enum _IPHLPAddrType { IPAAddr, IPABcast, IPAMask, IFMtu, IFStatus } IPHLPAddrType;