]>
Commit | Line | Data |
---|---|---|
65018ae4 JHS |
1 | /* |
2 | * genl.c "genl" utility frontend. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public License | |
6 | * as published by the Free Software Foundation; either version | |
7 | * 2 of the License, or (at your option) any later version. | |
8 | * | |
9 | * Authors: Jamal Hadi Salim | |
10 | * | |
11 | */ | |
12 | ||
13 | #include <stdio.h> | |
14 | #include <stdlib.h> | |
15 | #include <unistd.h> | |
65018ae4 JHS |
16 | #include <fcntl.h> |
17 | #include <dlfcn.h> | |
18 | #include <sys/socket.h> | |
19 | #include <netinet/in.h> | |
20 | #include <arpa/inet.h> | |
21 | #include <string.h> | |
22 | #include <errno.h> | |
23 | #include <linux/netlink.h> | |
24 | #include <linux/rtnetlink.h> /* until we put our own header */ | |
fbef6555 | 25 | #include "version.h" |
65018ae4 JHS |
26 | #include "utils.h" |
27 | #include "genl_utils.h" | |
28 | ||
3e5f8e0a SH |
29 | int show_stats; |
30 | int show_details; | |
31 | int show_raw; | |
65018ae4 JHS |
32 | |
33 | static void *BODY; | |
3e5f8e0a | 34 | static struct genl_util *genl_list; |
65018ae4 JHS |
35 | |
36 | ||
cd554f2c | 37 | static int print_nofopt(struct nlmsghdr *n, void *arg) |
65018ae4 JHS |
38 | { |
39 | fprintf((FILE *) arg, "unknown genl type ..\n"); | |
40 | return 0; | |
41 | } | |
42 | ||
43 | static int parse_nofopt(struct genl_util *f, int argc, char **argv) | |
44 | { | |
45 | if (argc) { | |
3e5f8e0a SH |
46 | fprintf(stderr, |
47 | "Unknown genl \"%s\", hence option \"%s\" is unparsable\n", | |
48 | f->name, *argv); | |
65018ae4 JHS |
49 | return -1; |
50 | } | |
51 | ||
52 | return 0; | |
53 | } | |
54 | ||
b27f005b | 55 | static struct genl_util *get_genl_kind(const char *str) |
65018ae4 JHS |
56 | { |
57 | void *dlh; | |
58 | char buf[256]; | |
59 | struct genl_util *f; | |
60 | ||
61 | for (f = genl_list; f; f = f->next) | |
62 | if (strcmp(f->name, str) == 0) | |
63 | return f; | |
64 | ||
65 | snprintf(buf, sizeof(buf), "%s.so", str); | |
66 | dlh = dlopen(buf, RTLD_LAZY); | |
67 | if (dlh == NULL) { | |
68 | dlh = BODY; | |
69 | if (dlh == NULL) { | |
70 | dlh = BODY = dlopen(NULL, RTLD_LAZY); | |
71 | if (dlh == NULL) | |
72 | goto noexist; | |
73 | } | |
74 | } | |
75 | ||
76 | snprintf(buf, sizeof(buf), "%s_genl_util", str); | |
77 | ||
78 | f = dlsym(dlh, buf); | |
79 | if (f == NULL) | |
80 | goto noexist; | |
81 | reg: | |
82 | f->next = genl_list; | |
83 | genl_list = f; | |
84 | return f; | |
85 | ||
86 | noexist: | |
f89bb021 | 87 | f = calloc(1, sizeof(*f)); |
65018ae4 | 88 | if (f) { |
65018ae4 JHS |
89 | strncpy(f->name, str, 15); |
90 | f->parse_genlopt = parse_nofopt; | |
91 | f->print_genlopt = print_nofopt; | |
92 | goto reg; | |
93 | } | |
94 | return f; | |
95 | } | |
96 | ||
97 | static void usage(void) __attribute__((noreturn)); | |
98 | ||
99 | static void usage(void) | |
100 | { | |
3e5f8e0a SH |
101 | fprintf(stderr, |
102 | "Usage: genl [ OPTIONS ] OBJECT [help] }\n" | |
103 | "where OBJECT := { ctrl etc }\n" | |
104 | " OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -V[ersion] | -h[elp] }\n"); | |
65018ae4 JHS |
105 | exit(-1); |
106 | } | |
107 | ||
108 | int main(int argc, char **argv) | |
109 | { | |
65018ae4 JHS |
110 | while (argc > 1) { |
111 | if (argv[1][0] != '-') | |
112 | break; | |
113 | if (matches(argv[1], "-stats") == 0 || | |
114 | matches(argv[1], "-statistics") == 0) { | |
115 | ++show_stats; | |
116 | } else if (matches(argv[1], "-details") == 0) { | |
117 | ++show_details; | |
118 | } else if (matches(argv[1], "-raw") == 0) { | |
119 | ++show_raw; | |
120 | } else if (matches(argv[1], "-Version") == 0) { | |
fbef6555 | 121 | printf("genl utility, iproute2-%s\n", version); |
65018ae4 JHS |
122 | exit(0); |
123 | } else if (matches(argv[1], "-help") == 0) { | |
124 | usage(); | |
125 | } else { | |
3e5f8e0a SH |
126 | fprintf(stderr, |
127 | "Option \"%s\" is unknown, try \"genl -help\".\n", | |
128 | argv[1]); | |
65018ae4 JHS |
129 | exit(-1); |
130 | } | |
131 | argc--; argv++; | |
132 | } | |
133 | ||
134 | if (argc > 1) { | |
3e5f8e0a | 135 | struct genl_util *a; |
65018ae4 | 136 | int ret; |
3e5f8e0a | 137 | |
65018ae4 | 138 | a = get_genl_kind(argv[1]); |
1b129bf2 | 139 | if (!a) { |
3e5f8e0a | 140 | fprintf(stderr, "bad genl %s\n", argv[1]); |
1b129bf2 | 141 | exit(-1); |
65018ae4 JHS |
142 | } |
143 | ||
144 | ret = a->parse_genlopt(a, argc-1, argv+1); | |
145 | return ret; | |
65018ae4 JHS |
146 | } |
147 | ||
148 | usage(); | |
149 | } |