Commit c52ee6b4 authored by Grégoire Henry's avatar Grégoire Henry Committed by Juliusz Chroboczek

Try to improve readability in kernel_socket.

parent 19626a7e
......@@ -389,11 +389,12 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
const unsigned char *newgate, int newifindex,
unsigned int newmetric)
{
unsigned char msg[512];
struct rt_msghdr *rtm;
struct sockaddr_in6 *sin6;
struct sockaddr_in *sin;
int rc, len, ipv4;
struct {
struct rt_msghdr m_rtm;
char m_space[512];
} msg;
char *data = msg.m_space;
int rc, ipv4;
char local6[1][1][16] = IN6ADDR_LOOPBACK_INIT;
char local4[1][1][16] =
......@@ -443,103 +444,90 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
if(kernel_socket < 0) kernel_setup_socket(1);
memset(&msg, 0, sizeof(msg));
rtm = (struct rt_msghdr *)msg;
rtm->rtm_version = RTM_VERSION;
msg.m_rtm.rtm_version = RTM_VERSION;
switch(operation) {
case ROUTE_FLUSH:
rtm->rtm_type = RTM_DELETE; break;
msg.m_rtm.rtm_type = RTM_DELETE; break;
case ROUTE_ADD:
rtm->rtm_type = RTM_ADD; break;
case ROUTE_MODIFY:
rtm->rtm_type = RTM_CHANGE; break;
default:
msg.m_rtm.rtm_type = RTM_ADD; break;
case ROUTE_MODIFY:
msg.m_rtm.rtm_type = RTM_CHANGE; break;
default:
return -1;
};
rtm->rtm_index = ifindex;
rtm->rtm_flags = RTF_UP | RTF_PROTO2;
if(plen == 128) rtm->rtm_flags |= RTF_HOST;
/* if(memcmp(nexthop->id, dest, 16) == 0) { */
/* rtm -> rtm_flags |= RTF_LLINFO; */
/* rtm -> rtm_flags |= RTF_CLONING; */
/* } else { */
rtm->rtm_flags |= RTF_GATEWAY;
/* } */
msg.m_rtm.rtm_index = ifindex;
msg.m_rtm.rtm_flags = RTF_UP | RTF_PROTO2;
if(plen == 128) msg.m_rtm.rtm_flags |= RTF_HOST;
msg.m_rtm.rtm_flags |= RTF_GATEWAY;
if(metric == KERNEL_INFINITY) {
rtm->rtm_flags |= RTF_BLACKHOLE;
msg.m_rtm.rtm_flags |= RTF_BLACKHOLE;
if(ifindex_lo < 0) {
ifindex_lo = if_nametoindex("lo0");
if(ifindex_lo <= 0)
return -1;
}
rtm->rtm_index = ifindex_lo;
}
rtm->rtm_seq = ++seq;
rtm->rtm_addrs = RTA_DST | RTA_GATEWAY;
if(!(operation == ROUTE_MODIFY && plen == 128)) {
rtm->rtm_addrs |= RTA_NETMASK;
msg.m_rtm.rtm_index = ifindex_lo;
}
msg.m_rtm.rtm_seq = ++seq;
msg.m_rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
if(plen != 128) msg.m_rtm.rtm_addrs |= RTA_NETMASK;
#define PUSHADDR(src) \
do { struct sockaddr_in *sin = (struct sockaddr_in*) data; \
sin->sin_len = sizeof(struct sockaddr_in); \
sin->sin_family = AF_INET; \
memcpy(&sin->sin_addr, (src) + 12, 4); \
data = data + ROUNDUP(sin->sin_len); \
} while (0)
#define push_sockaddr_in(ptr, offset) \
do { (ptr) = (struct sockaddr_in *)((char *)(ptr) + (offset)); \
(ptr)->sin_len = sizeof(struct sockaddr_in); \
(ptr)->sin_family = AF_INET; } while (0)
#define get_sin_addr(dst,src) \
do { memcpy((dst), (src) + 12, 4); } while (0)
#define push_sockaddr_in6(ptr, offset) \
do { (ptr) = (struct sockaddr_in6 *)((char *)(ptr) + (offset)); \
(ptr)->sin6_len = sizeof(struct sockaddr_in6); \
(ptr)->sin6_family = AF_INET6; } while (0)
#define get_sin6_addr(dst,src) \
do { memcpy((dst), (src), 16); } while (0)
#define PUSHADDR6(src) \
do { struct sockaddr_in6 *sin6 = (struct sockaddr_in6*) data; \
sin6->sin6_len = sizeof(struct sockaddr_in6); \
sin6->sin6_family = AF_INET6; \
memcpy(&sin6->sin6_addr, (src), 16); \
if(IN6_IS_ADDR_LINKLOCAL (&sin6->sin6_addr)) \
SET_IN6_LINKLOCAL_IFINDEX (sin6->sin6_addr, ifindex); \
data = data + ROUNDUP(sin6->sin6_len); \
} while (0)
/* KAME ipv6 stack does not support IPv4 mapped IPv6, so we have to
* duplicate the codepath */
if(ipv4) {
sin = (struct sockaddr_in *)msg;
/* destination */
push_sockaddr_in(sin, sizeof(*rtm));
get_sin_addr(&(sin->sin_addr), dest);
/* gateway */
push_sockaddr_in(sin, ROUNDUP(sin->sin_len));
if (metric == KERNEL_INFINITY)
get_sin_addr(&(sin->sin_addr),**local4);
else
get_sin_addr(&(sin->sin_addr),gate);
/* netmask */
if((rtm->rtm_addrs | RTA_NETMASK) != 0) {
PUSHADDR(dest);
if (metric == KERNEL_INFINITY) {
PUSHADDR(**local4);
} else {
PUSHADDR(gate);
}
if((msg.m_rtm.rtm_addrs & RTA_NETMASK) != 0) {
struct in6_addr tmp_sin6_addr;
push_sockaddr_in(sin, ROUNDUP(sin->sin_len));
plen2mask(plen, &tmp_sin6_addr);
get_sin_addr(&(sin->sin_addr), (char *)&tmp_sin6_addr);
PUSHADDR((char *)&tmp_sin6_addr);
}
len = (char *)sin + ROUNDUP(sin->sin_len) - (char *)msg;
} else {
sin6 = (struct sockaddr_in6 *)msg;
/* destination */
push_sockaddr_in6(sin6, sizeof(*rtm));
get_sin6_addr(&(sin6->sin6_addr), dest);
/* gateway */
push_sockaddr_in6(sin6, ROUNDUP(sin6->sin6_len));
if (metric == KERNEL_INFINITY)
get_sin6_addr(&(sin6->sin6_addr),**local6);
else
get_sin6_addr(&(sin6->sin6_addr),gate);
if(IN6_IS_ADDR_LINKLOCAL (&sin6->sin6_addr))
SET_IN6_LINKLOCAL_IFINDEX (sin6->sin6_addr, ifindex);
/* netmask */
if((rtm->rtm_addrs | RTA_NETMASK) != 0) {
push_sockaddr_in6(sin6, ROUNDUP(sin6->sin6_len));
plen2mask(plen, &sin6->sin6_addr);
PUSHADDR6(dest);
if (metric == KERNEL_INFINITY) {
PUSHADDR6(**local6);
} else {
PUSHADDR6(gate);
}
len = (char *)sin6 + ROUNDUP(sin6->sin6_len) - (char *)msg;
if((msg.m_rtm.rtm_addrs & RTA_NETMASK) != 0) {
struct in6_addr tmp_sin6_addr;
plen2mask(plen, &tmp_sin6_addr);
PUSHADDR6((char*)&tmp_sin6_addr);
}
}
rtm->rtm_msglen = len;
rc = write(kernel_socket, msg, rtm->rtm_msglen);
if (rc < rtm->rtm_msglen)
#undef PUSHADDR
#undef PUSHADDR6
msg.m_rtm.rtm_msglen = data - (char *)&msg;
rc = write(kernel_socket, (char*)&msg, msg.m_rtm.rtm_msglen);
if (rc < msg.m_rtm.rtm_msglen)
return -1;
return 1;
......
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