Commit 605674a6 authored by Jondy Zhao's avatar Jondy Zhao

Remove the trailing newline char when get ipv6 route;

Ignore ipv6 route which valid time is 0s;
Set publish=yes when add ipv6 route;
Change data type of struct cygroute prefix and gateway;
No blackhole route, it's difficult in the Windows;
Return maxroutes other than the total route entries in kernel_routes;
Add function cyginet_getifaddresses, but not used now.
parent 8d0de1c9
...@@ -490,6 +490,10 @@ libwinet_dump_ipv6_route_table(struct cyginet_route *routes, ...@@ -490,6 +490,10 @@ libwinet_dump_ipv6_route_table(struct cyginet_route *routes,
*s ++ = 0; /* Split the string */ *s ++ = 0; /* Split the string */
s ++; /* Skip space */ s ++; /* Skip space */
/* Remove the newline character at the end of line */
p = s + strlen(s) - 1;
while ( (p > s) && (*p == '\n' || *p == '\r'))
*p -- = 0;
/* The first field of route entry */ /* The first field of route entry */
if (strncmp(buffer, "Prefix", 6) == 0) { if (strncmp(buffer, "Prefix", 6) == 0) {
...@@ -518,6 +522,10 @@ libwinet_dump_ipv6_route_table(struct cyginet_route *routes, ...@@ -518,6 +522,10 @@ libwinet_dump_ipv6_route_table(struct cyginet_route *routes,
else if (strncmp(buffer, "Metric", 6) == 0) else if (strncmp(buffer, "Metric", 6) == 0)
route.metric = strtol(s, NULL, 10); route.metric = strtol(s, NULL, 10);
else if ((strncmp(buffer, "Valid Lifetime", 14) == 0) &&
(strncmp(s, "0s", 2) == 0))
ignored = 1;
/* Last field of the route entry */ /* Last field of the route entry */
else if (strncmp(buffer, "Site Prefix Length", 18) == 0) { else if (strncmp(buffer, "Site Prefix Length", 18) == 0) {
if (ignored) if (ignored)
...@@ -917,7 +925,7 @@ libwinet_edit_route_entry(const struct sockaddr *dest, ...@@ -917,7 +925,7 @@ libwinet_edit_route_entry(const struct sockaddr *dest,
const int MAX_BUFFER_SIZE = 1024; const int MAX_BUFFER_SIZE = 1024;
const char * cmdformat = "netsh interface ipv6 %s route " const char * cmdformat = "netsh interface ipv6 %s route "
"prefix=%s/%d interface=%d " "prefix=%s/%d interface=%d "
"nexthop=%s %cmetric=%d"; "nexthop=%s %s %cmetric=%d";
char cmdbuf[MAX_BUFFER_SIZE]; char cmdbuf[MAX_BUFFER_SIZE];
char sdest[INET6_ADDRSTRLEN]; char sdest[INET6_ADDRSTRLEN];
char sgate[INET6_ADDRSTRLEN]; char sgate[INET6_ADDRSTRLEN];
...@@ -945,6 +953,7 @@ libwinet_edit_route_entry(const struct sockaddr *dest, ...@@ -945,6 +953,7 @@ libwinet_edit_route_entry(const struct sockaddr *dest,
plen, plen,
ifindex, ifindex,
sgate, sgate,
cmdflag == RTM_ADD ? "publish=yes" : "",
cmdflag == RTM_DELETE ? '#' : ' ', cmdflag == RTM_DELETE ? '#' : ' ',
metric metric
) >= MAX_BUFFER_SIZE) ) >= MAX_BUFFER_SIZE)
...@@ -1452,6 +1461,96 @@ cyginet_interface_sdl(struct sockaddr_dl *sdl, char *ifname) ...@@ -1452,6 +1461,96 @@ cyginet_interface_sdl(struct sockaddr_dl *sdl, char *ifname)
return dwReturn; return dwReturn;
} }
int
cyginet_getifaddresses(char *ifname,
struct cyginet_route *routes,
int maxroutes
)
{
IP_ADAPTER_ADDRESSES *pAdaptAddr = NULL;
IP_ADAPTER_ADDRESSES *pTmpAdaptAddr = NULL;
DWORD dwRet = 0;
DWORD dwSize = 0x10000;
DWORD dwReturn = 0;
size_t size;
WCHAR *friendlyname = 0;
if (ifname) {
size = MultiByteToWideChar(CP_ACP,
0,
ifname,
-1,
NULL,
0
);
friendlyname = MALLOC(size * sizeof(WCHAR));
if (!friendlyname)
return -1;
if (MultiByteToWideChar(CP_ACP,
0,
ifname,
-1,
friendlyname,
size
) == 0) {
FREE(friendlyname);
return -1;
}
}
dwRet = GetAdaptersAddresses(AF_UNSPEC,
GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \
| GAA_FLAG_SKIP_DNS_SERVER,
NULL,
pAdaptAddr,
&dwSize
);
if (ERROR_BUFFER_OVERFLOW == dwRet) {
FREE(pAdaptAddr);
if (NULL == (pAdaptAddr = (IP_ADAPTER_ADDRESSES*)MALLOC(dwSize)))
return -1;
dwRet = GetAdaptersAddresses(AF_UNSPEC,
GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \
| GAA_FLAG_SKIP_DNS_SERVER,
NULL,
pAdaptAddr,
&dwSize
);
}
if (NO_ERROR == dwRet) {
pTmpAdaptAddr = pAdaptAddr;
while (pTmpAdaptAddr) {
if ((pTmpAdaptAddr -> OperStatus == IfOperStatusUp) &&
((ifname == NULL) ||
(wcscmp(pTmpAdaptAddr -> FriendlyName, friendlyname) == 0))) {
PIP_ADAPTER_UNICAST_ADDRESS p = pTmpAdaptAddr -> FirstUnicastAddress;
while (p) {
if (p -> ValidLifetime) {
SOCKET_ADDRESS *s = &(p -> Address);
memcpy(&routes[dwReturn].prefix,
s -> lpSockaddr,
s -> iSockaddrLength
);
dwReturn += 1;
if (dwReturn == maxroutes)
break;
}
p = p -> Next;
}
if (ifname)
break;
}
pTmpAdaptAddr = pTmpAdaptAddr->Next;
}
FREE(pAdaptAddr);
}
return dwReturn;
}
/* In the windows, loopback interface index is alawys 1 */ /* In the windows, loopback interface index is alawys 1 */
int int
cyginet_loopback_index(int family) cyginet_loopback_index(int family)
...@@ -3002,7 +3101,7 @@ int main(int argc, char* argv[]) ...@@ -3002,7 +3101,7 @@ int main(int argc, char* argv[])
else else
printf("libwinet_refresh_interface_map_table failed\n"); printf("libwinet_refresh_interface_map_table failed\n");
} }
/*
printf("\n\nTest ipv4 blackhole route:\n\n"); printf("\n\nTest ipv4 blackhole route:\n\n");
do { do {
SOCKADDR_IN dest = { AF_INET, 0, {{{ INADDR_ANY }}}, {0} }; SOCKADDR_IN dest = { AF_INET, 0, {{{ INADDR_ANY }}}, {0} };
...@@ -3023,8 +3122,20 @@ int main(int argc, char* argv[]) ...@@ -3023,8 +3122,20 @@ int main(int argc, char* argv[])
); );
printf("Add blackhole route return: %d", n); printf("Add blackhole route return: %d", n);
} while(0); } while(0);
*/
printf("\n\nTest myown cyg_getifaddress:\n\n");
do {
struct cyginet_route ptable[255];
int rc;
rc = cyginet_getifaddresses(NULL, ptable, 255);
printf("return %d\n", rc);
while (rc--) {
}
} while(0);
runTestCases(); // runTestCases();
/* printf("\n\nTest libwinet_init_ipv6_interface:\n\n"); */ /* printf("\n\nTest libwinet_init_ipv6_interface:\n\n"); */
/* libwinet_init_ipv6_interface(); */ /* libwinet_init_ipv6_interface(); */
......
...@@ -126,12 +126,12 @@ struct sockaddr_dl { ...@@ -126,12 +126,12 @@ struct sockaddr_dl {
}; };
struct cyginet_route { struct cyginet_route {
struct sockaddr prefix; struct sockaddr_storage prefix;
int plen; int plen;
int metric; int metric;
unsigned int ifindex; unsigned int ifindex;
int proto; int proto;
struct sockaddr gateway; struct sockaddr_storage gateway;
}; };
#if defined(INSIDE_BABELD_CYGINET) #if defined(INSIDE_BABELD_CYGINET)
...@@ -141,8 +141,10 @@ struct ifaddrs { ...@@ -141,8 +141,10 @@ struct ifaddrs {
char *ifa_name; char *ifa_name;
unsigned int ifa_flags; unsigned int ifa_flags;
struct sockaddr *ifa_addr; struct sockaddr *ifa_addr;
union {
struct sockaddr *ifa_netmask; struct sockaddr *ifa_netmask;
struct sockaddr *ifa_dstaddr; struct sockaddr *ifa_dstaddr;
};
void *ifa_data; void *ifa_data;
}; };
...@@ -227,4 +229,6 @@ int cyginet_update_route_entry(const struct sockaddr *, unsigned short, ...@@ -227,4 +229,6 @@ int cyginet_update_route_entry(const struct sockaddr *, unsigned short,
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();
int cyginet_getifaddresses(char *, struct cyginet_route *, int);
#endif /* __CYGIFNET_H__ */ #endif /* __CYGIFNET_H__ */
...@@ -362,7 +362,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -362,7 +362,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
route_ifindex = ifindex; route_ifindex = ifindex;
prefix_len = ipv4 ? plen - 96 : plen; prefix_len = ipv4 ? plen - 96 : plen;
if(metric == KERNEL_INFINITY) { if(0 && metric == KERNEL_INFINITY) {
/* It means this route has property: RTF_BLACKHOLE */ /* It means this route has property: RTF_BLACKHOLE */
if(ifindex_lo < 0) { if(ifindex_lo < 0) {
ifindex_lo = cyginet_loopback_index(AF_UNSPEC); ifindex_lo = cyginet_loopback_index(AF_UNSPEC);
...@@ -386,7 +386,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -386,7 +386,7 @@ 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 (0 && metric == KERNEL_INFINITY) {
/* blackhole route, now it doesn't work */ /* blackhole route, now it doesn't work */
kdebugf("Error: ipv4 blackhole route doesn't work.\n"); kdebugf("Error: ipv4 blackhole route doesn't work.\n");
return -1; return -1;
...@@ -402,7 +402,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -402,7 +402,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
} else { } else {
PUSHADDR6(destination, dest); PUSHADDR6(destination, dest);
if (metric == KERNEL_INFINITY) if (0 && metric == KERNEL_INFINITY)
PUSHADDR6(gateway, **local6); PUSHADDR6(gateway, **local6);
else else
PUSHADDR6(gateway, gate); PUSHADDR6(gateway, gate);
...@@ -483,7 +483,7 @@ parse_kernel_route(struct cyginet_route *src, struct kernel_route *route) ...@@ -483,7 +483,7 @@ parse_kernel_route(struct cyginet_route *src, struct kernel_route *route)
route -> proto = src -> proto; route -> proto = src -> proto;
route -> ifindex = src -> ifindex; route -> ifindex = src -> ifindex;
sa = &(src -> prefix); sa = (struct sockaddr*)&(src -> prefix);
if(sa->sa_family == AF_INET6) { if(sa->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
memcpy(route->prefix, &sin6->sin6_addr, 16); memcpy(route->prefix, &sin6->sin6_addr, 16);
...@@ -504,7 +504,7 @@ parse_kernel_route(struct cyginet_route *src, struct kernel_route *route) ...@@ -504,7 +504,7 @@ parse_kernel_route(struct cyginet_route *src, struct kernel_route *route)
} }
/* Gateway */ /* Gateway */
sa = &(src -> gateway); sa = (struct sockaddr*)&(src -> gateway);
if(sa->sa_family == AF_INET6) { if(sa->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
memcpy(route->gw, &sin6->sin6_addr, 16); memcpy(route->gw, &sin6->sin6_addr, 16);
...@@ -545,7 +545,8 @@ kernel_routes(struct kernel_route *routes, int maxroutes) ...@@ -545,7 +545,8 @@ kernel_routes(struct kernel_route *routes, int maxroutes)
if (rc < 0) { if (rc < 0) {
free(ptable); free(ptable);
return -1; return -1;
} } else if (maxroutes < rc)
return maxroutes;
for (i = 0, count = 0; i < rc; i++) { for (i = 0, count = 0; i < rc; i++) {
...@@ -559,6 +560,7 @@ kernel_routes(struct kernel_route *routes, int maxroutes) ...@@ -559,6 +560,7 @@ kernel_routes(struct kernel_route *routes, int maxroutes)
proute++; proute++;
count ++; count ++;
} }
free(ptable); free(ptable);
return count; return count;
} }
...@@ -581,6 +583,66 @@ compare_ifname(const char * ifapname, const char * ifname) ...@@ -581,6 +583,66 @@ compare_ifname(const char * ifapname, const char * ifname)
return -1; return -1;
} }
int
cyginet_kernel_addresses(char *ifname, int ifindex, int ll,
struct kernel_route *routes, int maxroutes)
{
int rc, i, n;
struct cyginet_route *ptable, *p;
n = maxroutes * 2;
while (1) {
if (NULL == (ptable = calloc(n, sizeof(struct cyginet_route))))
return -1;
rc = cyginet_getifaddresses(ifname, ptable, n);
if(rc < 0)
return -1;
if (rc < n)
break;
free(ptable);
n += n;
}
i = 0;
p = ptable; p --;
while (p ++, n --) {
struct sockaddr *s = (struct sockaddr*)&(p -> prefix);
if (s -> sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&(p->prefix);
if(!!ll != !!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
continue;
memcpy(routes[i].prefix, &sin6->sin6_addr, 16);
routes[i].plen = 128;
routes[i].metric = 0;
routes[i].ifindex = ifindex;
routes[i].proto = RTPROT_BABEL_LOCAL;
memset(routes[i].gw, 0, 16);
i++;
} else if (s -> sa_family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in*)&(p->prefix);
if(ll)
continue;
#if defined(IN_LINKLOCAL)
if(IN_LINKLOCAL(htonl(sin->sin_addr.s_addr)))
continue;
#endif
memcpy(routes[i].prefix, v4prefix, 12);
memcpy(routes[i].prefix + 12, &sin->sin_addr, 4);
routes[i].plen = 128;
routes[i].metric = 0;
routes[i].ifindex = ifindex;
routes[i].proto = RTPROT_BABEL_LOCAL;
memset(routes[i].gw, 0, 16);
i++;
}
}
free(ptable);
return i;
}
int int
kernel_addresses(char *ifname, int ifindex, int ll, kernel_addresses(char *ifname, int ifindex, int ll,
struct kernel_route *routes, int maxroutes) struct kernel_route *routes, int maxroutes)
......
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