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,
*s ++ = 0; /* Split the string */
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 */
if (strncmp(buffer, "Prefix", 6) == 0) {
......@@ -518,6 +522,10 @@ libwinet_dump_ipv6_route_table(struct cyginet_route *routes,
else if (strncmp(buffer, "Metric", 6) == 0)
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 */
else if (strncmp(buffer, "Site Prefix Length", 18) == 0) {
if (ignored)
......@@ -917,7 +925,7 @@ libwinet_edit_route_entry(const struct sockaddr *dest,
const int MAX_BUFFER_SIZE = 1024;
const char * cmdformat = "netsh interface ipv6 %s route "
"prefix=%s/%d interface=%d "
"nexthop=%s %cmetric=%d";
"nexthop=%s %s %cmetric=%d";
char cmdbuf[MAX_BUFFER_SIZE];
char sdest[INET6_ADDRSTRLEN];
char sgate[INET6_ADDRSTRLEN];
......@@ -945,6 +953,7 @@ libwinet_edit_route_entry(const struct sockaddr *dest,
plen,
ifindex,
sgate,
cmdflag == RTM_ADD ? "publish=yes" : "",
cmdflag == RTM_DELETE ? '#' : ' ',
metric
) >= MAX_BUFFER_SIZE)
......@@ -958,7 +967,7 @@ libwinet_edit_route_entry(const struct sockaddr *dest,
/* Add ipv4 route before Windows Vista, use IP Helper API */
else {
MIB_IPFORWARDROW Row;
unsigned long Res;
unsigned long Res;
struct in_addr mask;
plen2mask(plen, &mask);
......@@ -1452,6 +1461,96 @@ cyginet_interface_sdl(struct sockaddr_dl *sdl, char *ifname)
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 */
int
cyginet_loopback_index(int family)
......@@ -3002,7 +3101,7 @@ int main(int argc, char* argv[])
else
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} };
......@@ -3023,8 +3122,20 @@ int main(int argc, char* argv[])
);
printf("Add blackhole route return: %d", n);
} 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"); */
/* libwinet_init_ipv6_interface(); */
......
......@@ -126,12 +126,12 @@ struct sockaddr_dl {
};
struct cyginet_route {
struct sockaddr prefix;
struct sockaddr_storage prefix;
int plen;
int metric;
unsigned int ifindex;
int proto;
struct sockaddr gateway;
struct sockaddr_storage gateway;
};
#if defined(INSIDE_BABELD_CYGINET)
......@@ -141,8 +141,10 @@ struct ifaddrs {
char *ifa_name;
unsigned int ifa_flags;
struct sockaddr *ifa_addr;
struct sockaddr *ifa_netmask;
struct sockaddr *ifa_dstaddr;
union {
struct sockaddr *ifa_netmask;
struct sockaddr *ifa_dstaddr;
};
void *ifa_data;
};
......@@ -227,4 +229,6 @@ int cyginet_update_route_entry(const struct sockaddr *, unsigned short,
char * cyginet_ifname(const char *);
char * cyginet_guidname(const char *);
int cyginet_refresh_interface_table();
int cyginet_getifaddresses(char *, struct cyginet_route *, int);
#endif /* __CYGIFNET_H__ */
......@@ -329,7 +329,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
}
ipv4 = 0;
}
if(operation == ROUTE_MODIFY && newmetric == metric &&
memcmp(newgate, gate, 16) == 0 && newifindex == ifindex)
return 0;
......@@ -362,7 +362,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
route_ifindex = ifindex;
prefix_len = ipv4 ? plen - 96 : plen;
if(metric == KERNEL_INFINITY) {
if(0 && metric == KERNEL_INFINITY) {
/* It means this route has property: RTF_BLACKHOLE */
if(ifindex_lo < 0) {
ifindex_lo = cyginet_loopback_index(AF_UNSPEC);
......@@ -386,7 +386,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
if(ipv4) {
PUSHADDR(destination, dest);
if (metric == KERNEL_INFINITY) {
if (0 && metric == KERNEL_INFINITY) {
/* blackhole route, now it doesn't work */
kdebugf("Error: ipv4 blackhole route doesn't work.\n");
return -1;
......@@ -402,7 +402,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
} else {
PUSHADDR6(destination, dest);
if (metric == KERNEL_INFINITY)
if (0 && metric == KERNEL_INFINITY)
PUSHADDR6(gateway, **local6);
else
PUSHADDR6(gateway, gate);
......@@ -483,7 +483,7 @@ parse_kernel_route(struct cyginet_route *src, struct kernel_route *route)
route -> proto = src -> proto;
route -> ifindex = src -> ifindex;
sa = &(src -> prefix);
sa = (struct sockaddr*)&(src -> prefix);
if(sa->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
memcpy(route->prefix, &sin6->sin6_addr, 16);
......@@ -504,7 +504,7 @@ parse_kernel_route(struct cyginet_route *src, struct kernel_route *route)
}
/* Gateway */
sa = &(src -> gateway);
sa = (struct sockaddr*)&(src -> gateway);
if(sa->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
memcpy(route->gw, &sin6->sin6_addr, 16);
......@@ -545,8 +545,9 @@ kernel_routes(struct kernel_route *routes, int maxroutes)
if (rc < 0) {
free(ptable);
return -1;
}
} else if (maxroutes < rc)
return maxroutes;
for (i = 0, count = 0; i < rc; i++) {
if (parse_kernel_route(ptable + i, proute) != 0)
......@@ -559,6 +560,7 @@ kernel_routes(struct kernel_route *routes, int maxroutes)
proute++;
count ++;
}
free(ptable);
return count;
}
......@@ -581,6 +583,66 @@ compare_ifname(const char * ifapname, const char * ifname)
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
kernel_addresses(char *ifname, int ifindex, int ll,
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