diff options
author | /C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org </C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org> | 2007-01-26 02:35:30 +0000 |
---|---|---|
committer | /C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org </C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org> | 2007-01-26 02:35:30 +0000 |
commit | a0092d15955f23b0f32506a5666db365dfa56510 (patch) | |
tree | 6aef3b7ced37a50badf93b81bde4e7f3c1669b9b /src/rtnl.c | |
parent | 7e1f591a4796d45f8c655110cf3924e6a4566efb (diff) |
- Initial commit of index2interface API (Eric Leblond), still work to do
- added a test file to utils/iftest.c
Diffstat (limited to 'src/rtnl.c')
-rw-r--r-- | src/rtnl.c | 114 |
1 files changed, 64 insertions, 50 deletions
@@ -1,6 +1,8 @@ /* rtnl - rtnetlink utility functions * * (C) 2004 by Astaro AG, written by Harald Welte <hwelte@astaro.com> + * + * Adapted to nfnetlink by Eric Leblond <eric@inl.fr> * * This software is free software and licensed under GNU GPLv2. * @@ -26,26 +28,22 @@ #define rtnl_log(x, ...) -static int rtnl_fd; -static int rtnl_seq = 0; -static int rtnl_dump; -static struct sockaddr_nl rtnl_local; - -static struct rtnl_handler *handlers = NULL; - -static inline struct rtnl_handler *find_handler(u_int16_t type) +static inline struct rtnl_handler * +find_handler(struct rtnl_handle *rtnl_handle, u_int16_t type) { struct rtnl_handler *h; - for (h = handlers; h; h = h->next) { + for (h = rtnl_handle->handlers; h; h = h->next) { if (h->nlmsg_type == type) return h; } return NULL; } -static int call_handler(u_int16_t type, struct nlmsghdr *hdr) +static int call_handler(struct rtnl_handle *rtnl_handle, + u_int16_t type, + struct nlmsghdr *hdr) { - struct rtnl_handler *h = find_handler(type); + struct rtnl_handler *h = find_handler(rtnl_handle, type); if (!h) { rtnl_log(LOG_DEBUG, "no registered handler for type %u", @@ -59,31 +57,33 @@ static int call_handler(u_int16_t type, struct nlmsghdr *hdr) /* rtnl_handler_register - register handler for given nlmsg type * @hdlr: handler structure */ -int rtnl_handler_register(struct rtnl_handler *hdlr) +int rtnl_handler_register(struct rtnl_handle *rtnl_handle, + struct rtnl_handler *hdlr) { rtnl_log(LOG_DEBUG, "registering handler for type %u", hdlr->nlmsg_type); - hdlr->next = handlers; - handlers = hdlr; + hdlr->next = rtnl_handle->handlers; + rtnl_handle->handlers = hdlr; return 1; } /* rtnl_handler_unregister - unregister handler for given nlmst type * @hdlr: handler structure */ -int rtnl_handler_unregister(struct rtnl_handler *hdlr) +int rtnl_handler_unregister(struct rtnl_handle *rtnl_handle, + struct rtnl_handler *hdlr) { struct rtnl_handler *h, *prev = NULL; rtnl_log(LOG_DEBUG, "unregistering handler for type %u", hdlr->nlmsg_type); - for (h = handlers; h; h = h->next) { + for (h = rtnl_handle->handlers; h; h = h->next) { if (h == hdlr) { if (prev) prev->next = h->next; else - handlers = h->next; + rtnl_handle->handlers = h->next; return 1; } prev = h; @@ -107,7 +107,7 @@ int rtnl_parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) /* rtnl_dump_type - ask rtnetlink to dump a specific table * @type: type of table to be dumped */ -int rtnl_dump_type(unsigned int type) +int rtnl_dump_type(struct rtnl_handle *rtnl_handle, unsigned int type) { struct { struct nlmsghdr nlh; @@ -123,15 +123,15 @@ int rtnl_dump_type(unsigned int type) 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_dump = ++rtnl_seq; + req.nlh.nlmsg_seq = rtnl_handle->rtnl_dump = ++(rtnl_handle->rtnl_seq); req.g.rtgen_family = AF_INET; - return sendto(rtnl_fd, (void*)&req, sizeof(req), 0, + return sendto(rtnl_handle->rtnl_fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); } /* rtnl_receive - receive netlink packets from rtnetlink socket */ -int rtnl_receive() +int rtnl_receive(struct rtnl_handle *rtnl_handle) { int status; char buf[8192]; @@ -146,7 +146,7 @@ int rtnl_receive() 0 }; - status = recvmsg(rtnl_fd, &msg, 0); + status = recvmsg(rtnl_handle->rtnl_fd, &msg, 0); if (status < 0) { if (errno == EINTR) return 0; @@ -184,7 +184,7 @@ int rtnl_receive() return -1; } - if (call_handler(h->nlmsg_type, h) == 0) + if (call_handler(rtnl_handle, h->nlmsg_type, h) == 0) rtnl_log(LOG_NOTICE, "unhandled nlmsg_type %u", h->nlmsg_type); h = NLMSG_NEXT(h, status); @@ -193,54 +193,68 @@ int rtnl_receive() } /* rtnl_init - constructor of rtnetlink module */ -int rtnl_init(void) +struct rtnl_handle *rtnl_init(void) { - int addr_len; + unsigned int addr_len; + struct rtnl_handle *rtnl_handle = calloc(1, sizeof(struct rtnl_handle)); + + if (! rtnl_handle) + return NULL; + + rtnl_handle->rtnl_seq = 0; + rtnl_handle->handlers = NULL; - rtnl_local.nl_pid = getpid(); - rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (rtnl_fd < 0) { + rtnl_handle->rtnl_local.nl_pid = getpid(); + rtnl_handle->rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (rtnl_handle->rtnl_fd < 0) { rtnl_log(LOG_ERROR, "unable to create rtnetlink socket"); - return -1; + free(rtnl_handle); + return NULL; } - memset(&rtnl_local, 0, sizeof(rtnl_local)); - rtnl_local.nl_family = AF_NETLINK; - rtnl_local.nl_groups = RTMGRP_IPV4_ROUTE|RTMGRP_IPV4_IFADDR|RTMGRP_LINK; - - if (bind(rtnl_fd, (struct sockaddr *)&rtnl_local, sizeof(rtnl_local)) < 0) { + 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) { rtnl_log(LOG_ERROR, "unable to bind rtnetlink socket"); - return -1; + free(rtnl_handle); + return NULL; } - addr_len = sizeof(rtnl_local); - if (getsockname(rtnl_fd, (struct sockaddr *)&rtnl_local, + addr_len = sizeof(rtnl_handle->rtnl_local); + if (getsockname(rtnl_handle->rtnl_fd, + (struct sockaddr *)&(rtnl_handle->rtnl_local), &addr_len) < 0) { rtnl_log(LOG_ERROR, "cannot gescockname(rtnl_socket)"); - return -1; + free(rtnl_handle); + return NULL; } - if (addr_len != sizeof(rtnl_local)) { + if (addr_len != sizeof(rtnl_handle->rtnl_local)) { rtnl_log(LOG_ERROR, "invalid address size %u", addr_len); - return -1; + free(rtnl_handle); + return NULL; } - if (rtnl_local.nl_family != AF_NETLINK) { - rtnl_log(LOG_ERROR, "invalid AF %u", rtnl_local.nl_family); - return -1; + 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; } - rtnl_seq = time(NULL); + rtnl_handle->rtnl_seq = time(NULL); - return rtnl_fd; + return rtnl_handle; } /* rtnl_fini - destructor of rtnetlink module */ -void rtnl_fini(void) +void rtnl_fini(struct rtnl_handle *rtnl_handle) { - close(rtnl_fd); + close(rtnl_handle->rtnl_fd); + free(rtnl_handle); return; } - - - |