diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2011-07-28 17:43:12 +0200 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2011-07-28 17:43:12 +0200 |
commit | 39eb92db66600bd1bf8a63f24145c9ff1fd7f966 (patch) | |
tree | 085e39909fd173de5a57b625231032d0e98fb800 | |
parent | a6ed4816fa8c39484dfa5f763efff7d8d7291d9e (diff) | |
download | pingu-39eb92db66600bd1bf8a63f24145c9ff1fd7f966.tar.bz2 pingu-39eb92db66600bd1bf8a63f24145c9ff1fd7f966.tar.xz |
pingu: add gw to list and minor cleanup
- add default gateways to our gw list
- use sockaddr_init to init our gw
- implement sockaddr_to_string
TODO: delete default gateways from list
-rw-r--r-- | pingu_iface.c | 42 | ||||
-rw-r--r-- | pingu_iface.h | 2 | ||||
-rw-r--r-- | pingu_netlink.c | 8 | ||||
-rw-r--r-- | sockaddr_util.c | 14 | ||||
-rw-r--r-- | sockaddr_util.h | 1 |
5 files changed, 52 insertions, 15 deletions
diff --git a/pingu_iface.c b/pingu_iface.c index cbd4e40..9e843c5 100644 --- a/pingu_iface.c +++ b/pingu_iface.c @@ -1,6 +1,7 @@ #include <sys/socket.h> #include <arpa/inet.h> +#include <linux/rtnetlink.h> #include <stdio.h> #include <stdlib.h> @@ -107,6 +108,7 @@ struct pingu_iface *pingu_iface_new(struct ev_loop *loop, const char *name) return NULL; } list_init(&iface->ping_list); + list_init(&iface->gateway_list); list_add(&iface->iface_list_entry, &iface_list); return iface; } @@ -137,6 +139,17 @@ void pingu_gateway_add_sorted(struct pingu_iface *iface, list_add_tail(&new_gw->gateway_list_entry, &iface->gateway_list); } +void pingu_iface_gateway_dump(struct pingu_iface *iface) +{ + struct pingu_gateway *gw; + list_for_each_entry(gw, &iface->gateway_list, gateway_list_entry) { + char buf[64]; + sockaddr_to_string(&gw->gw, buf, sizeof(buf)); + log_debug("dump: %s: via %s metric %i", iface->name, buf, + gw->metric); + } +} + struct pingu_gateway *pingu_gateway_new(int family, void *addr, int metric) { @@ -145,18 +158,8 @@ struct pingu_gateway *pingu_gateway_new(int family, void *addr, log_perror("Failed to allocate gateway"); return NULL; } - gw->gw.sa.sa_family = family; + sockaddr_init(&gw->gw, family, addr); gw->metric = metric; - switch (family) { - case AF_INET: - memcpy(&gw->gw.sin.sin_addr, addr, - sizeof(gw->gw.sin.sin_addr)); - break; - case AF_INET6: - memcpy(&gw->gw.sin6.sin6_addr, addr, - sizeof(gw->gw.sin6.sin6_addr)); - break; - } return gw; } @@ -165,8 +168,21 @@ void pingu_iface_add_gateway(struct pingu_iface *iface, int family, { struct pingu_gateway *gw = pingu_gateway_new(family, addr, metric); - if (gw != NULL) - pingu_gateway_add_sorted(iface, gw); + if (gw == NULL) + return; + pingu_gateway_add_sorted(iface, gw); + log_debug("%s: added default gateway", iface->name); +} + +void pingu_iface_gateway(struct pingu_iface *iface, int family, + void *gateway_ptr, int metric, int action) +{ + switch (action) { + case RTM_NEWROUTE: + pingu_iface_add_gateway(iface, family, gateway_ptr, metric); + break; + } + pingu_iface_gateway_dump(iface); } int pingu_iface_init(struct ev_loop *loop, struct list_head *host_list) diff --git a/pingu_iface.h b/pingu_iface.h index 5d94136..ec55597 100644 --- a/pingu_iface.h +++ b/pingu_iface.h @@ -36,4 +36,6 @@ int pingu_iface_init(struct ev_loop *loop, struct list_head *host_list); void pingu_iface_set_addr(struct pingu_iface *iface, int family, void *data, int len); +void pingu_iface_gateway(struct pingu_iface *iface, int family, + void *gateway_ptr, int metric, int action); #endif diff --git a/pingu_netlink.c b/pingu_netlink.c index 18d5082..9e670ed 100644 --- a/pingu_netlink.c +++ b/pingu_netlink.c @@ -383,7 +383,7 @@ static void netlink_addr_del_cb(struct nlmsghdr *nlmsg) pingu_iface_set_addr(iface, 0, NULL, 0); } -static void netlink_route_cb_action(struct nlmsghdr *msg, int action) +static void netlink_route_cb_action(struct nlmsghdr *msg, int action) { struct pingu_iface *iface; struct rtmsg *rtm = NLMSG_DATA(msg); @@ -426,7 +426,11 @@ static void netlink_route_cb_action(struct nlmsghdr *msg, int action) netlink_route_modify(&talk_fd, action, destination, rtm->rtm_dst_len, gateway, metric, - iface->index, rtm->rtm_table); + iface->index, rtm->rtm_table); + + if (destination == 0 && gateway != 0) + pingu_iface_gateway(iface, rtm->rtm_family, &gateway, + metric, action); } static void netlink_route_new_cb(struct nlmsghdr *msg) diff --git a/sockaddr_util.c b/sockaddr_util.c index ab67b2e..8dbb30a 100644 --- a/sockaddr_util.c +++ b/sockaddr_util.c @@ -1,4 +1,5 @@ +#include <arpa/inet.h> #include <netinet/in.h> #include <string.h> @@ -39,3 +40,16 @@ union sockaddr_any *sockaddr_init(union sockaddr_any *sa, int family, } return sa; } + +char *sockaddr_to_string(union sockaddr_any *sa, char *str, size_t size) +{ + switch (sa->sa.sa_family) { + case AF_INET: + inet_ntop(sa->sa.sa_family, &sa->sin.sin_addr, str, size); + break; + case AF_INET6: + inet_ntop(sa->sa.sa_family, &sa->sin6.sin6_addr, str, size); + break; + } + return str; +} diff --git a/sockaddr_util.h b/sockaddr_util.h index 654941e..7ac766b 100644 --- a/sockaddr_util.h +++ b/sockaddr_util.h @@ -14,5 +14,6 @@ union sockaddr_any { int sockaddr_cmp(union sockaddr_any *a, union sockaddr_any *b); union sockaddr_any *sockaddr_init(union sockaddr_any *sa, int family, void *addr); +char *sockaddr_to_string(union sockaddr_any *sa, char *str, size_t size); #endif /* SOCKADDR_UTIL_H */ |