4 #include <sys/socket.h>
7 static int __netlink_enumerate(int fd
, unsigned int seq
, int type
, int af
,
8 int (*cb
)(void *ctx
, struct nlmsghdr
*h
), void *ctx
)
17 struct nlmsghdr reply
;
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);
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;
42 int __rtnetlink_enumerate(int link_af
, int addr_af
, int (*cb
)(void *ctx
, struct nlmsghdr
*h
), void *ctx
)
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
);