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
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
=====
......@@ -84,7 +89,6 @@ Notes
$ route add 100.28.0.0 mask 255.255.0.0 192.168.128.100 if 5
Destination network 100.28.0.0/16 will be unreachable.
9. IN6_LINKLOCAL_IFINDEX && SET_IN6_LINKLOCAL_IFINDEX, do both of them
work in the Windows?
\ No newline at end of file
work in the Windows?
......@@ -32,6 +32,9 @@
#include <iphlpapi.h>
#include <wlanapi.h>
#include <rtmv2.h>
#include <nldef.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
......@@ -56,6 +59,7 @@ static HRESULT (WINAPI *ws_guidfromstring)(LPCTSTR psz, LPGUID pguid) = NULL;
static HANDLE event_notify_monitor_thread = WSA_INVALID_EVENT;
static PLIBWINET_INTERFACE_MAP_TABLE interface_map_table = NULL;
static int libwinet_run_command(const char *);
static void
plen2mask(int n, struct in_addr *dest)
......@@ -106,6 +110,36 @@ mask2len(const unsigned char *p, const int size)
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
libwinet_free_interface_map_table()
{
......@@ -879,7 +913,6 @@ libwinet_edit_route_entry(const struct sockaddr *dest,
int cmdflag)
{
#if _WIN32_WINNT < _WIN32_WINNT_VISTA
/* Add ipv6 route before Windows Vista */
if(dest->sa_family == AF_INET6) {
const int MAX_BUFFER_SIZE = 1024;
......@@ -1102,7 +1135,20 @@ int
cyginet_set_ipv6_forwards(int value)
{
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,
"IPEnableRouter",
value,
......@@ -2075,36 +2121,6 @@ libwinet_is_wireless_device(const wchar_t *pszwAdapterName)
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,
int destLen,
SOCKADDR *localAddr,
......@@ -2332,6 +2348,52 @@ DWORD GetConnectedNetworks()
/* ------------------------------------------------------------- */
#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()
{
IP_ADAPTER_ADDRESSES *pAdaptAddr = NULL;
......
......@@ -45,6 +45,16 @@
IPv6 RFCs and Standards Working Groups
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__
......
......@@ -319,6 +319,13 @@ kernel_interface_channel(const char *ifname, int ifindex)
return -1;
}
static void
clear_kernel_socket_event()
{
int ch;
while (read(kernel_pipe_handles[0], &ch, 1) > 0);
}
/*
* RTF_REJECT
*
......@@ -357,7 +364,9 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
unsigned int newmetric)
{
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 prefix_len;
......@@ -368,12 +377,16 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
return -1;
}
ipv4 = 1;
destination = (struct sockaddr*)&ipv4_destnation;
gateway = (struct sockaddr*)&ipv4_gateway;
} else {
if(v4mapped(gate)) {
errno = EINVAL;
return -1;
}
ipv4 = 0;
destination = (struct sockaddr*)&ipv6_destnation;
gateway = (struct sockaddr*)&ipv6_gateway;
}
if(operation == ROUTE_MODIFY && newmetric == metric &&
......@@ -405,19 +418,16 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
if(kernel_socket < 0) kernel_setup_socket(1);
memset(&destination, 0, sizeof(destination));
memset(&gateway, 0, sizeof(gateway));
route_ifindex = ifindex;
prefix_len = ipv4 ? plen - 96 : plen;
if(metric == KERNEL_INFINITY) {
/* RTF_BLACKHOLE; */
/* ==> Set gateway to an unused ip address in the Windows */
/* It means this route has property: RTF_BLACKHOLE */
if (ifindex_blackhole < 0) {
ifindex_blackhole = cyginet_blackhole_index(&blackhole_addr6,
blackhole_addr[0][0]+12
);
/* ifindex_blackhole = cyginet_blackhole_index(&blackhole_addr6, */
/* blackhole_addr[0][0]+12 */
/* ); */
ifindex_blackhole = 1;
if(ifindex_blackhole <= 0)
return -1;
}
......@@ -425,13 +435,13 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
}
#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; \
memcpy(&sin->sin_addr, (src) + 12, 4); \
} while (0)
#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; \
memcpy(&sin6->sin6_addr, (src), 16); \
if(IN6_IS_ADDR_LINKLOCAL (&sin6->sin6_addr)) \
......@@ -455,28 +465,28 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
}
#undef PUSHADDR
#undef PUSHADDR6
/* What if route_ifindex == 0 */
/* What if route_ifindex == 0 */
switch(operation) {
case ROUTE_FLUSH:
rc = cyginet_delete_route_entry(&destination,
rc = cyginet_delete_route_entry(destination,
prefix_len,
&gateway,
gateway,
route_ifindex,
metric
);
break;
case ROUTE_ADD:
rc = cyginet_add_route_entry(&destination,
rc = cyginet_add_route_entry(destination,
prefix_len,
&gateway,
gateway,
route_ifindex,
metric
);
break;
case ROUTE_MODIFY:
rc = cyginet_update_route_entry(&destination,
rc = cyginet_update_route_entry(destination,
prefix_len,
&gateway,
gateway,
route_ifindex,
metric
);
......@@ -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
in the route table is happened. Here it's babeld itself to
change the route table, so kernel pipe need to be clean. */
/* int ch; */
/* while (read(kernel_pipe_handles[0], &ch, 1) > 0); */
clear_kernel_socket_event();
return rc;
}
......@@ -614,8 +623,8 @@ kernel_routes(struct kernel_route *routes, int maxroutes)
return count;
}
/* Note: ifname returned by getifaddrs maybe includes a suffix number,
it looks like:
/* Note: ifname returned by getifaddrs maybe includes a suffix number
in the Cygwin, it looks like:
{C05BAB6E-B82D-4C4D-AF07-EFF7C45C5DB0}_1
{C05BAB6E-B82D-4C4D-AF07-EFF7C45C5DB0}_2
......@@ -661,7 +670,7 @@ kernel_addresses(char *ifname, int ifindex, int ll,
routes[i].metric = 0;
routes[i].ifindex = ifindex;
routes[i].proto = RTPROT_BABEL_LOCAL;
memcpy(routes[i].gw, routes[i].prefix, 16);
memset(routes[i].gw, 0, 16);
i++;
} else if(ifap->ifa_addr->sa_family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in*)ifap->ifa_addr;
......@@ -677,7 +686,7 @@ kernel_addresses(char *ifname, int ifindex, int ll,
routes[i].metric = 0;
routes[i].ifindex = ifindex;
routes[i].proto = RTPROT_BABEL_LOCAL;
memcpy(routes[i].gw, routes[i].prefix, 16);
memset(routes[i].gw, 0, 16);
i++;
}
next:
......@@ -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
route table is really changed. */
kdebugf("Kernel table changed.");
kdebugf("Kernel table changed.\n");
clear_kernel_socket_event();
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