]>
Commit | Line | Data |
---|---|---|
8afcc288 JA |
1 | /* |
2 | * libgenl.c GENL library | |
3 | */ | |
4 | ||
5 | #include <stdio.h> | |
6 | #include <stdlib.h> | |
7 | #include <unistd.h> | |
8 | ||
9 | #include <linux/genetlink.h> | |
10 | #include "libgenl.h" | |
11 | ||
12 | static int genl_parse_getfamily(struct nlmsghdr *nlh) | |
13 | { | |
14 | struct rtattr *tb[CTRL_ATTR_MAX + 1]; | |
15 | struct genlmsghdr *ghdr = NLMSG_DATA(nlh); | |
16 | int len = nlh->nlmsg_len; | |
17 | struct rtattr *attrs; | |
18 | ||
19 | if (nlh->nlmsg_type != GENL_ID_CTRL) { | |
20 | fprintf(stderr, "Not a controller message, nlmsg_len=%d " | |
21 | "nlmsg_type=0x%x\n", nlh->nlmsg_len, nlh->nlmsg_type); | |
22 | return -1; | |
23 | } | |
24 | ||
25 | len -= NLMSG_LENGTH(GENL_HDRLEN); | |
26 | ||
27 | if (len < 0) { | |
28 | fprintf(stderr, "wrong controller message len %d\n", len); | |
29 | return -1; | |
30 | } | |
31 | ||
32 | if (ghdr->cmd != CTRL_CMD_NEWFAMILY) { | |
33 | fprintf(stderr, "Unknown controller command %d\n", ghdr->cmd); | |
34 | return -1; | |
35 | } | |
36 | ||
37 | attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN); | |
38 | parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len); | |
39 | ||
40 | if (tb[CTRL_ATTR_FAMILY_ID] == NULL) { | |
41 | fprintf(stderr, "Missing family id TLV\n"); | |
42 | return -1; | |
43 | } | |
44 | ||
45 | return rta_getattr_u16(tb[CTRL_ATTR_FAMILY_ID]); | |
46 | } | |
47 | ||
48 | int genl_resolve_family(struct rtnl_handle *grth, const char *family) | |
49 | { | |
328d482c JA |
50 | GENL_REQUEST(req, 1024, GENL_ID_CTRL, 0, 0, CTRL_CMD_GETFAMILY, |
51 | NLM_F_REQUEST); | |
8afcc288 | 52 | |
328d482c | 53 | addattr_l(&req.n, sizeof(req), CTRL_ATTR_FAMILY_NAME, |
8afcc288 JA |
54 | family, strlen(family) + 1); |
55 | ||
c079e121 | 56 | if (rtnl_talk(grth, &req.n, &req.n, sizeof(req)) < 0) { |
8afcc288 JA |
57 | fprintf(stderr, "Error talking to the kernel\n"); |
58 | return -2; | |
59 | } | |
60 | ||
61 | return genl_parse_getfamily(&req.n); | |
62 | } |