mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 17:39:53 +03:00
Add IPv6 route management for Windows client
This commit is contained in:
parent
5a05e7a249
commit
ce0591d924
@ -224,8 +224,7 @@ void RouteTrackingMain(SESSION *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Search for the default gateway
|
// Search for the default gateway
|
||||||
if (IPToUINT(&e->DestIP) == 0 &&
|
if (IsZeroIP(&e->DestIP) && IsZeroIP(&e->DestMask))
|
||||||
IPToUINT(&e->DestMask) == 0)
|
|
||||||
{
|
{
|
||||||
Debug("e->InterfaceID = %u, t->VLanInterfaceId = %u\n",
|
Debug("e->InterfaceID = %u, t->VLanInterfaceId = %u\n",
|
||||||
e->InterfaceID, t->VLanInterfaceId);
|
e->InterfaceID, t->VLanInterfaceId);
|
||||||
@ -236,30 +235,34 @@ void RouteTrackingMain(SESSION *s)
|
|||||||
is_vlan_want_to_be_default_gateway = true;
|
is_vlan_want_to_be_default_gateway = true;
|
||||||
vlan_default_gateway_metric = e->Metric;
|
vlan_default_gateway_metric = e->Metric;
|
||||||
|
|
||||||
if (vlan_default_gateway_metric >= 2 &&
|
// PPP route fix (IPv4 only)
|
||||||
|
if (IsIP4(&e->DestIP))
|
||||||
|
{
|
||||||
|
if (vlan_default_gateway_metric >= 2 &&
|
||||||
t->OldDefaultGatewayMetric == (vlan_default_gateway_metric - 1))
|
t->OldDefaultGatewayMetric == (vlan_default_gateway_metric - 1))
|
||||||
{
|
{
|
||||||
// Restore because the PPP server rewrites
|
// Restore because the PPP server rewrites
|
||||||
// the routing table selfishly
|
// the routing table selfishly
|
||||||
DeleteRouteEntry(e);
|
DeleteRouteEntry(e);
|
||||||
e->Metric--;
|
e->Metric--;
|
||||||
AddRouteEntry(e);
|
AddRouteEntry(e);
|
||||||
Debug("** Restore metric destroyed by PPP.\n");
|
Debug("** Restore metric destroyed by PPP.\n");
|
||||||
|
|
||||||
any_modified = true;
|
any_modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep this entry
|
||||||
|
if (t->DefaultGatewayByVLan != NULL)
|
||||||
|
{
|
||||||
|
// Delete if there is one added last time
|
||||||
|
FreeRouteEntry(t->DefaultGatewayByVLan);
|
||||||
|
}
|
||||||
|
|
||||||
|
t->DefaultGatewayByVLan = ZeroMalloc(sizeof(ROUTE_ENTRY));
|
||||||
|
Copy(t->DefaultGatewayByVLan, e, sizeof(ROUTE_ENTRY));
|
||||||
|
|
||||||
|
t->OldDefaultGatewayMetric = vlan_default_gateway_metric;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep this entry
|
|
||||||
if (t->DefaultGatewayByVLan != NULL)
|
|
||||||
{
|
|
||||||
// Delete if there is one added last time
|
|
||||||
FreeRouteEntry(t->DefaultGatewayByVLan);
|
|
||||||
}
|
|
||||||
|
|
||||||
t->DefaultGatewayByVLan = ZeroMalloc(sizeof(ROUTE_ENTRY));
|
|
||||||
Copy(t->DefaultGatewayByVLan, e, sizeof(ROUTE_ENTRY));
|
|
||||||
|
|
||||||
t->OldDefaultGatewayMetric = vlan_default_gateway_metric;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -372,8 +375,7 @@ void RouteTrackingMain(SESSION *s)
|
|||||||
|
|
||||||
if (e->InterfaceID != t->VLanInterfaceId)
|
if (e->InterfaceID != t->VLanInterfaceId)
|
||||||
{
|
{
|
||||||
if (IPToUINT(&e->DestIP) == 0 &&
|
if (IsZeroIP(&e->DestIP) && IsZeroIP(&e->DestMask))
|
||||||
IPToUINT(&e->DestMask) == 0)
|
|
||||||
{
|
{
|
||||||
char str[64];
|
char str[64];
|
||||||
// Default gateway is found
|
// Default gateway is found
|
||||||
@ -633,11 +635,6 @@ void RouteTrackingStart(SESSION *s)
|
|||||||
MsFreeAdapter(a);
|
MsFreeAdapter(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// For Win9x
|
|
||||||
Win32RenewDhcp9x(if_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the DNS cache
|
// Clear the DNS cache
|
||||||
Win32FlushDnsCache();
|
Win32FlushDnsCache();
|
||||||
@ -782,12 +779,12 @@ void RouteTrackingStop(SESSION *s, ROUTE_TRACKING *t)
|
|||||||
// If the restoring routing entry is a default gateway and
|
// If the restoring routing entry is a default gateway and
|
||||||
// the existing routing table contains another default gateway
|
// the existing routing table contains another default gateway
|
||||||
// on the interface, give up restoring the entry
|
// on the interface, give up restoring the entry
|
||||||
if (IPToUINT(&e->DestIP) == 0 && IPToUINT(&e->DestMask) == 0)
|
if (IsZeroIP(&e->DestIP) && IsZeroIP(&e->DestMask))
|
||||||
{
|
{
|
||||||
for (i = 0;i < table->NumEntry;i++)
|
for (i = 0;i < table->NumEntry;i++)
|
||||||
{
|
{
|
||||||
ROUTE_ENTRY *r = table->Entry[i];
|
ROUTE_ENTRY *r = table->Entry[i];
|
||||||
if (IPToUINT(&r->DestIP) == 0 && IPToUINT(&r->DestMask) == 0)
|
if (IsZeroIP(&r->DestIP) && IsZeroIP(&r->DestMask))
|
||||||
{
|
{
|
||||||
if (r->InterfaceID == e->InterfaceID)
|
if (r->InterfaceID == e->InterfaceID)
|
||||||
{
|
{
|
||||||
|
@ -62,6 +62,7 @@ struct ROUTE_CHANGE_DATA
|
|||||||
OVERLAPPED Overlapped;
|
OVERLAPPED Overlapped;
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
UINT NumCalled;
|
UINT NumCalled;
|
||||||
|
bool Changed;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -6124,7 +6125,7 @@ ICMP_RESULT *IcmpApiEchoSend(IP *dest_ip, UCHAR ttl, UCHAR *data, UINT size, UIN
|
|||||||
ROUTE_CHANGE *NewRouteChange()
|
ROUTE_CHANGE *NewRouteChange()
|
||||||
{
|
{
|
||||||
#ifdef OS_WIN32
|
#ifdef OS_WIN32
|
||||||
return Win32NewRouteChange();
|
return Win32NewRouteChange2(true, true, NULL);
|
||||||
#else // OS_WIN32
|
#else // OS_WIN32
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif // OS_WIN32
|
#endif // OS_WIN32
|
||||||
@ -6134,7 +6135,7 @@ ROUTE_CHANGE *NewRouteChange()
|
|||||||
void FreeRouteChange(ROUTE_CHANGE *r)
|
void FreeRouteChange(ROUTE_CHANGE *r)
|
||||||
{
|
{
|
||||||
#ifdef OS_WIN32
|
#ifdef OS_WIN32
|
||||||
Win32FreeRouteChange(r);
|
Win32FreeRouteChange2(r);
|
||||||
#endif // OS_WIN32
|
#endif // OS_WIN32
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6142,7 +6143,7 @@ void FreeRouteChange(ROUTE_CHANGE *r)
|
|||||||
bool IsRouteChanged(ROUTE_CHANGE *r)
|
bool IsRouteChanged(ROUTE_CHANGE *r)
|
||||||
{
|
{
|
||||||
#ifdef OS_WIN32
|
#ifdef OS_WIN32
|
||||||
return Win32IsRouteChanged(r);
|
return Win32IsRouteChanged2(r);
|
||||||
#else // OS_WIN32
|
#else // OS_WIN32
|
||||||
return false;
|
return false;
|
||||||
#endif // OS_WIN32
|
#endif // OS_WIN32
|
||||||
@ -6173,6 +6174,57 @@ ROUTE_CHANGE *Win32NewRouteChange()
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Win32RouteChangeCallback(void *context, MIB_IPFORWARD_ROW2 *row, MIB_NOTIFICATION_TYPE nt)
|
||||||
|
{
|
||||||
|
ROUTE_CHANGE_DATA *data = context;
|
||||||
|
data->Changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Routing table change detector function (For Vista and later)
|
||||||
|
ROUTE_CHANGE *Win32NewRouteChange2(bool ipv4, bool ipv6, void *callback)
|
||||||
|
{
|
||||||
|
ROUTE_CHANGE *r;
|
||||||
|
BOOL ret;
|
||||||
|
ADDRESS_FAMILY family;
|
||||||
|
|
||||||
|
r = ZeroMalloc(sizeof(ROUTE_CHANGE));
|
||||||
|
|
||||||
|
r->Data = ZeroMalloc(sizeof(ROUTE_CHANGE_DATA));
|
||||||
|
|
||||||
|
if (ipv4 && ipv6)
|
||||||
|
{
|
||||||
|
family = AF_UNSPEC;
|
||||||
|
}
|
||||||
|
else if (ipv6)
|
||||||
|
{
|
||||||
|
family = AF_INET6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
family = AF_INET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback != NULL)
|
||||||
|
{
|
||||||
|
ret = NotifyRouteChange2(family, (PIPFORWARD_CHANGE_CALLBACK)callback, r->Data, false, &r->Data->Handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use default callback if not provided
|
||||||
|
ret = NotifyRouteChange2(family, (PIPFORWARD_CHANGE_CALLBACK)Win32RouteChangeCallback, r->Data, false, &r->Data->Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != NO_ERROR)
|
||||||
|
{
|
||||||
|
Free(r->Data);
|
||||||
|
Free(r);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
void Win32FreeRouteChange(ROUTE_CHANGE *r)
|
void Win32FreeRouteChange(ROUTE_CHANGE *r)
|
||||||
{
|
{
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
@ -6188,6 +6240,20 @@ void Win32FreeRouteChange(ROUTE_CHANGE *r)
|
|||||||
Free(r);
|
Free(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Win32FreeRouteChange2(ROUTE_CHANGE *r)
|
||||||
|
{
|
||||||
|
// Validate arguments
|
||||||
|
if (r == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CancelMibChangeNotify2(r->Data->Handle);
|
||||||
|
|
||||||
|
Free(r->Data);
|
||||||
|
Free(r);
|
||||||
|
}
|
||||||
|
|
||||||
bool Win32IsRouteChanged(ROUTE_CHANGE *r)
|
bool Win32IsRouteChanged(ROUTE_CHANGE *r)
|
||||||
{
|
{
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
@ -6210,6 +6276,28 @@ bool Win32IsRouteChanged(ROUTE_CHANGE *r)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Win32IsRouteChanged2(ROUTE_CHANGE *r)
|
||||||
|
{
|
||||||
|
// Validate arguments
|
||||||
|
if (r == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((r->Data->NumCalled++) == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->Data->Changed)
|
||||||
|
{
|
||||||
|
r->Data->Changed = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct WIN32_ACCEPT_CHECK_DATA
|
typedef struct WIN32_ACCEPT_CHECK_DATA
|
||||||
{
|
{
|
||||||
bool IsIPv6;
|
bool IsIPv6;
|
||||||
@ -6481,6 +6569,17 @@ void GenerateEui64Address6(UCHAR *dst, UCHAR *mac)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Examine whether two IP addresses are in the same network
|
// Examine whether two IP addresses are in the same network
|
||||||
|
bool IsInSameNetwork(IP *a1, IP *a2, IP *subnet)
|
||||||
|
{
|
||||||
|
if (IsIP4(a1))
|
||||||
|
{
|
||||||
|
return IsInSameNetwork4(a1, a2, subnet);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return IsInSameNetwork6(a1, a2, subnet);
|
||||||
|
}
|
||||||
|
}
|
||||||
bool IsInSameNetwork6ByStr(char *ip1, char *ip2, char *subnet)
|
bool IsInSameNetwork6ByStr(char *ip1, char *ip2, char *subnet)
|
||||||
{
|
{
|
||||||
IP p1, p2, s;
|
IP p1, p2, s;
|
||||||
@ -9371,6 +9470,23 @@ void Win32DeleteRouteEntry(ROUTE_ENTRY *e)
|
|||||||
Free(p);
|
Free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove a routing entry from the routing table (For Vista and later)
|
||||||
|
void Win32DeleteRouteEntry2(ROUTE_ENTRY *e)
|
||||||
|
{
|
||||||
|
MIB_IPFORWARD_ROW2 *p;
|
||||||
|
// Validate arguments
|
||||||
|
if (e == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ZeroMallocFast(sizeof(MIB_IPFORWARD_ROW2));
|
||||||
|
Win32RouteEntryToIpForwardRow2(p, e);
|
||||||
|
|
||||||
|
DeleteIpForwardEntry2(p);
|
||||||
|
Free(p);
|
||||||
|
}
|
||||||
|
|
||||||
// Add a routing entry to the routing table
|
// Add a routing entry to the routing table
|
||||||
bool Win32AddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
|
bool Win32AddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
|
||||||
{
|
{
|
||||||
@ -9418,6 +9534,53 @@ bool Win32AddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a routing entry to the routing table (For Vista and later)
|
||||||
|
bool Win32AddRouteEntry2(ROUTE_ENTRY *e, bool *already_exists)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
bool dummy = false;
|
||||||
|
MIB_IPFORWARD_ROW2 *p;
|
||||||
|
UINT err = 0;
|
||||||
|
// Validate arguments
|
||||||
|
if (e == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (already_exists == NULL)
|
||||||
|
{
|
||||||
|
already_exists = &dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
*already_exists = false;
|
||||||
|
|
||||||
|
p = ZeroMallocFast(sizeof(MIB_IPFORWARD_ROW2));
|
||||||
|
Win32RouteEntryToIpForwardRow2(p, e);
|
||||||
|
|
||||||
|
err = CreateIpForwardEntry2(p);
|
||||||
|
if (err != 0)
|
||||||
|
{
|
||||||
|
if (err == ERROR_OBJECT_ALREADY_EXISTS)
|
||||||
|
{
|
||||||
|
Debug("CreateIpForwardEntry2: Already Exists\n");
|
||||||
|
*already_exists = true;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug("CreateIpForwardEntry2 Error: %u\n", err);
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Free(p);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the routing table
|
// Get the routing table
|
||||||
ROUTE_TABLE *Win32GetRouteTable()
|
ROUTE_TABLE *Win32GetRouteTable()
|
||||||
{
|
{
|
||||||
@ -9485,6 +9648,68 @@ FAILED:
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the routing table (For Vista and later)
|
||||||
|
ROUTE_TABLE *Win32GetRouteTable2(bool ipv4, bool ipv6)
|
||||||
|
{
|
||||||
|
ROUTE_TABLE *t = ZeroMallocFast(sizeof(ROUTE_TABLE));
|
||||||
|
MIB_IPFORWARD_TABLE2 *p = NULL;
|
||||||
|
UINT ret;
|
||||||
|
UINT num_retry = 0;
|
||||||
|
LIST *o;
|
||||||
|
UINT i;
|
||||||
|
ROUTE_ENTRY *e;
|
||||||
|
ADDRESS_FAMILY family;
|
||||||
|
|
||||||
|
if (ipv4 && ipv6)
|
||||||
|
{
|
||||||
|
family = AF_UNSPEC;
|
||||||
|
}
|
||||||
|
else if (ipv6)
|
||||||
|
{
|
||||||
|
family = AF_INET6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
family = AF_INET;
|
||||||
|
}
|
||||||
|
|
||||||
|
RETRY:
|
||||||
|
// Actually get
|
||||||
|
ret = GetIpForwardTable2(family, &p);
|
||||||
|
if (ret != NO_ERROR)
|
||||||
|
{
|
||||||
|
// Acquisition failure
|
||||||
|
if ((++num_retry) >= 5)
|
||||||
|
{
|
||||||
|
FreeMibTable(p);
|
||||||
|
t->Entry = MallocFast(0);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
FreeMibTable(p);
|
||||||
|
goto RETRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to the list along
|
||||||
|
o = NewListFast(Win32CompareRouteEntryByMetric);
|
||||||
|
for (i = 0; i < p->NumEntries; i++)
|
||||||
|
{
|
||||||
|
e = ZeroMallocFast(sizeof(ROUTE_ENTRY));
|
||||||
|
Win32IpForwardRow2ToRouteEntry(e, &p->Table[i]);
|
||||||
|
Add(o, e);
|
||||||
|
}
|
||||||
|
FreeMibTable(p);
|
||||||
|
|
||||||
|
// Sort by metric
|
||||||
|
Sort(o);
|
||||||
|
|
||||||
|
// Combine the results
|
||||||
|
t->NumEntry = LIST_NUM(o);
|
||||||
|
t->Entry = ToArrayEx(o, true);
|
||||||
|
ReleaseList(o);
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
// Sort the routing entries by metric
|
// Sort the routing entries by metric
|
||||||
int Win32CompareRouteEntryByMetric(void *p1, void *p2)
|
int Win32CompareRouteEntryByMetric(void *p1, void *p2)
|
||||||
{
|
{
|
||||||
@ -9572,6 +9797,67 @@ void Win32RouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry)
|
|||||||
Debug(" r->dwForwardIfIndex=%u\n", r->dwForwardIfIndex);
|
Debug(" r->dwForwardIfIndex=%u\n", r->dwForwardIfIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert the ROUTE_ENTRY to a MIB_IPFORWARD_ROW2 (For Vista and later)
|
||||||
|
void Win32RouteEntryToIpForwardRow2(void *ip_forward_row, ROUTE_ENTRY *entry)
|
||||||
|
{
|
||||||
|
MIB_IPFORWARD_ROW2 *r;
|
||||||
|
// Validate arguments
|
||||||
|
if (entry == NULL || ip_forward_row == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = (MIB_IPFORWARD_ROW2 *)ip_forward_row;
|
||||||
|
InitializeIpForwardEntry(r);
|
||||||
|
|
||||||
|
MIB_IPINTERFACE_ROW *p;
|
||||||
|
p = ZeroMallocFast(sizeof(MIB_IPINTERFACE_ROW));
|
||||||
|
|
||||||
|
if (IsIP4(&entry->DestIP))
|
||||||
|
{
|
||||||
|
// IP address
|
||||||
|
r->DestinationPrefix.Prefix.Ipv4.sin_family = AF_INET;
|
||||||
|
IPToInAddr(&r->DestinationPrefix.Prefix.Ipv4.sin_addr, &entry->DestIP);
|
||||||
|
// Subnet mask
|
||||||
|
r->DestinationPrefix.PrefixLength = SubnetMaskToInt4(&entry->DestMask);
|
||||||
|
// Gateway IP address
|
||||||
|
r->NextHop.Ipv4.sin_family = AF_INET;
|
||||||
|
IPToInAddr(&r->NextHop.Ipv4.sin_addr, &entry->GatewayIP);
|
||||||
|
// Interface
|
||||||
|
p->Family = AF_INET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// IP address
|
||||||
|
r->DestinationPrefix.Prefix.Ipv6.sin6_family = AF_INET6;
|
||||||
|
IPToInAddr6(&r->DestinationPrefix.Prefix.Ipv6.sin6_addr, &entry->DestIP);
|
||||||
|
// Subnet mask
|
||||||
|
r->DestinationPrefix.PrefixLength = SubnetMaskToInt6(&entry->DestMask);
|
||||||
|
// Gateway IP address
|
||||||
|
r->NextHop.Ipv6.sin6_family = AF_INET6;
|
||||||
|
IPToInAddr6(&r->NextHop.Ipv6.sin6_addr, &entry->GatewayIP);
|
||||||
|
// Interface
|
||||||
|
p->Family = AF_INET6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metric
|
||||||
|
p->InterfaceIndex = entry->InterfaceID;
|
||||||
|
if (GetIpInterfaceEntry(p) == NO_ERROR && entry->Metric >= p->Metric)
|
||||||
|
{
|
||||||
|
r->Metric = entry->Metric - p->Metric;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r->Metric = entry->Metric;
|
||||||
|
}
|
||||||
|
Free(p);
|
||||||
|
|
||||||
|
// Interface ID
|
||||||
|
r->InterfaceIndex = entry->InterfaceID;
|
||||||
|
|
||||||
|
Debug("Win32RouteEntryToIpForwardRow2()\n");
|
||||||
|
}
|
||||||
|
|
||||||
// Convert the MIB_IPFORWARDROW to a ROUTE_ENTRY
|
// Convert the MIB_IPFORWARDROW to a ROUTE_ENTRY
|
||||||
void Win32IpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
|
void Win32IpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
|
||||||
{
|
{
|
||||||
@ -9611,6 +9897,77 @@ void Win32IpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
|
|||||||
entry->InterfaceID = r->dwForwardIfIndex;
|
entry->InterfaceID = r->dwForwardIfIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert the MIB_IPFORWARD_ROW2 to a ROUTE_ENTRY (For Vista and later)
|
||||||
|
void Win32IpForwardRow2ToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
|
||||||
|
{
|
||||||
|
MIB_IPFORWARD_ROW2 *r;
|
||||||
|
// Validate arguments
|
||||||
|
if (entry == NULL || ip_forward_row == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = (MIB_IPFORWARD_ROW2 *)ip_forward_row;
|
||||||
|
|
||||||
|
Zero(entry, sizeof(ROUTE_ENTRY));
|
||||||
|
|
||||||
|
MIB_IPINTERFACE_ROW *p;
|
||||||
|
p = ZeroMallocFast(sizeof(MIB_IPINTERFACE_ROW));
|
||||||
|
|
||||||
|
if (((struct sockaddr *)&r->DestinationPrefix.Prefix)->sa_family != AF_INET6)
|
||||||
|
{
|
||||||
|
// IP address
|
||||||
|
InAddrToIP(&entry->DestIP, &r->DestinationPrefix.Prefix.Ipv4.sin_addr);
|
||||||
|
// Subnet mask
|
||||||
|
IntToSubnetMask4(&entry->DestMask, r->DestinationPrefix.PrefixLength);
|
||||||
|
// Gateway IP address
|
||||||
|
InAddrToIP(&entry->GatewayIP, &r->NextHop.Ipv4.sin_addr);
|
||||||
|
// Interface
|
||||||
|
p->Family = AF_INET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// IP address
|
||||||
|
InAddrToIP6(&entry->DestIP, &r->DestinationPrefix.Prefix.Ipv6.sin6_addr);
|
||||||
|
// Subnet mask
|
||||||
|
IntToSubnetMask6(&entry->DestMask, r->DestinationPrefix.PrefixLength);
|
||||||
|
// Gateway IP address
|
||||||
|
InAddrToIP6(&entry->GatewayIP, &r->NextHop.Ipv6.sin6_addr);
|
||||||
|
// Interface
|
||||||
|
p->Family = AF_INET6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local routing flag
|
||||||
|
if (IsZeroIP(&entry->GatewayIP))
|
||||||
|
{
|
||||||
|
entry->LocalRouting = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry->LocalRouting = false;
|
||||||
|
}
|
||||||
|
if (entry->LocalRouting && r->Protocol == 3)
|
||||||
|
{
|
||||||
|
// PPP. Danger!
|
||||||
|
entry->PPPConnection = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metric
|
||||||
|
p->InterfaceIndex = r->InterfaceIndex;
|
||||||
|
if (GetIpInterfaceEntry(p) == NO_ERROR)
|
||||||
|
{
|
||||||
|
entry->Metric = r->Metric + p->Metric;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry->Metric = r->Metric;
|
||||||
|
}
|
||||||
|
Free(p);
|
||||||
|
|
||||||
|
// Interface ID
|
||||||
|
entry->InterfaceID = r->InterfaceIndex;
|
||||||
|
}
|
||||||
|
|
||||||
// Initializing the socket library
|
// Initializing the socket library
|
||||||
void Win32InitSocketLibrary()
|
void Win32InitSocketLibrary()
|
||||||
{
|
{
|
||||||
@ -10233,23 +10590,12 @@ ROUTE_ENTRY *GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE *table, IP *ip, UINT
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsIP6(ip))
|
|
||||||
{
|
|
||||||
// IPv6 is not supported
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select routing table entry by following rule
|
// Select routing table entry by following rule
|
||||||
// 1. Largest subnet mask
|
// 1. Largest subnet mask
|
||||||
// 2. Smallest metric value
|
// 2. Smallest metric value
|
||||||
for (i = 0; i < table->NumEntry; i++)
|
for (i = 0; i < table->NumEntry; i++)
|
||||||
{
|
{
|
||||||
ROUTE_ENTRY *e = table->Entry[i];
|
ROUTE_ENTRY *e = table->Entry[i];
|
||||||
UINT dest, net, mask;
|
|
||||||
|
|
||||||
dest = IPToUINT(ip);
|
|
||||||
net = IPToUINT(&e->DestIP);
|
|
||||||
mask = IPToUINT(&e->DestMask);
|
|
||||||
|
|
||||||
if (exclude_if_id != 0)
|
if (exclude_if_id != 0)
|
||||||
{
|
{
|
||||||
@ -10260,10 +10606,10 @@ ROUTE_ENTRY *GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE *table, IP *ip, UINT
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mask test
|
// Mask test
|
||||||
if ((dest & mask) == (net & mask))
|
if (IsInSameNetwork(ip, &e->DestIP, &e->DestMask))
|
||||||
{
|
{
|
||||||
// Calculate the score
|
// Calculate the score
|
||||||
UINT score_high32 = mask;
|
UINT score_high32 = SubnetMaskToInt(&e->DestMask);
|
||||||
UINT score_low32 = 0xFFFFFFFF - e->Metric;
|
UINT score_low32 = 0xFFFFFFFF - e->Metric;
|
||||||
UINT64 score64 = (UINT64)score_high32 * (UINT64)0x80000000 * (UINT64)2 + (UINT64)score_low32;
|
UINT64 score64 = (UINT64)score_high32 * (UINT64)0x80000000 * (UINT64)2 + (UINT64)score_low32;
|
||||||
if (score64 == 0)
|
if (score64 == 0)
|
||||||
@ -10294,24 +10640,24 @@ ROUTE_ENTRY *GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE *table, IP *ip, UINT
|
|||||||
|
|
||||||
if (tmp != NULL)
|
if (tmp != NULL)
|
||||||
{
|
{
|
||||||
UINT dest, gateway, mask;
|
|
||||||
|
|
||||||
// Generate an entry
|
// Generate an entry
|
||||||
ret = ZeroMallocFast(sizeof(ROUTE_ENTRY));
|
ret = ZeroMallocFast(sizeof(ROUTE_ENTRY));
|
||||||
|
|
||||||
Copy(&ret->DestIP, ip, sizeof(IP));
|
Copy(&ret->DestIP, ip, sizeof(IP));
|
||||||
SetIP(&ret->DestMask, 255, 255, 255, 255);
|
if (IsIP4(ip))
|
||||||
|
{
|
||||||
|
IntToSubnetMask4(&ret->DestMask, 32);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IntToSubnetMask6(&ret->DestMask, 128);
|
||||||
|
}
|
||||||
Copy(&ret->GatewayIP, &tmp->GatewayIP, sizeof(IP));
|
Copy(&ret->GatewayIP, &tmp->GatewayIP, sizeof(IP));
|
||||||
ret->InterfaceID = tmp->InterfaceID;
|
ret->InterfaceID = tmp->InterfaceID;
|
||||||
ret->LocalRouting = tmp->LocalRouting;
|
ret->LocalRouting = tmp->LocalRouting;
|
||||||
ret->OldIfMetric = tmp->Metric;
|
ret->OldIfMetric = tmp->Metric;
|
||||||
ret->Metric = 1;
|
ret->Metric = 1;
|
||||||
ret->PPPConnection = tmp->PPPConnection;
|
ret->PPPConnection = tmp->PPPConnection;
|
||||||
|
|
||||||
// Calculation related to routing control
|
|
||||||
dest = IPToUINT(&tmp->DestIP);
|
|
||||||
gateway = IPToUINT(&tmp->GatewayIP);
|
|
||||||
mask = IPToUINT(&tmp->DestMask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -10479,7 +10825,7 @@ void DeleteRouteEntry(ROUTE_ENTRY *e)
|
|||||||
{
|
{
|
||||||
Debug("DeleteRouteEntry();\n");
|
Debug("DeleteRouteEntry();\n");
|
||||||
#ifdef OS_WIN32
|
#ifdef OS_WIN32
|
||||||
Win32DeleteRouteEntry(e);
|
Win32DeleteRouteEntry2(e);
|
||||||
#else // OS_WIN32
|
#else // OS_WIN32
|
||||||
UnixDeleteRouteEntry(e);
|
UnixDeleteRouteEntry(e);
|
||||||
#endif
|
#endif
|
||||||
@ -10496,7 +10842,7 @@ bool AddRouteEntryEx(ROUTE_ENTRY *e, bool *already_exists)
|
|||||||
bool ret = false;
|
bool ret = false;
|
||||||
Debug("AddRouteEntryEx();\n");
|
Debug("AddRouteEntryEx();\n");
|
||||||
#ifdef OS_WIN32
|
#ifdef OS_WIN32
|
||||||
ret = Win32AddRouteEntry(e, already_exists);
|
ret = Win32AddRouteEntry2(e, already_exists);
|
||||||
#else // OS_WIN32
|
#else // OS_WIN32
|
||||||
ret = UnixAddRouteEntry(e, already_exists);
|
ret = UnixAddRouteEntry(e, already_exists);
|
||||||
#endif
|
#endif
|
||||||
@ -10512,7 +10858,7 @@ ROUTE_TABLE *GetRouteTable()
|
|||||||
UCHAR hash[MD5_SIZE];
|
UCHAR hash[MD5_SIZE];
|
||||||
|
|
||||||
#ifdef OS_WIN32
|
#ifdef OS_WIN32
|
||||||
t = Win32GetRouteTable();
|
t = Win32GetRouteTable2(true, true);
|
||||||
#else //OS_WIN32
|
#else //OS_WIN32
|
||||||
t = UnixGetRouteTable();
|
t = UnixGetRouteTable();
|
||||||
#endif // OS_WIN32
|
#endif // OS_WIN32
|
||||||
|
@ -959,11 +959,16 @@ void Win32InitAsyncSocket(SOCK *sock);
|
|||||||
void Win32JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event);
|
void Win32JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event);
|
||||||
void Win32FreeAsyncSocket(SOCK *sock);
|
void Win32FreeAsyncSocket(SOCK *sock);
|
||||||
void Win32IpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row);
|
void Win32IpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row);
|
||||||
|
void Win32IpForwardRow2ToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row);
|
||||||
void Win32RouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry);
|
void Win32RouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry);
|
||||||
|
void Win32RouteEntryToIpForwardRow2(void *ip_forward_row, ROUTE_ENTRY *entry);
|
||||||
int Win32CompareRouteEntryByMetric(void *p1, void *p2);
|
int Win32CompareRouteEntryByMetric(void *p1, void *p2);
|
||||||
ROUTE_TABLE *Win32GetRouteTable();
|
ROUTE_TABLE *Win32GetRouteTable();
|
||||||
|
ROUTE_TABLE *Win32GetRouteTable2(bool ipv4, bool ipv6);
|
||||||
bool Win32AddRouteEntry(ROUTE_ENTRY *e, bool *already_exists);
|
bool Win32AddRouteEntry(ROUTE_ENTRY *e, bool *already_exists);
|
||||||
|
bool Win32AddRouteEntry2(ROUTE_ENTRY *e, bool *already_exists);
|
||||||
void Win32DeleteRouteEntry(ROUTE_ENTRY *e);
|
void Win32DeleteRouteEntry(ROUTE_ENTRY *e);
|
||||||
|
void Win32DeleteRouteEntry2(ROUTE_ENTRY *e);
|
||||||
void Win32UINTToIP(IP *ip, UINT i);
|
void Win32UINTToIP(IP *ip, UINT i);
|
||||||
UINT Win32IPToUINT(IP *ip);
|
UINT Win32IPToUINT(IP *ip);
|
||||||
UINT Win32GetVLanInterfaceID(char *instance_name);
|
UINT Win32GetVLanInterfaceID(char *instance_name);
|
||||||
@ -981,8 +986,11 @@ void Win32ReleaseDhcp9x(UINT if_id, bool wait);
|
|||||||
void Win32FlushDnsCache();
|
void Win32FlushDnsCache();
|
||||||
int CompareIpAdapterIndexMap(void *p1, void *p2);
|
int CompareIpAdapterIndexMap(void *p1, void *p2);
|
||||||
ROUTE_CHANGE *Win32NewRouteChange();
|
ROUTE_CHANGE *Win32NewRouteChange();
|
||||||
|
ROUTE_CHANGE *Win32NewRouteChange2(bool ipv4, bool ipv6, void *callback);
|
||||||
void Win32FreeRouteChange(ROUTE_CHANGE *r);
|
void Win32FreeRouteChange(ROUTE_CHANGE *r);
|
||||||
|
void Win32FreeRouteChange2(ROUTE_CHANGE *r);
|
||||||
bool Win32IsRouteChanged(ROUTE_CHANGE *r);
|
bool Win32IsRouteChanged(ROUTE_CHANGE *r);
|
||||||
|
bool Win32IsRouteChanged2(ROUTE_CHANGE *r);
|
||||||
bool Win32GetAdapterFromGuid(void *a, char *guid);
|
bool Win32GetAdapterFromGuid(void *a, char *guid);
|
||||||
SOCKET Win32Accept(SOCK *sock, SOCKET s, struct sockaddr *addr, int *addrlen, bool ipv6);
|
SOCKET Win32Accept(SOCK *sock, SOCKET s, struct sockaddr *addr, int *addrlen, bool ipv6);
|
||||||
|
|
||||||
@ -1225,6 +1233,7 @@ void GetLoopbackAddress6(IP *ip);
|
|||||||
UINT GetIPAddrType6(IP *ip);
|
UINT GetIPAddrType6(IP *ip);
|
||||||
UINT GetIPv6AddrType(IPV6_ADDR *addr);
|
UINT GetIPv6AddrType(IPV6_ADDR *addr);
|
||||||
void GetPrefixAddress6(IP *dst, IP *ip, IP *subnet);
|
void GetPrefixAddress6(IP *dst, IP *ip, IP *subnet);
|
||||||
|
bool IsInSameNetwork(IP *a1, IP *a2, IP *subnet);
|
||||||
bool IsInSameNetwork6(IP *a1, IP *a2, IP *subnet);
|
bool IsInSameNetwork6(IP *a1, IP *a2, IP *subnet);
|
||||||
bool IsInSameNetwork6ByStr(char *ip1, char *ip2, char *subnet);
|
bool IsInSameNetwork6ByStr(char *ip1, char *ip2, char *subnet);
|
||||||
void GenerateEui64Address6(UCHAR *dst, UCHAR *mac);
|
void GenerateEui64Address6(UCHAR *dst, UCHAR *mac);
|
||||||
|
Loading…
Reference in New Issue
Block a user