Commit 1ef8b276 authored by dermiste's avatar dermiste

fixes and cleanup

parent 6e7c6600
/* /*
Copyright (c) 2007, 2008 by Juliusz Chroboczek Copyright (c) 2007, 2008 by Juliusz Chroboczek
Copyright (c) 2010 by Vincent Gross
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
...@@ -102,7 +103,7 @@ int ...@@ -102,7 +103,7 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
int rc, fd, rfd, i, opt; int rc, fd, i, opt;
time_t expiry_time, source_expiry_time, kernel_dump_time; time_t expiry_time, source_expiry_time, kernel_dump_time;
char *config_file = NULL; char *config_file = NULL;
void *vrc; void *vrc;
...@@ -111,15 +112,8 @@ main(int argc, char **argv) ...@@ -111,15 +112,8 @@ main(int argc, char **argv)
gettime(&now); gettime(&now);
rfd = open(RND_DEV, O_RDONLY); if (read_random_bytes(&seed, sizeof(seed)) == -1)
if(rfd < 0) { perror("read_random_bytes(seed, sizeof(seed))");
perror("open(random)");
} else {
rc = read(rfd, &seed, sizeof(unsigned int));
if(rc < sizeof(unsigned int)) {
perror("read(random)");
}
}
seed ^= (now.tv_sec ^ now.tv_usec); seed ^= (now.tv_sec ^ now.tv_usec);
srandom(seed); srandom(seed);
...@@ -402,23 +396,14 @@ main(int argc, char **argv) ...@@ -402,23 +396,14 @@ main(int argc, char **argv)
fprintf(stderr, fprintf(stderr,
"Warning: couldn't find router id -- using random value.\n"); "Warning: couldn't find router id -- using random value.\n");
if(rfd >= 0) { if(read_random_bytes(myid, 8) == -1) {
rc = read(rfd, myid, 8); perror("read(random)");
if(rc < 8) {
perror("read(random)");
goto fail;
}
} else {
goto fail; goto fail;
} }
/* Clear group and global bits */ /* Clear group and global bits */
myid[0] &= ~3; myid[0] &= ~3;
have_id: have_id:
if(rfd >= 0)
close(rfd);
rfd = -1;
reboot_time = now.tv_sec; reboot_time = now.tv_sec;
myseqno = (random() & 0xFFFF); myseqno = (random() & 0xFFFF);
......
...@@ -80,14 +80,6 @@ THE SOFTWARE. ...@@ -80,14 +80,6 @@ THE SOFTWARE.
#endif #endif
#endif #endif
#if defined(__linux)
#define RND_DEV "/dev/urandom"
#elif defined(__OpenBSD__)
#define RND_DEV "/dev/arandom"
#else
#error "don't know which random device to use"
#endif
extern struct timeval now; extern struct timeval now;
extern int debug; extern int debug;
extern time_t reboot_time; extern time_t reboot_time;
......
...@@ -76,3 +76,33 @@ gettime(struct timeval *tv) ...@@ -76,3 +76,33 @@ gettime(struct timeval *tv)
previous = tv->tv_sec; previous = tv->tv_sec;
return rc; return rc;
} }
#if defined(__linux)
#define RND_DEV "/dev/urandom"
#elif defined (__OpenBSD__)
#define RND_DEV "/dev/arandom"
#endif
int
read_random_bytes(void *buf, size_t len)
{
int rfd;
int rc;
#ifdef RND_DEV
rfd = open(RND_DEV, O_RDONLY);
if(rfd < 0) {
rc = -1;
} else {
rc = read(rfd, buf, len);
if(rc < len)
rc = -1;
close(rfd);
}
#else
rc = -1;
errno = ENOSYS;
#endif
return rc;
}
...@@ -63,3 +63,4 @@ int kernel_addresses(char *ifname, int ifindex, int ll, ...@@ -63,3 +63,4 @@ int kernel_addresses(char *ifname, int ifindex, int ll,
struct kernel_route *routes, int maxroutes); struct kernel_route *routes, int maxroutes);
int if_eui64(char *ifname, int ifindex, unsigned char *eui); int if_eui64(char *ifname, int ifindex, unsigned char *eui);
int gettime(struct timeval *tv); int gettime(struct timeval *tv);
int read_random_bytes(void *buf, size_t len);
/* /*
Copyright (c) 2007 by Grégoire Henry Copyright (c) 2007 by Grégoire Henry
Copyright (c) 2008, 2009 by Juliusz Chroboczek Copyright (c) 2008, 2009 by Juliusz Chroboczek
Copyright (c) 2010 by Vincent Gross
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
...@@ -133,7 +134,7 @@ plen2mask(int n, struct in6_addr *dest) ...@@ -133,7 +134,7 @@ plen2mask(int n, struct in6_addr *dest)
int int
kernel_setup(int setup) kernel_setup(int setup)
{ {
int rc; int rc = 0;
int forwarding = 1; int forwarding = 1;
int accept_redirects = 0; int accept_redirects = 0;
int mib[4]; int mib[4];
...@@ -148,32 +149,27 @@ kernel_setup(int setup) ...@@ -148,32 +149,27 @@ kernel_setup(int setup)
datasize = sizeof(old_forwarding); datasize = sizeof(old_forwarding);
if (setup) if (setup)
rc = sysctl(mib, 4, &old_forwarding, &datasize, rc = sysctl(mib, 4, &old_forwarding, &datasize,
&forwarding, datasize); &forwarding, datasize);
else if (0 <= old_forwarding) else if (old_forwarding >= 0)
rc = sysctl(mib, 4, NULL, NULL, rc = sysctl(mib, 4, NULL, NULL,
&old_forwarding, datasize); &old_forwarding, datasize);
if (rc == -1) { if (rc == -1) {
if(errno == ENOMEM) perror("Couldn't tweak forwarding knob.");
perror("Couldn't read forwarding knob.");
else
perror("Couldn't write forwarding knob.");
return -1; return -1;
} }
rc = 0;
mib[2] = IPPROTO_ICMPV6; mib[2] = IPPROTO_ICMPV6;
mib[3] = ICMPV6CTL_REDIRACCEPT; mib[3] = ICMPV6CTL_REDIRACCEPT;
datasize = sizeof(old_accept_redirects); datasize = sizeof(old_accept_redirects);
if (setup) if (setup)
rc = sysctl(mib, 4, &old_accept_redirects, &datasize, rc = sysctl(mib, 4, &old_accept_redirects, &datasize,
&accept_redirects, datasize); &accept_redirects, datasize);
else if (0 <= old_accept_redirects) else if (old_accept_redirects >= 0)
rc = sysctl(mib, 4, NULL, NULL, rc = sysctl(mib, 4, NULL, NULL,
&old_accept_redirects, datasize); &old_accept_redirects, datasize);
if (rc == -1) { if (rc == -1) {
if(errno == ENOMEM) perror("Couldn't tweak accept_redirects knob.");
perror("Couldn't read accept_redirects knob.");
else
perror("Couldn't write accept_redirects knob.");
return -1; return -1;
} }
return 1; return 1;
...@@ -294,11 +290,11 @@ kernel_interface_wireless(const char *ifname, int ifindex) ...@@ -294,11 +290,11 @@ kernel_interface_wireless(const char *ifname, int ifindex)
rc = ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr); rc = ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr);
close(s); close(s);
if (rc < 0) if (rc < 0)
return rc; return rc;
if ((ifmr.ifm_active & IFM_NMASK) == IFM_IEEE80211) if ((ifmr.ifm_active & IFM_NMASK) == IFM_IEEE80211)
return 1; return 1;
else else
return 0; return 0;
} }
int int
...@@ -314,17 +310,16 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -314,17 +310,16 @@ 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)
{ {
unsigned char msg[512]; unsigned char msg[512];
struct rt_msghdr *rtm; struct rt_msghdr *rtm;
struct sockaddr_in6 *sin6; struct sockaddr_in6 *sin6;
struct sockaddr_in *sin4; struct sockaddr_in *sin;
int rc, len, ipv4; int rc, len, ipv4;
char local6[1][1][16] = IN6ADDR_LOOPBACK_INIT; char local6[1][1][16] = IN6ADDR_LOOPBACK_INIT;
char local4[1][1][16] = char local4[1][1][16] =
{{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x01 }}}; 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x01 }}};
/* Check that the protocol family is consistent. */ /* Check that the protocol family is consistent. */
if(plen >= 96 && v4mapped(dest)) { if(plen >= 96 && v4mapped(dest)) {
...@@ -352,35 +347,35 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -352,35 +347,35 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
} }
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",
format_address(dest), plen, metric, ifindex, format_address(dest), plen, metric, ifindex,
format_address(gate)); format_address(gate));
if(kernel_socket < 0) kernel_setup_socket(1); if(kernel_socket < 0) kernel_setup_socket(1);
memset(&msg, 0, sizeof(msg)); memset(&msg, 0, sizeof(msg));
rtm = (struct rt_msghdr *)msg; rtm = (struct rt_msghdr *)msg;
rtm->rtm_version = RTM_VERSION; rtm->rtm_version = RTM_VERSION;
switch(operation) { switch(operation) {
case ROUTE_FLUSH: case ROUTE_FLUSH:
rtm->rtm_type = RTM_DELETE; break; rtm->rtm_type = RTM_DELETE; break;
case ROUTE_ADD: case ROUTE_ADD:
rtm->rtm_type = RTM_ADD; break; rtm->rtm_type = RTM_ADD; break;
case ROUTE_MODIFY: case ROUTE_MODIFY:
rtm->rtm_type = RTM_CHANGE; break; rtm->rtm_type = RTM_CHANGE; break;
default: default:
return -1; return -1;
}; };
rtm->rtm_index = ifindex; rtm->rtm_index = ifindex;
rtm->rtm_flags = RTF_UP | RTF_PROTO2; rtm->rtm_flags = RTF_UP | RTF_PROTO2;
if(plen == 128) rtm->rtm_flags |= RTF_HOST; if(plen == 128) rtm->rtm_flags |= RTF_HOST;
/* if(memcmp(nexthop->id, dest, 16) == 0) { */ /* if(memcmp(nexthop->id, dest, 16) == 0) { */
/* rtm -> rtm_flags |= RTF_LLINFO; */ /* rtm -> rtm_flags |= RTF_LLINFO; */
/* rtm -> rtm_flags |= RTF_CLONING; */ /* rtm -> rtm_flags |= RTF_CLONING; */
/* } else { */ /* } else { */
rtm->rtm_flags |= RTF_GATEWAY; rtm->rtm_flags |= RTF_GATEWAY;
/* } */ /* } */
if(metric == KERNEL_INFINITY) { if(metric == KERNEL_INFINITY) {
rtm->rtm_flags |= RTF_BLACKHOLE; rtm->rtm_flags |= RTF_BLACKHOLE;
if(ifindex_lo < 0) { if(ifindex_lo < 0) {
...@@ -397,57 +392,58 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -397,57 +392,58 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
} }
#define push_sockaddr_in(ptr, offset) \ #define push_sockaddr_in(ptr, offset) \
do { (ptr) = (struct sockaddr_in *)((char *)(ptr) + (offset)); \ do { (ptr) = (struct sockaddr_in *)((char *)(ptr) + (offset)); \
(ptr)->sin_len = sizeof(struct sockaddr_in); \ (ptr)->sin_len = sizeof(struct sockaddr_in); \
(ptr)->sin_family = AF_INET; } while (0) (ptr)->sin_family = AF_INET; } while (0)
#define get_sin_addr(dst,src) \ #define get_sin_addr(dst,src) \
do { memcpy((dst), (src) + 12, 4); } while (0) do { memcpy((dst), (src) + 12, 4); } while (0)
#define push_sockaddr_in6(ptr, offset) \ #define push_sockaddr_in6(ptr, offset) \
do { (ptr) = (struct sockaddr_in6 *)((char *)(ptr) + (offset)); \ do { (ptr) = (struct sockaddr_in6 *)((char *)(ptr) + (offset)); \
(ptr)->sin6_len = sizeof(struct sockaddr_in6); \ (ptr)->sin6_len = sizeof(struct sockaddr_in6); \
(ptr)->sin6_family = AF_INET6; } while (0) (ptr)->sin6_family = AF_INET6; } while (0)
#define get_sin6_addr(dst,src) \ #define get_sin6_addr(dst,src) \
do { memcpy((dst), (src), 16); } while (0) do { memcpy((dst), (src), 16); } while (0)
/* KAME ipv6 stack does not support IPv4 mapped IPv6, so we have to */ /* KAME ipv6 stack does not support IPv4 mapped IPv6, so we have to
* duplicate the codepath */
if(ipv4) { if(ipv4) {
sin4 = (struct sockaddr_in *)msg; sin = (struct sockaddr_in *)msg;
/* destination */ /* destination */
push_sockaddr_in(sin4, sizeof(*rtm)); push_sockaddr_in(sin, sizeof(*rtm));
get_sin_addr(&(sin4->sin_addr), dest); get_sin_addr(&(sin->sin_addr), dest);
/* gateway */ /* gateway */
push_sockaddr_in(sin4, ROUNDUP(sin4->sin_len)); push_sockaddr_in(sin, ROUNDUP(sin->sin_len));
if (metric == KERNEL_INFINITY) if (metric == KERNEL_INFINITY)
get_sin_addr(&(sin4->sin_addr),**local4); get_sin_addr(&(sin->sin_addr),**local4);
else else
get_sin_addr(&(sin4->sin_addr),gate); get_sin_addr(&(sin->sin_addr),gate);
/* netmask */ /* netmask */
if((rtm->rtm_addrs | RTA_NETMASK) != 0) { if((rtm->rtm_addrs | RTA_NETMASK) != 0) {
struct in6_addr tmp_sin6_addr; struct in6_addr tmp_sin6_addr;
push_sockaddr_in(sin4, ROUNDUP(sin4->sin_len)); push_sockaddr_in(sin, ROUNDUP(sin->sin_len));
plen2mask(plen, &tmp_sin6_addr); plen2mask(plen, &tmp_sin6_addr);
get_sin_addr(&(sin4->sin_addr), (char *)&tmp_sin6_addr); get_sin_addr(&(sin->sin_addr), (char *)&tmp_sin6_addr);
} }
len = (char *)sin4 + ROUNDUP(sin4->sin_len) - (char *)msg; len = (char *)sin + ROUNDUP(sin->sin_len) - (char *)msg;
} else { } else {
sin6 = (struct sockaddr_in6 *)msg; sin6 = (struct sockaddr_in6 *)msg;
/* destination */ /* destination */
push_sockaddr_in6(sin6, sizeof(*rtm)); push_sockaddr_in6(sin6, sizeof(*rtm));
get_sin6_addr(&(sin6->sin6_addr), dest); get_sin6_addr(&(sin6->sin6_addr), dest);
/* gateway */ /* gateway */
push_sockaddr_in6(sin6, ROUNDUP(sin6->sin6_len)); push_sockaddr_in6(sin6, ROUNDUP(sin6->sin6_len));
if (metric == KERNEL_INFINITY) if (metric == KERNEL_INFINITY)
get_sin6_addr(&(sin6->sin6_addr),**local6); get_sin6_addr(&(sin6->sin6_addr),**local6);
else else
get_sin6_addr(&(sin6->sin6_addr),gate); get_sin6_addr(&(sin6->sin6_addr),gate);
if(IN6_IS_ADDR_LINKLOCAL (&sin6->sin6_addr)) if(IN6_IS_ADDR_LINKLOCAL (&sin6->sin6_addr))
SET_IN6_LINKLOCAL_IFINDEX (sin6->sin6_addr, ifindex); SET_IN6_LINKLOCAL_IFINDEX (sin6->sin6_addr, ifindex);
/* netmask */ /* netmask */
if((rtm->rtm_addrs | RTA_NETMASK) != 0) { if((rtm->rtm_addrs | RTA_NETMASK) != 0) {
push_sockaddr_in6(sin6, ROUNDUP(sin6->sin6_len)); push_sockaddr_in6(sin6, ROUNDUP(sin6->sin6_len));
plen2mask(plen, &sin6->sin6_addr); plen2mask(plen, &sin6->sin6_addr);
} }
len = (char *)sin6 + ROUNDUP(sin6->sin6_len) - (char *)msg; len = (char *)sin6 + ROUNDUP(sin6->sin6_len) - (char *)msg;
...@@ -666,9 +662,10 @@ kernel_addresses(char *ifname, int ifindex, int ll, ...@@ -666,9 +662,10 @@ kernel_addresses(char *ifname, int ifindex, int ll,
if(!!ll != !!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) if(!!ll != !!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
goto next; goto next;
memcpy(routes[i].prefix, &sin6->sin6_addr, 16); memcpy(routes[i].prefix, &sin6->sin6_addr, 16);
if(ll) /* This a perfect example of counter-productive optimisation : if(ll)
KAME encodes interface index onto bytes 2 and 3, so we have to /* This a perfect example of counter-productive optimisation :
reset those bytes to 0 before passing them to babel. */ KAME encodes interface index onto bytes 2 and 3, so we have to
reset those bytes to 0 before passing them to babeld. */
memset(routes[i].prefix + 2, 0, 2); memset(routes[i].prefix + 2, 0, 2);
routes[i].plen = 128; routes[i].plen = 128;
routes[i].metric = 0; routes[i].metric = 0;
...@@ -689,7 +686,7 @@ kernel_addresses(char *ifname, int ifindex, int ll, ...@@ -689,7 +686,7 @@ kernel_addresses(char *ifname, int ifindex, int ll,
memset(routes[i].gw, 0, 16); memset(routes[i].gw, 0, 16);
i++; i++;
} }
next: next:
ifap = ifap->ifa_next; ifap = ifap->ifa_next;
} }
......
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