| OLD | NEW |
| 1 #include <errno.h> | 1 #include <errno.h> |
| 2 #include <string.h> | 2 #include <string.h> |
| 3 #include <syscall.h> | 3 #include <syscall.h> |
| 4 #include <sys/socket.h> | 4 #include <sys/socket.h> |
| 5 #include "netlink.h" | 5 #include "netlink.h" |
| 6 | 6 |
| 7 static int __netlink_enumerate(int fd, unsigned int seq, int type, int af, | 7 static int __netlink_enumerate(int fd, |
| 8 » int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx) | 8 unsigned int seq, |
| 9 { | 9 int type, |
| 10 » struct nlmsghdr *h; | 10 int af, |
| 11 » union { | 11 int (*cb)(void* ctx, struct nlmsghdr* h), |
| 12 » » uint8_t buf[8192]; | 12 void* ctx) { |
| 13 » » struct { | 13 struct nlmsghdr* h; |
| 14 » » » struct nlmsghdr nlh; | 14 union { |
| 15 » » » struct rtgenmsg g; | 15 uint8_t buf[8192]; |
| 16 » » } req; | 16 struct { |
| 17 » » struct nlmsghdr reply; | 17 struct nlmsghdr nlh; |
| 18 » } u; | 18 struct rtgenmsg g; |
| 19 » int r, ret; | 19 } req; |
| 20 struct nlmsghdr reply; |
| 21 } u; |
| 22 int r, ret; |
| 20 | 23 |
| 21 » memset(&u.req, 0, sizeof(u.req)); | 24 memset(&u.req, 0, sizeof(u.req)); |
| 22 » u.req.nlh.nlmsg_len = sizeof(u.req); | 25 u.req.nlh.nlmsg_len = sizeof(u.req); |
| 23 » u.req.nlh.nlmsg_type = type; | 26 u.req.nlh.nlmsg_type = type; |
| 24 » u.req.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; | 27 u.req.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; |
| 25 » u.req.nlh.nlmsg_seq = seq; | 28 u.req.nlh.nlmsg_seq = seq; |
| 26 » u.req.g.rtgen_family = af; | 29 u.req.g.rtgen_family = af; |
| 27 » r = send(fd, &u.req, sizeof(u.req), 0); | 30 r = send(fd, &u.req, sizeof(u.req), 0); |
| 28 » if (r < 0) return r; | 31 if (r < 0) |
| 32 return r; |
| 29 | 33 |
| 30 » while (1) { | 34 while (1) { |
| 31 » » r = recv(fd, u.buf, sizeof(u.buf), MSG_DONTWAIT); | 35 r = recv(fd, u.buf, sizeof(u.buf), MSG_DONTWAIT); |
| 32 » » if (r <= 0) return -1; | 36 if (r <= 0) |
| 33 » » for (h = &u.reply; NLMSG_OK(h, (void*)&u.buf[r]); h = NLMSG_NEXT
(h)) { | 37 return -1; |
| 34 » » » if (h->nlmsg_type == NLMSG_DONE) return 0; | 38 for (h = &u.reply; NLMSG_OK(h, (void*)&u.buf[r]); h = NLMSG_NEXT(h)) { |
| 35 » » » if (h->nlmsg_type == NLMSG_ERROR) return -1; | 39 if (h->nlmsg_type == NLMSG_DONE) |
| 36 » » » ret = cb(ctx, h); | 40 return 0; |
| 37 » » » if (ret) return ret; | 41 if (h->nlmsg_type == NLMSG_ERROR) |
| 38 » » } | 42 return -1; |
| 39 » } | 43 ret = cb(ctx, h); |
| 44 if (ret) |
| 45 return ret; |
| 46 } |
| 47 } |
| 40 } | 48 } |
| 41 | 49 |
| 42 int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct
nlmsghdr *h), void *ctx) | 50 int __rtnetlink_enumerate(int link_af, |
| 43 { | 51 int addr_af, |
| 44 » int fd, r; | 52 int (*cb)(void* ctx, struct nlmsghdr* h), |
| 53 void* ctx) { |
| 54 int fd, r; |
| 45 | 55 |
| 46 » fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE); | 56 fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); |
| 47 » if (fd < 0) return -1; | 57 if (fd < 0) |
| 48 » r = __netlink_enumerate(fd, 1, RTM_GETLINK, link_af, cb, ctx); | 58 return -1; |
| 49 » if (!r) r = __netlink_enumerate(fd, 2, RTM_GETADDR, addr_af, cb, ctx); | 59 r = __netlink_enumerate(fd, 1, RTM_GETLINK, link_af, cb, ctx); |
| 50 » __syscall(SYS_close,fd); | 60 if (!r) |
| 51 » return r; | 61 r = __netlink_enumerate(fd, 2, RTM_GETADDR, addr_af, cb, ctx); |
| 62 __syscall(SYS_close, fd); |
| 63 return r; |
| 52 } | 64 } |
| OLD | NEW |