869fd8d04e33a8382b4036f0c77a5e4e70837fd9
[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.7 2000/12/19 00:26:16 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  *
37  */
38 #include <sys/types.h>
39 #include <sys/ioctl.h>
40 #include <sys/socket.h>
41 #include <net/if.h>
42 /* #include <net/route.h> realy broken */
43 #include <netinet/in.h>
44 #include <netdb.h>
45 #include <netinet/in.h>
46 #include <arpa/nameser.h>
47 #include <resolv.h>
48 #include <linux/param.h>
49 #include <stdio.h>
50 #include <errno.h>
51 #include <fcntl.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <getopt.h>
55 #include <unistd.h>
56 #include <ctype.h>
57 #include "net-support.h"
58 #include "config.h"
59 #include "intl.h"
60 #include "pathnames.h"
61 #include "version.h"
62
63 #define DFLT_AF "inet"
64
65 #define FEATURE_ROUTE
66 #include "lib/net-features.h"   /* needs some of the system includes above! */
67
68 char *Release = RELEASE, *Version = "route 1.96 (1999-01-01)";
69
70 int opt_n = 0;                  /* numerical output flag        */
71 int opt_v = 0;                  /* debugging output flag        */
72 int opt_e = 1;                  /* 1,2,3=type of routetable     */
73 int opt_fc = 0;                 /* routing cache/FIB */
74 int opt_h = 0;                  /* help selected                */
75 struct aftype *ap;              /* current address family       */
76
77 static void usage(void)
78 {
79     fprintf(stderr, _("Usage: route [-nNvee] [-FC] [<AF>]           List kernel routing tables\n"));
80     fprintf(stderr, _("       route [-v] [-FC] {add|del|flush} ...  Modify routing table for AF.\n\n"));
81
82     fprintf(stderr, _("       route {-h|--help} [<AF>]              Detailed usage syntax for specified AF.\n"));
83     fprintf(stderr, _("       route {-V|--version}                  Display version/author and exit.\n\n"));
84
85     fprintf(stderr, _("        -v, --verbose            be verbose\n"));
86     fprintf(stderr, _("        -n, --numeric            dont resolve names\n"));
87     fprintf(stderr, _("        -e, --extend             display other/more information\n"));
88     fprintf(stderr, _("        -F, --fib                display Forwarding Information Base (default)\n"));
89     fprintf(stderr, _("        -C, --cache              display routing cache instead of FIB\n\n"));
90
91     fprintf(stderr, _("  <AF>=Use '-A <af>' or '--<af>' Default: %s\n"), DFLT_AF);
92     fprintf(stderr, _("  List of possible address families (which support routing):\n"));
93     print_aflist(1); /* 1 = routeable */
94     exit(E_USAGE);
95 }
96
97
98 static void version(void)
99 {
100     fprintf(stderr, "%s\n%s\n%s\n", Release, Version, Features);
101     exit(E_VERSION);
102 }
103
104
105 int main(int argc, char **argv)
106 {
107     int i, lop, what = 0;
108     struct option longopts[] =
109     {
110         AFTRANS_OPTS,
111         {"extend", 0, 0, 'e'},
112         {"verbose", 0, 0, 'v'},
113         {"version", 0, 0, 'V'},
114         {"numeric", 0, 0, 'n'},
115         {"symbolic", 0, 0, 'N'},
116         {"protocol", 1, 0, 'A'},
117         {"cache", 0, 0, 'C'},
118         {"fib", 0, 0, 'F'},
119         {"help", 0, 0, 'h'},
120         {NULL, 0, 0, 0}
121     };
122     char **tmp;
123     char *progname;
124     int options;
125 #if I18N
126     bindtextdomain("net-tools", "/usr/share/locale");
127     textdomain("net-tools");
128 #endif
129     getroute_init();            /* Set up AF routing support */
130     setroute_init();
131     afname[0] = '\0';
132     progname = argv[0];
133
134     /* getopts and -net wont work :-/ */
135     for (tmp = argv; *tmp; tmp++) {
136         if (!strcmp(*tmp, "-net"))
137             strcpy(*tmp, "#net");
138         else if (!strcmp(*tmp, "-host"))
139             strcpy(*tmp, "#host");
140     }
141
142     /* Fetch the command-line arguments. */
143     while ((i = getopt_long(argc, argv, "A:eCFhnNVv?", longopts, &lop)) != EOF)
144         switch (i) {
145         case -1:
146             break;
147         case 'n':
148             opt_n |= FLAG_NUM;
149             break;
150         case 'N':
151             opt_n |= FLAG_SYM;
152             break;
153         case 'v':
154             opt_v |= FLAG_VERBOSE;
155             break;
156         case 'e':
157             opt_e++;
158             break;
159         case 1:
160             if (lop < 0 || lop >= AFTRANS_CNT) {
161                 EINTERN("route.c", "longopts 1 range");
162                 break;
163             }
164             if ((i = aftrans_opt(longopts[lop].name)))
165                 exit(i);
166             break;
167         case 'C':
168             opt_fc |= FLAG_CACHE;
169             break;
170         case 'F':
171             opt_fc |= FLAG_FIB;
172             break;
173         case 'A':
174             if ((i = aftrans_opt(optarg)))
175                 exit(i);
176             break;
177         case 'V':
178             version();
179         case 'h':
180         case '?':
181             opt_h++;
182             break;
183         default:
184             usage();
185         }
186
187     argv += optind;
188     argc -= optind;
189
190     if (opt_h) {
191         if (!afname[0])
192             usage();
193         else
194             what = RTACTION_HELP;
195     } else {
196         if (!afname[0])
197             /* this will initialise afname[] */
198             aftrans_def("route", progname, DFLT_AF);
199
200         /* Do we have to show the contents of the routing table? */
201         if (*argv == NULL) {
202             what = RTACTION_SHOW;
203         } else {
204             if (!strcmp(*argv, "add"))
205                 what = RTACTION_ADD;
206             else if (!strcmp(*argv, "del") || !strcmp(*argv, "delete"))
207                 what = RTACTION_DEL;
208             else if (!strcmp(*argv, "flush"))
209                 what = RTACTION_FLUSH;
210             else
211                 usage();
212         }
213     }
214
215     options = (opt_e & FLAG_EXT) | opt_n | opt_fc | opt_v;
216     if (!opt_fc)
217         options |= FLAG_FIB;
218
219     if (what == RTACTION_SHOW)
220         i = route_info(afname, options);
221     else
222         i = route_edit(what, afname, options, ++argv);
223
224     if (i == E_OPTERR)
225         usage();
226
227     return (i);
228 }