* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
static char sccsid
[] = "@(#)route.c 5.6 (Berkeley) %G%";
int forcehost
, forcenet
, doflush
, nflag
;
struct sockaddr_in sin
= { AF_INET
};
struct in_addr
inet_makeaddr();
printf("usage: route [ -n ] [ -f ] [ cmd [ net | host ] args ]\n"),
s
= socket(AF_INET
, SOCK_RAW
, 0);
for (; argc
> 0 && argv
[0][0] == '-'; argc
--, argv
++) {
for (argv
[0]++; *argv
[0]; argv
[0]++)
if (strcmp(*argv
, "add") == 0)
else if (strcmp(*argv
, "delete") == 0)
else if (strcmp(*argv
, "change") == 0)
changeroute(argc
-1, argv
+1);
printf("%s: huh?\n", *argv
);
* Purge all entries in the routing tables not
* associated with network interfaces.
register struct rtentry
*rt
;
int rthashsize
, i
, doinghost
= 1, kmem
;
char *routename(), *netname();
if (nl
[N_RTHOST
].n_value
== 0) {
printf("route: \"rthost\", symbol not in namelist\n");
if (nl
[N_RTNET
].n_value
== 0) {
printf("route: \"rtnet\", symbol not in namelist\n");
if (nl
[N_RTHASHSIZE
].n_value
== 0) {
printf("route: \"rthashsize\", symbol not in namelist\n");
kmem
= open("/dev/kmem", 0);
perror("route: /dev/kmem");
lseek(kmem
, nl
[N_RTHASHSIZE
].n_value
, 0);
read(kmem
, &rthashsize
, sizeof (rthashsize
));
routehash
= (struct mbuf
**)malloc(rthashsize
*sizeof (struct mbuf
*));
lseek(kmem
, nl
[N_RTHOST
].n_value
, 0);
read(kmem
, routehash
, rthashsize
*sizeof (struct mbuf
*));
printf("Flushing routing tables:\n");
for (i
= 0; i
< rthashsize
; i
++) {
read(kmem
, &mb
, sizeof (mb
));
rt
= mtod(&mb
, struct rtentry
*);
if (rt
->rt_flags
& RTF_GATEWAY
) {
printf("%-20.20s ", doinghost
?
printf("%-20.20s ", routename(&rt
->rt_gateway
));
if (ioctl(s
, SIOCDELRT
, (caddr_t
)rt
) < 0)
lseek(kmem
, nl
[N_RTNET
].n_value
, 0);
read(kmem
, routehash
, rthashsize
*sizeof (struct mbuf
*));
static char domain
[MAXHOSTNAMELEN
+ 1];
if (gethostname(domain
, MAXHOSTNAMELEN
) == 0 &&
(cp
= index(domain
, '.')))
(void) strcpy(domain
, cp
+ 1);
in
= ((struct sockaddr_in
*)sa
)->sin_addr
;
if (in
.s_addr
== INADDR_ANY
)
hp
= gethostbyaddr(&in
, sizeof (struct in_addr
),
if ((cp
= index(hp
->h_name
, '.')) &&
#define C(x) ((x) & 0xff)
in
.s_addr
= ntohl(in
.s_addr
);
sprintf(line
, "%u.%u.%u.%u", C(in
.s_addr
>> 24),
C(in
.s_addr
>> 16), C(in
.s_addr
>> 8), C(in
.s_addr
));
return (ns_print((struct sockaddr_ns
*)sa
));
{ u_short
*s
= (u_short
*)sa
->sa_data
;
sprintf(line
, "af %d: %x %x %x %x %x %x %x", sa
->sa_family
,
s
[0], s
[1], s
[2], s
[3], s
[4], s
[5], s
[6]);
* Return the name of the network whose address is given.
* The address is assumed to be that of a net or subnet, not a host.
in
= ((struct sockaddr_in
*)sa
)->sin_addr
;
in
.s_addr
= ntohl(in
.s_addr
);
} else if (IN_CLASSB(i
)) {
* If there are more bits than the standard mask
* would suggest, subnets must be in use.
* Guess at the subnet mask, assuming reasonable
while (in
.s_addr
&~ mask
)
mask
= (long)mask
>> subnetshift
;
np
= getnetbyaddr(net
, AF_INET
);
else if ((in
.s_addr
& 0xffffff) == 0)
sprintf(line
, "%u", C(in
.s_addr
>> 24));
else if ((in
.s_addr
& 0xffff) == 0)
sprintf(line
, "%u.%u", C(in
.s_addr
>> 24),
else if ((in
.s_addr
& 0xff) == 0)
sprintf(line
, "%u.%u.%u", C(in
.s_addr
>> 24),
C(in
.s_addr
>> 16), C(in
.s_addr
>> 8));
sprintf(line
, "%u.%u.%u.%u", C(in
.s_addr
>> 24),
C(in
.s_addr
>> 16), C(in
.s_addr
>> 8),
return (ns_print((struct sockaddr_ns
*)sa
));
{ u_short
*s
= (u_short
*)sa
->sa_data
;
sprintf(line
, "af %d: %x %x %x %x %x %x %x", sa
->sa_family
,
s
[0], s
[1], s
[2], s
[3], s
[4], s
[5], s
[6]);
char *cmd
, *dest
, *gateway
;
int ishost
, metric
= 0, ret
, attempts
, oerrno
;
if ((strcmp(argv
[1], "host")) == 0) {
} else if ((strcmp(argv
[1], "net")) == 0) {
printf("usage: %s destination gateway metric\n", cmd
);
printf("(metric of 0 if gateway is this host)\n");
printf("usage: %s destination gateway\n", cmd
);
sin
= (struct sockaddr_in
*)&route
.rt_dst
;
ishost
= getaddr(argv
[1], &route
.rt_dst
, &hp
, &dest
, forcenet
);
sin
= (struct sockaddr_in
*)&route
.rt_gateway
;
(void) getaddr(argv
[2], &route
.rt_gateway
, &hp
, &gateway
, 0);
route
.rt_flags
|= RTF_HOST
;
route
.rt_flags
|= RTF_GATEWAY
;
for (attempts
= 1; ; attempts
++) {
if ((ret
= ioctl(s
, *cmd
== 'a' ? SIOCADDRT
: SIOCDELRT
,
if (errno
!= ENETUNREACH
&& errno
!= ESRCH
)
if (hp
&& hp
->h_addr_list
[1]) {
bcopy(hp
->h_addr_list
[0], (caddr_t
)&sin
->sin_addr
,
printf("%s %s %s: gateway %s", cmd
, ishost
? "host" : "net",
if (attempts
> 1 && ret
== 0)
inet_ntoa(((struct sockaddr_in
*)&route
.rt_gateway
)->sin_addr
));
printf("not supported\n");
fprintf(stderr
, "not in table\n");
fprintf(stderr
, "entry in use\n");
else if (errno
== ENOBUFS
)
fprintf(stderr
, "routing table overflow\n");
sav
= malloc(strlen(s
) + 1);
fprintf("route: out of memory\n");
* Interpret an argument as a network address of some kind,
* returning 1 if a host address, 0 if a network address.
getaddr(s
, sin
, hpp
, name
, isnet
)
if (strcmp(s
, "default") == 0) {
sin
->sin_family
= AF_INET
;
sin
->sin_addr
= inet_makeaddr(0, INADDR_ANY
);
sin
->sin_family
= AF_INET
;
sin
->sin_addr
.s_addr
= val
;
return(inet_lnaof(sin
->sin_addr
) != INADDR_ANY
);
sin
->sin_addr
= inet_makeaddr(val
, INADDR_ANY
);
sin
->sin_family
= np
->n_addrtype
;
sin
->sin_addr
= inet_makeaddr(np
->n_net
, INADDR_ANY
);
*name
= savestr(np
->n_name
);
sin
->sin_family
= hp
->h_addrtype
;
bcopy(hp
->h_addr
, &sin
->sin_addr
, hp
->h_length
);
*name
= savestr(hp
->h_name
);
fprintf(stderr
, "%s: bad value\n", s
);
short ns_nullh
[] = {0,0,0};
short ns_bh
[] = {-1,-1,-1};
union { union ns_net net_e
; u_long long_e
; } net
;
static char mybuf
[50], cport
[10], chost
[25];
register char *p
; register u_char
*q
; u_char
*q_lim
;
port
= ntohs(work
.x_port
);
if (ns_nullhost(work
) && net
.long_e
== 0) {
sprintf(mybuf
, "*.%xH", port
);
if (bcmp(ns_bh
, work
.x_host
.c_host
, 6) == 0) {
} else if (bcmp(ns_nullh
, work
.x_host
.c_host
, 6) == 0) {
sprintf(chost
, "%02x%02x%02x%02x%02x%02xH",
q
[0], q
[1], q
[2], q
[3], q
[4], q
[5]);
for (p
= chost
; *p
== '0' && p
< chost
+ 12; p
++);
sprintf(cport
, ".%xH", htons(port
));
sprintf(mybuf
,"%xH.%s%s", ntohl(net
.long_e
), host
, cport
);
for (; *p
; p
++) switch (*p
) {
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':