X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Flibnetlink.c;h=67951fe7d768398bee7d7c283e90e96d2b7f7ce5;hb=refs%2Fheads%2Ffedora;hp=4cd2b2a11a5655a7999be27b32a5c4fb6219e341;hpb=cb820e861caa85bb3942ab0c673e04b9408be0ad;p=iproute2.git diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 4cd2b2a..67951fe 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -30,9 +30,10 @@ void rtnl_close(struct rtnl_handle *rth) close(rth->fd); } -int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol) +int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, + int protocol) { - int addr_len; + socklen_t addr_len; int sndbuf = 32768; int rcvbuf = 32768; @@ -95,6 +96,7 @@ int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; + memset(&req, 0, sizeof(req)); req.nlh.nlmsg_len = sizeof(req); req.nlh.nlmsg_type = type; req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; @@ -102,7 +104,8 @@ int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) req.nlh.nlmsg_seq = rth->dump = ++rth->seq; req.g.rtgen_family = family; - return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); + return sendto(rth->fd, (void*)&req, sizeof(req), 0, + (struct sockaddr*)&nladdr, sizeof(nladdr)); } int rtnl_send(struct rtnl_handle *rth, const char *buf, int len) @@ -119,12 +122,15 @@ int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) { struct nlmsghdr nlh; struct sockaddr_nl nladdr; - struct iovec iov[2] = { { &nlh, sizeof(nlh) }, { req, len } }; + struct iovec iov[2] = { + { .iov_base = &nlh, .iov_len = sizeof(nlh) }, + { .iov_base = req, .iov_len = len } + }; struct msghdr msg = { - (void*)&nladdr, sizeof(nladdr), - iov, 2, - NULL, 0, - 0 + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = iov, + .msg_iovlen = 2, }; memset(&nladdr, 0, sizeof(nladdr)); @@ -145,21 +151,22 @@ int rtnl_dump_filter(struct rtnl_handle *rth, rtnl_filter_t junk, void *arg2) { - char buf[16384]; struct sockaddr_nl nladdr; - struct iovec iov = { buf, sizeof(buf) }; + struct iovec iov; + struct msghdr msg = { + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + char buf[16384]; + iov.iov_base = buf; while (1) { int status; struct nlmsghdr *h; - struct msghdr msg = { - (void*)&nladdr, sizeof(nladdr), - &iov, 1, - NULL, 0, - 0 - }; - + iov.iov_len = sizeof(buf); status = recvmsg(rth->fd, &msg, 0); if (status < 0) { @@ -168,14 +175,11 @@ int rtnl_dump_filter(struct rtnl_handle *rth, perror("OVERRUN"); continue; } + if (status == 0) { fprintf(stderr, "EOF on netlink\n"); return -1; } - if (msg.msg_namelen != sizeof(nladdr)) { - fprintf(stderr, "sender address length == %d\n", msg.msg_namelen); - exit(1); - } h = (struct nlmsghdr*)buf; while (NLMSG_OK(h, status)) { @@ -231,14 +235,17 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, unsigned seq; struct nlmsghdr *h; struct sockaddr_nl nladdr; - struct iovec iov = { (void*)n, n->nlmsg_len }; - char buf[16384]; + struct iovec iov = { + .iov_base = (void*) n, + .iov_len = n->nlmsg_len + }; struct msghdr msg = { - (void*)&nladdr, sizeof(nladdr), - &iov, 1, - NULL, 0, - 0 + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, }; + char buf[16384]; memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; @@ -301,6 +308,9 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, if (err < 0) return err; } + /* Don't forget to skip that message. */ + status -= NLMSG_ALIGN(len); + h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); continue; } @@ -340,7 +350,7 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, } } -int rtnl_listen(struct rtnl_handle *rtnl, +int rtnl_listen(struct rtnl_handle *rtnl, rtnl_filter_t handler, void *jarg) { @@ -348,22 +358,20 @@ int rtnl_listen(struct rtnl_handle *rtnl, struct nlmsghdr *h; struct sockaddr_nl nladdr; struct iovec iov; - char buf[8192]; struct msghdr msg = { - (void*)&nladdr, sizeof(nladdr), - &iov, 1, - NULL, 0, - 0 + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, }; + char buf[8192]; memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; nladdr.nl_pid = 0; nladdr.nl_groups = 0; - iov.iov_base = buf; - while (1) { iov.iov_len = sizeof(buf); status = recvmsg(rtnl->fd, &msg, 0); @@ -485,13 +493,13 @@ int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data) return 0; } -int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, +int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen) { int len = RTA_LENGTH(alen); struct rtattr *rta; - if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) { + if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) { fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen); return -1; } @@ -499,7 +507,7 @@ int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, rta->rta_type = type; rta->rta_len = len; memcpy(RTA_DATA(rta), data, alen); - n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len; + n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); return 0; } @@ -533,13 +541,13 @@ int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data) return 0; } -int rta_addattr_l(struct rtattr *rta, int maxlen, int type, +int rta_addattr_l(struct rtattr *rta, int maxlen, int type, const void *data, int alen) { struct rtattr *subrta; int len = RTA_LENGTH(alen); - if (RTA_ALIGN(rta->rta_len) + len > maxlen) { + if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) { fprintf(stderr,"rta_addattr_l: Error! max allowed bound %d exceeded\n",maxlen); return -1; } @@ -547,7 +555,7 @@ int rta_addattr_l(struct rtattr *rta, int maxlen, int type, subrta->rta_type = type; subrta->rta_len = len; memcpy(RTA_DATA(subrta), data, alen); - rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len; + rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len); return 0; }