From f71e643690a0b328de88763e8ec2a36ff17f365a Mon Sep 17 00:00:00 2001 From: Ashish Shukla Date: Sun, 12 Oct 2008 04:06:37 +0530 Subject: [PATCH] 2008-10-12 Ashish Shukla * libroute/route_bsd.h: Added protoype declarations of bsd_replace and bsd_change functions. * libroute/route_bsd.c (bsd_replace, bsd_change): Created. (bsd_route_modify): Created. (bsd_delete, bsd_add): Refactored by taking out common code in 'bsd_route_modify' function. (bsd_rt_msg_send): Changed the signature to return success status. (bsd_backend): Replaced references to 'bsd_add' in the place of 'change' and 'replace' functions with 'bsd_change', and 'bsd_replace' respectively. --- ChangeLog | 15 +++ libroute/route_bsd.c | 342 ++++++++++++++++++++++++-------------------------- libroute/route_bsd.h | 16 +++ 3 files changed, 197 insertions(+), 176 deletions(-) diff --git a/ChangeLog b/ChangeLog index 09c67ad..a98d127 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2008-10-12 Ashish Shukla + + * libroute/route_bsd.h: Added protoype declarations of bsd_replace + and bsd_change functions. + + * libroute/route_bsd.c (bsd_replace, bsd_change): Created. + (bsd_route_modify): Created. + (bsd_delete, bsd_add): Refactored by taking out common code in + 'bsd_route_modify' function. + (bsd_rt_msg_send): Changed the signature to return success + status. + (bsd_backend): Replaced references to 'bsd_add' in the place of + 'change' and 'replace' functions with 'bsd_change', and + 'bsd_replace' respectively. + 2008-10-11 Ashish Shukla * libroute/route_bsd.c (bsd_rt_msg_send): Removed un-necessary diff --git a/libroute/route_bsd.c b/libroute/route_bsd.c index 9d46db4..df100b1 100644 --- a/libroute/route_bsd.c +++ b/libroute/route_bsd.c @@ -53,10 +53,10 @@ const route_backend_t bsd_backend = { bsd_add, bsd_add, - bsd_add, + bsd_change, bsd_delete, bsd_add, - bsd_add, + bsd_replace, bsd_show }; @@ -80,11 +80,11 @@ const struct sockaddr sa_empty = { sizeof(struct sockaddr), }; -static void bsd_rt_msg_send(int msg_type, - int msg_iface, - int msg_seq, - int msg_flags, - pf_route_message_t* message); +static int bsd_rt_msg_send(int msg_type, + int msg_iface, + int msg_seq, + int msg_flags, + pf_route_message_t* message); static void bsd_conv_addr_to_name (const struct sockaddr *const sock, char *const buffer, const size_t buffer_size, const short int resolve_names); @@ -96,6 +96,50 @@ static size_t bsd_sysctl (void ** buffer, size_t *const size); static struct rt_msghdr * bsd_rt_msg_next (const struct rt_msghdr *rtm, size_t *const length); +static int bsd_route_modify(const int flags, + const int address_family, + const void *const dest_addr, + const size_t dest_addr_size, + const unsigned char dest_addr_len, + const void *const gw_addr, + const size_t gw_addr_size, + const unsigned int iface); + +void +bsd_delete (const int address_family, + const void *const dest_addr, + const size_t dest_addr_size, + const unsigned char dest_addr_len) +{ + bsd_route_modify(RTM_DELETE, + address_family, + dest_addr, + dest_addr_size, + dest_addr_len, + NULL, + 0, + 0); +} + +void +bsd_change (const int address_family, + const void *const dest_addr, + const size_t dest_addr_size, + const unsigned char dest_addr_len, + const void *const gw_addr, + const size_t gw_addr_size, + const unsigned int iface) +{ + bsd_route_modify(RTM_CHANGE, + address_family, + dest_addr, + dest_addr_size, + dest_addr_len, + gw_addr, + gw_addr_size, + iface); +} + void bsd_add (const int address_family, const void *const dest_addr, @@ -105,130 +149,34 @@ bsd_add (const int address_family, const size_t gw_addr_size, const unsigned int iface) { - pf_route_message_t msg; - struct ifaddrs* ifas; - int i; - int flags = RTF_STATIC; - - memset(&msg, 0, sizeof(pf_route_message_t)); - - if(iface) - if(getifaddrs(&ifas) == -1) - return; - - if(address_family == AF_INET) - { - - if(dest_addr_len) - { - char* p; - - msg.addr[RTAX_NETMASK] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in)); - ((struct sockaddr_in*)msg.addr[RTAX_NETMASK])->sin_family = AF_INET; - ((struct sockaddr_in*)msg.addr[RTAX_NETMASK])->sin_len = sizeof(struct sockaddr_in); - p = (char*)&((struct sockaddr_in*)msg.addr[RTAX_NETMASK])->sin_addr; - - for(i = 1; i <= dest_addr_len; i++) - { - *p >>= 1; - *p |= 0x80; - - if(!(i & 7)) - p++; - } - } - - if(dest_addr) - { - msg.addr[RTAX_DST] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in)); - ((struct sockaddr_in*)msg.addr[RTAX_DST])->sin_family = AF_INET; - ((struct sockaddr_in*)msg.addr[RTAX_DST])->sin_len = sizeof(struct sockaddr_in); - memcpy(&((struct sockaddr_in*)msg.addr[RTAX_DST])->sin_addr, dest_addr, dest_addr_size); - } - - if(gw_addr) - { - msg.addr[RTAX_GATEWAY] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in)); - ((struct sockaddr_in*)msg.addr[RTAX_GATEWAY])->sin_family = AF_INET; - ((struct sockaddr_in*)msg.addr[RTAX_GATEWAY])->sin_len = sizeof(struct sockaddr_in); - memcpy(&((struct sockaddr_in*)msg.addr[RTAX_GATEWAY])->sin_addr, gw_addr, gw_addr_size); - flags |= RTF_GATEWAY; - } - } - else if(address_family == AF_INET6) - { - if(dest_addr_len) - { - char* p; - - msg.addr[RTAX_NETMASK] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in6)); - ((struct sockaddr_in6*)msg.addr[RTAX_NETMASK])->sin6_family = AF_INET6; - ((struct sockaddr_in6*)msg.addr[RTAX_NETMASK])->sin6_len = sizeof(struct sockaddr_in6); - p = (char*)&((struct sockaddr_in6*)msg.addr[RTAX_NETMASK])->sin6_addr; - - for(i = 1; i <= dest_addr_len; i++) - { - *p >>= 1; - *p |= 0x80; - - if(!(i & 7)) - p++; - } - } - - if(dest_addr) - { - msg.addr[RTAX_DST] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in6)); - ((struct sockaddr_in6*)msg.addr[RTAX_DST])->sin6_family = AF_INET6; - ((struct sockaddr_in6*)msg.addr[RTAX_DST])->sin6_len = sizeof(struct sockaddr_in6); - memcpy(&((struct sockaddr_in6*)msg.addr[RTAX_DST])->sin6_addr, dest_addr, dest_addr_size); - } - - if(gw_addr) - { - msg.addr[RTAX_GATEWAY] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in6)); - ((struct sockaddr_in6*)msg.addr[RTAX_GATEWAY])->sin6_family = AF_INET6; - ((struct sockaddr_in6*)msg.addr[RTAX_GATEWAY])->sin6_len = sizeof(struct sockaddr_in6); - memcpy(&((struct sockaddr_in6*)msg.addr[RTAX_GATEWAY])->sin6_addr, gw_addr, gw_addr_size); - flags |= RTF_GATEWAY; - } - } - - if(iface) - { - struct ifaddrs* ifa = ifas; - while(ifa) - { - if(((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index == iface) - { - if(msg.addr[RTAX_GATEWAY]) - free(msg.addr[RTAX_GATEWAY]); - - msg.addr[RTAX_GATEWAY] = xmalloc(SA_SIZE(ifa->ifa_addr)); - memcpy(msg.addr[RTAX_GATEWAY], ifa->ifa_addr, SA_SIZE(ifa->ifa_addr)); - break; - } - ifa = ifa->ifa_next; - } - flags &= ~RTF_GATEWAY; - } - - bsd_rt_msg_send(RTM_ADD, iface, 0, flags, &msg); - - for(i = 0; i < RTAX_MAX; i++) - if(msg.addr[i]) - { - free(msg.addr[i]); - msg.addr[i] = NULL; - } - - if(iface) - freeifaddrs(ifas); + bsd_route_modify(RTM_ADD, + address_family, + dest_addr, + dest_addr_size, + dest_addr_len, + gw_addr, + gw_addr_size, + iface); +} - return; +void +bsd_replace (const int address_family, + const void *const dest_addr, + const size_t dest_addr_size, + const unsigned char dest_addr_len, + const void *const gw_addr, + const size_t gw_addr_size, + const unsigned int iface) +{ + if(bsd_route_modify(RTM_CHANGE, address_family, dest_addr, + dest_addr_size, dest_addr_len, gw_addr, + gw_addr_size, iface)) + bsd_route_modify(RTM_ADD, address_family, dest_addr, + dest_addr_size, dest_addr_len, + gw_addr, gw_addr_size, iface); } -static void +static int bsd_rt_msg_send(int msg_type, int msg_iface, int msg_seq, int msg_flags, pf_route_message_t* message) { @@ -265,14 +213,17 @@ bsd_rt_msg_send(int msg_type, int msg_iface, int msg_seq, rtm->rtm_msglen = len; - if((fd = socket(PF_ROUTE, SOCK_RAW, 0)) == -1) - return; + if((fd = socket(PF_ROUTE, SOCK_RAW, 0)) > 0) + write(fd, rtm, rtm->rtm_msglen); + + i = errno; - if(write(fd, rtm, rtm->rtm_msglen) == -1) - return; + if(fd > 0) + close(fd); - close(fd); free(rtm); + + return i; } static void @@ -513,40 +464,45 @@ bsd_rt_msg_next (const struct rt_msghdr *rtm, size_t *const length) return next; } -void -bsd_delete (const int address_family, - const void *const dest_addr, - const size_t dest_addr_size, - const unsigned char dest_addr_len) +static int +bsd_route_modify (const int type, + const int address_family, + const void *const dest_addr, + const size_t dest_addr_size, + const unsigned char dest_addr_len, + const void *const gw_addr, + const size_t gw_addr_size, + const unsigned int iface) { pf_route_message_t msg; + struct ifaddrs* ifas; int i; - + int flags = RTF_STATIC; + memset(&msg, 0, sizeof(pf_route_message_t)); + if(iface) + if(getifaddrs(&ifas) == -1) + return errno; + if(address_family == AF_INET) { + char* p; + + msg.addr[RTAX_NETMASK] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in)); + ((struct sockaddr_in*)msg.addr[RTAX_NETMASK])->sin_family = AF_INET; + ((struct sockaddr_in*)msg.addr[RTAX_NETMASK])->sin_len = sizeof(struct sockaddr_in); + p = (char*)&((struct sockaddr_in*)msg.addr[RTAX_NETMASK])->sin_addr; - if(dest_addr_len) + for(i = 1; i <= dest_addr_len; i++) { - - char* p; - - msg.addr[RTAX_NETMASK] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in)); - ((struct sockaddr_in*)msg.addr[RTAX_NETMASK])->sin_family = AF_INET; - ((struct sockaddr_in*)msg.addr[RTAX_NETMASK])->sin_len = sizeof(struct sockaddr_in); - p = (char*)&((struct sockaddr_in*)msg.addr[RTAX_NETMASK])->sin_addr; - - for(i = 1; i <= dest_addr_len; i++) - { - *p >>= 1; - *p |= 0x80; + *p >>= 1; + *p |= 0x80; - if(!(i & 7)) - p++; - } + if(!(i & 7)) + p++; } - + if(dest_addr) { msg.addr[RTAX_DST] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in)); @@ -554,30 +510,34 @@ bsd_delete (const int address_family, ((struct sockaddr_in*)msg.addr[RTAX_DST])->sin_len = sizeof(struct sockaddr_in); memcpy(&((struct sockaddr_in*)msg.addr[RTAX_DST])->sin_addr, dest_addr, dest_addr_size); } + + if(gw_addr) + { + msg.addr[RTAX_GATEWAY] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in)); + ((struct sockaddr_in*)msg.addr[RTAX_GATEWAY])->sin_family = AF_INET; + ((struct sockaddr_in*)msg.addr[RTAX_GATEWAY])->sin_len = sizeof(struct sockaddr_in); + memcpy(&((struct sockaddr_in*)msg.addr[RTAX_GATEWAY])->sin_addr, gw_addr, gw_addr_size); + flags |= RTF_GATEWAY; + } } else if(address_family == AF_INET6) { - - if(dest_addr_len) + char* p; + + msg.addr[RTAX_NETMASK] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in6)); + ((struct sockaddr_in6*)msg.addr[RTAX_NETMASK])->sin6_family = AF_INET6; + ((struct sockaddr_in6*)msg.addr[RTAX_NETMASK])->sin6_len = sizeof(struct sockaddr_in6); + p = (char*)&((struct sockaddr_in6*)msg.addr[RTAX_NETMASK])->sin6_addr; + + for(i = 1; i <= dest_addr_len; i++) { + *p >>= 1; + *p |= 0x80; - char* p; + if(!(i & 7)) + p++; + } - msg.addr[RTAX_NETMASK] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in6)); - ((struct sockaddr_in6*)msg.addr[RTAX_NETMASK])->sin6_family = AF_INET6; - ((struct sockaddr_in6*)msg.addr[RTAX_NETMASK])->sin6_len = sizeof(struct sockaddr_in6); - p = (char*)&((struct sockaddr_in6*)msg.addr[RTAX_NETMASK])->sin6_addr; - - for(i = 1; i <= dest_addr_len; i++) - { - *p >>= 1; - *p |= 0x80; - - if(!(i & 7)) - p++; - } - } - if(dest_addr) { msg.addr[RTAX_DST] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in6)); @@ -585,10 +545,37 @@ bsd_delete (const int address_family, ((struct sockaddr_in6*)msg.addr[RTAX_DST])->sin6_len = sizeof(struct sockaddr_in6); memcpy(&((struct sockaddr_in6*)msg.addr[RTAX_DST])->sin6_addr, dest_addr, dest_addr_size); } + + if(gw_addr) + { + msg.addr[RTAX_GATEWAY] = (struct sockaddr*)xcalloc(1, sizeof(struct sockaddr_in6)); + ((struct sockaddr_in6*)msg.addr[RTAX_GATEWAY])->sin6_family = AF_INET6; + ((struct sockaddr_in6*)msg.addr[RTAX_GATEWAY])->sin6_len = sizeof(struct sockaddr_in6); + memcpy(&((struct sockaddr_in6*)msg.addr[RTAX_GATEWAY])->sin6_addr, gw_addr, gw_addr_size); + flags |= RTF_GATEWAY; + } } + if(iface) + { + struct ifaddrs* ifa = ifas; + while(ifa) + { + if(((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index == iface) + { + if(msg.addr[RTAX_GATEWAY]) + free(msg.addr[RTAX_GATEWAY]); + + msg.addr[RTAX_GATEWAY] = xmalloc(SA_SIZE(ifa->ifa_addr)); + memcpy(msg.addr[RTAX_GATEWAY], ifa->ifa_addr, SA_SIZE(ifa->ifa_addr)); + break; + } + ifa = ifa->ifa_next; + } + flags &= ~RTF_GATEWAY; + } - bsd_rt_msg_send(RTM_DELETE, 0, 0, RTF_UP | RTF_STATIC, &msg); + flags = bsd_rt_msg_send(type, iface, 0, flags, &msg); for(i = 0; i < RTAX_MAX; i++) if(msg.addr[i]) @@ -597,5 +584,8 @@ bsd_delete (const int address_family, msg.addr[i] = NULL; } - return; + if(iface) + freeifaddrs(ifas); + + return flags; } diff --git a/libroute/route_bsd.h b/libroute/route_bsd.h index 8a38f79..75ca02f 100644 --- a/libroute/route_bsd.h +++ b/libroute/route_bsd.h @@ -32,6 +32,22 @@ extern void bsd_add (const int address_family, const size_t gw_addr_size, const unsigned int iface); +extern void bsd_change (const int address_family, + const void *const dest_addr, + const size_t dest_addr_size, + const unsigned char dest_len, + const void *const gw_addr, + const size_t gw_addr_size, + const unsigned int iface); + +extern void bsd_replace (const int address_family, + const void *const dest_addr, + const size_t dest_addr_size, + const unsigned char dest_len, + const void *const gw_addr, + const size_t gw_addr_size, + const unsigned int iface); + extern void bsd_delete (const int format, const void *const dest_addr, const size_t dest_addr_size, -- 1.6.0.2