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 (at) 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; 22 static void *BODY; 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) { 35 fprintf(stderr, "Unknown exec \"%s\", hence option \"%s\" is unparsable\n", 36 eu->id, *argv); 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: 74 eu = calloc(1, sizeof(*eu)); 75 if (eu) { 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; 87 char kind[16] = {}; 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 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 } 108