1
/* Simple LPGLed rtnetlink library */
2
#include <sys/socket.h>
3
#include <linux/rtnetlink.h>
4
#include <linux/netlink.h>
5
#include <netinet/in.h>
8
#define hidden __attribute__((visibility("hidden")))
12
hidden void *rta_put(struct nlmsghdr *m, int type, int len)
14
struct rtattr *rta = (void *)m + NLMSG_ALIGN(m->nlmsg_len);
15
int rtalen = RTA_LENGTH(len);
18
rta->rta_len = rtalen;
19
m->nlmsg_len = NLMSG_ALIGN(m->nlmsg_len) + RTA_ALIGN(rtalen);
23
hidden struct rtattr *rta_get(struct nlmsghdr *m, struct rtattr *p, int offset)
28
rta = RTA_NEXT(p, m->nlmsg_len);
29
if (!RTA_OK(rta, m->nlmsg_len))
32
rta = (void *)m + NLMSG_ALIGN(offset);
38
rta_put_address(struct nlmsghdr *msg, int type, struct sockaddr *adr)
40
switch (adr->sa_family) {
42
struct in_addr *i = rta_put(msg, type, 4);
43
*i = ((struct sockaddr_in *)adr)->sin_addr;
47
struct in6_addr *i6 = rta_put(msg, type, 16);
48
*i6 = ((struct sockaddr_in6 *)adr)->sin6_addr;
57
/* Assumes no truncation. Make the buffer large enough. */
59
rtnetlink_request(struct nlmsghdr *msg, int buflen, struct sockaddr_nl *adr)
65
/* Use a private socket to avoid having to keep state
66
for a sequence number. */
67
rsk = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
70
n = sendto(rsk, msg, msg->nlmsg_len, 0, (struct sockaddr *)adr,
71
sizeof(struct sockaddr_nl));
73
socklen_t adrlen = sizeof(struct sockaddr_nl);
74
n = recvfrom(rsk, msg, buflen, 0, (struct sockaddr *)adr,
82
/* Assume we only get a single reply back. This is (hopefully?)
83
safe because it's a single use socket. */
84
if (msg->nlmsg_type == NLMSG_ERROR) {
85
struct nlmsgerr *err = NLMSG_DATA(msg);