/* * route This file contains an implementation of the command * that manages the IP routing table in the kernel. * * Version: $Id: route.c,v 1.10 2002/07/30 05:24:20 ecki Exp $ * * Maintainer: Bernd 'eckes' Eckenfels, * * Author: Fred N. van Kempen, * (derived from FvK's 'route.c 1.70 01/04/94') * * Modifications: * Johannes Stille: for Net-2Debugged by * * Linus Torvalds: Misc Changes * Alan Cox: add the new mtu/window stuff * Miquel van Smoorenburg: rt_add and rt_del * {1.79} Bernd Eckenfels: route_info * {1.80} Bernd Eckenfels: reject, metric, irtt, 1.2.x support. * {1.81} Bernd Eckenfels: reject routes need a dummy device *960127 {1.82} Bernd Eckenfels: 'mod' and 'dyn' 'reinstate' added *960129 {1.83} Bernd Eckenfels: resolve and getsock now in lib/, * REJECT displays '-' as gatway. *960202 {1.84} Bernd Eckenfels: net-features support added *960203 {1.85} Bernd Eckenfels: "#ifdef' in '#if' for net-features * -A (aftrans) support, get_longopts *960206 {1.86} Bernd Eckenfels: route_init(); *960218 {1.87} Bernd Eckenfels: netinet/in.h added *960221 {1.88} Bernd Eckenfels: aftrans_dfl support *960222 {1.90} Bernd Eckenfels: moved all AF specific code to lib/. *960413 {1.91} Bernd Eckenfels: new RTACTION support+FLAG_CACHE/FIB *960426 {1.92} Bernd Eckenfels: FLAG_SYM/-N support *960823 {x.xx} Frank Strauss: INET6 stuff *980629 {1.95} Arnaldo Carvalho de Melo: gettext instead of catgets *990101 {1.96} Bernd Eckenfels: fixed usage and FLAG_CACHE Output *20010404 {1.97} Arnaldo Carvalho de Melo: use setlocale * */ #include #include #include #include /* #include realy broken */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "net-support.h" #include "config.h" #include "intl.h" #include "pathnames.h" #include "version.h" #include "util.h" #define DFLT_AF "inet" #define FEATURE_ROUTE #include "lib/net-features.h" /* needs some of the system includes above! */ static char *Release = RELEASE; int opt_n = 0; // numerical output FLAG_NUM | FLAG_SYM int opt_v = 0; // debugging output flag int opt_e = 1; // 1,2,3=type of routetable int opt_fc = 0; // routing cache/FIB int opt_h = 0; // help selected struct aftype *ap; // selected address family static void usage(int rc) { fprintf(stderr, _("Usage: route [-nNvee] [-FC] [] List kernel routing tables\n")); fprintf(stderr, _(" route [-v] [-FC] {add|del|flush} ... Modify routing table for AF.\n\n")); fprintf(stderr, _(" route {-h|--help} [] Detailed usage syntax for specified AF.\n")); fprintf(stderr, _(" route {-V|--version} Display version/author and exit.\n\n")); fprintf(stderr, _(" -v, --verbose be verbose\n")); fprintf(stderr, _(" -n, --numeric don't resolve names\n")); fprintf(stderr, _(" -e, --extend display other/more information\n")); fprintf(stderr, _(" -F, --fib display Forwarding Information Base (default)\n")); fprintf(stderr, _(" -C, --cache display routing cache instead of FIB\n\n")); fprintf(stderr, _(" =Use -4, -6, '-A ' or '--'; default: %s\n"), DFLT_AF); fprintf(stderr, _(" List of possible address families (which support routing):\n")); print_aflist(1); /* 1 = routeable */ exit(rc); } static void version(void) { fprintf(stderr, "%s\n%s\n", Release, Features); exit(E_VERSION); } int main(int argc, char **argv) { int i, lop, what = 0; struct option longopts[] = { AFTRANS_OPTS, {"extend", 0, 0, 'e'}, {"verbose", 0, 0, 'v'}, {"version", 0, 0, 'V'}, {"numeric", 0, 0, 'n'}, {"symbolic", 0, 0, 'N'}, {"protocol", 1, 0, 'A'}, {"cache", 0, 0, 'C'}, {"fib", 0, 0, 'F'}, {"help", 0, 0, 'h'}, {NULL, 0, 0, 0} }; char **tmp; char *progname; int options; #if I18N setlocale (LC_ALL, ""); bindtextdomain("net-tools", "/usr/share/locale"); textdomain("net-tools"); #endif getroute_init(); /* Set up AF routing support */ setroute_init(); afname[0] = '\0'; progname = argv[0]; /* getopts and -net wont work :-/ */ for (tmp = argv; *tmp; tmp++) { if (!strcmp(*tmp, "-net") || !strcmp(*tmp, "-host")) (*tmp)[0]='#'; } /* Fetch the command-line arguments. */ while ((i = getopt_long(argc, argv, "A:eCFhnN64Vv?", longopts, &lop)) != EOF) switch (i) { case -1: break; case 'n': opt_n |= FLAG_NUM; break; case 'N': opt_n |= FLAG_SYM; break; case 'v': opt_v |= FLAG_VERBOSE; break; case 'e': opt_e++; break; case 1: if (lop < 0 || lop >= AFTRANS_CNT) { EINTERN("route.c", "longopts 1 range"); break; } if ((i = aftrans_opt(longopts[lop].name))) exit(i); break; case 'C': opt_fc |= FLAG_CACHE; break; case 'F': opt_fc |= FLAG_FIB; break; case 'A': if ((i = aftrans_opt(optarg))) exit(i); break; case '6': if ((i = aftrans_opt("inet6"))) exit(i); break; case '4': if ((i = aftrans_opt("inet"))) exit(i); break; case 'V': version(); case 'h': case '?': opt_h++; break; default: usage(E_OPTERR); } argv += optind; argc -= optind; if (opt_h) { if (!afname[0]) usage(E_USAGE); else what = RTACTION_HELP; } else { if (!afname[0]) /* this will initialise afname[] */ aftrans_def("route", progname, DFLT_AF); /* Do we have to show the contents of the routing table? */ if (*argv == NULL) { what = RTACTION_SHOW; } else { if (!strcmp(*argv, "add")) what = RTACTION_ADD; else if (!strcmp(*argv, "del") || !strcmp(*argv, "delete")) what = RTACTION_DEL; else if (!strcmp(*argv, "flush")) what = RTACTION_FLUSH; else usage(E_OPTERR); } } options = (opt_e & FLAG_EXT) | opt_n | opt_fc | opt_v; if (!opt_fc) options |= FLAG_FIB; if (what == RTACTION_SHOW) i = route_info(afname, options); else i = route_edit(what, afname, options, ++argv); return (i); }