Author: cgutman Date: Sat Jan 14 19:42:58 2012 New Revision: 54966
URL: http://svn.reactos.org/svn/reactos?rev=54966&view=rev Log: - Merge 54929, 54930, 54932, 54933, 54934, 54939, 54941, 54942, 54944, 54945, 54946, and 54947 - The DHCP service now recognizes adapter configuration and media state changes without manual intervention - Multiple bugs with a static IP configuration are fixed - IpRenewAddress (ipconfig /renew) and IpReleaseAddress (ipconfig /release) no longer corrupt internal DHCP state - Routes that cannot currently be resolved by ARP no longer become corrupted by the neighbor timeout
Modified: trunk/reactos/ (props changed) trunk/reactos/dll/win32/dhcpcsvc/dhcp/adapter.c trunk/reactos/dll/win32/dhcpcsvc/dhcp/api.c trunk/reactos/dll/win32/dhcpcsvc/dhcp/dhclient.c trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c trunk/reactos/dll/win32/netcfgx/tcpipconf_notify.c trunk/reactos/drivers/network/tcpip/datalink/lan.c trunk/reactos/drivers/network/tcpip/include/ip.h trunk/reactos/drivers/network/tcpip/include/lan.h trunk/reactos/drivers/network/tcpip/include/neighbor.h trunk/reactos/drivers/network/tcpip/include/router.h trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c trunk/reactos/lib/drivers/ip/network/ip.c trunk/reactos/lib/drivers/ip/network/loopback.c trunk/reactos/lib/drivers/ip/network/neighbor.c trunk/reactos/lib/drivers/ip/network/router.c
Propchange: trunk/reactos/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Sat Jan 14 19:42:58 2012 @@ -10,4 +10,4 @@ /branches/ros-amd64-bringup/reactos:34711-34712,34741,34743,34770,34780-34782,34803,34812,34839,34842,34864,34870,34874,34877,34908-34909,34917,34965,35323-35324,35347-35348,35361,35436,35509,35515,35588,35655,35683,35739,35746,35762,35771,35777,35781,35789,35805,35823,35827,35902,35904-35906,35942,35947-35949,35952-35953,35966,36011-36013,36172,36360,36380,36388-36389,36393,36397,36443,36445,36475,36502-36503,36505,36570,36614,36852,36898-36899,36930,36936,36949,36951,36958,36961,36964,36969,36972,36987-36988,36990,36992,37019,37322-37323,37333-37334,37434,37472,37475,37536,37820-37821,37868-37869,37873,37990-37991,38013-38014,38092,38100,38148-38151,38264-38265,38268,38355,39151,39333,39335,39345,39639,40120,40122-40123,40125,40127-40128,40155,40247,40324,40608,40753,40926-40928,40986-40987,40989,40991,40993,40995-40996,41000-41001,41027-41030,41044-41045,41047-41050,41052,41070,41082-41086,41097-41098,41101,41449,41479-41480,41483-41485,41499-41500,41502,41531,41536,41540,41546-41547,41549,43080,43426,43451,43454,43506,43566,43574,43598,43600-43602,43604-43605,43677,43682,43757,43775,43836,43838-43840,43852,43857-43858,43860,43905-43907,43952,43954,43965,43969,43979,43981,43992,44002,44036-44037,44039-44040,44044-44045,44053,44065,44095,44123,44143-44144,44205,44238,44257,44259,44294,44338-44339,44385,44389,44391,44426,44460,44467-44468,44470-44471,44499,44501,44503-44504,44506,44510-44512,44521,44523-44526,44530,44540,44601,44634,44639,44772,44818,45124,45126-45127,45430,46394,46404,46478,46511,46523-46524,46526,46534-46535,46537-46539,46589,46805,46868,47472,47846-47847,47878,47882 /branches/shell32_new-bringup:51893-53652,53661,53700 /branches/tcp-rewrite-branch:48720,48840-48841,49424-49426,49454 -/branches/wlan-bringup:54895-54896,54899,54912-54913,54915-54916 +/branches/wlan-bringup:54895-54896,54899,54912-54913,54915-54916,54929-54930,54932-54934,54939,54941-54942,54944-54947
Modified: trunk/reactos/dll/win32/dhcpcsvc/dhcp/adapter.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/dhcpcsvc/dhcp/ada... ============================================================================== --- trunk/reactos/dll/win32/dhcpcsvc/dhcp/adapter.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/dhcpcsvc/dhcp/adapter.c [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -200,6 +200,85 @@ return 0; }
+BOOL +IsReconnectHackNeeded(PDHCP_ADAPTER Adapter, const MIB_IFROW* IfEntry) +{ + struct protocol *proto; + PIP_ADAPTER_INFO AdapterInfo, Orig; + DWORD Size, Ret; + char *ZeroAddress = "0.0.0.0"; + + proto = find_protocol_by_adapter(&Adapter->DhclientInfo); + + if (Adapter->DhclientInfo.client->state == S_BOUND && !proto) + return FALSE; + + if (Adapter->DhclientInfo.client->state != S_BOUND && + Adapter->DhclientInfo.client->state != S_STATIC) + return FALSE; + + ApiUnlock(); + + Orig = AdapterInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO)); + Size = sizeof(IP_ADAPTER_INFO); + if (!AdapterInfo) + { + ApiLock(); + return FALSE; + } + + Ret = GetAdaptersInfo(AdapterInfo, &Size); + if (Ret == ERROR_BUFFER_OVERFLOW) + { + HeapFree(GetProcessHeap(), 0, AdapterInfo); + AdapterInfo = HeapAlloc(GetProcessHeap(), 0, Size); + if (!AdapterInfo) + { + ApiLock(); + return FALSE; + } + + if (GetAdaptersInfo(AdapterInfo, &Size) != NO_ERROR) + { + ApiLock(); + return FALSE; + } + + Orig = AdapterInfo; + for (; AdapterInfo != NULL; AdapterInfo = AdapterInfo->Next) + { + if (AdapterInfo->Index == IfEntry->dwIndex) + break; + } + + if (AdapterInfo == NULL) + { + HeapFree(GetProcessHeap(), 0, Orig); + ApiLock(); + return FALSE; + } + } + else if (Ret != NO_ERROR) + { + HeapFree(GetProcessHeap(), 0, Orig); + ApiLock(); + return FALSE; + } + + if (!strcmp(AdapterInfo->IpAddressList.IpAddress.String, ZeroAddress)) + { + HeapFree(GetProcessHeap(), 0, Orig); + ApiLock(); + return TRUE; + } + else + { + HeapFree(GetProcessHeap(), 0, Orig); + ApiLock(); + return FALSE; + } +} + /* * XXX Figure out the way to bind a specific adapter to a socket. */ @@ -241,12 +320,35 @@
if ((Adapter = AdapterFindByHardwareAddress(Table->table[i].bPhysAddr, Table->table[i].dwPhysAddrLen))) { + proto = find_protocol_by_adapter(&Adapter->DhclientInfo); + /* This is an existing adapter */ if (InterfaceConnected(&Table->table[i])) { /* We're still active so we stay in the list */ ifi = &Adapter->DhclientInfo; + + /* This is a hack because IP helper API sucks */ + if (IsReconnectHackNeeded(Adapter, &Table->table[i])) + { + /* This handles a disconnect/reconnect */ + + if (proto) + remove_protocol(proto); + Adapter->DhclientInfo.client->state = S_INIT; + + /* These are already invalid since the media state change */ + Adapter->RouterMib.dwForwardNextHop = 0; + Adapter->NteContext = 0; + + add_protocol(Adapter->DhclientInfo.name, + Adapter->DhclientInfo.rfdesc, + got_one, &Adapter->DhclientInfo); + state_init(&Adapter->DhclientInfo); + + SetEvent(AdapterStateChangedEvent); + } + } else { - proto = find_protocol_by_adapter(&Adapter->DhclientInfo); if (proto) remove_protocol(proto);
Modified: trunk/reactos/dll/win32/dhcpcsvc/dhcp/api.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/dhcpcsvc/dhcp/api... ============================================================================== --- trunk/reactos/dll/win32/dhcpcsvc/dhcp/api.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/dhcpcsvc/dhcp/api.c [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -101,9 +101,15 @@
if( Adapter ) { if (Adapter->NteContext) + { DeleteIPAddress( Adapter->NteContext ); + Adapter->NteContext = 0; + } if (Adapter->RouterMib.dwForwardNextHop) + { DeleteIpForwardEntry( &Adapter->RouterMib ); + Adapter->RouterMib.dwForwardNextHop = 0; + }
proto = find_protocol_by_adapter( &Adapter->DhclientInfo ); if (proto) @@ -171,9 +177,15 @@
if( Adapter ) { if (Adapter->NteContext) + { DeleteIPAddress( Adapter->NteContext ); + Adapter->NteContext = 0; + } if (Adapter->RouterMib.dwForwardNextHop) + { DeleteIpForwardEntry( &Adapter->RouterMib ); + Adapter->RouterMib.dwForwardNextHop = 0; + }
Adapter->DhclientState.state = S_STATIC; proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
Modified: trunk/reactos/dll/win32/dhcpcsvc/dhcp/dhclient.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/dhcpcsvc/dhcp/dhc... ============================================================================== --- trunk/reactos/dll/win32/dhcpcsvc/dhcp/dhclient.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/dhcpcsvc/dhcp/dhclient.c [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -548,7 +548,10 @@
if( Adapter->NteContext ) + { DeleteIPAddress( Adapter->NteContext ); + Adapter->NteContext = 0; + }
/* Set up our default router if we got one from the DHCP server */ if( new_lease->options[DHO_SUBNET_MASK].len ) { @@ -1007,7 +1010,7 @@ we haven't found anything for this interface yet. */ if (interval > ip->client->config->timeout) { state_panic(ip); - return; + ip->client->first_sending = cur_time; }
/* If we're selecting media, try the whole list before doing @@ -1100,16 +1103,8 @@ { struct interface_info *ip = ipp; PDHCP_ADAPTER Adapter = AdapterFindInfo(ip); - time_t cur_time; - - time(&cur_time);
note("No DHCPOFFERS received."); - - note("No working leases in persistent database - sleeping.\n"); - ip->client->state = S_INIT; - add_timeout(cur_time + ip->client->config->retry_interval, state_init, - ip);
if (!Adapter->NteContext) { @@ -1181,7 +1176,10 @@ discover a new address. */
if( Adapter ) + { DeleteIPAddress( Adapter->NteContext ); + Adapter->NteContext = 0; + }
ip->client->state = S_INIT; state_init(ip);
Modified: trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/iphlpapi/iphlpapi... ============================================================================== --- trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -639,6 +639,7 @@ ptr->IpAddressList.IpAddress.String); toIPAddressString(getInterfaceMaskByIndex(table->indexes[ndx]), ptr->IpAddressList.IpMask.String); + ptr->IpAddressList.Context = ptr->Index; toIPAddressString(getInterfaceGatewayByIndex(table->indexes[ndx]), ptr->GatewayList.IpAddress.String); getDhcpInfoForAdapter(table->indexes[ndx], &dhcpEnabled, @@ -1189,7 +1190,7 @@ pIpForwardTable->dwNumEntries = table->numRoutes; for (ndx = 0; ndx < numRoutes; ndx++) { pIpForwardTable->table[ndx].dwForwardIfIndex = - table->routes[ndx].ifIndex + 1; + table->routes[ndx].ifIndex; pIpForwardTable->table[ndx].dwForwardDest = table->routes[ndx].dest; pIpForwardTable->table[ndx].dwForwardMask =
Modified: trunk/reactos/dll/win32/netcfgx/tcpipconf_notify.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/netcfgx/tcpipconf... ============================================================================== --- trunk/reactos/dll/win32/netcfgx/tcpipconf_notify.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/netcfgx/tcpipconf_notify.c [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -3230,27 +3230,25 @@ } }
- if (pOldConfig->Gw) - { - dwSize = 0; - if (GetIpForwardTable(NULL, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) - { - DWORD Index; - PMIB_IPFORWARDTABLE pIpForwardTable = (PMIB_IPFORWARDTABLE)CoTaskMemAlloc(dwSize); - if (pIpForwardTable) + dwSize = 0; + if (GetIpForwardTable(NULL, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) + { + DWORD Index; + PMIB_IPFORWARDTABLE pIpForwardTable = (PMIB_IPFORWARDTABLE)CoTaskMemAlloc(dwSize); + if (pIpForwardTable) + { + if (GetIpForwardTable(pIpForwardTable, &dwSize, FALSE) == NO_ERROR) { - if (GetIpForwardTable(pIpForwardTable, &dwSize, FALSE) == NO_ERROR) + for (Index = 0; Index < pIpForwardTable->dwNumEntries; Index++) { - for (Index = 0; Index < pIpForwardTable->dwNumEntries; Index++) + if (pIpForwardTable->table[Index].dwForwardIfIndex == pOldConfig->Index && + pIpForwardTable->table[Index].dwForwardDest == 0) { - if (pIpForwardTable->table[Index].dwForwardIfIndex == pOldConfig->Index) - { - DeleteIpForwardEntry(&pIpForwardTable->table[Index]); - } + DeleteIpForwardEntry(&pIpForwardTable->table[Index]); } } - CoTaskMemFree(pIpForwardTable); } + CoTaskMemFree(pIpForwardTable); } }
Modified: trunk/reactos/drivers/network/tcpip/datalink/lan.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/datal... ============================================================================== --- trunk/reactos/drivers/network/tcpip/datalink/lan.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/datalink/lan.c [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -23,6 +23,11 @@ UINT BytesTransferred; BOOLEAN LegacyReceive; } LAN_WQ_ITEM, *PLAN_WQ_ITEM; + +typedef struct _RECONFIGURE_CONTEXT { + ULONG State; + PLAN_ADAPTER Adapter; +} RECONFIGURE_CONTEXT, *PRECONFIGURE_CONTEXT;
NDIS_HANDLE NdisProtocolHandle = (NDIS_HANDLE)NULL; BOOLEAN ProtocolRegistered = FALSE; @@ -555,6 +560,237 @@ TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); }
+BOOLEAN ReadIpConfiguration(PIP_INTERFACE Interface) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE ParameterHandle; + PKEY_VALUE_PARTIAL_INFORMATION KeyValueInfo; + WCHAR Buffer[150]; + UNICODE_STRING IPAddress = RTL_CONSTANT_STRING(L"IPAddress"); + UNICODE_STRING Netmask = RTL_CONSTANT_STRING(L"SubnetMask"); + UNICODE_STRING Gateway = RTL_CONSTANT_STRING(L"DefaultGateway"); + UNICODE_STRING EnableDhcp = RTL_CONSTANT_STRING(L"EnableDHCP"); + UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\Registry\Machine\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\"); + UNICODE_STRING TcpipRegistryPath; + UNICODE_STRING RegistryDataU; + ANSI_STRING RegistryDataA; + ULONG Unused; + NTSTATUS Status; + IP_ADDRESS DefaultMask, Router; + + AddrInitIPv4(&DefaultMask, 0); + + TcpipRegistryPath.MaximumLength = sizeof(WCHAR) * 150; + TcpipRegistryPath.Length = 0; + TcpipRegistryPath.Buffer = Buffer; + + /* Build the registry path */ + RtlAppendUnicodeStringToString(&TcpipRegistryPath, &Prefix); + RtlAppendUnicodeStringToString(&TcpipRegistryPath, &Interface->Name); + + InitializeObjectAttributes(&ObjectAttributes, + &TcpipRegistryPath, + OBJ_CASE_INSENSITIVE, + 0, + NULL); + + /* Open a handle to the adapter parameters */ + Status = ZwOpenKey(&ParameterHandle, KEY_READ, &ObjectAttributes); + + if (!NT_SUCCESS(Status)) + { + return FALSE; + } + else + { + KeyValueInfo = ExAllocatePool(PagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR)); + if (!KeyValueInfo) + { + ZwClose(ParameterHandle); + return FALSE; + } + + /* Read the EnableDHCP entry */ + Status = ZwQueryValueKey(ParameterHandle, + &EnableDhcp, + KeyValuePartialInformation, + KeyValueInfo, + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG), + &Unused); + if (NT_SUCCESS(Status) && KeyValueInfo->DataLength == sizeof(ULONG) && (*(PULONG)KeyValueInfo->Data) == 0) + { + RegistryDataU.MaximumLength = 16 + sizeof(WCHAR); + RegistryDataU.Buffer = (PWCHAR)KeyValueInfo->Data; + + /* Read the IP address */ + Status = ZwQueryValueKey(ParameterHandle, + &IPAddress, + KeyValuePartialInformation, + KeyValueInfo, + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR), + &Unused); + if (NT_SUCCESS(Status)) + { + RegistryDataU.Length = KeyValueInfo->DataLength; + + RtlUnicodeStringToAnsiString(&RegistryDataA, + &RegistryDataU, + TRUE); + + AddrInitIPv4(&Interface->Unicast, inet_addr(RegistryDataA.Buffer)); + + RtlFreeAnsiString(&RegistryDataA); + } + + Status = ZwQueryValueKey(ParameterHandle, + &Netmask, + KeyValuePartialInformation, + KeyValueInfo, + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR), + &Unused); + if (NT_SUCCESS(Status)) + { + RegistryDataU.Length = KeyValueInfo->DataLength; + + RtlUnicodeStringToAnsiString(&RegistryDataA, + &RegistryDataU, + TRUE); + + AddrInitIPv4(&Interface->Netmask, inet_addr(RegistryDataA.Buffer)); + + RtlFreeAnsiString(&RegistryDataA); + } + + /* We have to wait until both IP address and subnet mask + * are read to add the interface route, but we must do it + * before we add the default gateway */ + if (!AddrIsUnspecified(&Interface->Unicast) && + !AddrIsUnspecified(&Interface->Netmask)) + IPAddInterfaceRoute(Interface); + + /* Read default gateway info */ + Status = ZwQueryValueKey(ParameterHandle, + &Gateway, + KeyValuePartialInformation, + KeyValueInfo, + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR), + &Unused); + if (NT_SUCCESS(Status)) + { + RegistryDataU.Length = KeyValueInfo->DataLength; + + RtlUnicodeStringToAnsiString(&RegistryDataA, + &RegistryDataU, + TRUE); + + AddrInitIPv4(&Router, inet_addr(RegistryDataA.Buffer)); + + if (!AddrIsUnspecified(&Router)) + RouterCreateRoute(&DefaultMask, &DefaultMask, &Router, Interface, 1); + + RtlFreeAnsiString(&RegistryDataA); + } + } + + ZwClose(ParameterHandle); + } + + return TRUE; +} + +BOOLEAN ReconfigureAdapter(PRECONFIGURE_CONTEXT Context) +{ + PLAN_ADAPTER Adapter = Context->Adapter; + PIP_INTERFACE Interface = Adapter->Context; + //NDIS_STATUS NdisStatus; + IP_ADDRESS DefaultMask; + + /* Initalize the default unspecified address (0.0.0.0) */ + AddrInitIPv4(&DefaultMask, 0); + if (Context->State == LAN_STATE_STARTED && + !Context->Adapter->CompletingReset) + { + /* Read the IP configuration */ + ReadIpConfiguration(Interface); + + /* Compute the broadcast address */ + Interface->Broadcast.Type = IP_ADDRESS_V4; + Interface->Broadcast.Address.IPv4Address = Interface->Unicast.Address.IPv4Address | + ~Interface->Netmask.Address.IPv4Address; + } + else if (!Context->Adapter->CompletingReset) + { + /* Clear IP configuration */ + Interface->Unicast = DefaultMask; + Interface->Netmask = DefaultMask; + Interface->Broadcast = DefaultMask; + + /* Remove all interface routes */ + RouterRemoveRoutesForInterface(Interface); + + /* Destroy all cached neighbors */ + NBDestroyNeighborsForInterface(Interface); + } + + Context->Adapter->CompletingReset = FALSE; + + /* We're done here if the adapter isn't connected */ + if (Context->State != LAN_STATE_STARTED) + { + Adapter->State = Context->State; + return TRUE; + } + + /* NDIS Bug! */ +#if 0 + /* Get maximum link speed */ + NdisStatus = NDISCall(Adapter, + NdisRequestQueryInformation, + OID_GEN_LINK_SPEED, + &Interface->Speed, + sizeof(UINT)); + + if (!NT_SUCCESS(NdisStatus)) + Interface->Speed = IP_DEFAULT_LINK_SPEED; + + Adapter->Speed = Interface->Speed * 100L; + + /* Get maximum frame size */ + NdisStatus = NDISCall(Adapter, + NdisRequestQueryInformation, + OID_GEN_MAXIMUM_FRAME_SIZE, + &Adapter->MTU, + sizeof(UINT)); + if (NdisStatus != NDIS_STATUS_SUCCESS) + return FALSE; + + Interface->MTU = Adapter->MTU; + + /* Get maximum packet size */ + NdisStatus = NDISCall(Adapter, + NdisRequestQueryInformation, + OID_GEN_MAXIMUM_TOTAL_SIZE, + &Adapter->MaxPacketSize, + sizeof(UINT)); + if (NdisStatus != NDIS_STATUS_SUCCESS) + return FALSE; +#endif + + Adapter->State = Context->State; + + return TRUE; +} + +VOID ReconfigureAdapterWorker(PVOID Context) +{ + PRECONFIGURE_CONTEXT ReconfigureContext = Context; + + /* Complete the reconfiguration asynchronously */ + ReconfigureAdapter(ReconfigureContext); + + /* Free the context */ + ExFreePool(ReconfigureContext); +}
VOID NTAPI ProtocolStatus( NDIS_HANDLE BindingContext, @@ -571,31 +807,73 @@ */ { PLAN_ADAPTER Adapter = BindingContext; + PRECONFIGURE_CONTEXT Context;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); + + Context = ExAllocatePool(NonPagedPool, sizeof(RECONFIGURE_CONTEXT)); + if (!Context) + return; + + Context->Adapter = Adapter;
switch(GeneralStatus) { - case NDIS_STATUS_MEDIA_CONNECT: - DbgPrint("NDIS_STATUS_MEDIA_CONNECT\n"); - break; - - case NDIS_STATUS_MEDIA_DISCONNECT: - DbgPrint("NDIS_STATUS_MEDIA_DISCONNECT\n"); - break; - - case NDIS_STATUS_RESET_START: - Adapter->State = LAN_STATE_RESETTING; - break; - - case NDIS_STATUS_RESET_END: - Adapter->State = LAN_STATE_STARTED; - break; - - default: - DbgPrint("Unhandled status: %x", GeneralStatus); - break; - } + case NDIS_STATUS_MEDIA_CONNECT: + DbgPrint("NDIS_STATUS_MEDIA_CONNECT\n"); + + if (Adapter->State == LAN_STATE_STARTED) + { + ExFreePool(Context); + return; + } + + Context->State = LAN_STATE_STARTED; + break; + + case NDIS_STATUS_MEDIA_DISCONNECT: + DbgPrint("NDIS_STATUS_MEDIA_DISCONNECT\n"); + + if (Adapter->State == LAN_STATE_STOPPED) + { + ExFreePool(Context); + return; + } + + Context->State = LAN_STATE_STOPPED; + break; + + case NDIS_STATUS_RESET_START: + Adapter->OldState = Adapter->State; + Adapter->State = LAN_STATE_RESETTING; + /* Nothing else to do here */ + ExFreePool(Context); + return; + + case NDIS_STATUS_RESET_END: + Adapter->CompletingReset = TRUE; + Context->State = Adapter->OldState; + break; + + default: + DbgPrint("Unhandled status: %x", GeneralStatus); + ExFreePool(Context); + return; + } + + /* Queue the work item */ + if (!ChewCreate(ReconfigureAdapterWorker, Context)) + ExFreePool(Context); +} + +VOID NTAPI ProtocolStatusComplete(NDIS_HANDLE NdisBindingContext) +/* + * FUNCTION: Called by NDIS when a status-change has occurred + * ARGUMENTS: + * BindingContext = Pointer to a device context (LAN_ADAPTER) + */ +{ + TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); }
NDIS_STATUS NTAPI @@ -625,17 +903,6 @@ DbgPrint("Unhandled event type: %ld\n", PnPEvent->NetEvent); return NDIS_STATUS_SUCCESS; } -} - -VOID NTAPI ProtocolStatusComplete( - NDIS_HANDLE NdisBindingContext) -/* - * FUNCTION: Called by NDIS when a status-change has occurred - * ARGUMENTS: - * BindingContext = Pointer to a device context (LAN_ADAPTER) - */ -{ - TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); }
VOID NTAPI ProtocolBindAdapter( @@ -1033,21 +1300,8 @@ PIP_INTERFACE IF; NDIS_STATUS NdisStatus; LLIP_BIND_INFO BindInfo; - IP_ADDRESS DefaultMask, Router; - ULONG Lookahead = LOOKAHEAD_SIZE, Unused; + ULONG Lookahead = LOOKAHEAD_SIZE; NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE ParameterHandle; - PKEY_VALUE_PARTIAL_INFORMATION KeyValueInfo; - WCHAR Buffer[150]; - UNICODE_STRING IPAddress = RTL_CONSTANT_STRING(L"IPAddress"); - UNICODE_STRING Netmask = RTL_CONSTANT_STRING(L"SubnetMask"); - UNICODE_STRING Gateway = RTL_CONSTANT_STRING(L"DefaultGateway"); - UNICODE_STRING EnableDhcp = RTL_CONSTANT_STRING(L"EnableDHCP"); - UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\Registry\Machine\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\"); - UNICODE_STRING TcpipRegistryPath; - UNICODE_STRING RegistryDataU; - ANSI_STRING RegistryDataA;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
@@ -1067,7 +1321,6 @@ BindInfo.Context = Adapter; BindInfo.HeaderSize = Adapter->HeaderSize; BindInfo.MinFrameSize = Adapter->MinFrameSize; - BindInfo.MTU = Adapter->MTU; BindInfo.Address = (PUCHAR)&Adapter->HWAddress; BindInfo.AddressLength = Adapter->HWAddressLength; BindInfo.Transmit = LANTransmit; @@ -1100,148 +1353,43 @@ TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n", &IF->Description));
- TcpipRegistryPath.MaximumLength = sizeof(WCHAR) * 150; - TcpipRegistryPath.Length = 0; - TcpipRegistryPath.Buffer = Buffer; - - RtlAppendUnicodeStringToString(&TcpipRegistryPath, - &Prefix); - - RtlAppendUnicodeStringToString(&TcpipRegistryPath, - &IF->Name); - - InitializeObjectAttributes(&ObjectAttributes, - &TcpipRegistryPath, - OBJ_CASE_INSENSITIVE, - 0, - NULL); - - AddrInitIPv4(&DefaultMask, 0); - - Status = ZwOpenKey(&ParameterHandle, KEY_READ, &ObjectAttributes); - - if (!NT_SUCCESS(Status)) - { - IF->Unicast = DefaultMask; - IF->Netmask = DefaultMask; - } - else - { - KeyValueInfo = ExAllocatePool(PagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR)); - if (!KeyValueInfo) - { - ZwClose(ParameterHandle); - IPDestroyInterface(IF); - return FALSE; - } - - Status = ZwQueryValueKey(ParameterHandle, - &EnableDhcp, - KeyValuePartialInformation, - KeyValueInfo, - sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG), - &Unused); - if (NT_SUCCESS(Status) && KeyValueInfo->DataLength == sizeof(ULONG) && (*(PULONG)KeyValueInfo->Data) == 0) - { - RegistryDataU.MaximumLength = 16 + sizeof(WCHAR); - RegistryDataU.Buffer = (PWCHAR)KeyValueInfo->Data; - - Status = ZwQueryValueKey(ParameterHandle, - &IPAddress, - KeyValuePartialInformation, - KeyValueInfo, - sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR), - &Unused); - if (NT_SUCCESS(Status)) - { - RegistryDataU.Length = KeyValueInfo->DataLength; - - RtlUnicodeStringToAnsiString(&RegistryDataA, - &RegistryDataU, - TRUE); - - AddrInitIPv4(&IF->Unicast, inet_addr(RegistryDataA.Buffer)); - - RtlFreeAnsiString(&RegistryDataA); - - } - else - { - IF->Unicast = DefaultMask; - } - - Status = ZwQueryValueKey(ParameterHandle, - &Netmask, - KeyValuePartialInformation, - KeyValueInfo, - sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR), - &Unused); - if (NT_SUCCESS(Status)) - { - RegistryDataU.Length = KeyValueInfo->DataLength; - - RtlUnicodeStringToAnsiString(&RegistryDataA, - &RegistryDataU, - TRUE); - - AddrInitIPv4(&IF->Netmask, inet_addr(RegistryDataA.Buffer)); - - RtlFreeAnsiString(&RegistryDataA); - } - else - { - IF->Netmask = DefaultMask; - } - - Status = ZwQueryValueKey(ParameterHandle, - &Gateway, - KeyValuePartialInformation, - KeyValueInfo, - sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR), - &Unused); - if (NT_SUCCESS(Status)) - { - RegistryDataU.Length = KeyValueInfo->DataLength; - - RtlUnicodeStringToAnsiString(&RegistryDataA, - &RegistryDataU, - TRUE); - - AddrInitIPv4(&Router, inet_addr(RegistryDataA.Buffer)); - - RtlFreeAnsiString(&RegistryDataA); - - if (!AddrIsUnspecified(&Router)) RouterCreateRoute(&DefaultMask, &DefaultMask, &Router, IF, 1); - } - } - else - { - IF->Unicast = DefaultMask; - IF->Netmask = DefaultMask; - } - - ZwClose(ParameterHandle); - } - - IF->Broadcast.Type = IP_ADDRESS_V4; - IF->Broadcast.Address.IPv4Address = - IF->Unicast.Address.IPv4Address | - ~IF->Netmask.Address.IPv4Address; - - TI_DbgPrint(DEBUG_DATALINK,("BCAST(IF) %s\n", A2S(&IF->Broadcast))); - /* Get maximum link speed */ NdisStatus = NDISCall(Adapter, NdisRequestQueryInformation, OID_GEN_LINK_SPEED, &IF->Speed, sizeof(UINT)); - - if( !NT_SUCCESS(NdisStatus) ) - IF->Speed = IP_DEFAULT_LINK_SPEED; - + + if (!NT_SUCCESS(NdisStatus)) + IF->Speed = IP_DEFAULT_LINK_SPEED; + + Adapter->Speed = IF->Speed * 100L; + + /* Get maximum frame size */ + NdisStatus = NDISCall(Adapter, + NdisRequestQueryInformation, + OID_GEN_MAXIMUM_FRAME_SIZE, + &Adapter->MTU, + sizeof(UINT)); + if (NdisStatus != NDIS_STATUS_SUCCESS) + return FALSE; + + IF->MTU = Adapter->MTU; + + /* Get maximum packet size */ + NdisStatus = NDISCall(Adapter, + NdisRequestQueryInformation, + OID_GEN_MAXIMUM_TOTAL_SIZE, + &Adapter->MaxPacketSize, + sizeof(UINT)); + if (NdisStatus != NDIS_STATUS_SUCCESS) + return FALSE; + /* Register interface with IP layer */ IPRegisterInterface(IF); + + /* Set adapter state */ + Adapter->Context = IF;
/* Set packet filter so we can send and receive packets */ NdisStatus = NDISCall(Adapter, @@ -1256,9 +1404,10 @@ IPDestroyInterface(IF); return FALSE; } - - Adapter->Context = IF; - Adapter->State = LAN_STATE_STARTED; + + /* Indicate media connect (our drivers are broken and don't do this) */ + ProtocolStatus(Adapter, NDIS_STATUS_MEDIA_CONNECT, NULL, 0); + return TRUE; }
@@ -1301,7 +1450,6 @@ UINT MediaIndex; NDIS_MEDIUM MediaArray[MAX_MEDIA]; UINT AddressOID; - UINT Speed;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
@@ -1372,30 +1520,6 @@ return NDIS_STATUS_NOT_SUPPORTED; }
- /* Get maximum frame size */ - NdisStatus = NDISCall(IF, - NdisRequestQueryInformation, - OID_GEN_MAXIMUM_FRAME_SIZE, - &IF->MTU, - sizeof(UINT)); - if (NdisStatus != NDIS_STATUS_SUCCESS) { - TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (NDISCall)\n", AdapterName)); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); - return NdisStatus; - } - - /* Get maximum packet size */ - NdisStatus = NDISCall(IF, - NdisRequestQueryInformation, - OID_GEN_MAXIMUM_TOTAL_SIZE, - &IF->MaxPacketSize, - sizeof(UINT)); - if (NdisStatus != NDIS_STATUS_SUCCESS) { - TI_DbgPrint(MIN_TRACE, ("Query for maximum packet size failed.\n")); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); - return NdisStatus; - } - /* Get maximum number of packets we can pass to NdisSend(Packets) at one time */ NdisStatus = NDISCall(IF, NdisRequestQueryInformation, @@ -1418,21 +1542,6 @@ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); return NdisStatus; } - - /* Get maximum link speed */ - NdisStatus = NDISCall(IF, - NdisRequestQueryInformation, - OID_GEN_LINK_SPEED, - &Speed, - sizeof(UINT)); - if (NdisStatus != NDIS_STATUS_SUCCESS) { - TI_DbgPrint(MIN_TRACE, ("Query for maximum link speed failed.\n")); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); - return NdisStatus; - } - - /* Convert returned link speed to bps (it is in 100bps increments) */ - IF->Speed = Speed * 100L;
/* Bind adapter to IP layer */ if( !BindAdapter(IF, RegistryPath) ) {
Modified: trunk/reactos/drivers/network/tcpip/include/ip.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/inclu... ============================================================================== --- trunk/reactos/drivers/network/tcpip/include/ip.h [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/include/ip.h [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -127,7 +127,6 @@ PVOID Context; /* Pointer to link layer context information */ UINT HeaderSize; /* Size of link level header */ UINT MinFrameSize; /* Minimum frame size in bytes */ - UINT MTU; /* Maximum transmission unit */ PUCHAR Address; /* Pointer to interface address */ UINT AddressLength; /* Length of address in bytes */ LL_TRANSMIT_ROUTINE Transmit; /* Transmit function for this interface */
Modified: trunk/reactos/drivers/network/tcpip/include/lan.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/inclu... ============================================================================== --- trunk/reactos/drivers/network/tcpip/include/lan.h [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/include/lan.h [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -39,7 +39,8 @@ typedef struct LAN_ADAPTER { LIST_ENTRY ListEntry; /* Entry on list */ KSPIN_LOCK Lock; /* Lock for this structure */ - UCHAR State; /* State of the adapter */ + UCHAR State, OldState; /* State of the adapter */ + BOOLEAN CompletingReset; /* Reset is finishing */ KEVENT Event; /* Opening event */ PVOID Context; /* Upper layer context information */ NDIS_HANDLE NdisHandle; /* NDIS binding handle */
Modified: trunk/reactos/drivers/network/tcpip/include/neighbor.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/inclu... ============================================================================== --- trunk/reactos/drivers/network/tcpip/include/neighbor.h [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/include/neighbor.h [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -43,16 +43,16 @@ #define NUD_STALE 0x04
/* Timeout for incomplete NCE ARP requests */ -#define ARP_INCOMPLETE_TIMEOUT 5 +#define ARP_INCOMPLETE_TIMEOUT 3
/* Number of seconds between ARP transmissions */ #define ARP_RATE 900
/* Number of seconds before the NCE times out */ -#define ARP_COMPLETE_TIMEOUT (ARP_RATE + 15) +#define ARP_COMPLETE_TIMEOUT (ARP_RATE + 9)
/* Number of seconds before retransmission */ -#define ARP_TIMEOUT_RETRANSMISSION 5 +#define ARP_TIMEOUT_RETRANSMISSION 3
extern NEIGHBOR_CACHE_TABLE NeighborCache[NB_HASHMASK + 1];
@@ -87,7 +87,8 @@
PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor( PIP_INTERFACE Interface, - PIP_ADDRESS Address); + PIP_ADDRESS Address, + BOOLEAN NoTimeout);
BOOLEAN NBQueuePacket( PNEIGHBOR_CACHE_ENTRY NCE, @@ -105,4 +106,6 @@ VOID NBResetNeighborTimeout( PIP_ADDRESS Address);
+VOID NBDestroyNeighborsForInterface(PIP_INTERFACE Interface); + /* EOF */
Modified: trunk/reactos/drivers/network/tcpip/include/router.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/inclu... ============================================================================== --- trunk/reactos/drivers/network/tcpip/include/router.h [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/include/router.h [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -43,6 +43,8 @@ NTSTATUS RouterShutdown( VOID);
+VOID RouterRemoveRoutesForInterface(PIP_INTERFACE Interface); + UINT CountFIBs(PIP_INTERFACE IF);
UINT CopyFIBs( PIP_INTERFACE IF, PFIB_ENTRY Target );
Modified: trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip... ============================================================================== --- trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -1552,8 +1552,10 @@
IF->Unicast.Type = IP_ADDRESS_V4; IF->Unicast.Address.IPv4Address = IpAddrChange->Address; + IF->Netmask.Type = IP_ADDRESS_V4; IF->Netmask.Address.IPv4Address = IpAddrChange->Netmask; + IF->Broadcast.Type = IP_ADDRESS_V4; IF->Broadcast.Address.IPv4Address = IF->Unicast.Address.IPv4Address | @@ -1587,10 +1589,13 @@ IPRemoveInterfaceRoute( IF ); IF->Unicast.Type = IP_ADDRESS_V4; IF->Unicast.Address.IPv4Address = 0; + IF->Netmask.Type = IP_ADDRESS_V4; IF->Netmask.Address.IPv4Address = 0; + IF->Broadcast.Type = IP_ADDRESS_V4; IF->Broadcast.Address.IPv4Address = 0; + Status = STATUS_SUCCESS; } } EndFor(IF);
Modified: trunk/reactos/lib/drivers/ip/network/ip.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/ip.c... ============================================================================== --- trunk/reactos/lib/drivers/ip/network/ip.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/network/ip.c [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -206,7 +206,6 @@ IF->Context = BindInfo->Context; IF->HeaderSize = BindInfo->HeaderSize; IF->MinFrameSize = BindInfo->MinFrameSize; - IF->MTU = BindInfo->MTU; IF->Address = BindInfo->Address; IF->AddressLength = BindInfo->AddressLength; IF->Transmit = BindInfo->Transmit; @@ -314,11 +313,6 @@
IF->Index = ChosenIndex;
- if (!AddrIsUnspecified(&IF->Unicast)) - { - IPAddInterfaceRoute(IF); - } - /* Add interface to the global interface list */ TcpipInterlockedInsertTailList(&InterfaceListHead, &IF->ListEntry,
Modified: trunk/reactos/lib/drivers/ip/network/loopback.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/loop... ============================================================================== --- trunk/reactos/lib/drivers/ip/network/loopback.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/network/loopback.c [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -106,13 +106,14 @@ BindInfo.Context = NULL; BindInfo.HeaderSize = 0; BindInfo.MinFrameSize = 0; - BindInfo.MTU = 16384; BindInfo.Address = NULL; BindInfo.AddressLength = 0; BindInfo.Transmit = LoopTransmit;
Loopback = IPCreateInterface(&BindInfo); if (!Loopback) return NDIS_STATUS_RESOURCES; + + Loopback->MTU = 16384;
Loopback->Name.Buffer = L"Loopback"; Loopback->Name.MaximumLength = Loopback->Name.Length = @@ -123,6 +124,8 @@ AddrInitIPv4(&Loopback->Broadcast, LOOPBACK_BCASTADDR_IPv4);
IPRegisterInterface(Loopback); + + IPAddInterfaceRoute(Loopback);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
Modified: trunk/reactos/lib/drivers/ip/network/neighbor.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/neig... ============================================================================== --- trunk/reactos/lib/drivers/ip/network/neighbor.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/network/neighbor.c [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -106,17 +106,27 @@
for (PrevNCE = &NeighborCache[i].Cache; (NCE = *PrevNCE) != NULL;) { + if (NCE->State & NUD_INCOMPLETE) + { + /* Solicit for an address */ + NBSendSolicit(NCE); + if (NCE->EventTimer == 0) + { + NCE->EventCount++; + if (NCE->EventCount == ARP_INCOMPLETE_TIMEOUT) + { + NBFlushPacketQueue(NCE, NDIS_STATUS_NETWORK_UNREACHABLE); + NCE->EventCount = 0; + } + } + } + /* Check if event timer is running */ if (NCE->EventTimer > 0) { ASSERT(!(NCE->State & NUD_PERMANENT)); NCE->EventCount++; - if (NCE->State & NUD_INCOMPLETE) - { - /* We desperately need an address in this state or - * we timeout in 5 seconds */ - NBSendSolicit(NCE); - } - else if ((NCE->EventCount > ARP_RATE && + + if ((NCE->EventCount > ARP_RATE && NCE->EventCount % ARP_TIMEOUT_RETRANSMISSION == 0) || (NCE->EventCount == ARP_RATE)) { @@ -129,7 +139,7 @@ if (NCE->EventTimer - NCE->EventCount == 0) { /* Unlink and destroy the NCE */ *PrevNCE = NCE->Next; - + /* Choose the proper failure status */ if (NCE->State & NUD_INCOMPLETE) { @@ -141,8 +151,9 @@ /* This guy was stale for way too long */ Status = NDIS_STATUS_REQUEST_ABORTED; } - + NBFlushPacketQueue(NCE, Status); + ExFreePoolWithTag(NCE, NCE_TAG);
continue; @@ -221,6 +232,42 @@ ARPTransmit(&NCE->Address, (NCE->State & NUD_INCOMPLETE) ? NULL : NCE->LinkAddress, NCE->Interface); +} + +VOID NBDestroyNeighborsForInterface(PIP_INTERFACE Interface) +{ + KIRQL OldIrql; + PNEIGHBOR_CACHE_ENTRY *PrevNCE; + PNEIGHBOR_CACHE_ENTRY NCE; + ULONG i; + + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + for (i = 0; i <= NB_HASHMASK; i++) + { + TcpipAcquireSpinLockAtDpcLevel(&NeighborCache[i].Lock); + + for (PrevNCE = &NeighborCache[i].Cache; + (NCE = *PrevNCE) != NULL;) + { + if (NCE->Interface == Interface) + { + /* Unlink and destroy the NCE */ + *PrevNCE = NCE->Next; + + NBFlushPacketQueue(NCE, NDIS_STATUS_REQUEST_ABORTED); + ExFreePoolWithTag(NCE, NCE_TAG); + + continue; + } + else + { + PrevNCE = &NCE->Next; + } + } + + TcpipReleaseSpinLockFromDpcLevel(&NeighborCache[i].Lock); + } + KeLowerIrql(OldIrql); }
PNEIGHBOR_CACHE_ENTRY NBAddNeighbor( @@ -331,7 +378,7 @@
if( !(NCE->State & NUD_INCOMPLETE) ) { - NCE->EventTimer = ARP_COMPLETE_TIMEOUT; + if (NCE->EventTimer) NCE->EventTimer = ARP_COMPLETE_TIMEOUT; NBSendPackets( NCE ); } } @@ -410,7 +457,8 @@
PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor( PIP_INTERFACE Interface, - PIP_ADDRESS Address) + PIP_ADDRESS Address, + BOOLEAN NoTimeout) /* * FUNCTION: Tries to find a neighbor and if unsuccesful, creates a new NCE * ARGUMENTS: @@ -438,7 +486,7 @@ Interface->AddressLength, NUD_PERMANENT, 0); } else { NCE = NBAddNeighbor(Interface, Address, NULL, - Interface->AddressLength, NUD_INCOMPLETE, ARP_INCOMPLETE_TIMEOUT); + Interface->AddressLength, NUD_INCOMPLETE, NoTimeout ? 0 : ARP_INCOMPLETE_TIMEOUT); if (!NCE) return NULL; NBSendSolicit(NCE); }
Modified: trunk/reactos/lib/drivers/ip/network/router.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/rout... ============================================================================== --- trunk/reactos/lib/drivers/ip/network/router.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/network/router.c [iso-8859-1] Sat Jan 14 19:42:58 2012 @@ -327,7 +327,7 @@ Interface = FindOnLinkInterface(Destination); if (Interface) { /* The destination address is on-link. Check our neighbor cache */ - NCE = NBFindOrCreateNeighbor(Interface, Destination); + NCE = NBFindOrCreateNeighbor(Interface, Destination, FALSE); } else { /* Destination is not on any subnets we're on. Find a router to use */ NCE = RouterGetRoute(Destination); @@ -337,6 +337,29 @@ TI_DbgPrint(DEBUG_ROUTER,("Interface->MTU: %d\n", NCE->Interface->MTU));
return NCE; +} + +VOID RouterRemoveRoutesForInterface(PIP_INTERFACE Interface) +{ + KIRQL OldIrql; + PLIST_ENTRY CurrentEntry; + PLIST_ENTRY NextEntry; + PFIB_ENTRY Current; + + TcpipAcquireSpinLock(&FIBLock, &OldIrql); + + CurrentEntry = FIBListHead.Flink; + while (CurrentEntry != &FIBListHead) { + NextEntry = CurrentEntry->Flink; + Current = CONTAINING_RECORD(CurrentEntry, FIB_ENTRY, ListEntry); + + if (Interface == Current->Router->Interface) + DestroyFIBE(Current); + + CurrentEntry = NextEntry; + } + + TcpipReleaseSpinLock(&FIBLock, OldIrql); }
NTSTATUS RouterRemoveRoute(PIP_ADDRESS Target, PIP_ADDRESS Router) @@ -431,8 +454,10 @@
NCE = Current->Router;
- if( AddrIsEqual(NetworkAddress, &Current->NetworkAddress) && - AddrIsEqual(Netmask, &Current->Netmask) ) { + if(AddrIsEqual(NetworkAddress, &Current->NetworkAddress) && + AddrIsEqual(Netmask, &Current->Netmask) && + NCE->Interface == Interface) + { TI_DbgPrint(DEBUG_ROUTER,("Attempting to add duplicate route to %s\n", A2S(NetworkAddress))); TcpipReleaseSpinLock(&FIBLock, OldIrql); return NULL; @@ -444,7 +469,7 @@ TcpipReleaseSpinLock(&FIBLock, OldIrql);
/* The NCE references RouterAddress. The NCE is referenced for us */ - NCE = NBFindOrCreateNeighbor(Interface, RouterAddress); + NCE = NBFindOrCreateNeighbor(Interface, RouterAddress, TRUE);
if (!NCE) { /* Not enough free resources */