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