summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am1
-rw-r--r--src/iftable.c151
-rw-r--r--src/rtnl.c106
-rw-r--r--src/rtnl.h4
4 files changed, 116 insertions, 146 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index def8175..b1d5e82 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,5 @@
include $(top_srcdir)/Make_global.am
-INCLUDES = $(all_includes) -I$(top_srcdir)/include
AM_CFLAGS=-fPIC -Wall
LIBS=
diff --git a/src/iftable.c b/src/iftable.c
index e97d2ba..7e6172b 100644
--- a/src/iftable.c
+++ b/src/iftable.c
@@ -13,9 +13,10 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
-
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <errno.h>
+#include <assert.h>
#include <linux/netdevice.h>
@@ -38,8 +39,8 @@ struct ifindex_map {
struct nlif_handle {
struct ifindex_map *ifindex_map[16];
struct rtnl_handle *rtnl_handle;
- struct rtnl_handler *ifadd_handler;
- struct rtnl_handler *ifdel_handler;
+ struct rtnl_handler ifadd_handler;
+ struct rtnl_handler ifdel_handler;
};
/* iftable_add - Add/Update an entry to/in the interface table
@@ -49,7 +50,7 @@ struct nlif_handle {
* This function adds/updates an entry in the intrface table.
* Returns -1 on error, 1 on success.
*/
-int iftable_add(struct nlmsghdr *n, void *arg)
+static int iftable_add(struct nlmsghdr *n, void *arg)
{
unsigned int hash;
struct ifinfomsg *ifi_msg = NLMSG_DATA(n);
@@ -120,7 +121,7 @@ int iftable_add(struct nlmsghdr *n, void *arg)
* Delete an entry from the interface table.
* Returns -1 on error, 0 if no matching entry was found or 1 on success.
*/
-int iftable_del(struct nlmsghdr *n, void *arg)
+static int iftable_del(struct nlmsghdr *n, void *arg)
{
struct ifinfomsg *ifi_msg = NLMSG_DATA(n);
struct rtattr *cb[IFLA_MAX+1];
@@ -179,6 +180,9 @@ int nlif_index2name(struct nlif_handle *nlif_handle,
{
struct ifindex_map *im;
+ assert(nlif_handle != NULL);
+ assert(name != NULL);
+
if (index == 0) {
strcpy(name, "*");
return 1;
@@ -189,15 +193,11 @@ int nlif_index2name(struct nlif_handle *nlif_handle,
return 1;
}
+ errno = ENOENT;
return -1;
}
-/* iftable_up - Determine whether a given interface is UP
- * @index: ifindex of interface
- *
- * Return value: -1 if interface unknown, 1 if interface up, 0 if not.
- */
-int iftable_up(struct nlif_handle *nlif_handle, unsigned int index)
+static int iftable_up(struct nlif_handle *nlif_handle, unsigned int index)
{
struct ifindex_map *im;
@@ -212,73 +212,6 @@ int iftable_up(struct nlif_handle *nlif_handle, unsigned int index)
return -1;
}
-static struct nlif_handle *init_or_fini(struct nlif_handle *orig)
-{
- struct nlif_handle *nlif_handle;
- int ret = 0;
-
- if (orig) {
- nlif_handle = orig;
- goto cleanup;
- }
-
-
- nlif_handle = calloc(1, sizeof(struct nlif_handle));
- if (!nlif_handle)
- goto cleanup_none;
-
- nlif_handle->ifadd_handler = calloc(1, sizeof(struct rtnl_handler));
- nlif_handle->ifadd_handler->nlmsg_type = RTM_NEWLINK;
- nlif_handle->ifadd_handler->handlefn = &iftable_add;
- nlif_handle->ifadd_handler->arg = nlif_handle;
- nlif_handle->ifdel_handler = calloc(1, sizeof(struct rtnl_handler));
- nlif_handle->ifdel_handler->nlmsg_type = RTM_DELLINK;
- nlif_handle->ifdel_handler->handlefn = &iftable_del;
- nlif_handle->ifdel_handler->arg = nlif_handle;
-
- nlif_handle->rtnl_handle = rtnl_init();
-
- if (! nlif_handle->rtnl_handle)
- goto cleanup_none;
-
- if (rtnl_handler_register(nlif_handle->rtnl_handle,
- nlif_handle->ifadd_handler) < 0) {
- ret = -1;
- goto cleanup_none;
- }
-
- if (rtnl_handler_register(nlif_handle->rtnl_handle,
- nlif_handle->ifdel_handler) < 0) {
- ret = -1;
- goto cleanup_0;
- }
-
-
- return nlif_handle;
-
-#if 0
- if (rtnl_wilddump_requet(rtnl_fd, AF_UNSPEC, RTM_GETLINK) < 0) {
- iftb_log(LOG_ERROR, "unable to send dump request");
- return -1;
- }
-
-#endif
-
-cleanup:
- rtnl_handler_unregister(nlif_handle->rtnl_handle,
- nlif_handle->ifadd_handler);
- free(nlif_handle->ifadd_handler);
-cleanup_0:
- rtnl_handler_unregister(nlif_handle->rtnl_handle,
- nlif_handle->ifdel_handler);
- free(nlif_handle->ifdel_handler);
- rtnl_fini(nlif_handle->rtnl_handle);
- free(nlif_handle);
-
-cleanup_none:
- return nlif_handle;
-}
-
/** Initialize interface table
*
* Initialize rtnl interface and interface table
@@ -288,8 +221,38 @@ cleanup_none:
*/
struct nlif_handle *nlif_open(void)
{
- iftb_log(LOG_DEBUG, "%s", __FUNCTION__);
- return init_or_fini(NULL);
+ struct nlif_handle *h;
+
+ h = calloc(1, sizeof(struct nlif_handle));
+ if (h == NULL)
+ goto err;
+
+ h->ifadd_handler.nlmsg_type = RTM_NEWLINK;
+ h->ifadd_handler.handlefn = iftable_add;
+ h->ifadd_handler.arg = h;
+ h->ifdel_handler.nlmsg_type = RTM_DELLINK;
+ h->ifdel_handler.handlefn = iftable_del;
+ h->ifdel_handler.arg = h;
+
+ h->rtnl_handle = rtnl_open();
+ if (h->rtnl_handle == NULL)
+ goto err;
+
+ if (rtnl_handler_register(h->rtnl_handle, &h->ifadd_handler) < 0)
+ goto err_close;
+
+ if (rtnl_handler_register(h->rtnl_handle, &h->ifdel_handler) < 0)
+ goto err_unregister;
+
+ return h;
+
+err_unregister:
+ rtnl_handler_unregister(h->rtnl_handle, &h->ifdel_handler);
+err_close:
+ rtnl_close(h->rtnl_handle);
+ free(h);
+err:
+ return NULL;
}
/** Destructor of interface table
@@ -297,9 +260,15 @@ struct nlif_handle *nlif_open(void)
* \param nlif_handle A pointer to a ::nlif_handle created
* via nlif_open()
*/
-void nlif_close(struct nlif_handle *nlif_handle)
+void nlif_close(struct nlif_handle *h)
{
- init_or_fini(nlif_handle);
+ assert(h != NULL);
+
+ rtnl_handler_unregister(h->rtnl_handle, &h->ifadd_handler);
+ rtnl_handler_unregister(h->rtnl_handle, &h->ifdel_handler);
+ rtnl_close(h->rtnl_handle);
+ free(h);
+ h = NULL; /* bugtrap */
}
/** Receive message from netlink and update interface table
@@ -309,10 +278,12 @@ void nlif_close(struct nlif_handle *nlif_handle)
*/
int nlif_catch(struct nlif_handle *nlif_handle)
{
- if (nlif_handle && nlif_handle->rtnl_handle)
+ assert(nlif_handle != NULL);
+
+ if (nlif_handle->rtnl_handle)
return rtnl_receive(nlif_handle->rtnl_handle);
- else
- return -1;
+
+ return -1;
}
/**
@@ -321,6 +292,8 @@ int nlif_catch(struct nlif_handle *nlif_handle)
*/
int nlif_query(struct nlif_handle *h)
{
+ assert(h != NULL);
+
if (rtnl_dump_type(h->rtnl_handle, RTM_GETLINK) < 0)
return -1;
@@ -334,8 +307,10 @@ int nlif_query(struct nlif_handle *h)
*/
int nlif_fd(struct nlif_handle *nlif_handle)
{
- if (nlif_handle && nlif_handle->rtnl_handle)
+ assert(nlif_handle != NULL);
+
+ if (nlif_handle->rtnl_handle)
return nlif_handle->rtnl_handle->rtnl_fd;
- else
- return -1;
+
+ return -1;
}
diff --git a/src/rtnl.c b/src/rtnl.c
index be1e77e..e6c5247 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -46,8 +46,7 @@ static int call_handler(struct rtnl_handle *rtnl_handle,
struct rtnl_handler *h = find_handler(rtnl_handle, type);
if (!h) {
- rtnl_log(LOG_DEBUG, "no registered handler for type %u",
- type);
+ rtnl_log(LOG_DEBUG, "no registered handler for type %u", type);
return 0;
}
@@ -109,24 +108,24 @@ int rtnl_parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
*/
int rtnl_dump_type(struct rtnl_handle *rtnl_handle, unsigned int type)
{
- struct {
- struct nlmsghdr nlh;
- struct rtgenmsg g;
- } req;
- struct sockaddr_nl nladdr;
+ struct {
+ struct nlmsghdr nlh;
+ struct rtgenmsg g;
+ } req;
+ struct sockaddr_nl nladdr;
- memset(&nladdr, 0, sizeof(nladdr));
+ memset(&nladdr, 0, sizeof(nladdr));
memset(&req, 0, sizeof(req));
- nladdr.nl_family = AF_NETLINK;
+ nladdr.nl_family = AF_NETLINK;
- req.nlh.nlmsg_len = sizeof(req);
- req.nlh.nlmsg_type = type;
- req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
- req.nlh.nlmsg_pid = 0;
- req.nlh.nlmsg_seq = rtnl_handle->rtnl_dump = ++(rtnl_handle->rtnl_seq);
- req.g.rtgen_family = AF_INET;
+ req.nlh.nlmsg_len = sizeof(req);
+ req.nlh.nlmsg_type = type;
+ req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
+ req.nlh.nlmsg_pid = 0;
+ req.nlh.nlmsg_seq = rtnl_handle->rtnl_dump = ++(rtnl_handle->rtnl_seq);
+ req.g.rtgen_family = AF_INET;
- return sendto(rtnl_handle->rtnl_fd, (void*)&req, sizeof(req), 0,
+ return sendto(rtnl_handle->rtnl_fd, (void*)&req, sizeof(req), 0,
(struct sockaddr*)&nladdr, sizeof(nladdr));
}
@@ -192,67 +191,64 @@ int rtnl_receive(struct rtnl_handle *rtnl_handle)
return 1;
}
-/* rtnl_init - constructor of rtnetlink module */
-struct rtnl_handle *rtnl_init(void)
+/* rtnl_open - constructor of rtnetlink module */
+struct rtnl_handle *rtnl_open(void)
{
- unsigned int addr_len;
- struct rtnl_handle *rtnl_handle = calloc(1, sizeof(struct rtnl_handle));
+ size_t addrlen;
+ struct rtnl_handle *h;
- if (! rtnl_handle)
+ h = calloc(1, sizeof(struct rtnl_handle));
+ if (!h)
return NULL;
- rtnl_handle->rtnl_seq = 0;
- rtnl_handle->handlers = NULL;
+ addrlen = sizeof(h->rtnl_local);
- rtnl_handle->rtnl_local.nl_pid = getpid();
- rtnl_handle->rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (rtnl_handle->rtnl_fd < 0) {
+ h->rtnl_local.nl_pid = getpid();
+ h->rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (h->rtnl_fd < 0) {
rtnl_log(LOG_ERROR, "unable to create rtnetlink socket");
- free(rtnl_handle);
- return NULL;
+ goto err;
}
- memset(&(rtnl_handle->rtnl_local), 0, sizeof(rtnl_handle->rtnl_local));
- rtnl_handle->rtnl_local.nl_family = AF_NETLINK;
- rtnl_handle->rtnl_local.nl_groups =
- RTMGRP_IPV4_ROUTE|RTMGRP_IPV4_IFADDR|RTMGRP_LINK;
- if (bind(rtnl_handle->rtnl_fd,
- (struct sockaddr *)&(rtnl_handle->rtnl_local),
- sizeof(rtnl_handle->rtnl_local)) < 0) {
+ memset(&h->rtnl_local, 0, sizeof(h->rtnl_local));
+ h->rtnl_local.nl_family = AF_NETLINK;
+ h->rtnl_local.nl_groups =
+ RTMGRP_IPV4_ROUTE|RTMGRP_IPV4_IFADDR|RTMGRP_LINK;
+ if (bind(h->rtnl_fd, (struct sockaddr *) &h->rtnl_local, addrlen) < 0) {
rtnl_log(LOG_ERROR, "unable to bind rtnetlink socket");
- free(rtnl_handle);
- return NULL;
+ goto err_close;
}
- addr_len = sizeof(rtnl_handle->rtnl_local);
- if (getsockname(rtnl_handle->rtnl_fd,
- (struct sockaddr *)&(rtnl_handle->rtnl_local),
- &addr_len) < 0) {
+ if (getsockname(h->rtnl_fd,
+ (struct sockaddr *) &h->rtnl_local,
+ &addrlen) < 0) {
rtnl_log(LOG_ERROR, "cannot gescockname(rtnl_socket)");
- free(rtnl_handle);
- return NULL;
+ goto err_close;
}
- if (addr_len != sizeof(rtnl_handle->rtnl_local)) {
+ if (addrlen != sizeof(h->rtnl_local)) {
rtnl_log(LOG_ERROR, "invalid address size %u", addr_len);
- free(rtnl_handle);
- return NULL;
+ goto err_close;
}
- if (rtnl_handle->rtnl_local.nl_family != AF_NETLINK) {
- rtnl_log(LOG_ERROR, "invalid AF %u",
- rtnl_handle->rtnl_local.nl_family);
- free(rtnl_handle);
- return NULL;
+ if (h->rtnl_local.nl_family != AF_NETLINK) {
+ rtnl_log(LOG_ERROR, "invalid AF %u", h->rtnl_local.nl_family);
+ goto err_close;
}
- rtnl_handle->rtnl_seq = time(NULL);
+ h->rtnl_seq = time(NULL);
- return rtnl_handle;
+ return h;
+
+err_close:
+ close(h->rtnl_fd);
+err:
+ free(h);
+ return NULL;
}
-/* rtnl_fini - destructor of rtnetlink module */
-void rtnl_fini(struct rtnl_handle *rtnl_handle)
+/* rtnl_close - destructor of rtnetlink module */
+void rtnl_close(struct rtnl_handle *rtnl_handle)
{
close(rtnl_handle->rtnl_fd);
free(rtnl_handle);
diff --git a/src/rtnl.h b/src/rtnl.h
index b6644e6..bf018d4 100644
--- a/src/rtnl.h
+++ b/src/rtnl.h
@@ -29,8 +29,8 @@ int rtnl_parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
int rtnl_dump_type(struct rtnl_handle *rtnl_handle, unsigned int type);
/* api for core program */
-struct rtnl_handle *rtnl_init(void);
-void rtnl_fini(struct rtnl_handle *rtnl_handle);
+struct rtnl_handle *rtnl_open(void);
+void rtnl_close(struct rtnl_handle *rtnl_handle);
int rtnl_receive(struct rtnl_handle *rtnl_handle);
#endif