mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 20:50:29 +00:00
- 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 svn path=/trunk/; revision=54966
This commit is contained in:
parent
c673f85060
commit
f679ffe173
15 changed files with 570 additions and 270 deletions
|
@ -200,6 +200,85 @@ InterfaceConnected(const MIB_IFROW* IfEntry)
|
||||||
return 0;
|
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.
|
* XXX Figure out the way to bind a specific adapter to a socket.
|
||||||
*/
|
*/
|
||||||
|
@ -241,12 +320,35 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
|
||||||
|
|
||||||
if ((Adapter = AdapterFindByHardwareAddress(Table->table[i].bPhysAddr, Table->table[i].dwPhysAddrLen)))
|
if ((Adapter = AdapterFindByHardwareAddress(Table->table[i].bPhysAddr, Table->table[i].dwPhysAddrLen)))
|
||||||
{
|
{
|
||||||
|
proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
|
||||||
|
|
||||||
/* This is an existing adapter */
|
/* This is an existing adapter */
|
||||||
if (InterfaceConnected(&Table->table[i])) {
|
if (InterfaceConnected(&Table->table[i])) {
|
||||||
/* We're still active so we stay in the list */
|
/* We're still active so we stay in the list */
|
||||||
ifi = &Adapter->DhclientInfo;
|
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 {
|
} else {
|
||||||
proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
|
|
||||||
if (proto)
|
if (proto)
|
||||||
remove_protocol(proto);
|
remove_protocol(proto);
|
||||||
|
|
||||||
|
|
|
@ -101,9 +101,15 @@ DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
|
||||||
|
|
||||||
if( Adapter ) {
|
if( Adapter ) {
|
||||||
if (Adapter->NteContext)
|
if (Adapter->NteContext)
|
||||||
|
{
|
||||||
DeleteIPAddress( Adapter->NteContext );
|
DeleteIPAddress( Adapter->NteContext );
|
||||||
|
Adapter->NteContext = 0;
|
||||||
|
}
|
||||||
if (Adapter->RouterMib.dwForwardNextHop)
|
if (Adapter->RouterMib.dwForwardNextHop)
|
||||||
|
{
|
||||||
DeleteIpForwardEntry( &Adapter->RouterMib );
|
DeleteIpForwardEntry( &Adapter->RouterMib );
|
||||||
|
Adapter->RouterMib.dwForwardNextHop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
|
proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
|
||||||
if (proto)
|
if (proto)
|
||||||
|
@ -171,9 +177,15 @@ DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
|
||||||
|
|
||||||
if( Adapter ) {
|
if( Adapter ) {
|
||||||
if (Adapter->NteContext)
|
if (Adapter->NteContext)
|
||||||
|
{
|
||||||
DeleteIPAddress( Adapter->NteContext );
|
DeleteIPAddress( Adapter->NteContext );
|
||||||
|
Adapter->NteContext = 0;
|
||||||
|
}
|
||||||
if (Adapter->RouterMib.dwForwardNextHop)
|
if (Adapter->RouterMib.dwForwardNextHop)
|
||||||
|
{
|
||||||
DeleteIpForwardEntry( &Adapter->RouterMib );
|
DeleteIpForwardEntry( &Adapter->RouterMib );
|
||||||
|
Adapter->RouterMib.dwForwardNextHop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Adapter->DhclientState.state = S_STATIC;
|
Adapter->DhclientState.state = S_STATIC;
|
||||||
proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
|
proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
|
||||||
|
|
|
@ -548,7 +548,10 @@ void setup_adapter( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) {
|
||||||
|
|
||||||
|
|
||||||
if( Adapter->NteContext )
|
if( Adapter->NteContext )
|
||||||
|
{
|
||||||
DeleteIPAddress( Adapter->NteContext );
|
DeleteIPAddress( Adapter->NteContext );
|
||||||
|
Adapter->NteContext = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set up our default router if we got one from the DHCP server */
|
/* Set up our default router if we got one from the DHCP server */
|
||||||
if( new_lease->options[DHO_SUBNET_MASK].len ) {
|
if( new_lease->options[DHO_SUBNET_MASK].len ) {
|
||||||
|
@ -1007,7 +1010,7 @@ send_discover(void *ipp)
|
||||||
we haven't found anything for this interface yet. */
|
we haven't found anything for this interface yet. */
|
||||||
if (interval > ip->client->config->timeout) {
|
if (interval > ip->client->config->timeout) {
|
||||||
state_panic(ip);
|
state_panic(ip);
|
||||||
return;
|
ip->client->first_sending = cur_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're selecting media, try the whole list before doing
|
/* If we're selecting media, try the whole list before doing
|
||||||
|
@ -1100,17 +1103,9 @@ state_panic(void *ipp)
|
||||||
{
|
{
|
||||||
struct interface_info *ip = ipp;
|
struct interface_info *ip = ipp;
|
||||||
PDHCP_ADAPTER Adapter = AdapterFindInfo(ip);
|
PDHCP_ADAPTER Adapter = AdapterFindInfo(ip);
|
||||||
time_t cur_time;
|
|
||||||
|
|
||||||
time(&cur_time);
|
|
||||||
|
|
||||||
note("No DHCPOFFERS received.");
|
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)
|
if (!Adapter->NteContext)
|
||||||
{
|
{
|
||||||
/* Generate an automatic private address */
|
/* Generate an automatic private address */
|
||||||
|
@ -1181,7 +1176,10 @@ send_request(void *ipp)
|
||||||
discover a new address. */
|
discover a new address. */
|
||||||
|
|
||||||
if( Adapter )
|
if( Adapter )
|
||||||
|
{
|
||||||
DeleteIPAddress( Adapter->NteContext );
|
DeleteIPAddress( Adapter->NteContext );
|
||||||
|
Adapter->NteContext = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ip->client->state = S_INIT;
|
ip->client->state = S_INIT;
|
||||||
state_init(ip);
|
state_init(ip);
|
||||||
|
|
|
@ -639,6 +639,7 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
|
||||||
ptr->IpAddressList.IpAddress.String);
|
ptr->IpAddressList.IpAddress.String);
|
||||||
toIPAddressString(getInterfaceMaskByIndex(table->indexes[ndx]),
|
toIPAddressString(getInterfaceMaskByIndex(table->indexes[ndx]),
|
||||||
ptr->IpAddressList.IpMask.String);
|
ptr->IpAddressList.IpMask.String);
|
||||||
|
ptr->IpAddressList.Context = ptr->Index;
|
||||||
toIPAddressString(getInterfaceGatewayByIndex(table->indexes[ndx]),
|
toIPAddressString(getInterfaceGatewayByIndex(table->indexes[ndx]),
|
||||||
ptr->GatewayList.IpAddress.String);
|
ptr->GatewayList.IpAddress.String);
|
||||||
getDhcpInfoForAdapter(table->indexes[ndx], &dhcpEnabled,
|
getDhcpInfoForAdapter(table->indexes[ndx], &dhcpEnabled,
|
||||||
|
@ -1189,7 +1190,7 @@ DWORD WINAPI GetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable, PULONG pdwSi
|
||||||
pIpForwardTable->dwNumEntries = table->numRoutes;
|
pIpForwardTable->dwNumEntries = table->numRoutes;
|
||||||
for (ndx = 0; ndx < numRoutes; ndx++) {
|
for (ndx = 0; ndx < numRoutes; ndx++) {
|
||||||
pIpForwardTable->table[ndx].dwForwardIfIndex =
|
pIpForwardTable->table[ndx].dwForwardIfIndex =
|
||||||
table->routes[ndx].ifIndex + 1;
|
table->routes[ndx].ifIndex;
|
||||||
pIpForwardTable->table[ndx].dwForwardDest =
|
pIpForwardTable->table[ndx].dwForwardDest =
|
||||||
table->routes[ndx].dest;
|
table->routes[ndx].dest;
|
||||||
pIpForwardTable->table[ndx].dwForwardMask =
|
pIpForwardTable->table[ndx].dwForwardMask =
|
||||||
|
|
|
@ -3230,8 +3230,6 @@ INetCfgComponentControl_fnApplyRegistryChanges(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pOldConfig->Gw)
|
|
||||||
{
|
|
||||||
dwSize = 0;
|
dwSize = 0;
|
||||||
if (GetIpForwardTable(NULL, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
|
if (GetIpForwardTable(NULL, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
|
||||||
{
|
{
|
||||||
|
@ -3243,7 +3241,8 @@ INetCfgComponentControl_fnApplyRegistryChanges(
|
||||||
{
|
{
|
||||||
for (Index = 0; Index < pIpForwardTable->dwNumEntries; Index++)
|
for (Index = 0; Index < pIpForwardTable->dwNumEntries; Index++)
|
||||||
{
|
{
|
||||||
if (pIpForwardTable->table[Index].dwForwardIfIndex == pOldConfig->Index)
|
if (pIpForwardTable->table[Index].dwForwardIfIndex == pOldConfig->Index &&
|
||||||
|
pIpForwardTable->table[Index].dwForwardDest == 0)
|
||||||
{
|
{
|
||||||
DeleteIpForwardEntry(&pIpForwardTable->table[Index]);
|
DeleteIpForwardEntry(&pIpForwardTable->table[Index]);
|
||||||
}
|
}
|
||||||
|
@ -3252,7 +3251,6 @@ INetCfgComponentControl_fnApplyRegistryChanges(
|
||||||
CoTaskMemFree(pIpForwardTable);
|
CoTaskMemFree(pIpForwardTable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (pCurrentConfig->Gw)
|
if (pCurrentConfig->Gw)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,6 +24,11 @@ typedef struct _LAN_WQ_ITEM {
|
||||||
BOOLEAN LegacyReceive;
|
BOOLEAN LegacyReceive;
|
||||||
} LAN_WQ_ITEM, *PLAN_WQ_ITEM;
|
} 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;
|
NDIS_HANDLE NdisProtocolHandle = (NDIS_HANDLE)NULL;
|
||||||
BOOLEAN ProtocolRegistered = FALSE;
|
BOOLEAN ProtocolRegistered = FALSE;
|
||||||
LIST_ENTRY AdapterListHead;
|
LIST_ENTRY AdapterListHead;
|
||||||
|
@ -555,6 +560,237 @@ VOID NTAPI ProtocolReceiveComplete(
|
||||||
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
|
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(
|
VOID NTAPI ProtocolStatus(
|
||||||
NDIS_HANDLE BindingContext,
|
NDIS_HANDLE BindingContext,
|
||||||
|
@ -571,31 +807,73 @@ VOID NTAPI ProtocolStatus(
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PLAN_ADAPTER Adapter = BindingContext;
|
PLAN_ADAPTER Adapter = BindingContext;
|
||||||
|
PRECONFIGURE_CONTEXT Context;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
|
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
|
||||||
|
|
||||||
|
Context = ExAllocatePool(NonPagedPool, sizeof(RECONFIGURE_CONTEXT));
|
||||||
|
if (!Context)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Context->Adapter = Adapter;
|
||||||
|
|
||||||
switch(GeneralStatus)
|
switch(GeneralStatus)
|
||||||
{
|
{
|
||||||
case NDIS_STATUS_MEDIA_CONNECT:
|
case NDIS_STATUS_MEDIA_CONNECT:
|
||||||
DbgPrint("NDIS_STATUS_MEDIA_CONNECT\n");
|
DbgPrint("NDIS_STATUS_MEDIA_CONNECT\n");
|
||||||
|
|
||||||
|
if (Adapter->State == LAN_STATE_STARTED)
|
||||||
|
{
|
||||||
|
ExFreePool(Context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context->State = LAN_STATE_STARTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NDIS_STATUS_MEDIA_DISCONNECT:
|
case NDIS_STATUS_MEDIA_DISCONNECT:
|
||||||
DbgPrint("NDIS_STATUS_MEDIA_DISCONNECT\n");
|
DbgPrint("NDIS_STATUS_MEDIA_DISCONNECT\n");
|
||||||
|
|
||||||
|
if (Adapter->State == LAN_STATE_STOPPED)
|
||||||
|
{
|
||||||
|
ExFreePool(Context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context->State = LAN_STATE_STOPPED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NDIS_STATUS_RESET_START:
|
case NDIS_STATUS_RESET_START:
|
||||||
|
Adapter->OldState = Adapter->State;
|
||||||
Adapter->State = LAN_STATE_RESETTING;
|
Adapter->State = LAN_STATE_RESETTING;
|
||||||
break;
|
/* Nothing else to do here */
|
||||||
|
ExFreePool(Context);
|
||||||
|
return;
|
||||||
|
|
||||||
case NDIS_STATUS_RESET_END:
|
case NDIS_STATUS_RESET_END:
|
||||||
Adapter->State = LAN_STATE_STARTED;
|
Adapter->CompletingReset = TRUE;
|
||||||
|
Context->State = Adapter->OldState;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DbgPrint("Unhandled status: %x", GeneralStatus);
|
DbgPrint("Unhandled status: %x", GeneralStatus);
|
||||||
break;
|
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
|
NDIS_STATUS NTAPI
|
||||||
|
@ -627,17 +905,6 @@ ProtocolPnPEvent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
VOID NTAPI ProtocolBindAdapter(
|
||||||
OUT PNDIS_STATUS Status,
|
OUT PNDIS_STATUS Status,
|
||||||
IN NDIS_HANDLE BindContext,
|
IN NDIS_HANDLE BindContext,
|
||||||
|
@ -1033,21 +1300,8 @@ BOOLEAN BindAdapter(
|
||||||
PIP_INTERFACE IF;
|
PIP_INTERFACE IF;
|
||||||
NDIS_STATUS NdisStatus;
|
NDIS_STATUS NdisStatus;
|
||||||
LLIP_BIND_INFO BindInfo;
|
LLIP_BIND_INFO BindInfo;
|
||||||
IP_ADDRESS DefaultMask, Router;
|
ULONG Lookahead = LOOKAHEAD_SIZE;
|
||||||
ULONG Lookahead = LOOKAHEAD_SIZE, Unused;
|
|
||||||
NTSTATUS Status;
|
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"));
|
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
|
||||||
|
|
||||||
|
@ -1067,7 +1321,6 @@ BOOLEAN BindAdapter(
|
||||||
BindInfo.Context = Adapter;
|
BindInfo.Context = Adapter;
|
||||||
BindInfo.HeaderSize = Adapter->HeaderSize;
|
BindInfo.HeaderSize = Adapter->HeaderSize;
|
||||||
BindInfo.MinFrameSize = Adapter->MinFrameSize;
|
BindInfo.MinFrameSize = Adapter->MinFrameSize;
|
||||||
BindInfo.MTU = Adapter->MTU;
|
|
||||||
BindInfo.Address = (PUCHAR)&Adapter->HWAddress;
|
BindInfo.Address = (PUCHAR)&Adapter->HWAddress;
|
||||||
BindInfo.AddressLength = Adapter->HWAddressLength;
|
BindInfo.AddressLength = Adapter->HWAddressLength;
|
||||||
BindInfo.Transmit = LANTransmit;
|
BindInfo.Transmit = LANTransmit;
|
||||||
|
@ -1100,136 +1353,6 @@ BOOLEAN BindAdapter(
|
||||||
TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n",
|
TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n",
|
||||||
&IF->Description));
|
&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 */
|
/* Get maximum link speed */
|
||||||
NdisStatus = NDISCall(Adapter,
|
NdisStatus = NDISCall(Adapter,
|
||||||
NdisRequestQueryInformation,
|
NdisRequestQueryInformation,
|
||||||
|
@ -1237,12 +1360,37 @@ BOOLEAN BindAdapter(
|
||||||
&IF->Speed,
|
&IF->Speed,
|
||||||
sizeof(UINT));
|
sizeof(UINT));
|
||||||
|
|
||||||
if( !NT_SUCCESS(NdisStatus) )
|
if (!NT_SUCCESS(NdisStatus))
|
||||||
IF->Speed = IP_DEFAULT_LINK_SPEED;
|
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 */
|
/* Register interface with IP layer */
|
||||||
IPRegisterInterface(IF);
|
IPRegisterInterface(IF);
|
||||||
|
|
||||||
|
/* Set adapter state */
|
||||||
|
Adapter->Context = IF;
|
||||||
|
|
||||||
/* Set packet filter so we can send and receive packets */
|
/* Set packet filter so we can send and receive packets */
|
||||||
NdisStatus = NDISCall(Adapter,
|
NdisStatus = NDISCall(Adapter,
|
||||||
NdisRequestSetInformation,
|
NdisRequestSetInformation,
|
||||||
|
@ -1257,8 +1405,9 @@ BOOLEAN BindAdapter(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Adapter->Context = IF;
|
/* Indicate media connect (our drivers are broken and don't do this) */
|
||||||
Adapter->State = LAN_STATE_STARTED;
|
ProtocolStatus(Adapter, NDIS_STATUS_MEDIA_CONNECT, NULL, 0);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1301,7 +1450,6 @@ NDIS_STATUS LANRegisterAdapter(
|
||||||
UINT MediaIndex;
|
UINT MediaIndex;
|
||||||
NDIS_MEDIUM MediaArray[MAX_MEDIA];
|
NDIS_MEDIUM MediaArray[MAX_MEDIA];
|
||||||
UINT AddressOID;
|
UINT AddressOID;
|
||||||
UINT Speed;
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
|
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
|
||||||
|
|
||||||
|
@ -1372,30 +1520,6 @@ NDIS_STATUS LANRegisterAdapter(
|
||||||
return NDIS_STATUS_NOT_SUPPORTED;
|
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 */
|
/* Get maximum number of packets we can pass to NdisSend(Packets) at one time */
|
||||||
NdisStatus = NDISCall(IF,
|
NdisStatus = NDISCall(IF,
|
||||||
NdisRequestQueryInformation,
|
NdisRequestQueryInformation,
|
||||||
|
@ -1419,21 +1543,6 @@ NDIS_STATUS LANRegisterAdapter(
|
||||||
return NdisStatus;
|
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 */
|
/* Bind adapter to IP layer */
|
||||||
if( !BindAdapter(IF, RegistryPath) ) {
|
if( !BindAdapter(IF, RegistryPath) ) {
|
||||||
TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (BindAdapter)\n", AdapterName));
|
TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (BindAdapter)\n", AdapterName));
|
||||||
|
|
|
@ -127,7 +127,6 @@ typedef struct _LLIP_BIND_INFO {
|
||||||
PVOID Context; /* Pointer to link layer context information */
|
PVOID Context; /* Pointer to link layer context information */
|
||||||
UINT HeaderSize; /* Size of link level header */
|
UINT HeaderSize; /* Size of link level header */
|
||||||
UINT MinFrameSize; /* Minimum frame size in bytes */
|
UINT MinFrameSize; /* Minimum frame size in bytes */
|
||||||
UINT MTU; /* Maximum transmission unit */
|
|
||||||
PUCHAR Address; /* Pointer to interface address */
|
PUCHAR Address; /* Pointer to interface address */
|
||||||
UINT AddressLength; /* Length of address in bytes */
|
UINT AddressLength; /* Length of address in bytes */
|
||||||
LL_TRANSMIT_ROUTINE Transmit; /* Transmit function for this interface */
|
LL_TRANSMIT_ROUTINE Transmit; /* Transmit function for this interface */
|
||||||
|
|
|
@ -39,7 +39,8 @@ typedef struct ETH_HEADER {
|
||||||
typedef struct LAN_ADAPTER {
|
typedef struct LAN_ADAPTER {
|
||||||
LIST_ENTRY ListEntry; /* Entry on list */
|
LIST_ENTRY ListEntry; /* Entry on list */
|
||||||
KSPIN_LOCK Lock; /* Lock for this structure */
|
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 */
|
KEVENT Event; /* Opening event */
|
||||||
PVOID Context; /* Upper layer context information */
|
PVOID Context; /* Upper layer context information */
|
||||||
NDIS_HANDLE NdisHandle; /* NDIS binding handle */
|
NDIS_HANDLE NdisHandle; /* NDIS binding handle */
|
||||||
|
|
|
@ -43,16 +43,16 @@ typedef struct NEIGHBOR_CACHE_ENTRY {
|
||||||
#define NUD_STALE 0x04
|
#define NUD_STALE 0x04
|
||||||
|
|
||||||
/* Timeout for incomplete NCE ARP requests */
|
/* Timeout for incomplete NCE ARP requests */
|
||||||
#define ARP_INCOMPLETE_TIMEOUT 5
|
#define ARP_INCOMPLETE_TIMEOUT 3
|
||||||
|
|
||||||
/* Number of seconds between ARP transmissions */
|
/* Number of seconds between ARP transmissions */
|
||||||
#define ARP_RATE 900
|
#define ARP_RATE 900
|
||||||
|
|
||||||
/* Number of seconds before the NCE times out */
|
/* 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 */
|
/* Number of seconds before retransmission */
|
||||||
#define ARP_TIMEOUT_RETRANSMISSION 5
|
#define ARP_TIMEOUT_RETRANSMISSION 3
|
||||||
|
|
||||||
extern NEIGHBOR_CACHE_TABLE NeighborCache[NB_HASHMASK + 1];
|
extern NEIGHBOR_CACHE_TABLE NeighborCache[NB_HASHMASK + 1];
|
||||||
|
|
||||||
|
@ -87,7 +87,8 @@ PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
|
||||||
|
|
||||||
PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
|
PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
|
||||||
PIP_INTERFACE Interface,
|
PIP_INTERFACE Interface,
|
||||||
PIP_ADDRESS Address);
|
PIP_ADDRESS Address,
|
||||||
|
BOOLEAN NoTimeout);
|
||||||
|
|
||||||
BOOLEAN NBQueuePacket(
|
BOOLEAN NBQueuePacket(
|
||||||
PNEIGHBOR_CACHE_ENTRY NCE,
|
PNEIGHBOR_CACHE_ENTRY NCE,
|
||||||
|
@ -105,4 +106,6 @@ ULONG NBCopyNeighbors(
|
||||||
VOID NBResetNeighborTimeout(
|
VOID NBResetNeighborTimeout(
|
||||||
PIP_ADDRESS Address);
|
PIP_ADDRESS Address);
|
||||||
|
|
||||||
|
VOID NBDestroyNeighborsForInterface(PIP_INTERFACE Interface);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -43,6 +43,8 @@ NTSTATUS RouterStartup(
|
||||||
NTSTATUS RouterShutdown(
|
NTSTATUS RouterShutdown(
|
||||||
VOID);
|
VOID);
|
||||||
|
|
||||||
|
VOID RouterRemoveRoutesForInterface(PIP_INTERFACE Interface);
|
||||||
|
|
||||||
UINT CountFIBs(PIP_INTERFACE IF);
|
UINT CountFIBs(PIP_INTERFACE IF);
|
||||||
|
|
||||||
UINT CopyFIBs( PIP_INTERFACE IF, PFIB_ENTRY Target );
|
UINT CopyFIBs( PIP_INTERFACE IF, PFIB_ENTRY Target );
|
||||||
|
|
|
@ -1552,8 +1552,10 @@ NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
|
||||||
|
|
||||||
IF->Unicast.Type = IP_ADDRESS_V4;
|
IF->Unicast.Type = IP_ADDRESS_V4;
|
||||||
IF->Unicast.Address.IPv4Address = IpAddrChange->Address;
|
IF->Unicast.Address.IPv4Address = IpAddrChange->Address;
|
||||||
|
|
||||||
IF->Netmask.Type = IP_ADDRESS_V4;
|
IF->Netmask.Type = IP_ADDRESS_V4;
|
||||||
IF->Netmask.Address.IPv4Address = IpAddrChange->Netmask;
|
IF->Netmask.Address.IPv4Address = IpAddrChange->Netmask;
|
||||||
|
|
||||||
IF->Broadcast.Type = IP_ADDRESS_V4;
|
IF->Broadcast.Type = IP_ADDRESS_V4;
|
||||||
IF->Broadcast.Address.IPv4Address =
|
IF->Broadcast.Address.IPv4Address =
|
||||||
IF->Unicast.Address.IPv4Address |
|
IF->Unicast.Address.IPv4Address |
|
||||||
|
@ -1587,10 +1589,13 @@ NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
|
||||||
IPRemoveInterfaceRoute( IF );
|
IPRemoveInterfaceRoute( IF );
|
||||||
IF->Unicast.Type = IP_ADDRESS_V4;
|
IF->Unicast.Type = IP_ADDRESS_V4;
|
||||||
IF->Unicast.Address.IPv4Address = 0;
|
IF->Unicast.Address.IPv4Address = 0;
|
||||||
|
|
||||||
IF->Netmask.Type = IP_ADDRESS_V4;
|
IF->Netmask.Type = IP_ADDRESS_V4;
|
||||||
IF->Netmask.Address.IPv4Address = 0;
|
IF->Netmask.Address.IPv4Address = 0;
|
||||||
|
|
||||||
IF->Broadcast.Type = IP_ADDRESS_V4;
|
IF->Broadcast.Type = IP_ADDRESS_V4;
|
||||||
IF->Broadcast.Address.IPv4Address = 0;
|
IF->Broadcast.Address.IPv4Address = 0;
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
} EndFor(IF);
|
} EndFor(IF);
|
||||||
|
|
|
@ -206,7 +206,6 @@ PIP_INTERFACE IPCreateInterface(
|
||||||
IF->Context = BindInfo->Context;
|
IF->Context = BindInfo->Context;
|
||||||
IF->HeaderSize = BindInfo->HeaderSize;
|
IF->HeaderSize = BindInfo->HeaderSize;
|
||||||
IF->MinFrameSize = BindInfo->MinFrameSize;
|
IF->MinFrameSize = BindInfo->MinFrameSize;
|
||||||
IF->MTU = BindInfo->MTU;
|
|
||||||
IF->Address = BindInfo->Address;
|
IF->Address = BindInfo->Address;
|
||||||
IF->AddressLength = BindInfo->AddressLength;
|
IF->AddressLength = BindInfo->AddressLength;
|
||||||
IF->Transmit = BindInfo->Transmit;
|
IF->Transmit = BindInfo->Transmit;
|
||||||
|
@ -314,11 +313,6 @@ BOOLEAN IPRegisterInterface(
|
||||||
|
|
||||||
IF->Index = ChosenIndex;
|
IF->Index = ChosenIndex;
|
||||||
|
|
||||||
if (!AddrIsUnspecified(&IF->Unicast))
|
|
||||||
{
|
|
||||||
IPAddInterfaceRoute(IF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add interface to the global interface list */
|
/* Add interface to the global interface list */
|
||||||
TcpipInterlockedInsertTailList(&InterfaceListHead,
|
TcpipInterlockedInsertTailList(&InterfaceListHead,
|
||||||
&IF->ListEntry,
|
&IF->ListEntry,
|
||||||
|
|
|
@ -106,7 +106,6 @@ NDIS_STATUS LoopRegisterAdapter(
|
||||||
BindInfo.Context = NULL;
|
BindInfo.Context = NULL;
|
||||||
BindInfo.HeaderSize = 0;
|
BindInfo.HeaderSize = 0;
|
||||||
BindInfo.MinFrameSize = 0;
|
BindInfo.MinFrameSize = 0;
|
||||||
BindInfo.MTU = 16384;
|
|
||||||
BindInfo.Address = NULL;
|
BindInfo.Address = NULL;
|
||||||
BindInfo.AddressLength = 0;
|
BindInfo.AddressLength = 0;
|
||||||
BindInfo.Transmit = LoopTransmit;
|
BindInfo.Transmit = LoopTransmit;
|
||||||
|
@ -114,6 +113,8 @@ NDIS_STATUS LoopRegisterAdapter(
|
||||||
Loopback = IPCreateInterface(&BindInfo);
|
Loopback = IPCreateInterface(&BindInfo);
|
||||||
if (!Loopback) return NDIS_STATUS_RESOURCES;
|
if (!Loopback) return NDIS_STATUS_RESOURCES;
|
||||||
|
|
||||||
|
Loopback->MTU = 16384;
|
||||||
|
|
||||||
Loopback->Name.Buffer = L"Loopback";
|
Loopback->Name.Buffer = L"Loopback";
|
||||||
Loopback->Name.MaximumLength = Loopback->Name.Length =
|
Loopback->Name.MaximumLength = Loopback->Name.Length =
|
||||||
wcslen(Loopback->Name.Buffer) * sizeof(WCHAR);
|
wcslen(Loopback->Name.Buffer) * sizeof(WCHAR);
|
||||||
|
@ -124,6 +125,8 @@ NDIS_STATUS LoopRegisterAdapter(
|
||||||
|
|
||||||
IPRegisterInterface(Loopback);
|
IPRegisterInterface(Loopback);
|
||||||
|
|
||||||
|
IPAddInterfaceRoute(Loopback);
|
||||||
|
|
||||||
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
||||||
|
|
||||||
return NDIS_STATUS_SUCCESS;
|
return NDIS_STATUS_SUCCESS;
|
||||||
|
|
|
@ -106,17 +106,27 @@ VOID NBTimeout(VOID)
|
||||||
|
|
||||||
for (PrevNCE = &NeighborCache[i].Cache;
|
for (PrevNCE = &NeighborCache[i].Cache;
|
||||||
(NCE = *PrevNCE) != NULL;) {
|
(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 */
|
/* Check if event timer is running */
|
||||||
if (NCE->EventTimer > 0) {
|
if (NCE->EventTimer > 0) {
|
||||||
ASSERT(!(NCE->State & NUD_PERMANENT));
|
ASSERT(!(NCE->State & NUD_PERMANENT));
|
||||||
NCE->EventCount++;
|
NCE->EventCount++;
|
||||||
if (NCE->State & NUD_INCOMPLETE)
|
|
||||||
{
|
if ((NCE->EventCount > ARP_RATE &&
|
||||||
/* We desperately need an address in this state or
|
|
||||||
* we timeout in 5 seconds */
|
|
||||||
NBSendSolicit(NCE);
|
|
||||||
}
|
|
||||||
else if ((NCE->EventCount > ARP_RATE &&
|
|
||||||
NCE->EventCount % ARP_TIMEOUT_RETRANSMISSION == 0) ||
|
NCE->EventCount % ARP_TIMEOUT_RETRANSMISSION == 0) ||
|
||||||
(NCE->EventCount == ARP_RATE))
|
(NCE->EventCount == ARP_RATE))
|
||||||
{
|
{
|
||||||
|
@ -143,6 +153,7 @@ VOID NBTimeout(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
NBFlushPacketQueue(NCE, Status);
|
NBFlushPacketQueue(NCE, Status);
|
||||||
|
|
||||||
ExFreePoolWithTag(NCE, NCE_TAG);
|
ExFreePoolWithTag(NCE, NCE_TAG);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -223,6 +234,42 @@ VOID NBSendSolicit(PNEIGHBOR_CACHE_ENTRY NCE)
|
||||||
NCE->Interface);
|
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(
|
PNEIGHBOR_CACHE_ENTRY NBAddNeighbor(
|
||||||
PIP_INTERFACE Interface,
|
PIP_INTERFACE Interface,
|
||||||
PIP_ADDRESS Address,
|
PIP_ADDRESS Address,
|
||||||
|
@ -331,7 +378,7 @@ VOID NBUpdateNeighbor(
|
||||||
|
|
||||||
if( !(NCE->State & NUD_INCOMPLETE) )
|
if( !(NCE->State & NUD_INCOMPLETE) )
|
||||||
{
|
{
|
||||||
NCE->EventTimer = ARP_COMPLETE_TIMEOUT;
|
if (NCE->EventTimer) NCE->EventTimer = ARP_COMPLETE_TIMEOUT;
|
||||||
NBSendPackets( NCE );
|
NBSendPackets( NCE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -410,7 +457,8 @@ PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
|
||||||
|
|
||||||
PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
|
PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
|
||||||
PIP_INTERFACE Interface,
|
PIP_INTERFACE Interface,
|
||||||
PIP_ADDRESS Address)
|
PIP_ADDRESS Address,
|
||||||
|
BOOLEAN NoTimeout)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Tries to find a neighbor and if unsuccesful, creates a new NCE
|
* FUNCTION: Tries to find a neighbor and if unsuccesful, creates a new NCE
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
|
@ -438,7 +486,7 @@ PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
|
||||||
Interface->AddressLength, NUD_PERMANENT, 0);
|
Interface->AddressLength, NUD_PERMANENT, 0);
|
||||||
} else {
|
} else {
|
||||||
NCE = NBAddNeighbor(Interface, Address, NULL,
|
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;
|
if (!NCE) return NULL;
|
||||||
NBSendSolicit(NCE);
|
NBSendSolicit(NCE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,7 +327,7 @@ PNEIGHBOR_CACHE_ENTRY RouteGetRouteToDestination(PIP_ADDRESS Destination)
|
||||||
Interface = FindOnLinkInterface(Destination);
|
Interface = FindOnLinkInterface(Destination);
|
||||||
if (Interface) {
|
if (Interface) {
|
||||||
/* The destination address is on-link. Check our neighbor cache */
|
/* The destination address is on-link. Check our neighbor cache */
|
||||||
NCE = NBFindOrCreateNeighbor(Interface, Destination);
|
NCE = NBFindOrCreateNeighbor(Interface, Destination, FALSE);
|
||||||
} else {
|
} else {
|
||||||
/* Destination is not on any subnets we're on. Find a router to use */
|
/* Destination is not on any subnets we're on. Find a router to use */
|
||||||
NCE = RouterGetRoute(Destination);
|
NCE = RouterGetRoute(Destination);
|
||||||
|
@ -339,6 +339,29 @@ PNEIGHBOR_CACHE_ENTRY RouteGetRouteToDestination(PIP_ADDRESS Destination)
|
||||||
return NCE;
|
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)
|
NTSTATUS RouterRemoveRoute(PIP_ADDRESS Target, PIP_ADDRESS Router)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Removes a route from the Forward Information Base (FIB)
|
* FUNCTION: Removes a route from the Forward Information Base (FIB)
|
||||||
|
@ -431,8 +454,10 @@ PFIB_ENTRY RouterCreateRoute(
|
||||||
|
|
||||||
NCE = Current->Router;
|
NCE = Current->Router;
|
||||||
|
|
||||||
if( AddrIsEqual(NetworkAddress, &Current->NetworkAddress) &&
|
if(AddrIsEqual(NetworkAddress, &Current->NetworkAddress) &&
|
||||||
AddrIsEqual(Netmask, &Current->Netmask) ) {
|
AddrIsEqual(Netmask, &Current->Netmask) &&
|
||||||
|
NCE->Interface == Interface)
|
||||||
|
{
|
||||||
TI_DbgPrint(DEBUG_ROUTER,("Attempting to add duplicate route to %s\n", A2S(NetworkAddress)));
|
TI_DbgPrint(DEBUG_ROUTER,("Attempting to add duplicate route to %s\n", A2S(NetworkAddress)));
|
||||||
TcpipReleaseSpinLock(&FIBLock, OldIrql);
|
TcpipReleaseSpinLock(&FIBLock, OldIrql);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -444,7 +469,7 @@ PFIB_ENTRY RouterCreateRoute(
|
||||||
TcpipReleaseSpinLock(&FIBLock, OldIrql);
|
TcpipReleaseSpinLock(&FIBLock, OldIrql);
|
||||||
|
|
||||||
/* The NCE references RouterAddress. The NCE is referenced for us */
|
/* The NCE references RouterAddress. The NCE is referenced for us */
|
||||||
NCE = NBFindOrCreateNeighbor(Interface, RouterAddress);
|
NCE = NBFindOrCreateNeighbor(Interface, RouterAddress, TRUE);
|
||||||
|
|
||||||
if (!NCE) {
|
if (!NCE) {
|
||||||
/* Not enough free resources */
|
/* Not enough free resources */
|
||||||
|
|
Loading…
Reference in a new issue