]>
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> | |
16 | #include <syslog.h> | |
17 | #include <fcntl.h> | |
18 | #include <dlfcn.h> | |
19 | #include <sys/socket.h> | |
20 | #include <netinet/in.h> | |
21 | #include <arpa/inet.h> | |
22 | #include <string.h> | |
23 | #include <errno.h> | |
24 | #include <linux/netlink.h> | |
25 | #include <linux/rtnetlink.h> /* until we put our own header */ | |
26 | #include "SNAPSHOT.h" | |
27 | #include "utils.h" | |
28 | #include "genl_utils.h" | |
29 | ||
30 | int show_stats = 0; | |
31 | int show_details = 0; | |
32 | int show_raw = 0; | |
33 | int resolve_hosts = 0; | |
34 | ||
35 | static void *BODY; | |
36 | static struct genl_util * genl_list; | |
37 | ||
38 | ||
39 | static int print_nofopt(const struct sockaddr_nl *who, struct nlmsghdr *n, | |
40 | void *arg) | |
41 | { | |
42 | fprintf((FILE *) arg, "unknown genl type ..\n"); | |
43 | return 0; | |
44 | } | |
45 | ||
46 | static int parse_nofopt(struct genl_util *f, int argc, char **argv) | |
47 | { | |
48 | if (argc) { | |
49 | fprintf(stderr, "Unknown genl \"%s\", hence option \"%s\" " | |
50 | "is unparsable\n", f->name, *argv); | |
51 | return -1; | |
52 | } | |
53 | ||
54 | return 0; | |
55 | } | |
56 | ||
57 | static struct genl_util *get_genl_kind(char *str) | |
58 | { | |
59 | void *dlh; | |
60 | char buf[256]; | |
61 | struct genl_util *f; | |
62 | ||
63 | for (f = genl_list; f; f = f->next) | |
64 | if (strcmp(f->name, str) == 0) | |
65 | return f; | |
66 | ||
67 | snprintf(buf, sizeof(buf), "%s.so", str); | |
68 | dlh = dlopen(buf, RTLD_LAZY); | |
69 | if (dlh == NULL) { | |
70 | dlh = BODY; | |
71 | if (dlh == NULL) { | |
72 | dlh = BODY = dlopen(NULL, RTLD_LAZY); | |
73 | if (dlh == NULL) | |
74 | goto noexist; | |
75 | } | |
76 | } | |
77 | ||
78 | snprintf(buf, sizeof(buf), "%s_genl_util", str); | |
79 | ||
80 | f = dlsym(dlh, buf); | |
81 | if (f == NULL) | |
82 | goto noexist; | |
83 | reg: | |
84 | f->next = genl_list; | |
85 | genl_list = f; | |
86 | return f; | |
87 | ||
88 | noexist: | |
89 | f = malloc(sizeof(*f)); | |
90 | if (f) { | |
91 | memset(f, 0, sizeof(*f)); | |
92 | strncpy(f->name, str, 15); | |
93 | f->parse_genlopt = parse_nofopt; | |
94 | f->print_genlopt = print_nofopt; | |
95 | goto reg; | |
96 | } | |
97 | return f; | |
98 | } | |
99 | ||
100 | static void usage(void) __attribute__((noreturn)); | |
101 | ||
102 | static void usage(void) | |
103 | { | |
104 | fprintf(stderr, "Usage: genl [ OPTIONS ] OBJECT | help }\n" | |
105 | "where OBJECT := { ctrl etc }\n" | |
106 | " OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] }\n"); | |
107 | exit(-1); | |
108 | } | |
109 | ||
110 | int main(int argc, char **argv) | |
111 | { | |
112 | char *basename; | |
113 | ||
114 | basename = strrchr(argv[0], '/'); | |
115 | if (basename == NULL) | |
116 | basename = argv[0]; | |
117 | else | |
118 | basename++; | |
119 | ||
120 | while (argc > 1) { | |
121 | if (argv[1][0] != '-') | |
122 | break; | |
123 | if (matches(argv[1], "-stats") == 0 || | |
124 | matches(argv[1], "-statistics") == 0) { | |
125 | ++show_stats; | |
126 | } else if (matches(argv[1], "-details") == 0) { | |
127 | ++show_details; | |
128 | } else if (matches(argv[1], "-raw") == 0) { | |
129 | ++show_raw; | |
130 | } else if (matches(argv[1], "-Version") == 0) { | |
131 | printf("genl utility, iproute2-ss%s\n", SNAPSHOT); | |
132 | exit(0); | |
133 | } else if (matches(argv[1], "-help") == 0) { | |
134 | usage(); | |
135 | } else { | |
136 | fprintf(stderr, "Option \"%s\" is unknown, try " | |
137 | "\"genl -help\".\n", argv[1]); | |
138 | exit(-1); | |
139 | } | |
140 | argc--; argv++; | |
141 | } | |
142 | ||
143 | if (argc > 1) { | |
144 | int ret; | |
145 | struct genl_util *a = NULL; | |
146 | a = get_genl_kind(argv[1]); | |
147 | if (NULL == a) { | |
148 | fprintf(stderr,"bad genl %s\n",argv[1]); | |
149 | } | |
150 | ||
151 | ret = a->parse_genlopt(a, argc-1, argv+1); | |
152 | return ret; | |
65018ae4 JHS |
153 | } |
154 | ||
155 | usage(); | |
156 | } |