3 1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
4 1999-10-07 - Kurt Garloff - for -host and gws: prefer host names
5 over networks (or even reject)
11 #include <asm/types.h>
12 #include <sys/param.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17 #include <arpa/nameser.h>
18 #include <net/route.h> /* realy broken */
19 #include <sys/ioctl.h>
29 #include "net-support.h"
30 #include "pathnames.h"
32 #include "net-features.h"
36 #define mask_in_addr(x) (((struct sockaddr_in *)&((x).rt_genmask))->sin_addr.s_addr)
37 #define full_mask(x) (x)
39 #define mask_in_addr(x) ((x).rt_genmask)
40 #define full_mask(x) (((struct sockaddr_in *)&(x))->sin_addr.s_addr)
43 extern struct aftype inet_aftype
;
48 static int usage(void)
50 fprintf(stderr
, _("Usage: inet_route [-vF] del {-host|-net} Target[/prefix] [gw Gw] [metric M] [[dev] If]\n"));
51 fprintf(stderr
, _(" inet_route [-vF] add {-host|-net} Target[/prefix] [gw Gw] [metric M]\n"));
52 fprintf(stderr
, _(" [netmask N] [mss Mss] [window W] [irtt I]\n"));
53 fprintf(stderr
, _(" [mod] [dyn] [reinstate] [[dev] If]\n"));
54 fprintf(stderr
, _(" inet_route [-vF] add {-host|-net} Target[/prefix] [metric M] reject\n"));
55 fprintf(stderr
, _(" inet_route [-FC] flush NOT supported\n"));
59 static int INET_setroute(int action
, int options
, char **args
)
62 char target
[128], gateway
[128] = "NONE", netmask
[128] = "default";
67 if (!strcmp(*args
, "#net")) {
70 } else if (!strcmp(*args
, "#host")) {
77 safe_strncpy(target
, *args
++, (sizeof target
));
79 /* Clean out the RTREQ structure. */
80 memset((char *) &rt
, 0, sizeof(struct rtentry
));
82 /* Special hack for /prefix syntax */
90 n
= inet_aftype
.getmask(target
, &mask
.d
, netmask
);
94 rt
.rt_genmask
= full_mask(mask
.d
);
97 /* Prefer hostname lookup is -host flag was given */
98 if ((isnet
= inet_aftype
.input((xflag
!=2? 0: 256), target
, &rt
.rt_dst
)) < 0) {
99 inet_aftype
.herror(target
);
110 /* Fill in the other fields. */
111 rt
.rt_flags
= (RTF_UP
| RTF_HOST
);
113 rt
.rt_flags
&= ~RTF_HOST
;
116 if (!strcmp(*args
, "metric")) {
120 if (!*args
|| !isdigit(**args
))
122 metric
= atoi(*args
);
124 rt
.rt_metric
= metric
+ 1;
126 ENOSUPP("inet_setroute", "NEW_ADDRT (metric)");
131 if (!strcmp(*args
, "netmask")) {
132 struct sockaddr mask
;
135 if (!*args
|| mask_in_addr(rt
))
137 safe_strncpy(netmask
, *args
, (sizeof netmask
));
138 if ((isnet
= inet_aftype
.input(0, netmask
, &mask
)) < 0) {
139 inet_aftype
.herror(netmask
);
142 rt
.rt_genmask
= full_mask(mask
);
146 if (!strcmp(*args
, "gw") || !strcmp(*args
, "gateway")) {
150 if (rt
.rt_flags
& RTF_GATEWAY
)
152 safe_strncpy(gateway
, *args
, (sizeof gateway
));
153 if ((isnet
= inet_aftype
.input(256, gateway
, &rt
.rt_gateway
)) < 0) {
154 inet_aftype
.herror(gateway
);
158 fprintf(stderr
, _("route: %s: cannot use a NETWORK as gateway!\n"),
162 rt
.rt_flags
|= RTF_GATEWAY
;
166 if (!strcmp(*args
, "mss") || !strcmp(*args
,"mtu")) {
168 rt
.rt_flags
|= RTF_MSS
;
171 rt
.rt_mss
= atoi(*args
);
173 if (rt
.rt_mss
< 64 || rt
.rt_mss
> 65536) {
174 fprintf(stderr
, _("route: Invalid MSS/MTU.\n"));
179 if (!strcmp(*args
, "window")) {
183 rt
.rt_flags
|= RTF_WINDOW
;
184 rt
.rt_window
= atoi(*args
);
186 if (rt
.rt_window
< 128) {
187 fprintf(stderr
, _("route: Invalid window.\n"));
192 if (!strcmp(*args
, "irtt")) {
198 rt
.rt_flags
|= RTF_IRTT
;
199 rt
.rt_irtt
= atoi(*(args
- 1));
200 rt
.rt_irtt
*= (HZ
/ 100); /* FIXME */
201 #if 0 /* FIXME: do we need to check anything of this? */
202 if (rt
.rt_irtt
< 1 || rt
.rt_irtt
> (120 * HZ
)) {
203 fprintf(stderr
, _("route: Invalid initial rtt.\n"));
208 ENOSUPP("inet_setroute", "RTF_IRTT");
212 if (!strcmp(*args
, "reject")) {
215 rt
.rt_flags
|= RTF_REJECT
;
217 ENOSUPP("inet_setroute", "RTF_REJECT");
221 if (!strcmp(*args
, "mod")) {
223 rt
.rt_flags
|= RTF_MODIFIED
;
226 if (!strcmp(*args
, "dyn")) {
228 rt
.rt_flags
|= RTF_DYNAMIC
;
231 if (!strcmp(*args
, "reinstate")) {
233 rt
.rt_flags
|= RTF_REINSTATE
;
236 if (!strcmp(*args
, "device") || !strcmp(*args
, "dev")) {
238 if (rt
.rt_dev
|| *args
== NULL
)
243 /* nothing matches */
247 return usage(); /* must be last to catch typos */
253 if ((rt
.rt_flags
& RTF_REJECT
) && !rt
.rt_dev
)
257 /* sanity checks.. */
258 if (mask_in_addr(rt
)) {
259 __u32 mask
= ~ntohl(mask_in_addr(rt
));
260 if ((rt
.rt_flags
& RTF_HOST
) && mask
!= 0xffffffff) {
261 fprintf(stderr
, _("route: netmask %.8x doesn't make sense with host route\n"), mask
);
264 if (mask
& (mask
+ 1)) {
265 fprintf(stderr
, _("route: bogus netmask %s\n"), netmask
);
268 mask
= ((struct sockaddr_in
*) &rt
.rt_dst
)->sin_addr
.s_addr
;
269 if (mask
& ~mask_in_addr(rt
)) {
270 fprintf(stderr
, _("route: netmask doesn't match route address\n"));
274 /* Fill out netmask if still unset */
275 if ((action
== RTACTION_ADD
) && rt
.rt_flags
& RTF_HOST
)
276 mask_in_addr(rt
) = 0xffffffff;
278 /* Create a socket to the INET kernel. */
279 if ((skfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
283 /* Tell the kernel to accept this route. */
284 if (action
== RTACTION_DEL
) {
285 if (ioctl(skfd
, SIOCDELRT
, &rt
) < 0) {
291 if (ioctl(skfd
, SIOCADDRT
, &rt
) < 0) {
298 /* Close the socket. */
303 int INET_rinput(int action
, int options
, char **args
)
305 if (action
== RTACTION_FLUSH
) {
306 fprintf(stderr
, _("Flushing `inet' routing table not supported\n"));
309 if (options
& FLAG_CACHE
) {
310 fprintf(stderr
, _("Modifying `inet' routing cache not supported\n"));
313 if ((*args
== NULL
) || (action
== RTACTION_HELP
))
316 return (INET_setroute(action
, options
, args
));
318 #endif /* HAVE_AFINET */