struct qdisc_util *get_qdisc_kind(const char *str) { void *dlh; char buf[256]; struct qdisc_util *q; #ifdef ANDROID if (!strcmp(str, "cbq")) return &cbq_qdisc_util; else if (!strcmp(str, "htb")) return &htb_qdisc_util; else if (!strcmp(str, "ingress")) return &ingress_qdisc_util; else { fprintf(stderr, "Android does not support qdisc '%s'\n", str); return NULL; } #endif for (q = qdisc_list; q; q = q->next) if (strcmp(q->id, str) == 0) return q; snprintf(buf, sizeof(buf), "%s/q_%s.so", get_tc_lib(), str); dlh = dlopen(buf, RTLD_LAZY); if (!dlh) { /* look in current binary, only open once */ dlh = BODY; if (dlh == NULL) { dlh = BODY = dlopen(NULL, RTLD_LAZY); if (dlh == NULL) goto noexist; } } snprintf(buf, sizeof(buf), "%s_qdisc_util", str); q = dlsym(dlh, buf); if (q == NULL) goto noexist; reg: q->next = qdisc_list; qdisc_list = q; return q; noexist: q = malloc(sizeof(*q)); if (q) { memset(q, 0, sizeof(*q)); q->id = strcpy(malloc(strlen(str)+1), str); q->parse_qopt = parse_noqopt; q->print_qopt = print_noqopt; goto reg; } return q; }
struct filter_util *get_filter_kind(const char *str) { void *dlh; char buf[256]; struct filter_util *q; #ifdef ANDROID if (!strcmp(str, "u32")) return &u32_filter_util; #ifdef FEATURE_PRIO else if (!strcmp(str, "fw")) return &fw_filter_util; #endif else { fprintf(stderr, "Android does not support filter '%s'\n", str); return NULL; } #endif for (q = filter_list; q; q = q->next) if (strcmp(q->id, str) == 0) return q; snprintf(buf, sizeof(buf), "%s/f_%s.so", get_tc_lib(), str); dlh = dlopen(buf, RTLD_LAZY); if (dlh == NULL) { dlh = BODY; if (dlh == NULL) { dlh = BODY = dlopen(NULL, RTLD_LAZY); if (dlh == NULL) goto noexist; } } snprintf(buf, sizeof(buf), "%s_filter_util", str); q = dlsym(dlh, buf); if (q == NULL) goto noexist; reg: q->next = filter_list; filter_list = q; return q; noexist: q = malloc(sizeof(*q)); if (q) { memset(q, 0, sizeof(*q)); strncpy(q->id, str, 15); q->parse_fopt = parse_nofopt; q->print_fopt = print_nofopt; goto reg; } return q; }
struct qdisc_util *get_qdisc_kind(const char *str) { void *dlh; char buf[256]; struct qdisc_util *q; for (q = qdisc_list; q; q = q->next) if (strcmp(q->id, str) == 0) return q; snprintf(buf, sizeof(buf), "%s/q_%s.so", get_tc_lib(), str); dlh = dlopen(buf, RTLD_LAZY); if (!dlh) { /* look in current binary, only open once */ dlh = BODY; if (dlh == NULL) { dlh = BODY = dlopen(NULL, RTLD_LAZY); if (dlh == NULL) goto noexist; } } snprintf(buf, sizeof(buf), "%s_qdisc_util", str); q = dlsym(dlh, buf); if (q == NULL) goto noexist; reg: q->next = qdisc_list; qdisc_list = q; return q; noexist: q = malloc(sizeof(*q)); if (q) { memset(q, 0, sizeof(*q)); q->id = strcpy(malloc(strlen(str)+1), str); q->parse_qopt = parse_noqopt; q->print_qopt = print_noqopt; goto reg; } return q; }
/* * Simplistic file parser for distrbution data. * Format is: * # comment line(s) * data0 data1 ... */ static int get_distribution(const char *type, __s16 *data, int maxdata) { FILE *f; int n; long x; size_t len; char *line = NULL; char name[128]; snprintf(name, sizeof(name), "%s/%s.dist", get_tc_lib(), type); if ((f = fopen(name, "r")) == NULL) { fprintf(stderr, "No distribution data for %s (%s: %s)\n", type, name, strerror(errno)); return -1; } n = 0; while (getline(&line, &len, f) != -1) { char *p, *endp; if (*line == '\n' || *line == '#') continue; for (p = line; ; p = endp) { x = strtol(p, &endp, 0); if (endp == p) break; if (n >= maxdata) { fprintf(stderr, "%s: too much data\n", name); n = -1; goto error; } data[n++] = x; } } error: free(line); fclose(f); return n; }
struct filter_util *get_filter_kind(const char *str) { void *dlh; char buf[256]; struct filter_util *q; for (q = filter_list; q; q = q->next) if (strcmp(q->id, str) == 0) return q; snprintf(buf, sizeof(buf), "%s/f_%s.so", get_tc_lib(), str); dlh = dlopen(buf, RTLD_LAZY); if (dlh == NULL) { dlh = BODY; if (dlh == NULL) { dlh = BODY = dlopen(NULL, RTLD_LAZY); if (dlh == NULL) goto noexist; } } snprintf(buf, sizeof(buf), "%s_filter_util", str); q = dlsym(dlh, buf); if (q == NULL) goto noexist; reg: q->next = filter_list; filter_list = q; return q; noexist: q = malloc(sizeof(*q)); if (q) { memset(q, 0, sizeof(*q)); strncpy(q->id, str, 15); q->parse_fopt = parse_nofopt; q->print_fopt = print_nofopt; goto reg; } return q; }
struct action_util *get_action_kind(char *str) { #ifdef ANDROID if (!strcmp(str, "mirred")) { return &mirred_action_util; } else { fprintf(stderr, "Android does not support action '%s'", str); return NULL; } #endif static void *aBODY; void *dlh; char buf[256]; struct action_util *a; #ifdef CONFIG_GACT int looked4gact = 0; restart_s: #endif for (a = action_list; a; a = a->next) { if (strcmp(a->id, str) == 0) return a; } snprintf(buf, sizeof(buf), "%s/m_%s.so", get_tc_lib(), str); dlh = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL); if (dlh == NULL) { dlh = aBODY; if (dlh == NULL) { dlh = aBODY = dlopen(NULL, RTLD_LAZY); if (dlh == NULL) goto noexist; } } snprintf(buf, sizeof(buf), "%s_action_util", str); a = dlsym(dlh, buf); if (a == NULL) goto noexist; reg: a->next = action_list; action_list = a; return a; noexist: #ifdef CONFIG_GACT if (!looked4gact) { looked4gact = 1; strcpy(str,"gact"); goto restart_s; } #endif a = malloc(sizeof(*a)); if (a) { memset(a, 0, sizeof(*a)); strncpy(a->id, "noact", 15); a->parse_aopt = parse_noaopt; a->print_aopt = print_noaopt; goto reg; } return a; }
struct action_util *get_action_kind(char *str) { #ifndef NO_DL static void *aBODY; void *dlh; char buf[256]; #endif struct action_util *a; #ifdef CONFIG_GACT int looked4gact = 0; restart_s: #endif for (a = action_list; a; a = a->next) { if (strcmp(a->id, str) == 0) return a; } #ifdef NO_DL { int i; for (i = 0; action[i]; i++) if (strcmp(action[i]->id, str) == 0) { a = action[i]; goto reg; } goto noexist; } #else snprintf(buf, sizeof(buf), "%s/m_%s.so", get_tc_lib(), str); dlh = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL); if (dlh == NULL) { dlh = aBODY; if (dlh == NULL) { dlh = aBODY = dlopen(NULL, RTLD_LAZY); if (dlh == NULL) goto noexist; } } snprintf(buf, sizeof(buf), "%s_action_util", str); a = dlsym(dlh, buf); if (a == NULL) goto noexist; #endif reg: a->next = action_list; action_list = a; return a; noexist: #ifdef CONFIG_GACT if (!looked4gact) { looked4gact = 1; strcpy(str,"gact"); goto restart_s; } #endif a = malloc(sizeof(*a)); if (a) { memset(a, 0, sizeof(*a)); strncpy(a->id, "noact", 15); a->parse_aopt = parse_noaopt; a->print_aopt = print_noaopt; goto reg; } return a; }