Commit 055ff708 authored by Jondy Zhao's avatar Jondy Zhao

Restore gateway to 0 in the kernel_addresses;

Change the data type of destination and gate in the kernel_route;
Set blackhole interface index to 1;
Clear pipe data after checking route table.
parent 4f0e3348
...@@ -41,7 +41,12 @@ $ ./testc.exe ...@@ -41,7 +41,12 @@ $ ./testc.exe
Interface Names Interface Names
=============== ===============
Use network connection name as interface name. Use network connection name as interface name. On XP Go to Start ->
Control Panel -> Network Connections.
You should see all the connections like "Local Area Connection
3". Right click and rename this to something shorter and without
embedded spaces such as "my-tap".
Notes Notes
===== =====
...@@ -85,6 +90,5 @@ Notes ...@@ -85,6 +90,5 @@ Notes
Destination network 100.28.0.0/16 will be unreachable. Destination network 100.28.0.0/16 will be unreachable.
9. IN6_LINKLOCAL_IFINDEX && SET_IN6_LINKLOCAL_IFINDEX, do both of them 9. IN6_LINKLOCAL_IFINDEX && SET_IN6_LINKLOCAL_IFINDEX, do both of them
work in the Windows? work in the Windows?
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
#include <iphlpapi.h> #include <iphlpapi.h>
#include <wlanapi.h> #include <wlanapi.h>
#include <rtmv2.h>
#include <nldef.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
...@@ -56,6 +59,7 @@ static HRESULT (WINAPI *ws_guidfromstring)(LPCTSTR psz, LPGUID pguid) = NULL; ...@@ -56,6 +59,7 @@ static HRESULT (WINAPI *ws_guidfromstring)(LPCTSTR psz, LPGUID pguid) = NULL;
static HANDLE event_notify_monitor_thread = WSA_INVALID_EVENT; static HANDLE event_notify_monitor_thread = WSA_INVALID_EVENT;
static PLIBWINET_INTERFACE_MAP_TABLE interface_map_table = NULL; static PLIBWINET_INTERFACE_MAP_TABLE interface_map_table = NULL;
static int libwinet_run_command(const char *);
static void static void
plen2mask(int n, struct in_addr *dest) plen2mask(int n, struct in_addr *dest)
...@@ -106,6 +110,36 @@ mask2len(const unsigned char *p, const int size) ...@@ -106,6 +110,36 @@ mask2len(const unsigned char *p, const int size)
return i; return i;
} }
static int
libwinet_ipv6_interfaces_forwards(int forward)
{
const int MAX_BUFFER_SIZE = 255;
char cmdbuf[MAX_BUFFER_SIZE];
int result;
struct if_nameindex * p;
struct if_nameindex * ptr;
if (NULL == (ptr = (struct if_nameindex *)if_nameindex()))
return -1;
p = ptr;
while (p -> if_index) {
if (snprintf(cmdbuf,
MAX_BUFFER_SIZE,
"netsh interface ipv6 set interface %d forwarding=%s",
p -> if_index,
forward ? "enabled" : "disabled"
) >= MAX_BUFFER_SIZE)
break;
if (libwinet_run_command(cmdbuf) != 0)
break;
p ++;
}
result = ! (p -> if_index);
if_freenameindex(ptr);
return result;
}
static void static void
libwinet_free_interface_map_table() libwinet_free_interface_map_table()
{ {
...@@ -879,7 +913,6 @@ libwinet_edit_route_entry(const struct sockaddr *dest, ...@@ -879,7 +913,6 @@ libwinet_edit_route_entry(const struct sockaddr *dest,
int cmdflag) int cmdflag)
{ {
#if _WIN32_WINNT < _WIN32_WINNT_VISTA #if _WIN32_WINNT < _WIN32_WINNT_VISTA
/* Add ipv6 route before Windows Vista */ /* Add ipv6 route before Windows Vista */
if(dest->sa_family == AF_INET6) { if(dest->sa_family == AF_INET6) {
const int MAX_BUFFER_SIZE = 1024; const int MAX_BUFFER_SIZE = 1024;
...@@ -1102,7 +1135,20 @@ int ...@@ -1102,7 +1135,20 @@ int
cyginet_set_ipv6_forwards(int value) cyginet_set_ipv6_forwards(int value)
{ {
char * key = "SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters"; char * key = "SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters";
/*
int rc;
rc = libwinet_ipv6_interfaces_forwards(value);
if (rc == -1)
return -1;
if (value) {
if (ERROR_IO_PENDING != EnableRouter(NULL, NULL))
return -1;
}
else {
if (NO_ERROR != UnenableRouter(NULL, NULL))
return -1;
}
*/
return libwinet_set_registry_key(key, return libwinet_set_registry_key(key,
"IPEnableRouter", "IPEnableRouter",
value, value,
...@@ -2075,36 +2121,6 @@ libwinet_is_wireless_device(const wchar_t *pszwAdapterName) ...@@ -2075,36 +2121,6 @@ libwinet_is_wireless_device(const wchar_t *pszwAdapterName)
return 1; return 1;
} }
static int
libwinet_ipv6_interfaces_forwards(int forward)
{
const int MAX_BUFFER_SIZE = 80;
char cmdbuf[MAX_BUFFER_SIZE];
int result;
struct if_nameindex * p;
struct if_nameindex * ptr;
if (NULL == (ptr = (struct if_nameindex *)if_nameindex()))
return -1;
p = ptr;
while (p -> if_index) {
if (snprintf(cmdbuf,
MAX_BUFFER_SIZE,
"ipv6 ifc %d %cforward",
p -> if_index,
forward ? ' ' : '-'
) >= MAX_BUFFER_SIZE)
break;
if (libwinet_run_command(cmdbuf) != 0)
break;
p ++;
}
result = ! (p -> if_index);
if_freenameindex(ptr);
return result;
}
BOOL RouteLookup(SOCKADDR *destAddr, BOOL RouteLookup(SOCKADDR *destAddr,
int destLen, int destLen,
SOCKADDR *localAddr, SOCKADDR *localAddr,
...@@ -2332,6 +2348,52 @@ DWORD GetConnectedNetworks() ...@@ -2332,6 +2348,52 @@ DWORD GetConnectedNetworks()
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
#ifdef TEST_CYGINET #ifdef TEST_CYGINET
// The following #defines are from routprot.h in the Platform Software Develoment Kit (SDK)
#define PROTO_TYPE_UCAST 0
#define PROTOCOL_ID(Type, VendorId, ProtocolId) \
(((Type & 0x03)<<30)|((VendorId & 0x3FFF)<<16)|(ProtocolId & 0xFFFF))
#define PROTO_VENDOR_ID 0x3FAA
DWORD (WINAPI * fRtmRegisterEntity)(PRTM_ENTITY_INFO,PRTM_ENTITY_EXPORT_METHODS,
RTM_EVENT_CALLBACK,WINBOOL,PRTM_REGN_PROFILE,PRTM_ENTITY_HANDLE);
DWORD (WINAPI * fRtmDeregisterEntity)(RTM_ENTITY_HANDLE);
int test_rtm2()
{
HMODULE lib;
if ((lib = LoadLibraryW(L"rtm.dll"))) {
fRtmRegisterEntity = GetProcAddress(lib, (LPCSTR)"RtmRegisterEntity");
fRtmDeregisterEntity = GetProcAddress(lib, (LPCSTR)"RtmDeregisterEntity");
FreeLibrary(lib);
}
else
return -1;
RTM_ENTITY_HANDLE RtmRegHandle;
RTM_ENTITY_INFO EntityInfo;
RTM_REGN_PROFILE RegnProfile;
DWORD dwRet = ERROR_SUCCESS;
EntityInfo.RtmInstanceId = 0;
EntityInfo.AddressFamily = AF_INET;
EntityInfo.EntityId.EntityProtocolId = PROTO_IP_OTHER;
EntityInfo.EntityId.EntityInstanceId = PROTOCOL_ID(PROTO_TYPE_UCAST, PROTO_VENDOR_ID, PROTO_IP_OTHER);
// Register the new entity
dwRet = fRtmRegisterEntity(&EntityInfo, NULL, NULL, FALSE, &RegnProfile, &RtmRegHandle);
if (dwRet != ERROR_SUCCESS){
// Registration failed - Log an Error and Quit
return -1;
}
// Clean-up: Deregister the new entity
dwRet = fRtmDeregisterEntity(RtmRegHandle);
if (dwRet != ERROR_SUCCESS){
// Registration failed - Log an Error and Quit
return -1;
}
return 0;
}
VOID PrintAllInterfaces() VOID PrintAllInterfaces()
{ {
IP_ADAPTER_ADDRESSES *pAdaptAddr = NULL; IP_ADAPTER_ADDRESSES *pAdaptAddr = NULL;
......
...@@ -45,6 +45,16 @@ ...@@ -45,6 +45,16 @@
IPv6 RFCs and Standards Working Groups IPv6 RFCs and Standards Working Groups
http://www.ipv6now.com.au/RFC.php http://www.ipv6now.com.au/RFC.php
Routing Table Manager Version 2
http://msdn.microsoft.com/en-us/library/windows/desktop/bb404201(v=vs.85).aspx
Using Routing Table Manager Version 2
http://msdn.microsoft.com/en-us/library/windows/desktop/aa382335(v=vs.85).aspx
This section contains sample code that can be used when developing
clients such as routing protocols.
*/ */
#ifndef __CYGIFNET_H__ #ifndef __CYGIFNET_H__
......
...@@ -319,6 +319,13 @@ kernel_interface_channel(const char *ifname, int ifindex) ...@@ -319,6 +319,13 @@ kernel_interface_channel(const char *ifname, int ifindex)
return -1; return -1;
} }
static void
clear_kernel_socket_event()
{
int ch;
while (read(kernel_pipe_handles[0], &ch, 1) > 0);
}
/* /*
* RTF_REJECT * RTF_REJECT
* *
...@@ -357,7 +364,9 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -357,7 +364,9 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
unsigned int newmetric) unsigned int newmetric)
{ {
int rc, ipv4; int rc, ipv4;
struct sockaddr destination, gateway; struct sockaddr_in ipv4_destnation={0}, ipv4_gateway={0};
struct sockaddr_in6 ipv6_destnation={0}, ipv6_gateway={0};
struct sockaddr *destination, *gateway;
int route_ifindex; int route_ifindex;
int prefix_len; int prefix_len;
...@@ -368,12 +377,16 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -368,12 +377,16 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
return -1; return -1;
} }
ipv4 = 1; ipv4 = 1;
destination = (struct sockaddr*)&ipv4_destnation;
gateway = (struct sockaddr*)&ipv4_gateway;
} else { } else {
if(v4mapped(gate)) { if(v4mapped(gate)) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
ipv4 = 0; ipv4 = 0;
destination = (struct sockaddr*)&ipv6_destnation;
gateway = (struct sockaddr*)&ipv6_gateway;
} }
if(operation == ROUTE_MODIFY && newmetric == metric && if(operation == ROUTE_MODIFY && newmetric == metric &&
...@@ -405,19 +418,16 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -405,19 +418,16 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
if(kernel_socket < 0) kernel_setup_socket(1); if(kernel_socket < 0) kernel_setup_socket(1);
memset(&destination, 0, sizeof(destination));
memset(&gateway, 0, sizeof(gateway));
route_ifindex = ifindex; route_ifindex = ifindex;
prefix_len = ipv4 ? plen - 96 : plen; prefix_len = ipv4 ? plen - 96 : plen;
if(metric == KERNEL_INFINITY) { if(metric == KERNEL_INFINITY) {
/* RTF_BLACKHOLE; */ /* It means this route has property: RTF_BLACKHOLE */
/* ==> Set gateway to an unused ip address in the Windows */
if (ifindex_blackhole < 0) { if (ifindex_blackhole < 0) {
ifindex_blackhole = cyginet_blackhole_index(&blackhole_addr6, /* ifindex_blackhole = cyginet_blackhole_index(&blackhole_addr6, */
blackhole_addr[0][0]+12 /* blackhole_addr[0][0]+12 */
); /* ); */
ifindex_blackhole = 1;
if(ifindex_blackhole <= 0) if(ifindex_blackhole <= 0)
return -1; return -1;
} }
...@@ -425,13 +435,13 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -425,13 +435,13 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
} }
#define PUSHADDR(dst, src) \ #define PUSHADDR(dst, src) \
do { struct sockaddr_in *sin = (struct sockaddr_in*)(&(dst)); \ do { struct sockaddr_in *sin = (struct sockaddr_in*)(dst); \
sin->sin_family = AF_INET; \ sin->sin_family = AF_INET; \
memcpy(&sin->sin_addr, (src) + 12, 4); \ memcpy(&sin->sin_addr, (src) + 12, 4); \
} while (0) } while (0)
#define PUSHADDR6(dst, src) \ #define PUSHADDR6(dst, src) \
do { struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)(&(dst)); \ do { struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)(dst); \
sin6->sin6_family = AF_INET6; \ sin6->sin6_family = AF_INET6; \
memcpy(&sin6->sin6_addr, (src), 16); \ memcpy(&sin6->sin6_addr, (src), 16); \
if(IN6_IS_ADDR_LINKLOCAL (&sin6->sin6_addr)) \ if(IN6_IS_ADDR_LINKLOCAL (&sin6->sin6_addr)) \
...@@ -458,25 +468,25 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -458,25 +468,25 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
/* What if route_ifindex == 0 */ /* What if route_ifindex == 0 */
switch(operation) { switch(operation) {
case ROUTE_FLUSH: case ROUTE_FLUSH:
rc = cyginet_delete_route_entry(&destination, rc = cyginet_delete_route_entry(destination,
prefix_len, prefix_len,
&gateway, gateway,
route_ifindex, route_ifindex,
metric metric
); );
break; break;
case ROUTE_ADD: case ROUTE_ADD:
rc = cyginet_add_route_entry(&destination, rc = cyginet_add_route_entry(destination,
prefix_len, prefix_len,
&gateway, gateway,
route_ifindex, route_ifindex,
metric metric
); );
break; break;
case ROUTE_MODIFY: case ROUTE_MODIFY:
rc = cyginet_update_route_entry(&destination, rc = cyginet_update_route_entry(destination,
prefix_len, prefix_len,
&gateway, gateway,
route_ifindex, route_ifindex,
metric metric
); );
...@@ -488,8 +498,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -488,8 +498,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
/* Monitor thread will write data to kernel pipe when any change /* Monitor thread will write data to kernel pipe when any change
in the route table is happened. Here it's babeld itself to in the route table is happened. Here it's babeld itself to
change the route table, so kernel pipe need to be clean. */ change the route table, so kernel pipe need to be clean. */
/* int ch; */ clear_kernel_socket_event();
/* while (read(kernel_pipe_handles[0], &ch, 1) > 0); */
return rc; return rc;
} }
...@@ -614,8 +623,8 @@ kernel_routes(struct kernel_route *routes, int maxroutes) ...@@ -614,8 +623,8 @@ kernel_routes(struct kernel_route *routes, int maxroutes)
return count; return count;
} }
/* Note: ifname returned by getifaddrs maybe includes a suffix number, /* Note: ifname returned by getifaddrs maybe includes a suffix number
it looks like: in the Cygwin, it looks like:
{C05BAB6E-B82D-4C4D-AF07-EFF7C45C5DB0}_1 {C05BAB6E-B82D-4C4D-AF07-EFF7C45C5DB0}_1
{C05BAB6E-B82D-4C4D-AF07-EFF7C45C5DB0}_2 {C05BAB6E-B82D-4C4D-AF07-EFF7C45C5DB0}_2
...@@ -661,7 +670,7 @@ kernel_addresses(char *ifname, int ifindex, int ll, ...@@ -661,7 +670,7 @@ kernel_addresses(char *ifname, int ifindex, int ll,
routes[i].metric = 0; routes[i].metric = 0;
routes[i].ifindex = ifindex; routes[i].ifindex = ifindex;
routes[i].proto = RTPROT_BABEL_LOCAL; routes[i].proto = RTPROT_BABEL_LOCAL;
memcpy(routes[i].gw, routes[i].prefix, 16); memset(routes[i].gw, 0, 16);
i++; i++;
} else if(ifap->ifa_addr->sa_family == AF_INET) { } else if(ifap->ifa_addr->sa_family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in*)ifap->ifa_addr; struct sockaddr_in *sin = (struct sockaddr_in*)ifap->ifa_addr;
...@@ -677,7 +686,7 @@ kernel_addresses(char *ifname, int ifindex, int ll, ...@@ -677,7 +686,7 @@ kernel_addresses(char *ifname, int ifindex, int ll,
routes[i].metric = 0; routes[i].metric = 0;
routes[i].ifindex = ifindex; routes[i].ifindex = ifindex;
routes[i].proto = RTPROT_BABEL_LOCAL; routes[i].proto = RTPROT_BABEL_LOCAL;
memcpy(routes[i].gw, routes[i].prefix, 16); memset(routes[i].gw, 0, 16);
i++; i++;
} }
next: next:
...@@ -695,7 +704,9 @@ kernel_callback(int (*fn)(int, void*), void *closure) ...@@ -695,7 +704,9 @@ kernel_callback(int (*fn)(int, void*), void *closure)
/* In the Windows, we can't get the exact changed route, but the /* In the Windows, we can't get the exact changed route, but the
route table is really changed. */ route table is really changed. */
kdebugf("Kernel table changed."); kdebugf("Kernel table changed.\n");
clear_kernel_socket_event();
return fn(~0, closure); return fn(~0, closure);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment