/*
* 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, <net-tools@lina.inka.de>
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* (derived from FvK's 'route.c 1.70 01/04/94')
*
* Modifications:
* Johannes Stille: for Net-2Debugged by
* <johannes@titan.os.open.de>
* 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 <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
/* #include <net/route.h> realy broken */
#include <netinet/in.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <linux/param.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include <ctype.h>
#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)
{
FILE *fp = rc ? stderr : stdout;
fprintf(fp, _("Usage: route [-nNvee] [-FC] [<AF>] List kernel routing tables\n"));
fprintf(fp, _(" route [-v] [-FC] {add|del|flush} ... Modify routing table for AF.\n\n"));
fprintf(fp, _(" route {-h|--help} [<AF>] Detailed usage syntax for specified AF.\n"));
fprintf(fp, _(" route {-V|--version} Display version/author and exit.\n\n"));
fprintf(fp, _(" -v, --verbose be verbose\n"));
fprintf(fp, _(" -n, --numeric don't resolve names\n"));
fprintf(fp, _(" -e, --extend display other/more information\n"));
fprintf(fp, _(" -F, --fib display Forwarding Information Base (default)\n"));
fprintf(fp, _(" -C, --cache display routing cache instead of FIB\n\n"));
fprintf(fp, _(" <AF>=Use -4, -6, '-A <af>' or '--<af>'; default: %s\n"), DFLT_AF);
fprintf(fp, _(" List of possible address families (which support routing):\n"));
print_aflist(1); /* 1 = routeable */
exit(rc);
}
static void version(void)
{
printf("%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);
}