]>
Commit | Line | Data |
---|---|---|
4bd62446 DB |
1 | /* |
2 | * tc_exec.c "tc exec". | |
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: Daniel Borkmann <daniel@iogearbox.net> | |
10 | */ | |
11 | ||
12 | #include <stdio.h> | |
13 | #include <stdlib.h> | |
14 | #include <dlfcn.h> | |
15 | ||
16 | #include "utils.h" | |
17 | ||
18 | #include "tc_util.h" | |
19 | #include "tc_common.h" | |
20 | ||
21 | static struct exec_util *exec_list; | |
32a121cb | 22 | static void *BODY; |
4bd62446 DB |
23 | |
24 | static void usage(void) | |
25 | { | |
26 | fprintf(stderr, "Usage: tc exec [ EXEC_TYPE ] [ help | OPTIONS ]\n"); | |
27 | fprintf(stderr, "Where:\n"); | |
28 | fprintf(stderr, "EXEC_TYPE := { bpf | etc. }\n"); | |
29 | fprintf(stderr, "OPTIONS := ... try tc exec <desired EXEC_KIND> help\n"); | |
30 | } | |
31 | ||
32 | static int parse_noeopt(struct exec_util *eu, int argc, char **argv) | |
33 | { | |
34 | if (argc) { | |
32a121cb SH |
35 | fprintf(stderr, "Unknown exec \"%s\", hence option \"%s\" is unparsable\n", |
36 | eu->id, *argv); | |
4bd62446 DB |
37 | return -1; |
38 | } | |
39 | ||
40 | return 0; | |
41 | } | |
42 | ||
43 | static struct exec_util *get_exec_kind(const char *name) | |
44 | { | |
45 | struct exec_util *eu; | |
46 | char buf[256]; | |
47 | void *dlh; | |
48 | ||
49 | for (eu = exec_list; eu; eu = eu->next) | |
50 | if (strcmp(eu->id, name) == 0) | |
51 | return eu; | |
52 | ||
53 | snprintf(buf, sizeof(buf), "%s/e_%s.so", get_tc_lib(), name); | |
54 | dlh = dlopen(buf, RTLD_LAZY); | |
55 | if (dlh == NULL) { | |
56 | dlh = BODY; | |
57 | if (dlh == NULL) { | |
58 | dlh = BODY = dlopen(NULL, RTLD_LAZY); | |
59 | if (dlh == NULL) | |
60 | goto noexist; | |
61 | } | |
62 | } | |
63 | ||
64 | snprintf(buf, sizeof(buf), "%s_exec_util", name); | |
65 | eu = dlsym(dlh, buf); | |
66 | if (eu == NULL) | |
67 | goto noexist; | |
68 | reg: | |
69 | eu->next = exec_list; | |
70 | exec_list = eu; | |
71 | ||
72 | return eu; | |
73 | noexist: | |
f89bb021 | 74 | eu = calloc(1, sizeof(*eu)); |
4bd62446 | 75 | if (eu) { |
4bd62446 DB |
76 | strncpy(eu->id, name, sizeof(eu->id) - 1); |
77 | eu->parse_eopt = parse_noeopt; | |
78 | goto reg; | |
79 | } | |
80 | ||
81 | return eu; | |
82 | } | |
83 | ||
84 | int do_exec(int argc, char **argv) | |
85 | { | |
86 | struct exec_util *eu; | |
b317557f | 87 | char kind[FILTER_NAMESZ] = {}; |
4bd62446 DB |
88 | |
89 | if (argc < 1) { | |
90 | fprintf(stderr, "No command given, try \"tc exec help\".\n"); | |
91 | return -1; | |
92 | } | |
93 | ||
94 | if (matches(*argv, "help") == 0) { | |
95 | usage(); | |
96 | return 0; | |
97 | } | |
98 | ||
4bd62446 DB |
99 | strncpy(kind, *argv, sizeof(kind) - 1); |
100 | ||
101 | eu = get_exec_kind(kind); | |
102 | ||
103 | argc--; | |
104 | argv++; | |
105 | ||
106 | return eu->parse_eopt(eu, argc, argv); | |
107 | } |