165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim/* 265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * genl.c "genl" utility frontend. 365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * 465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * This program is free software; you can redistribute it and/or 565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * modify it under the terms of the GNU General Public License 665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * as published by the Free Software Foundation; either version 765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * 2 of the License, or (at your option) any later version. 865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * 965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * Authors: Jamal Hadi Salim 1065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * 1165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim */ 1265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 1365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <stdio.h> 1465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <stdlib.h> 1565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <unistd.h> 1665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <syslog.h> 1765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <fcntl.h> 1865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <dlfcn.h> 1965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <sys/socket.h> 2065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <netinet/in.h> 2165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <arpa/inet.h> 2265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <string.h> 2365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <errno.h> 2465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <linux/netlink.h> 2565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <linux/rtnetlink.h> /* until we put our own header */ 2665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include "SNAPSHOT.h" 2765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include "utils.h" 2865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include "genl_utils.h" 2965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 3065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimint show_stats = 0; 3165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimint show_details = 0; 3265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimint show_raw = 0; 3365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimint resolve_hosts = 0; 3465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 3565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic void *BODY; 3665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic struct genl_util * genl_list; 3765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 3865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 3965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic int print_nofopt(const struct sockaddr_nl *who, struct nlmsghdr *n, 4065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim void *arg) 4165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim{ 4265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf((FILE *) arg, "unknown genl type ..\n"); 4365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return 0; 4465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim} 4565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 4665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic int parse_nofopt(struct genl_util *f, int argc, char **argv) 4765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim{ 4865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (argc) { 4965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Unknown genl \"%s\", hence option \"%s\" " 5065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "is unparsable\n", f->name, *argv); 5165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return -1; 5265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 5365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 5465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return 0; 5565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim} 5665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 5765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic struct genl_util *get_genl_kind(char *str) 5865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim{ 5965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim void *dlh; 6065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim char buf[256]; 6165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct genl_util *f; 6265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 6365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim for (f = genl_list; f; f = f->next) 6465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (strcmp(f->name, str) == 0) 6565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return f; 6665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 6765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim snprintf(buf, sizeof(buf), "%s.so", str); 6865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim dlh = dlopen(buf, RTLD_LAZY); 6965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (dlh == NULL) { 7065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim dlh = BODY; 7165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (dlh == NULL) { 7265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim dlh = BODY = dlopen(NULL, RTLD_LAZY); 7365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (dlh == NULL) 7465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto noexist; 7565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 7665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 7765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 7865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim snprintf(buf, sizeof(buf), "%s_genl_util", str); 7965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 8065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim f = dlsym(dlh, buf); 8165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (f == NULL) 8265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto noexist; 8365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimreg: 8465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim f->next = genl_list; 8565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim genl_list = f; 8665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return f; 8765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 8865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimnoexist: 8965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim f = malloc(sizeof(*f)); 9065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (f) { 9165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim memset(f, 0, sizeof(*f)); 9265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim strncpy(f->name, str, 15); 9365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim f->parse_genlopt = parse_nofopt; 9465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim f->print_genlopt = print_nofopt; 9565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto reg; 9665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 9765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return f; 9865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim} 9965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 10065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic void usage(void) __attribute__((noreturn)); 10165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 10265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic void usage(void) 10365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim{ 10465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Usage: genl [ OPTIONS ] OBJECT | help }\n" 10565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "where OBJECT := { ctrl etc }\n" 10665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim " OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] }\n"); 10765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim exit(-1); 10865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim} 10965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 11065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimint main(int argc, char **argv) 11165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim{ 11265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim while (argc > 1) { 11365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (argv[1][0] != '-') 11465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim break; 11565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (matches(argv[1], "-stats") == 0 || 11665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim matches(argv[1], "-statistics") == 0) { 11765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ++show_stats; 11865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } else if (matches(argv[1], "-details") == 0) { 11965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ++show_details; 12065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } else if (matches(argv[1], "-raw") == 0) { 12165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ++show_raw; 12265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } else if (matches(argv[1], "-Version") == 0) { 12365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim printf("genl utility, iproute2-ss%s\n", SNAPSHOT); 12465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim exit(0); 12565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } else if (matches(argv[1], "-help") == 0) { 12665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim usage(); 12765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } else { 12865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Option \"%s\" is unknown, try " 12965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "\"genl -help\".\n", argv[1]); 13065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim exit(-1); 13165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 13265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim argc--; argv++; 13365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 13465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 13565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (argc > 1) { 13665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim int ret; 13765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct genl_util *a = NULL; 13865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim a = get_genl_kind(argv[1]); 1391b129bf2fe280f9aa7a22cbcd00dd3114dd5d65cDan McGee if (!a) { 1401b129bf2fe280f9aa7a22cbcd00dd3114dd5d65cDan McGee fprintf(stderr,"bad genl %s\n", argv[1]); 1411b129bf2fe280f9aa7a22cbcd00dd3114dd5d65cDan McGee exit(-1); 14265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 14365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 14465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ret = a->parse_genlopt(a, argc-1, argv+1); 14565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return ret; 14665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 14765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 14865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim usage(); 14965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim} 150