fixes for man page bugs reported by Hugh Redelmeier.
[oss-qm-packages.git] / route.c
blobd7029f7dab19de3de7883fc100cee41130762672
1 /*
2 * route This file contains an implementation of the command
3 * that manages the IP routing table in the kernel.
5 * Version: $Id: route.c,v 1.10 2002/07/30 05:24:20 ecki Exp $
7 * Maintainer: Bernd 'eckes' Eckenfels, <net-tools@lina.inka.de>
9 * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
10 * (derived from FvK's 'route.c 1.70 01/04/94')
12 * Modifications:
13 * Johannes Stille: for Net-2Debugged by
14 * <johannes@titan.os.open.de>
15 * Linus Torvalds: Misc Changes
16 * Alan Cox: add the new mtu/window stuff
17 * Miquel van Smoorenburg: rt_add and rt_del
18 * {1.79} Bernd Eckenfels: route_info
19 * {1.80} Bernd Eckenfels: reject, metric, irtt, 1.2.x support.
20 * {1.81} Bernd Eckenfels: reject routes need a dummy device
21 *960127 {1.82} Bernd Eckenfels: 'mod' and 'dyn' 'reinstate' added
22 *960129 {1.83} Bernd Eckenfels: resolve and getsock now in lib/,
23 * REJECT displays '-' as gatway.
24 *960202 {1.84} Bernd Eckenfels: net-features support added
25 *960203 {1.85} Bernd Eckenfels: "#ifdef' in '#if' for net-features
26 * -A (aftrans) support, get_longopts
27 *960206 {1.86} Bernd Eckenfels: route_init();
28 *960218 {1.87} Bernd Eckenfels: netinet/in.h added
29 *960221 {1.88} Bernd Eckenfels: aftrans_dfl support
30 *960222 {1.90} Bernd Eckenfels: moved all AF specific code to lib/.
31 *960413 {1.91} Bernd Eckenfels: new RTACTION support+FLAG_CACHE/FIB
32 *960426 {1.92} Bernd Eckenfels: FLAG_SYM/-N support
33 *960823 {x.xx} Frank Strauss: INET6 stuff
34 *980629 {1.95} Arnaldo Carvalho de Melo: gettext instead of catgets
35 *990101 {1.96} Bernd Eckenfels: fixed usage and FLAG_CACHE Output
36 *20010404 {1.97} Arnaldo Carvalho de Melo: use setlocale
39 #include <sys/types.h>
40 #include <sys/ioctl.h>
41 #include <sys/socket.h>
42 #include <net/if.h>
43 /* #include <net/route.h> realy broken */
44 #include <netinet/in.h>
45 #include <netdb.h>
46 #include <netinet/in.h>
47 #include <arpa/nameser.h>
48 #include <resolv.h>
49 #include <linux/param.h>
50 #include <stdio.h>
51 #include <errno.h>
52 #include <fcntl.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <getopt.h>
56 #include <unistd.h>
57 #include <ctype.h>
58 #include "net-support.h"
59 #include "config.h"
60 #include "intl.h"
61 #include "pathnames.h"
62 #include "version.h"
64 #define DFLT_AF "inet"
66 #define FEATURE_ROUTE
67 #include "lib/net-features.h" /* needs some of the system includes above! */
69 char *Release = RELEASE, *Version = "route 1.98 (2001-04-15)";
71 int opt_n = 0; /* numerical output flag */
72 int opt_v = 0; /* debugging output flag */
73 int opt_e = 1; /* 1,2,3=type of routetable */
74 int opt_fc = 0; /* routing cache/FIB */
75 int opt_h = 0; /* help selected */
76 struct aftype *ap; /* current address family */
78 static void usage(void)
80 fprintf(stderr, _("Usage: route [-nNvee] [-FC] [<AF>] List kernel routing tables\n"));
81 fprintf(stderr, _(" route [-v] [-FC] {add|del|flush} ... Modify routing table for AF.\n\n"));
83 fprintf(stderr, _(" route {-h|--help} [<AF>] Detailed usage syntax for specified AF.\n"));
84 fprintf(stderr, _(" route {-V|--version} Display version/author and exit.\n\n"));
86 fprintf(stderr, _(" -v, --verbose be verbose\n"));
87 fprintf(stderr, _(" -n, --numeric don't resolve names\n"));
88 fprintf(stderr, _(" -e, --extend display other/more information\n"));
89 fprintf(stderr, _(" -F, --fib display Forwarding Information Base (default)\n"));
90 fprintf(stderr, _(" -C, --cache display routing cache instead of FIB\n\n"));
92 fprintf(stderr, _(" <AF>=Use '-A <af>' or '--<af>'; default: %s\n"), DFLT_AF);
93 fprintf(stderr, _(" List of possible address families (which support routing):\n"));
94 print_aflist(1); /* 1 = routeable */
95 exit(E_USAGE);
99 static void version(void)
101 fprintf(stderr, "%s\n%s\n%s\n", Release, Version, Features);
102 exit(E_VERSION);
106 int main(int argc, char **argv)
108 int i, lop, what = 0;
109 struct option longopts[] =
111 AFTRANS_OPTS,
112 {"extend", 0, 0, 'e'},
113 {"verbose", 0, 0, 'v'},
114 {"version", 0, 0, 'V'},
115 {"numeric", 0, 0, 'n'},
116 {"symbolic", 0, 0, 'N'},
117 {"protocol", 1, 0, 'A'},
118 {"cache", 0, 0, 'C'},
119 {"fib", 0, 0, 'F'},
120 {"help", 0, 0, 'h'},
121 {NULL, 0, 0, 0}
123 char **tmp;
124 char *progname;
125 int options;
126 #if I18N
127 setlocale (LC_ALL, "");
128 bindtextdomain("net-tools", "/usr/share/locale");
129 textdomain("net-tools");
130 #endif
131 getroute_init(); /* Set up AF routing support */
132 setroute_init();
133 afname[0] = '\0';
134 progname = argv[0];
136 /* getopts and -net wont work :-/ */
137 for (tmp = argv; *tmp; tmp++) {
138 if (!strcmp(*tmp, "-net"))
139 strcpy(*tmp, "#net");
140 else if (!strcmp(*tmp, "-host"))
141 strcpy(*tmp, "#host");
144 /* Fetch the command-line arguments. */
145 while ((i = getopt_long(argc, argv, "A:eCFhnN64Vv?", longopts, &lop)) != EOF)
146 switch (i) {
147 case -1:
148 break;
149 case 'n':
150 opt_n |= FLAG_NUM;
151 break;
152 case 'N':
153 opt_n |= FLAG_SYM;
154 break;
155 case 'v':
156 opt_v |= FLAG_VERBOSE;
157 break;
158 case 'e':
159 opt_e++;
160 break;
161 case 1:
162 if (lop < 0 || lop >= AFTRANS_CNT) {
163 EINTERN("route.c", "longopts 1 range");
164 break;
166 if ((i = aftrans_opt(longopts[lop].name)))
167 exit(i);
168 break;
169 case 'C':
170 opt_fc |= FLAG_CACHE;
171 break;
172 case 'F':
173 opt_fc |= FLAG_FIB;
174 break;
175 case 'A':
176 if ((i = aftrans_opt(optarg)))
177 exit(i);
178 break;
179 case '6':
180 if ((i = aftrans_opt("inet6")))
181 exit(i);
182 break;
183 case '4':
184 if ((i = aftrans_opt("inet")))
185 exit(i);
186 break;
187 case 'V':
188 version();
189 case 'h':
190 case '?':
191 opt_h++;
192 break;
193 default:
194 usage();
197 argv += optind;
198 argc -= optind;
200 if (opt_h) {
201 if (!afname[0])
202 usage();
203 else
204 what = RTACTION_HELP;
205 } else {
206 if (!afname[0])
207 /* this will initialise afname[] */
208 aftrans_def("route", progname, DFLT_AF);
210 /* Do we have to show the contents of the routing table? */
211 if (*argv == NULL) {
212 what = RTACTION_SHOW;
213 } else {
214 if (!strcmp(*argv, "add"))
215 what = RTACTION_ADD;
216 else if (!strcmp(*argv, "del") || !strcmp(*argv, "delete"))
217 what = RTACTION_DEL;
218 else if (!strcmp(*argv, "flush"))
219 what = RTACTION_FLUSH;
220 else
221 usage();
225 options = (opt_e & FLAG_EXT) | opt_n | opt_fc | opt_v;
226 if (!opt_fc)
227 options |= FLAG_FIB;
229 if (what == RTACTION_SHOW)
230 i = route_info(afname, options);
231 else
232 i = route_edit(what, afname, options, ++argv);
234 if (i == E_OPTERR)
235 usage();
237 return (i);