Commit 791bc592 authored by Jondy Zhao's avatar Jondy Zhao

Use IN6ADDR_ANY as ipv6 blackhole gateway instead IN6ADDR_LOOPBACK.

parent 582eb114
...@@ -196,3 +196,6 @@ Notes ...@@ -196,3 +196,6 @@ Notes
format to specify interface index in the link local address: format to specify interface index in the link local address:
fe80::2ff:38ff:fed8:7d97%11 fe80::2ff:38ff:fed8:7d97%11
10. For ipv4, blackhole route doesn't work now. I can't find a simple
way to do it in the Windows.
\ No newline at end of file
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <wchar.h> #include <wchar.h>
#include <assert.h>
#define INSIDE_BABELD_CYGINET #define INSIDE_BABELD_CYGINET
#include "cyginet.h" #include "cyginet.h"
...@@ -861,7 +862,6 @@ cyginet_blackhole_index(struct in6_addr* addr6, char * addr) ...@@ -861,7 +862,6 @@ cyginet_blackhole_index(struct in6_addr* addr6, char * addr)
} }
FREE(pAdaptAddr); FREE(pAdaptAddr);
} }
return dwReturn; return dwReturn;
} }
...@@ -958,8 +958,7 @@ libwinet_edit_route_entry(const struct sockaddr *dest, ...@@ -958,8 +958,7 @@ libwinet_edit_route_entry(const struct sockaddr *dest,
/* Add ipv4 route before Windows Vista, use IP Helper API */ /* Add ipv4 route before Windows Vista, use IP Helper API */
else { else {
MIB_IPFORWARDROW Row; MIB_IPFORWARDROW Row;
unsigned long Res; unsigned long Res;
struct in_addr mask; struct in_addr mask;
plen2mask(plen, &mask); plen2mask(plen, &mask);
...@@ -972,12 +971,12 @@ libwinet_edit_route_entry(const struct sockaddr *dest, ...@@ -972,12 +971,12 @@ libwinet_edit_route_entry(const struct sockaddr *dest,
Row.dwForwardMask = mask.S_un.S_addr; Row.dwForwardMask = mask.S_un.S_addr;
/* /*
* MIB_IPROUTE_TYPE_DIRECT <==> dwForwardNextHop == dwForwardDest * MIB_IPROUTE_TYPE_DIRECT <==> dwForwardNextHop == dwForwardDest
* MIB_IPROUTE_TYPE_LOCAL <==> dwForwardNextHop in local interfaces
* MIB_IPROUTE_TYPE_INDIRECT all the others * MIB_IPROUTE_TYPE_INDIRECT all the others
* Refer to:
* http://technet.microsoft.com/en-us/library/dd379495(v=ws.10).aspx
*/ */
Row.dwForwardType = Row.dwForwardNextHop == Row.dwForwardDest ? \ Row.dwForwardType = (Row.dwForwardNextHop == Row.dwForwardDest) ?
MIB_IPROUTE_TYPE_DIRECT : MIB_IPROUTE_TYPE_INDIRECT; MIB_IPROUTE_TYPE_DIRECT : MIB_IPROUTE_TYPE_INDIRECT;
Row.dwForwardType = MIB_IPROUTE_TYPE_INDIRECT;
Row.dwForwardProto = MIB_IPPROTO_NETMGMT; Row.dwForwardProto = MIB_IPPROTO_NETMGMT;
Row.dwForwardAge = 0; Row.dwForwardAge = 0;
Row.dwForwardNextHopAS = 0; Row.dwForwardNextHopAS = 0;
...@@ -1004,7 +1003,7 @@ libwinet_edit_route_entry(const struct sockaddr *dest, ...@@ -1004,7 +1003,7 @@ libwinet_edit_route_entry(const struct sockaddr *dest,
return -1; return -1;
} }
#if 0 /* Use route command */ #if 0 /* Use route command */
else { else {
/* route ADD dest MASK mask gate METRIC n IF index */ /* route ADD dest MASK mask gate METRIC n IF index */
/* route CHANGE dest MASK mask gate METRIC n IF index */ /* route CHANGE dest MASK mask gate METRIC n IF index */
...@@ -1533,7 +1532,6 @@ cyginet_dump_route_table(struct cyginet_route *routes, int maxroutes) ...@@ -1533,7 +1532,6 @@ cyginet_dump_route_table(struct cyginet_route *routes, int maxroutes)
proute -> metric = pRow -> dwForwardMetric1; proute -> metric = pRow -> dwForwardMetric1;
proute -> proto = pRow -> dwForwardProto; proute -> proto = pRow -> dwForwardProto;
proute -> plen = mask2len((unsigned char*)&(pRow -> dwForwardMask), 4); proute -> plen = mask2len((unsigned char*)&(pRow -> dwForwardMask), 4);
/* Note that the IPv4 addresses returned in GetIpForwardTable /* Note that the IPv4 addresses returned in GetIpForwardTable
* entries are in network byte order * entries are in network byte order
*/ */
...@@ -1629,7 +1627,7 @@ cyginet_read_route_socket(void *buffer, size_t size) ...@@ -1629,7 +1627,7 @@ cyginet_read_route_socket(void *buffer, size_t size)
return 0; return 0;
} }
int int
cyginet_refresh_interface_table() cyginet_refresh_interface_table()
{ {
return libwinet_refresh_interface_map_table(); return libwinet_refresh_interface_map_table();
...@@ -1685,37 +1683,102 @@ cyginet_ifname(const char * guidname) ...@@ -1685,37 +1683,102 @@ cyginet_ifname(const char * guidname)
return NULL; return NULL;
} }
int static int
cyginet_add_ipentry(int ifindex, struct sockaddr *addr) libwinet_edit_netentry(int operation,
int ifindex,
struct sockaddr *addr,
int type)
{ {
MIB_IPNETROW row; MIB_IPNETROW row = {0};
PLIBWINET_INTERFACE_MAP_TABLE p; DWORD dwRetVal = NO_ERROR;
if (!g_interface_map_table) DWORD dest = (((SOCKADDR_IN*)addr) -> sin_addr).S_un.S_addr;
libwinet_refresh_interface_map_table();
if (operation == 1) {
p = g_interface_map_table; /* We need send an arp request to get mac address */
while (p) { /* TO DO: src should be address assigned to ifindex */
if (p -> IfIndex == ifindex) { DWORD src = 0;
row.dwPhysAddrLen = p -> PhysicalAddressLength; if (type != MIB_IPNET_TYPE_INVALID) {
if (row.dwPhysAddrLen > MAXLEN_PHYSADDR) dwRetVal = SendARP(dest, src, (PULONG)row.bPhysAddr, &row.dwPhysAddrLen);
if (dwRetVal != NO_ERROR)
return -1; return -1;
memcpy(row.bPhysAddr, p -> PhysicalAddress, row.dwPhysAddrLen);
break;
} }
p = p -> next; row.dwIndex = ifindex;
row.dwAddr = dest;
row.dwType = MIB_IPNET_TYPE_DYNAMIC;
dwRetVal = CreateIpNetEntry ( &row );
} }
if (row.dwPhysAddrLen) { else if (operation == 0) {
row.dwIndex = ifindex; row.dwIndex = ifindex;
row.dwAddr = (((SOCKADDR_IN*)addr) -> sin_addr).S_un.S_addr; row.dwAddr = dest;
row.dwType = MIB_IPNET_TYPE_DYNAMIC; dwRetVal = DeleteIpNetEntry(&row);
return CreateIpNetEntry ( &row );
} }
return -1; else assert(0);
return 0 ? dwRetVal == NO_ERROR : dwRetVal;
} }
/* The following functions are reserved. */ /* The following functions are reserved. */
#if 0 #if 0
int
cyginet_search_netentry(int add, int ifindex, struct sockaddr *addr)
{
MIB_IPNETROW row = {0};
MIB_IPNETTABLE * ptable;
MIB_IPNETROW * prow = NULL;
DWORD dwSize;
DWORD dwRetVal = NO_ERROR;
DWORD dest = (((SOCKADDR_IN*)addr) -> sin_addr).S_un.S_addr;
DWORD n;
ptable = (MIB_IPNETTABLE *) MALLOC(sizeof (MIB_IPNETTABLE));
if (ptable == NULL)
return -1;
/* Make an initial call to get the necessary size into dwSize */
dwSize = sizeof (MIB_IPNETTABLE);
if (GetIpNetTable(ptable, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) {
FREE(ptable);
ptable = (MIB_IPNETTABLE *) MALLOC(dwSize);
if (ptable == NULL)
return -1;
}
/* Make a second call to get the actual data we want. */
if ((dwRetVal = GetIpNetTable(ptable, &dwSize, FALSE)) != NO_ERROR) {
FREE(ptable);
return -1;
}
/* Search entry in the table */
prow = ptable -> table;
for (n = 0; n < ptable -> dwNumEntries; n++, prow++)
if ( prow -> dwAddr == dest)
break;
if (add) {
if (!prow) {
/* We need send an arp request to get mac address */
/* TO DO: src should be address assigned to ifindex */
DWORD src = 0;
dwRetVal = SendARP(dest, src, (PULONG)row.bPhysAddr, &row.dwPhysAddrLen);
if (dwRetVal != NO_ERROR) {
FREE(ptable);
return -1;
}
row.dwIndex = ifindex;
row.dwAddr = dest;
row.dwType = MIB_IPNET_TYPE_DYNAMIC;
dwRetVal = CreateIpNetEntry ( &row );
}
}
else {
if (prow)
dwRetVal = DeleteIpNetEntry(prow);
}
FREE(ptable);
return 0 ? dwRetVal == NO_ERROR : dwRetVal;
}
char * char *
cyginet_ipv4_index2ifname(int ifindex) cyginet_ipv4_index2ifname(int ifindex)
{ {
...@@ -2432,52 +2495,6 @@ DWORD GetConnectedNetworks() ...@@ -2432,52 +2495,6 @@ 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;
...@@ -2755,6 +2772,15 @@ runTestCases() ...@@ -2755,6 +2772,15 @@ runTestCases()
} }
} }
printf("\n\nTest cyginet_dump_route_table:\n\n");
do {
#define MAX_ROUTES 120
struct cyginet_route routes[MAX_ROUTES];
memset(routes, 0, sizeof(struct cyginet_route) * MAX_ROUTES);
int n = cyginet_dump_route_table(routes, MAX_ROUTES);
printf("Get route numbers: %d\n", n);
} while (0);
printf("\n\nTest libwinet_monitor_route_thread_proc:\n\n"); printf("\n\nTest libwinet_monitor_route_thread_proc:\n\n");
do { do {
int mypipes[2]; int mypipes[2];
...@@ -2923,6 +2949,7 @@ runTestCases() ...@@ -2923,6 +2949,7 @@ runTestCases()
printf("Delete Ipv6 route return %d\n", n); printf("Delete Ipv6 route return %d\n", n);
} while(0); } while(0);
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[])
...@@ -2976,6 +3003,27 @@ int main(int argc, char* argv[]) ...@@ -2976,6 +3003,27 @@ int main(int argc, char* argv[])
printf("libwinet_refresh_interface_map_table failed\n"); printf("libwinet_refresh_interface_map_table failed\n");
} }
printf("\n\nTest ipv4 blackhole route:\n\n");
do {
SOCKADDR_IN dest = { AF_INET, 0, {{{ INADDR_ANY }}}, {0} };
SOCKADDR_IN gate = { AF_INET, 0, {{{ INADDR_ANY }}}, {0} };
int ifindex = 1;
int n;
if (inet_pton(AF_INET, "123.58.180.0", &dest.sin_addr) != 1)
break;
if (inet_pton(AF_INET, "127.0.0.1", &gate.sin_addr) != 1)
break;
n = libwinet_edit_route_entry((struct sockaddr*)&dest,
24,
(struct sockaddr*)&gate,
ifindex,
1,
RTM_ADD
);
printf("Add blackhole route return: %d", n);
} while(0);
runTestCases(); runTestCases();
/* printf("\n\nTest libwinet_init_ipv6_interface:\n\n"); */ /* printf("\n\nTest libwinet_init_ipv6_interface:\n\n"); */
......
...@@ -90,6 +90,10 @@ ...@@ -90,6 +90,10 @@
IPv6 Addresses, it explains the relation between link-local address IPv6 Addresses, it explains the relation between link-local address
and interface id and interface id
http://msdn.microsoft.com/en-us/library/aa921042.aspx http://msdn.microsoft.com/en-us/library/aa921042.aspx
TCP/IP (v4 and v6) Technical Reference, it shows ipv4 and ipv6 how
to work in the windows. (Recommended)
http://technet.microsoft.com/en-us/library/dd379473(v=ws.10).aspx
*/ */
#ifndef __CYGIFNET_H__ #ifndef __CYGIFNET_H__
...@@ -220,8 +224,6 @@ int cyginet_delete_route_entry(const struct sockaddr *, unsigned short, ...@@ -220,8 +224,6 @@ int cyginet_delete_route_entry(const struct sockaddr *, unsigned short,
int cyginet_update_route_entry(const struct sockaddr *, unsigned short, int cyginet_update_route_entry(const struct sockaddr *, unsigned short,
const struct sockaddr *, int , unsigned int); const struct sockaddr *, int , unsigned int);
int cyginet_add_ipentry(int, struct sockaddr*);
char * cyginet_ifname(const char *); char * cyginet_ifname(const char *);
char * cyginet_guidname(const char *); char * cyginet_guidname(const char *);
int cyginet_refresh_interface_table(); int cyginet_refresh_interface_table();
......
...@@ -116,7 +116,7 @@ static int kernel_pipe_handles[2]; ...@@ -116,7 +116,7 @@ static int kernel_pipe_handles[2];
* *
* For ipv6, no global options to enable forwarding, but for each * For ipv6, no global options to enable forwarding, but for each
* interface respectively. * interface respectively.
* *
* Option 2: * Option 2:
* *
* ICMPV6CTL_REDIRACCEPT * ICMPV6CTL_REDIRACCEPT
...@@ -140,7 +140,7 @@ static int kernel_pipe_handles[2]; ...@@ -140,7 +140,7 @@ static int kernel_pipe_handles[2];
* Refer to: * Refer to:
* http://technet.microsoft.com/en-us/library/cc766102(v=ws.10).aspx * http://technet.microsoft.com/en-us/library/cc766102(v=ws.10).aspx
* http://msdn.microsoft.com/en-us/library/aa915651.aspx * http://msdn.microsoft.com/en-us/library/aa915651.aspx
* *
* Notice the msdn page of Windows CE, value is "EnableICMPRedirects", * Notice the msdn page of Windows CE, value is "EnableICMPRedirects",
* it's plural. But I'd rather use singluar form "EnableICMPRedirect". * it's plural. But I'd rather use singluar form "EnableICMPRedirect".
* *
...@@ -158,7 +158,7 @@ kernel_setup(int setup) ...@@ -158,7 +158,7 @@ kernel_setup(int setup)
return -1; return -1;
/* We don't disable ICMPv6 redirect in the Windows */ /* We don't disable ICMPv6 redirect in the Windows */
/* /*
if ((rc = cyginet_set_icmp6_redirect_accept(0)) == -1) { if ((rc = cyginet_set_icmp6_redirect_accept(0)) == -1) {
fprintf(stderr, "Cannot disable ICMPv6 redirect.\n"); fprintf(stderr, "Cannot disable ICMPv6 redirect.\n");
return -1; return -1;
...@@ -171,7 +171,7 @@ kernel_setup(int setup) ...@@ -171,7 +171,7 @@ kernel_setup(int setup)
); );
return -1; return -1;
} }
*/ */
FOR_ALL_INTERFACES(ifp) { FOR_ALL_INTERFACES(ifp) {
if (cyginet_set_interface_forwards(ifp->name, 1) == -1) { if (cyginet_set_interface_forwards(ifp->name, 1) == -1) {
fprintf(stderr, "Cannot enable IPv6 forwarding.\n"); fprintf(stderr, "Cannot enable IPv6 forwarding.\n");
...@@ -305,8 +305,10 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -305,8 +305,10 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
const unsigned char *newgate, int newifindex, const unsigned char *newgate, int newifindex,
unsigned int newmetric) unsigned int newmetric)
{ {
char blackhole_addr6[1][1][16] = {{{0}}}; char local6[1][1][16] = {{IN6ADDR_ANY_INIT}};
char blackhole_addr[1][1][16] = {{{0}}}; char local4[1][1][16] =
{{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x01 }}};
int rc, ipv4; int rc, ipv4;
int route_ifindex; int route_ifindex;
int prefix_len; int prefix_len;
...@@ -353,8 +355,6 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -353,8 +355,6 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
IN6_IS_ADDR_UNSPECIFIED(newgate)) IN6_IS_ADDR_UNSPECIFIED(newgate))
return 0; return 0;
kdebugf("kernel_route: %s %s/%d metric %d dev %d nexthop %s\n", kdebugf("kernel_route: %s %s/%d metric %d dev %d nexthop %s\n",
operation == ROUTE_ADD ? "add" : operation == ROUTE_ADD ? "add" :
operation == ROUTE_FLUSH ? "flush" : "change", operation == ROUTE_FLUSH ? "flush" : "change",
...@@ -390,27 +390,30 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -390,27 +390,30 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
if(ipv4) { if(ipv4) {
PUSHADDR(destination, dest); PUSHADDR(destination, dest);
if (metric == KERNEL_INFINITY) if (metric == KERNEL_INFINITY) {
PUSHADDR(gateway, **blackhole_addr); /* blackhole route, now it doesn't work */
kdebugf("Error: ipv4 blackhole route doesn't work.\n");
return -1;
assert (operation != ROUTE_MODIFY);
PUSHADDR(gateway, **local4);
}
else if(plen == 128 && memcmp(dest+12, gate+12, 4) == 0) { else if(plen == 128 && memcmp(dest+12, gate+12, 4) == 0) {
/* It means add arp record, add dest ip to this interface */ assert (operation != ROUTE_MODIFY);
if (cyginet_add_ipentry(ifindex, PUSHADDR(gateway, gate); /* MIB_IPROUTE_TYPE_DIRECT */
(struct sockaddr*)&destination) != 0)
return -1;
} }
else else
PUSHADDR(gateway, gate); PUSHADDR(gateway, gate); /* MIB_IPROUTE_TYPE_INDIRECT */
} else { } else {
PUSHADDR6(destination, dest); PUSHADDR6(destination, dest);
if (metric == KERNEL_INFINITY) if (metric == KERNEL_INFINITY)
PUSHADDR6(gateway, **blackhole_addr6); PUSHADDR6(gateway, **local6);
else else
PUSHADDR6(gateway, gate); PUSHADDR6(gateway, gate);
} }
#undef PUSHADDR #undef PUSHADDR
#undef PUSHADDR6 #undef PUSHADDR6
/* 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((struct sockaddr*)&destination, rc = cyginet_delete_route_entry((struct sockaddr*)&destination,
...@@ -465,7 +468,7 @@ print_kernel_route(int add, struct kernel_route *route) ...@@ -465,7 +468,7 @@ print_kernel_route(int add, struct kernel_route *route)
ifname ? ifname : "unk", ifname ? ifname : "unk",
route->ifindex route->ifindex
); );
} }
static int static int
parse_kernel_route(struct cyginet_route *src, struct kernel_route *route) parse_kernel_route(struct cyginet_route *src, struct kernel_route *route)
...@@ -619,7 +622,7 @@ kernel_addresses(char *ifname, int ifindex, int ll, ...@@ -619,7 +622,7 @@ kernel_addresses(char *ifname, int ifindex, int ll,
memcpy(routes[i].prefix, v4prefix, 12); memcpy(routes[i].prefix, v4prefix, 12);
memcpy(routes[i].prefix + 12, &sin->sin_addr, 4); memcpy(routes[i].prefix + 12, &sin->sin_addr, 4);
routes[i].plen = 128; routes[i].plen = 128;
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;
memset(routes[i].gw, 0, 16); memset(routes[i].gw, 0, 16);
...@@ -643,7 +646,7 @@ kernel_callback(int (*fn)(int, void*), void *closure) ...@@ -643,7 +646,7 @@ kernel_callback(int (*fn)(int, void*), void *closure)
kdebugf("Kernel table changed.\n"); kdebugf("Kernel table changed.\n");
cyginet_refresh_interface_table(); cyginet_refresh_interface_table();
clear_kernel_socket_event(); 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