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/ad…
==============================================================================
--- 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/ap…
==============================================================================
--- 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/dh…
==============================================================================
--- 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/iphlpap…
==============================================================================
--- 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/tcpipcon…
==============================================================================
--- 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/data…
==============================================================================
--- 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/incl…
==============================================================================
--- 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/incl…
==============================================================================
--- 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/incl…
==============================================================================
--- 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/incl…
==============================================================================
--- 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/tcpi…
==============================================================================
--- 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.…
==============================================================================
--- 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/loo…
==============================================================================
--- 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/nei…
==============================================================================
--- 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/rou…
==============================================================================
--- 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 */