4 Created August 7, 1991 by Philip Homburg
7 #define _POSIX_C_SOURCE 2
10 #include <sys/ioctl.h>
19 #include <net/netlib.h>
20 #include <net/gen/netdb.h>
21 #include <net/gen/in.h>
22 #include <net/gen/inet.h>
23 #include <net/gen/route.h>
24 #include <net/gen/socket.h>
25 #include <net/gen/ip_io.h>
27 static char *prog_name
;
28 static enum { ADD
, DEL
} action
;
30 static void usage(void);
31 static int name_to_ip(const char *name
, ipaddr_t
*addr
);
32 static int parse_cidr(const char *cidr
, ipaddr_t
*addr
, ipaddr_t
*mask
);
34 int main(int argc
, char *argv
[])
36 struct netent
*netent
;
37 ipaddr_t gateway
, destination
, netmask
, defaultmask
=0;
45 char *netmask_str
, *metric_str
, *destination_str
, *gateway_str
;
47 char *d_arg
, *g_arg
, *m_arg
, *n_arg
, *I_arg
;
48 int i_flag
, o_flag
, D_flag
, v_flag
;
51 prog_name
= strrchr(argv
[0], '/');
52 if (prog_name
== NULL
) prog_name
= argv
[0]; else prog_name
++;
54 if (strcmp(prog_name
, "add_route") == 0)
56 else if (strcmp(prog_name
, "del_route") == 0)
60 fprintf(stderr
, "Don't know what to do when named '%s'\n",
74 while ((c
= getopt(argc
, argv
, "iovDg:d:m:n:I:?")) != -1)
126 fprintf(stderr
, "%s: getopt failed\n", prog_name
);
132 if (i_flag
&& o_flag
)
138 if (g_arg
== NULL
|| d_arg
== NULL
|| m_arg
== NULL
)
143 if (g_arg
== NULL
|| (d_arg
== NULL
&& n_arg
!= NULL
))
150 destination_str
= d_arg
;
155 if (!name_to_ip(gateway_str
, &gateway
))
157 fprintf(stderr
, "%s: unknown host '%s'\n", prog_name
,
168 if (parse_cidr(destination_str
, &destination
, &netmask
))
170 else if (inet_aton(destination_str
, &destination
))
172 else if ((netent
= getnetbyname(destination_str
)) != NULL
)
173 destination
= netent
->n_net
;
174 else if (!name_to_ip(destination_str
, &destination
))
176 fprintf(stderr
, "%s: unknown network/host '%s'\n",
177 prog_name
, destination_str
);
180 high_byte
= *(u8_t
*)&destination
;
181 if (!(high_byte
& 0x80)) /* class A or 0 */
185 defaultmask
= htonl(0xff000000);
187 defaultmask
= HTONL(0xff000000);
191 else if (!(high_byte
& 0x40)) /* class B */
194 defaultmask
= htonl(0xffff0000);
196 defaultmask
= HTONL(0xffff0000);
200 else if (!(high_byte
& 0x20)) /* class C */
203 defaultmask
= htonl(0xffffff00);
205 defaultmask
= HTONL(0xffffff00);
209 else /* class D is multicast ... */
211 fprintf(stderr
, "%s: Warning: Martian address '%s'\n",
212 prog_name
, inet_ntoa(destination
));
214 defaultmask
= htonl(0xffffffff);
216 defaultmask
= HTONL(0xffffffff);
219 if (destination
& ~defaultmask
)
223 defaultmask
= htonl(0xffffffff);
225 defaultmask
= HTONL(0xffffffff);
229 netmask
= defaultmask
;
236 if (inet_aton(netmask_str
, &netmask
) == 0)
238 fprintf(stderr
, "%s: illegal netmask'%s'\n", prog_name
,
246 metric
= strtol(metric_str
, &check
, 0);
247 if (check
[0] != '\0' || metric
< 1)
249 fprintf(stderr
, "%s: illegal metric %s\n",
250 prog_name
, metric_str
);
257 ip_device
= getenv("IP_DEVICE");
259 ip_device
= IP_DEVICE
;
261 ip_fd
= open(ip_device
, O_RDWR
);
264 fprintf(stderr
, "%s: unable to open('%s'): %s\n",
265 prog_name
, ip_device
, strerror(errno
));
271 printf("%s %s route to %s ",
272 action
== ADD
? "adding" : "deleting",
273 itab
? "input" : "output",
274 inet_ntoa(destination
));
275 printf("with netmask %s ", inet_ntoa(netmask
));
276 printf("using gateway %s", inet_ntoa(gateway
));
277 if (itab
&& action
== ADD
)
278 printf(" at distance %d", metric
);
283 route
.nwr_dest
= destination
;
284 route
.nwr_netmask
= netmask
;
285 route
.nwr_gateway
= gateway
;
286 route
.nwr_dist
= action
== ADD
? metric
: 0;
287 route
.nwr_flags
= (action
== DEL
&& D_flag
) ? 0 : NWRF_STATIC
;
292 r
= ioctl(ip_fd
, itab
? NWIOSIPIROUTE
: NWIOSIPOROUTE
, &route
);
294 r
= ioctl(ip_fd
, itab
? NWIODIPIROUTE
: NWIODIPOROUTE
, &route
);
297 fprintf(stderr
, "%s: NWIO%cIP%cROUTE: %s\n",
299 action
== ADD
? 'S' : 'D',
307 static void usage(void)
311 "\t[-o] %s-g gw [-d dst [-n netmask]] %s[-I ipdev] [-v]\n"
312 "\t-i %s-g gw -d dst [-n netmask] %s[-I ipdev] [-v]\n"
313 "Note: <dst> may be in CIDR notation\n",
315 action
== DEL
? "[-D] " : "",
316 action
== ADD
? "[-m metric] " : "",
317 action
== DEL
? "[-D] " : "",
318 action
== ADD
? "-m metric " : ""
323 static int name_to_ip(const char *name
, ipaddr_t
*addr
)
325 /* Translate a name to an IP address. Try first with inet_aton(), then
326 * with gethostbyname(). (The latter can also recognize an IP address,
327 * but only decimals with at least one dot).)
329 struct hostent
*hostent
;
331 if (!inet_aton(name
, addr
)) {
332 if ((hostent
= gethostbyname(name
)) == NULL
) return 0;
333 if (hostent
->h_addrtype
!= AF_INET
) return 0;
334 if (hostent
->h_length
!= sizeof(*addr
)) return 0;
335 memcpy(addr
, hostent
->h_addr
, sizeof(*addr
));
340 static int parse_cidr(const char *cidr
, ipaddr_t
*addr
, ipaddr_t
*mask
)
347 if ((slash
= strchr(cidr
, '/')) == NULL
)
353 if (!inet_aton(cidr
, &a
))
356 len
= strtoul(slash
, &check
, 10);
357 if (check
== slash
|| *check
!= 0 || len
> 32)
364 *mask
= htonl(len
== 0 ? 0 : (0xFFFFFFFF << (32-len
)) & 0xFFFFFFFF);
369 * $PchId: add_route.c,v 1.6 2001/04/20 10:45:07 philip Exp $