move netstat to /usr/bin
[platform/upstream/net-tools.git] / route.c
1 /*
2  * route        This file contains an implementation of the command
3  *              that manages the IP routing table in the kernel.
4  *
5  * Version:     $Id: route.c,v 1.10 2002/07/30 05:24:20 ecki Exp $
6  *
7  * Maintainer:  Bernd 'eckes' Eckenfels, <net-tools@lina.inka.de>
8  *
9  * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
10  *              (derived from FvK's 'route.c     1.70    01/04/94')
11  *
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
37  *
38  */
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"
63
64 #define DFLT_AF "inet"
65
66 #define FEATURE_ROUTE
67 #include "lib/net-features.h"   /* needs some of the system includes above! */
68
69 char *Release = RELEASE, *Version = "route 1.98 (2001-04-15)";
70
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       */
77
78 static void usage(void)
79 {
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"));
82
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"));
85
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"));
91
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);
96 }
97
98
99 static void version(void)
100 {
101     fprintf(stderr, "%s\n%s\n%s\n", Release, Version, Features);
102     exit(E_VERSION);
103 }
104
105
106 int main(int argc, char **argv)
107 {
108     int i, lop, what = 0;
109     struct option longopts[] =
110     {
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}
122     };
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];
135
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");
142     }
143
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;
165             }
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();
195         }
196
197     argv += optind;
198     argc -= optind;
199
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);
209
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();
222         }
223     }
224
225     options = (opt_e & FLAG_EXT) | opt_n | opt_fc | opt_v;
226     if (!opt_fc)
227         options |= FLAG_FIB;
228
229     if (what == RTACTION_SHOW)
230         i = route_info(afname, options);
231     else
232         i = route_edit(what, afname, options, ++argv);
233
234     if (i == E_OPTERR)
235         usage();
236
237     return (i);
238 }