4 Created August 7, 1991 by Philip Homburg
17 #include <net/netlib.h>
19 #include <net/gen/in.h>
20 #include <net/gen/inet.h>
21 #include <net/gen/route.h>
22 #include <net/gen/socket.h>
23 #include <net/gen/ip_io.h>
25 static char *prog_name
;
26 static enum { ADD
, DEL
} action
;
28 static void usage(void);
29 static int name_to_ip(const char *name
, ipaddr_t
*addr
);
30 static int parse_cidr(const char *cidr
, ipaddr_t
*addr
, ipaddr_t
*mask
);
32 int main(int argc
, char *argv
[])
34 struct netent
*netent
;
35 ipaddr_t gateway
, destination
, netmask
, defaultmask
=0;
43 char *netmask_str
, *metric_str
, *destination_str
, *gateway_str
;
45 char *d_arg
, *g_arg
, *m_arg
, *n_arg
, *I_arg
;
46 int i_flag
, o_flag
, D_flag
, v_flag
;
49 prog_name
= strrchr(argv
[0], '/');
50 if (prog_name
== NULL
) prog_name
= argv
[0]; else prog_name
++;
52 if (strcmp(prog_name
, "add_route") == 0)
54 else if (strcmp(prog_name
, "del_route") == 0)
58 fprintf(stderr
, "Don't know what to do when named '%s'\n",
72 while ((c
= getopt(argc
, argv
, "iovDg:d:m:n:I:?")) != -1)
124 fprintf(stderr
, "%s: getopt failed\n", prog_name
);
130 if (i_flag
&& o_flag
)
136 if (g_arg
== NULL
|| d_arg
== NULL
|| m_arg
== NULL
)
141 if (g_arg
== NULL
|| (d_arg
== NULL
&& n_arg
!= NULL
))
148 destination_str
= d_arg
;
153 if (!name_to_ip(gateway_str
, &gateway
))
155 fprintf(stderr
, "%s: unknown host '%s'\n", prog_name
,
166 if (parse_cidr(destination_str
, &destination
, &netmask
))
168 else if (inet_aton(destination_str
, &destination
))
170 else if ((netent
= getnetbyname(destination_str
)) != NULL
)
171 destination
= netent
->n_net
;
172 else if (!name_to_ip(destination_str
, &destination
))
174 fprintf(stderr
, "%s: unknown network/host '%s'\n",
175 prog_name
, destination_str
);
178 high_byte
= *(u8_t
*)&destination
;
179 if (!(high_byte
& 0x80)) /* class A or 0 */
182 defaultmask
= htonl(0xff000000);
185 else if (!(high_byte
& 0x40)) /* class B */
187 defaultmask
= htonl(0xffff0000);
190 else if (!(high_byte
& 0x20)) /* class C */
192 defaultmask
= htonl(0xffffff00);
194 else /* class D is multicast ... */
196 fprintf(stderr
, "%s: Warning: Martian address '%s'\n",
197 prog_name
, inet_ntoa(destination
));
198 defaultmask
= htonl(0xffffffff);
200 if (destination
& ~defaultmask
)
203 defaultmask
= htonl(0xffffffff);
206 netmask
= defaultmask
;
213 if (inet_aton(netmask_str
, &netmask
) == 0)
215 fprintf(stderr
, "%s: illegal netmask'%s'\n", prog_name
,
223 metric
= strtol(metric_str
, &check
, 0);
224 if (check
[0] != '\0' || metric
< 1)
226 fprintf(stderr
, "%s: illegal metric %s\n",
227 prog_name
, metric_str
);
234 ip_device
= getenv("IP_DEVICE");
236 ip_device
= IP_DEVICE
;
238 ip_fd
= open(ip_device
, O_RDWR
);
241 fprintf(stderr
, "%s: unable to open('%s'): %s\n",
242 prog_name
, ip_device
, strerror(errno
));
248 printf("%s %s route to %s ",
249 action
== ADD
? "adding" : "deleting",
250 itab
? "input" : "output",
251 inet_ntoa(destination
));
252 printf("with netmask %s ", inet_ntoa(netmask
));
253 printf("using gateway %s", inet_ntoa(gateway
));
254 if (itab
&& action
== ADD
)
255 printf(" at distance %d", metric
);
260 route
.nwr_dest
= destination
;
261 route
.nwr_netmask
= netmask
;
262 route
.nwr_gateway
= gateway
;
263 route
.nwr_dist
= action
== ADD
? metric
: 0;
264 route
.nwr_flags
= (action
== DEL
&& D_flag
) ? 0 : NWRF_STATIC
;
269 r
= ioctl(ip_fd
, itab
? NWIOSIPIROUTE
: NWIOSIPOROUTE
, &route
);
271 r
= ioctl(ip_fd
, itab
? NWIODIPIROUTE
: NWIODIPOROUTE
, &route
);
274 fprintf(stderr
, "%s: NWIO%cIP%cROUTE: %s\n",
276 action
== ADD
? 'S' : 'D',
284 static void usage(void)
288 "\t[-o] %s-g gw [-d dst [-n netmask]] %s[-I ipdev] [-v]\n"
289 "\t-i %s-g gw -d dst [-n netmask] %s[-I ipdev] [-v]\n"
290 "Note: <dst> may be in CIDR notation\n",
292 action
== DEL
? "[-D] " : "",
293 action
== ADD
? "[-m metric] " : "",
294 action
== DEL
? "[-D] " : "",
295 action
== ADD
? "-m metric " : ""
300 static int name_to_ip(const char *name
, ipaddr_t
*addr
)
302 /* Translate a name to an IP address. Try first with inet_aton(), then
303 * with gethostbyname(). (The latter can also recognize an IP address,
304 * but only decimals with at least one dot).)
306 struct hostent
*hostent
;
308 if (!inet_aton(name
, addr
)) {
309 if ((hostent
= gethostbyname(name
)) == NULL
) return 0;
310 if (hostent
->h_addrtype
!= AF_INET
) return 0;
311 if (hostent
->h_length
!= sizeof(*addr
)) return 0;
312 memcpy(addr
, hostent
->h_addr
, sizeof(*addr
));
317 static int parse_cidr(const char *cidr
, ipaddr_t
*addr
, ipaddr_t
*mask
)
324 if ((slash
= strchr(cidr
, '/')) == NULL
)
330 if (!inet_aton(cidr
, &a
))
333 len
= strtoul(slash
, &check
, 10);
334 if (check
== slash
|| *check
!= 0 || len
> 32)
341 *mask
= htonl(len
== 0 ? 0 : (0xFFFFFFFF << (32-len
)) & 0xFFFFFFFF);
346 * $PchId: add_route.c,v 1.6 2001/04/20 10:45:07 philip Exp $