aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2011-07-28 17:43:12 +0200
committerNatanael Copa <ncopa@alpinelinux.org>2011-07-28 17:43:12 +0200
commit39eb92db66600bd1bf8a63f24145c9ff1fd7f966 (patch)
tree085e39909fd173de5a57b625231032d0e98fb800
parenta6ed4816fa8c39484dfa5f763efff7d8d7291d9e (diff)
downloadpingu-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.c42
-rw-r--r--pingu_iface.h2
-rw-r--r--pingu_netlink.c8
-rw-r--r--sockaddr_util.c14
-rw-r--r--sockaddr_util.h1
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 */