1#include <stdint.h>
2
3/* linux/netlink.h */
4
5#define NETLINK_ROUTE 0
6
7struct nlmsghdr {
8    uint32_t nlmsg_len;
9    uint16_t nlmsg_type;
10    uint16_t nlmsg_flags;
11    uint32_t nlmsg_seq;
12    uint32_t nlmsg_pid;
13};
14
15#define NLM_F_REQUEST 1
16#define NLM_F_MULTI 2
17#define NLM_F_ACK 4
18
19#define NLM_F_ROOT 0x100
20#define NLM_F_MATCH 0x200
21#define NLM_F_ATOMIC 0x400
22#define NLM_F_DUMP (NLM_F_ROOT | NLM_F_MATCH)
23
24#define NLMSG_NOOP 0x1
25#define NLMSG_ERROR 0x2
26#define NLMSG_DONE 0x3
27#define NLMSG_OVERRUN 0x4
28
29/* linux/rtnetlink.h */
30
31#define RTM_NEWLINK 16
32#define RTM_GETLINK 18
33#define RTM_NEWADDR 20
34#define RTM_GETADDR 22
35
36struct rtattr {
37    unsigned short rta_len;
38    unsigned short rta_type;
39};
40
41struct rtgenmsg {
42    unsigned char rtgen_family;
43};
44
45struct ifinfomsg {
46    unsigned char ifi_family;
47    unsigned char __ifi_pad;
48    unsigned short ifi_type;
49    int ifi_index;
50    unsigned ifi_flags;
51    unsigned ifi_change;
52};
53
54/* linux/if_link.h */
55
56#define IFLA_ADDRESS 1
57#define IFLA_BROADCAST 2
58#define IFLA_IFNAME 3
59#define IFLA_STATS 7
60
61/* linux/if_addr.h */
62
63struct ifaddrmsg {
64    uint8_t ifa_family;
65    uint8_t ifa_prefixlen;
66    uint8_t ifa_flags;
67    uint8_t ifa_scope;
68    uint32_t ifa_index;
69};
70
71#define IFA_ADDRESS 1
72#define IFA_LOCAL 2
73#define IFA_LABEL 3
74#define IFA_BROADCAST 4
75
76/* musl */
77
78#define NETLINK_ALIGN(len) (((len) + 3) & ~3)
79#define NLMSG_DATA(nlh) ((void*)((char*)(nlh) + sizeof(struct nlmsghdr)))
80#define NLMSG_DATALEN(nlh) ((nlh)->nlmsg_len - sizeof(struct nlmsghdr))
81#define NLMSG_DATAEND(nlh) ((char*)(nlh) + (nlh)->nlmsg_len)
82#define NLMSG_NEXT(nlh) (struct nlmsghdr*)((char*)(nlh) + NETLINK_ALIGN((nlh)->nlmsg_len))
83#define NLMSG_OK(nlh, end) ((char*)(end) - (char*)(nlh) >= sizeof(struct nlmsghdr))
84
85#define RTA_DATA(rta) ((void*)((char*)(rta) + sizeof(struct rtattr)))
86#define RTA_DATALEN(rta) ((rta)->rta_len - sizeof(struct rtattr))
87#define RTA_DATAEND(rta) ((char*)(rta) + (rta)->rta_len)
88#define RTA_NEXT(rta) (struct rtattr*)((char*)(rta) + NETLINK_ALIGN((rta)->rta_len))
89#define RTA_OK(nlh, end) ((char*)(end) - (char*)(rta) >= sizeof(struct rtattr))
90
91#define NLMSG_RTA(nlh, len) ((void*)((char*)(nlh) + sizeof(struct nlmsghdr) + NETLINK_ALIGN(len)))
92#define NLMSG_RTAOK(rta, nlh) RTA_OK(rta, NLMSG_DATAEND(nlh))
93
94int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void* ctx, struct nlmsghdr* h),
95                          void* ctx);
96