version 1.106, 2007/02/18 01:48:37 |
version 1.106.12.2, 2009/01/17 13:48:53 |
|
|
|
|
#include <sys/cdefs.h> |
#include <sys/cdefs.h> |
#ifndef lint |
#ifndef lint |
__COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1991, 1993\n\ |
__COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1991, 1993\ |
The Regents of the University of California. All rights reserved.\n"); |
The Regents of the University of California. All rights reserved."); |
#endif /* not lint */ |
#endif /* not lint */ |
|
|
#ifndef lint |
#ifndef lint |
Line 73 __RCSID("$NetBSD$"); |
|
Line 73 __RCSID("$NetBSD$"); |
|
#include "keywords.h" |
#include "keywords.h" |
#include "extern.h" |
#include "extern.h" |
|
|
|
union sockunion { |
|
struct sockaddr sa; |
|
struct sockaddr_in sin; |
|
#ifdef INET6 |
|
struct sockaddr_in6 sin6; |
|
#endif |
|
struct sockaddr_at sat; |
|
struct sockaddr_dl sdl; |
|
#ifndef SMALL |
|
struct sockaddr_iso siso; |
|
#endif /* SMALL */ |
|
}; |
|
|
typedef union sockunion *sup; |
typedef union sockunion *sup; |
|
|
|
struct sou { |
|
union sockunion so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp; |
|
}; |
|
|
static char *any_ntoa(const struct sockaddr *); |
static char *any_ntoa(const struct sockaddr *); |
static const char *route_strerror(int); |
static const char *route_strerror(int); |
static void set_metric(char *, int); |
static void set_metric(const char *, int); |
static int newroute(int, char **); |
static int newroute(int, char *const *); |
static void inet_makenetandmask(u_int32_t, struct sockaddr_in *); |
static void inet_makenetandmask(u_int32_t, struct sockaddr_in *, struct sou *); |
#ifdef INET6 |
#ifdef INET6 |
static int inet6_makenetandmask(struct sockaddr_in6 *); |
static int inet6_makenetandmask(const struct sockaddr_in6 *, struct sou *); |
#endif |
#endif |
static int getaddr(int, char *, struct hostent **); |
static int getaddr(int, const char *, struct hostent **, struct sou *); |
static int flushroutes(int, char *[], int); |
static int flushroutes(int, char *const [], int); |
static int prefixlen(const char *); |
static int prefixlen(const char *, struct sou *); |
#ifndef SMALL |
#ifndef SMALL |
static void interfaces(void); |
static void interfaces(void); |
static void monitor(void); |
static void monitor(void); |
static int print_getmsg(struct rt_msghdr *, int); |
static int print_getmsg(struct rt_msghdr *, int, struct sou *); |
static const char *linkstate(struct if_msghdr *); |
static const char *linkstate(struct if_msghdr *); |
#endif /* SMALL */ |
#endif /* SMALL */ |
static int rtmsg(int, int ); |
static int rtmsg(int, int, struct sou *); |
static void mask_addr(void); |
static void mask_addr(struct sou *); |
static void print_rtmsg(struct rt_msghdr *, int); |
static void print_rtmsg(struct rt_msghdr *, int); |
static void pmsg_common(struct rt_msghdr *); |
static void pmsg_common(struct rt_msghdr *); |
static void pmsg_addrs(char *, int); |
static void pmsg_addrs(const char *, int); |
static void bprintf(FILE *, int, const char *); |
static void bprintf(FILE *, int, const char *); |
static void sodump(sup, const char *); |
static void sodump(sup, const char *); |
static void sockaddr(char *, struct sockaddr *); |
static void sockaddr(const char *, struct sockaddr *); |
|
|
union sockunion { |
|
struct sockaddr sa; |
|
struct sockaddr_in sin; |
|
#ifdef INET6 |
|
struct sockaddr_in6 sin6; |
|
#endif |
|
struct sockaddr_at sat; |
|
struct sockaddr_dl sdl; |
|
#ifndef SMALL |
|
struct sockaddr_iso siso; |
|
#endif /* SMALL */ |
|
} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp; |
|
|
|
int pid, rtm_addrs; |
int pid, rtm_addrs; |
int sock; |
int sock; |
Line 146 usage(const char *cp) |
|
Line 150 usage(const char *cp) |
|
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) |
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) |
|
|
int |
int |
main(int argc, char **argv) |
main(int argc, char * const *argv) |
{ |
{ |
int ch; |
int ch; |
|
|
Line 241 main(int argc, char **argv) |
|
Line 245 main(int argc, char **argv) |
|
* associated with network interfaces. |
* associated with network interfaces. |
*/ |
*/ |
static int |
static int |
flushroutes(int argc, char *argv[], int doall) |
flushroutes(int argc, char * const argv[], int doall) |
{ |
{ |
struct sockaddr *sa; |
struct sockaddr *sa; |
size_t needed; |
size_t needed; |
Line 253 flushroutes(int argc, char *argv[], int |
|
Line 257 flushroutes(int argc, char *argv[], int |
|
flags = 0; |
flags = 0; |
af = AF_UNSPEC; |
af = AF_UNSPEC; |
shutdown(sock, SHUT_RD); /* Don't want to read back our messages */ |
shutdown(sock, SHUT_RD); /* Don't want to read back our messages */ |
parse_show_opts(argc, argv, &af, &flags, &afname, 0); |
parse_show_opts(argc, argv, &af, &flags, &afname, false); |
mib[0] = CTL_NET; |
mib[0] = CTL_NET; |
mib[1] = PF_ROUTE; |
mib[1] = PF_ROUTE; |
mib[2] = 0; /* protocol */ |
mib[2] = 0; /* protocol */ |
Line 419 netmask_length(struct sockaddr *nm, int |
|
Line 423 netmask_length(struct sockaddr *nm, int |
|
} |
} |
|
|
char * |
char * |
netmask_string(struct sockaddr *mask, int len, int family) |
netmask_string(const struct sockaddr *mask, int len, int family) |
{ |
{ |
static char smask[INET6_ADDRSTRLEN]; |
static char smask[INET6_ADDRSTRLEN]; |
struct sockaddr_in nsin; |
struct sockaddr_in nsin; |
Line 450 netmask_string(struct sockaddr *mask, in |
|
Line 454 netmask_string(struct sockaddr *mask, in |
|
} |
} |
|
|
const char * |
const char * |
routename(struct sockaddr *sa, struct sockaddr *nm, int flags) |
routename(const struct sockaddr *sa, struct sockaddr *nm, int flags) |
{ |
{ |
const char *cp; |
const char *cp; |
static char line[50]; |
static char line[50]; |
Line 477 routename(struct sockaddr *sa, struct so |
|
Line 481 routename(struct sockaddr *sa, struct so |
|
else switch (sa->sa_family) { |
else switch (sa->sa_family) { |
|
|
case AF_INET: |
case AF_INET: |
in = ((struct sockaddr_in *)sa)->sin_addr; |
in = ((const struct sockaddr_in *)sa)->sin_addr; |
nml = netmask_length(nm, AF_INET); |
nml = netmask_length(nm, AF_INET); |
|
|
cp = 0; |
cp = 0; |
Line 511 routename(struct sockaddr *sa, struct so |
|
Line 515 routename(struct sockaddr *sa, struct so |
|
break; |
break; |
|
|
case AF_LINK: |
case AF_LINK: |
return (link_ntoa((struct sockaddr_dl *)sa)); |
return link_ntoa((const struct sockaddr_dl *)sa); |
|
|
#ifdef INET6 |
#ifdef INET6 |
case AF_INET6: |
case AF_INET6: |
Line 563 routename(struct sockaddr *sa, struct so |
|
Line 567 routename(struct sockaddr *sa, struct so |
|
#ifndef SMALL |
#ifndef SMALL |
case AF_ISO: |
case AF_ISO: |
(void)snprintf(line, sizeof line, "iso %s", |
(void)snprintf(line, sizeof line, "iso %s", |
iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr)); |
iso_ntoa(&((const struct sockaddr_iso *)sa)->siso_addr)); |
break; |
break; |
|
|
case AF_APPLETALK: |
case AF_APPLETALK: |
(void)snprintf(line, sizeof(line), "atalk %d.%d", |
(void)snprintf(line, sizeof(line), "atalk %d.%d", |
((struct sockaddr_at *)sa)->sat_addr.s_net, |
((const struct sockaddr_at *)sa)->sat_addr.s_net, |
((struct sockaddr_at *)sa)->sat_addr.s_node); |
((const struct sockaddr_at *)sa)->sat_addr.s_node); |
break; |
break; |
#endif /* SMALL */ |
#endif /* SMALL */ |
|
|
Line 579 routename(struct sockaddr *sa, struct so |
|
Line 583 routename(struct sockaddr *sa, struct so |
|
break; |
break; |
|
|
} |
} |
return (line); |
return line; |
} |
} |
|
|
/* |
/* |
Line 587 routename(struct sockaddr *sa, struct so |
|
Line 591 routename(struct sockaddr *sa, struct so |
|
* The address is assumed to be that of a net or subnet, not a host. |
* The address is assumed to be that of a net or subnet, not a host. |
*/ |
*/ |
const char * |
const char * |
netname(struct sockaddr *sa, struct sockaddr *nm) |
netname(const struct sockaddr *sa, struct sockaddr *nm) |
{ |
{ |
const char *cp = 0; |
const char *cp = 0; |
static char line[50]; |
static char line[50]; |
Line 600 netname(struct sockaddr *sa, struct sock |
|
Line 604 netname(struct sockaddr *sa, struct sock |
|
switch (sa->sa_family) { |
switch (sa->sa_family) { |
|
|
case AF_INET: |
case AF_INET: |
in = ((struct sockaddr_in *)sa)->sin_addr; |
in = ((const struct sockaddr_in *)sa)->sin_addr; |
i = ntohl(in.s_addr); |
i = ntohl(in.s_addr); |
nml = netmask_length(nm, AF_INET); |
nml = netmask_length(nm, AF_INET); |
if (i == 0) { |
if (i == 0) { |
Line 658 netname(struct sockaddr *sa, struct sock |
|
Line 662 netname(struct sockaddr *sa, struct sock |
|
break; |
break; |
|
|
case AF_LINK: |
case AF_LINK: |
return (link_ntoa((struct sockaddr_dl *)sa)); |
return link_ntoa((const struct sockaddr_dl *)sa); |
|
|
#ifdef INET6 |
#ifdef INET6 |
case AF_INET6: |
case AF_INET6: |
Line 702 netname(struct sockaddr *sa, struct sock |
|
Line 706 netname(struct sockaddr *sa, struct sock |
|
#ifndef SMALL |
#ifndef SMALL |
case AF_ISO: |
case AF_ISO: |
(void)snprintf(line, sizeof line, "iso %s", |
(void)snprintf(line, sizeof line, "iso %s", |
iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr)); |
iso_ntoa(&((const struct sockaddr_iso *)sa)->siso_addr)); |
break; |
break; |
|
|
case AF_APPLETALK: |
case AF_APPLETALK: |
(void)snprintf(line, sizeof(line), "atalk %d.%d", |
(void)snprintf(line, sizeof(line), "atalk %d.%d", |
((struct sockaddr_at *)sa)->sat_addr.s_net, |
((const struct sockaddr_at *)sa)->sat_addr.s_net, |
((struct sockaddr_at *)sa)->sat_addr.s_node); |
((const struct sockaddr_at *)sa)->sat_addr.s_node); |
break; |
break; |
#endif /* SMALL */ |
#endif /* SMALL */ |
|
|
Line 717 netname(struct sockaddr *sa, struct sock |
|
Line 721 netname(struct sockaddr *sa, struct sock |
|
sa->sa_family, any_ntoa(sa)); |
sa->sa_family, any_ntoa(sa)); |
break; |
break; |
} |
} |
return (line); |
return line; |
} |
} |
|
|
static const char * |
static const char * |
Line 737 route_strerror(int error) |
|
Line 741 route_strerror(int error) |
|
} |
} |
|
|
static void |
static void |
set_metric(char *value, int key) |
set_metric(const char *value, int key) |
{ |
{ |
int flag = 0; |
int flag = 0; |
u_long noval, *valp = &noval; |
u_long noval, *valp = &noval; |
Line 758 set_metric(char *value, int key) |
|
Line 762 set_metric(char *value, int key) |
|
rt_metrics.rmx_locks |= flag; |
rt_metrics.rmx_locks |= flag; |
if (locking) |
if (locking) |
locking = 0; |
locking = 0; |
*valp = atoi(value); |
*valp = strtoul(value, NULL, 0); |
} |
} |
|
|
static int |
static int |
newroute(int argc, char **argv) |
newroute(int argc, char *const *argv) |
{ |
{ |
const char *cmd, *dest = "", *gateway = ""; |
const char *cmd, *dest = "", *gateway = ""; |
int ishost = 0, ret, attempts, oerrno, flags = RTF_STATIC; |
int ishost = 0, ret, attempts, oerrno, flags = RTF_STATIC; |
int key; |
int key; |
struct hostent *hp = 0; |
struct hostent *hp = 0; |
|
struct sou sou, *soup = &sou; |
|
|
|
memset(&sou, 0, sizeof(sou)); |
|
|
cmd = argv[0]; |
cmd = argv[0]; |
af = AF_UNSPEC; |
af = AF_UNSPEC; |
Line 866 newroute(int argc, char **argv) |
|
Line 873 newroute(int argc, char **argv) |
|
case K_IFA: |
case K_IFA: |
if (!--argc) |
if (!--argc) |
usage(1+*argv); |
usage(1+*argv); |
(void)getaddr(RTA_IFA, *++argv, 0); |
(void)getaddr(RTA_IFA, *++argv, 0, soup); |
break; |
break; |
case K_IFP: |
case K_IFP: |
if (!--argc) |
if (!--argc) |
usage(1+*argv); |
usage(1+*argv); |
(void)getaddr(RTA_IFP, *++argv, 0); |
(void)getaddr(RTA_IFP, *++argv, 0, soup); |
break; |
break; |
case K_GENMASK: |
case K_GENMASK: |
if (!--argc) |
if (!--argc) |
usage(1+*argv); |
usage(1+*argv); |
(void)getaddr(RTA_GENMASK, *++argv, 0); |
(void)getaddr(RTA_GENMASK, *++argv, 0, soup); |
break; |
break; |
case K_GATEWAY: |
case K_GATEWAY: |
if (!--argc) |
if (!--argc) |
usage(1+*argv); |
usage(1+*argv); |
(void)getaddr(RTA_GATEWAY, *++argv, 0); |
(void)getaddr(RTA_GATEWAY, *++argv, 0, soup); |
break; |
break; |
case K_DST: |
case K_DST: |
if (!--argc) |
if (!--argc) |
usage(1+*argv); |
usage(1+*argv); |
ishost = getaddr(RTA_DST, *++argv, &hp); |
ishost = getaddr(RTA_DST, *++argv, &hp, soup); |
dest = *argv; |
dest = *argv; |
break; |
break; |
case K_NETMASK: |
case K_NETMASK: |
if (!--argc) |
if (!--argc) |
usage(1+*argv); |
usage(1+*argv); |
(void)getaddr(RTA_NETMASK, *++argv, 0); |
(void)getaddr(RTA_NETMASK, *++argv, 0, soup); |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case K_NET: |
case K_NET: |
forcenet++; |
forcenet++; |
Line 900 newroute(int argc, char **argv) |
|
Line 907 newroute(int argc, char **argv) |
|
case K_PREFIXLEN: |
case K_PREFIXLEN: |
if (!--argc) |
if (!--argc) |
usage(1+*argv); |
usage(1+*argv); |
ishost = prefixlen(*++argv); |
ishost = prefixlen(*++argv, soup); |
break; |
break; |
case K_MTU: |
case K_MTU: |
case K_HOPCOUNT: |
case K_HOPCOUNT: |
Line 920 newroute(int argc, char **argv) |
|
Line 927 newroute(int argc, char **argv) |
|
} else { |
} else { |
if ((rtm_addrs & RTA_DST) == 0) { |
if ((rtm_addrs & RTA_DST) == 0) { |
dest = *argv; |
dest = *argv; |
ishost = getaddr(RTA_DST, *argv, &hp); |
ishost = getaddr(RTA_DST, *argv, &hp, soup); |
} else if ((rtm_addrs & RTA_GATEWAY) == 0) { |
} else if ((rtm_addrs & RTA_GATEWAY) == 0) { |
gateway = *argv; |
gateway = *argv; |
(void)getaddr(RTA_GATEWAY, *argv, &hp); |
(void)getaddr(RTA_GATEWAY, *argv, &hp, soup); |
} else { |
} else { |
ret = atoi(*argv); |
ret = atoi(*argv); |
|
|
Line 947 newroute(int argc, char **argv) |
|
Line 954 newroute(int argc, char **argv) |
|
iflag = 0; |
iflag = 0; |
continue; |
continue; |
} |
} |
(void)getaddr(RTA_NETMASK, *argv, 0); |
(void)getaddr(RTA_NETMASK, *argv, 0, soup); |
} |
} |
} |
} |
} |
} |
Line 964 newroute(int argc, char **argv) |
|
Line 971 newroute(int argc, char **argv) |
|
flags |= RTF_GATEWAY; |
flags |= RTF_GATEWAY; |
for (attempts = 1; ; attempts++) { |
for (attempts = 1; ; attempts++) { |
errno = 0; |
errno = 0; |
if ((ret = rtmsg(*cmd, flags)) == 0) |
if ((ret = rtmsg(*cmd, flags, soup)) == 0) |
break; |
break; |
if (errno != ENETUNREACH && errno != ESRCH) |
if (errno != ENETUNREACH && errno != ESRCH) |
break; |
break; |
if (af == AF_INET && *gateway && hp && hp->h_addr_list[1]) { |
if (af == AF_INET && *gateway && hp && hp->h_addr_list[1]) { |
hp->h_addr_list++; |
hp->h_addr_list++; |
memmove(&so_gate.sin.sin_addr, hp->h_addr_list[0], |
memmove(&soup->so_gate.sin.sin_addr, hp->h_addr_list[0], |
hp->h_length); |
hp->h_length); |
} else |
} else |
break; |
break; |
} |
} |
if (*cmd == 'g') |
if (*cmd == 'g') |
return (ret != 0); |
return ret != 0; |
if (!qflag) { |
if (!qflag) { |
oerrno = errno; |
oerrno = errno; |
(void)printf("%s %s %s", cmd, ishost? "host" : "net", dest); |
(void)printf("%s %s %s", cmd, ishost? "host" : "net", dest); |
Line 984 newroute(int argc, char **argv) |
|
Line 991 newroute(int argc, char **argv) |
|
(void)printf(": gateway %s", gateway); |
(void)printf(": gateway %s", gateway); |
if (attempts > 1 && ret == 0 && af == AF_INET) |
if (attempts > 1 && ret == 0 && af == AF_INET) |
(void)printf(" (%s)", |
(void)printf(" (%s)", |
inet_ntoa(so_gate.sin.sin_addr)); |
inet_ntoa(soup->so_gate.sin.sin_addr)); |
} |
} |
if (ret == 0) |
if (ret == 0) |
(void)printf("\n"); |
(void)printf("\n"); |
else |
else |
(void)printf(": %s\n", route_strerror(oerrno)); |
(void)printf(": %s\n", route_strerror(oerrno)); |
} |
} |
return (ret != 0); |
return ret != 0; |
} |
} |
|
|
static void |
static void |
inet_makenetandmask(u_int32_t net, struct sockaddr_in *isin) |
inet_makenetandmask(const u_int32_t net, struct sockaddr_in * const isin, |
|
struct sou *soup) |
{ |
{ |
|
struct sockaddr_in *sin; |
u_int32_t addr, mask = 0; |
u_int32_t addr, mask = 0; |
char *cp; |
char *cp; |
|
|
Line 1042 inet_makenetandmask(u_int32_t net, struc |
|
Line 1051 inet_makenetandmask(u_int32_t net, struc |
|
mask = -1; |
mask = -1; |
} |
} |
isin->sin_addr.s_addr = htonl(addr); |
isin->sin_addr.s_addr = htonl(addr); |
isin = &so_mask.sin; |
sin = &soup->so_mask.sin; |
isin->sin_addr.s_addr = htonl(mask); |
sin->sin_addr.s_addr = htonl(mask); |
isin->sin_len = 0; |
sin->sin_len = 0; |
isin->sin_family = 0; |
sin->sin_family = 0; |
cp = (char *)(&isin->sin_addr + 1); |
cp = (char *)(&sin->sin_addr + 1); |
while (*--cp == 0 && cp > (char *)isin) |
while (*--cp == 0 && cp > (char *)sin) |
; |
; |
isin->sin_len = 1 + cp - (char *)isin; |
sin->sin_len = 1 + cp - (char *)sin; |
isin->sin_family = AF_INET; |
sin->sin_family = AF_INET; |
} |
} |
|
|
#ifdef INET6 |
#ifdef INET6 |
Line 1058 inet_makenetandmask(u_int32_t net, struc |
|
Line 1067 inet_makenetandmask(u_int32_t net, struc |
|
* XXX the function may need more improvement... |
* XXX the function may need more improvement... |
*/ |
*/ |
static int |
static int |
inet6_makenetandmask(struct sockaddr_in6 *sin6) |
inet6_makenetandmask(const struct sockaddr_in6 * const sin6, struct sou *soup) |
{ |
{ |
const char *plen; |
const char *plen; |
struct in6_addr in6; |
struct in6_addr in6; |
Line 1078 inet6_makenetandmask(struct sockaddr_in6 |
|
Line 1087 inet6_makenetandmask(struct sockaddr_in6 |
|
return 1; |
return 1; |
else { |
else { |
rtm_addrs |= RTA_NETMASK; |
rtm_addrs |= RTA_NETMASK; |
(void)prefixlen(plen); |
(void)prefixlen(plen, soup); |
return 0; |
return 0; |
} |
} |
} |
} |
Line 1089 inet6_makenetandmask(struct sockaddr_in6 |
|
Line 1098 inet6_makenetandmask(struct sockaddr_in6 |
|
* returning 1 if a host address, 0 if a network address. |
* returning 1 if a host address, 0 if a network address. |
*/ |
*/ |
static int |
static int |
getaddr(int which, char *s, struct hostent **hpp) |
getaddr(int which, const char *s, struct hostent **hpp, struct sou *soup) |
{ |
{ |
sup su; |
sup su; |
struct hostent *hp; |
struct hostent *hp; |
Line 1106 getaddr(int which, char *s, struct hoste |
|
Line 1115 getaddr(int which, char *s, struct hoste |
|
rtm_addrs |= which; |
rtm_addrs |= which; |
switch (which) { |
switch (which) { |
case RTA_DST: |
case RTA_DST: |
su = &so_dst; |
su = &soup->so_dst; |
break; |
break; |
case RTA_GATEWAY: |
case RTA_GATEWAY: |
su = &so_gate; |
su = &soup->so_gate; |
break; |
break; |
case RTA_NETMASK: |
case RTA_NETMASK: |
su = &so_mask; |
su = &soup->so_mask; |
break; |
break; |
case RTA_GENMASK: |
case RTA_GENMASK: |
su = &so_genmask; |
su = &soup->so_genmask; |
break; |
break; |
case RTA_IFP: |
case RTA_IFP: |
su = &so_ifp; |
su = &soup->so_ifp; |
afamily = AF_LINK; |
afamily = AF_LINK; |
break; |
break; |
case RTA_IFA: |
case RTA_IFA: |
su = &so_ifa; |
su = &soup->so_ifa; |
su->sa.sa_family = af; |
su->sa.sa_family = af; |
break; |
break; |
default: |
default: |
Line 1136 getaddr(int which, char *s, struct hoste |
|
Line 1145 getaddr(int which, char *s, struct hoste |
|
switch (which) { |
switch (which) { |
case RTA_DST: |
case RTA_DST: |
forcenet++; |
forcenet++; |
(void)getaddr(RTA_NETMASK, s, 0); |
(void)getaddr(RTA_NETMASK, s, 0, soup); |
break; |
break; |
case RTA_NETMASK: |
case RTA_NETMASK: |
case RTA_GENMASK: |
case RTA_GENMASK: |
su->sa.sa_len = 0; |
su->sa.sa_len = 0; |
} |
} |
return (0); |
return 0; |
} |
} |
switch (afamily) { |
switch (afamily) { |
#ifdef INET6 |
#ifdef INET6 |
Line 1187 getaddr(int which, char *s, struct hoste |
|
Line 1196 getaddr(int which, char *s, struct hoste |
|
#endif |
#endif |
if (hints.ai_flags == AI_NUMERICHOST) { |
if (hints.ai_flags == AI_NUMERICHOST) { |
if (slash) |
if (slash) |
return (prefixlen(slash + 1)); |
return prefixlen(slash + 1, soup); |
if (which == RTA_DST) |
if (which == RTA_DST) |
return (inet6_makenetandmask(&su->sin6)); |
return inet6_makenetandmask(&su->sin6, soup); |
return (0); |
return 0; |
} else |
} else |
return (1); |
return 1; |
} |
} |
#endif |
#endif |
|
|
Line 1205 getaddr(int which, char *s, struct hoste |
|
Line 1214 getaddr(int which, char *s, struct hoste |
|
do {--cp ;} while ((cp > (char *)su) && (*cp == 0)); |
do {--cp ;} while ((cp > (char *)su) && (*cp == 0)); |
su->siso.siso_len = 1 + cp - (char *)su; |
su->siso.siso_len = 1 + cp - (char *)su; |
} |
} |
return (1); |
return 1; |
#endif /* SMALL */ |
#endif /* SMALL */ |
|
|
case PF_ROUTE: |
case PF_ROUTE: |
su->sa.sa_len = sizeof(*su); |
su->sa.sa_len = sizeof(*su); |
sockaddr(s, &su->sa); |
sockaddr(s, &su->sa); |
return (1); |
return 1; |
|
|
#ifndef SMALL |
#ifndef SMALL |
case AF_APPLETALK: |
case AF_APPLETALK: |
|
|
|
|
case AF_LINK: |
case AF_LINK: |
link_addr(s, &su->sdl); |
link_addr(s, &su->sdl); |
return (1); |
return 1; |
|
|
case AF_INET: |
case AF_INET: |
default: |
default: |
|
|
*t = '\0'; |
*t = '\0'; |
if (forcenet == 0) { |
if (forcenet == 0) { |
if ((val = inet_addr(s)) != INADDR_NONE) { |
if ((val = inet_addr(s)) != INADDR_NONE) { |
inet_makenetandmask(htonl(val), &su->sin); |
inet_makenetandmask(htonl(val), &su->sin, soup); |
return prefixlen(&t[1]); |
return prefixlen(&t[1], soup); |
} |
} |
} else { |
} else { |
if ((val = inet_network(s)) != INADDR_NONE) { |
if ((val = inet_network(s)) != INADDR_NONE) { |
inet_makenetandmask(val, &su->sin); |
inet_makenetandmask(val, &su->sin, soup); |
return prefixlen(&t[1]); |
return prefixlen(&t[1], soup); |
} |
} |
} |
} |
*t = '/'; |
*t = '/'; |
|
|
(which != RTA_DST || forcenet == 0)) { |
(which != RTA_DST || forcenet == 0)) { |
val = su->sin.sin_addr.s_addr; |
val = su->sin.sin_addr.s_addr; |
if (inet_lnaof(su->sin.sin_addr) != INADDR_ANY) |
if (inet_lnaof(su->sin.sin_addr) != INADDR_ANY) |
return (1); |
return 1; |
else { |
else { |
val = ntohl(val); |
val = ntohl(val); |
goto netdone; |
goto netdone; |
|
|
((np = getnetbyname(s)) != NULL && (val = np->n_net) != 0)) { |
((np = getnetbyname(s)) != NULL && (val = np->n_net) != 0)) { |
netdone: |
netdone: |
if (which == RTA_DST) |
if (which == RTA_DST) |
inet_makenetandmask(val, &su->sin); |
inet_makenetandmask(val, &su->sin, soup); |
return (0); |
return 0; |
} |
} |
hp = gethostbyname(s); |
hp = gethostbyname(s); |
if (hp) { |
if (hp) { |
*hpp = hp; |
*hpp = hp; |
su->sin.sin_family = hp->h_addrtype; |
su->sin.sin_family = hp->h_addrtype; |
memmove(&su->sin.sin_addr, hp->h_addr, hp->h_length); |
memmove(&su->sin.sin_addr, hp->h_addr, hp->h_length); |
return (1); |
return 1; |
} |
} |
errx(EXIT_FAILURE, "%s: bad value", s); |
errx(EXIT_FAILURE, "%s: bad value", s); |
/*NOTREACHED*/ |
/*NOTREACHED*/ |
} |
} |
|
|
int |
int |
prefixlen(const char *s) |
prefixlen(const char *s, struct sou *soup) |
{ |
{ |
int len = atoi(s), q, r; |
int len = atoi(s), q, r; |
int max; |
int max; |
Line 1316 prefixlen(const char *s) |
|
Line 1325 prefixlen(const char *s) |
|
r = len & 7; |
r = len & 7; |
switch (af) { |
switch (af) { |
case AF_INET: |
case AF_INET: |
memset(&so_mask, 0, sizeof(so_mask)); |
memset(&soup->so_mask, 0, sizeof(soup->so_mask)); |
so_mask.sin.sin_family = AF_INET; |
soup->so_mask.sin.sin_family = AF_INET; |
so_mask.sin.sin_len = sizeof(struct sockaddr_in); |
soup->so_mask.sin.sin_len = sizeof(struct sockaddr_in); |
so_mask.sin.sin_addr.s_addr = (len == 0 ? 0 |
soup->so_mask.sin.sin_addr.s_addr = (len == 0 ? 0 |
: htonl(0xffffffff << (32 - len))); |
: htonl(0xffffffff << (32 - len))); |
break; |
break; |
#ifdef INET6 |
#ifdef INET6 |
case AF_INET6: |
case AF_INET6: |
so_mask.sin6.sin6_family = AF_INET6; |
soup->so_mask.sin6.sin6_family = AF_INET6; |
so_mask.sin6.sin6_len = sizeof(struct sockaddr_in6); |
soup->so_mask.sin6.sin6_len = sizeof(struct sockaddr_in6); |
memset((void *)&so_mask.sin6.sin6_addr, 0, |
memset(&soup->so_mask.sin6.sin6_addr, 0, |
sizeof(so_mask.sin6.sin6_addr)); |
sizeof(soup->so_mask.sin6.sin6_addr)); |
if (q > 0) |
if (q > 0) |
memset((void *)&so_mask.sin6.sin6_addr, 0xff, q); |
memset(&soup->so_mask.sin6.sin6_addr, 0xff, q); |
if (r > 0) |
if (r > 0) |
*((u_char *)&so_mask.sin6.sin6_addr + q) = |
*((u_char *)&soup->so_mask.sin6.sin6_addr + q) = |
(0xff00 >> r) & 0xff; |
(0xff00 >> r) & 0xff; |
break; |
break; |
#endif |
#endif |
} |
} |
return (len == max); |
return len == max; |
} |
} |
|
|
#ifndef SMALL |
#ifndef SMALL |
|
|
monitor(void) |
monitor(void) |
{ |
{ |
int n; |
int n; |
char msg[2048]; |
union { |
|
char msg[2048]; |
|
struct rt_msghdr hdr; |
|
} u; |
|
|
verbose = 1; |
verbose = 1; |
if (debugonly) { |
if (debugonly) { |
|
|
} |
} |
for(;;) { |
for(;;) { |
time_t now; |
time_t now; |
n = read(sock, msg, 2048); |
n = read(sock, &u, sizeof(u)); |
now = time(NULL); |
now = time(NULL); |
(void)printf("got message of size %d on %s", n, ctime(&now)); |
(void)printf("got message of size %d on %s", n, ctime(&now)); |
print_rtmsg((struct rt_msghdr *)msg, n); |
print_rtmsg(&u.hdr, n); |
} |
} |
} |
} |
|
|
|
|
} m_rtmsg; |
} m_rtmsg; |
|
|
static int |
static int |
rtmsg(int cmd, int flags) |
rtmsg(int cmd, int flags, struct sou *soup) |
{ |
{ |
static int seq; |
static int seq; |
int rlen; |
int rlen; |
Line 1422 rtmsg(int cmd, int flags) |
|
Line 1434 rtmsg(int cmd, int flags) |
|
cmd = RTM_CHANGE; |
cmd = RTM_CHANGE; |
else if (cmd == 'g') { |
else if (cmd == 'g') { |
#ifdef SMALL |
#ifdef SMALL |
return (-1); |
return -1; |
#else /* SMALL */ |
#else /* SMALL */ |
cmd = RTM_GET; |
cmd = RTM_GET; |
if (so_ifp.sa.sa_family == 0) { |
if (soup->so_ifp.sa.sa_family == AF_UNSPEC) { |
so_ifp.sa.sa_family = AF_LINK; |
soup->so_ifp.sa.sa_family = AF_LINK; |
so_ifp.sa.sa_len = sizeof(struct sockaddr_dl); |
soup->so_ifp.sa.sa_len = sizeof(struct sockaddr_dl); |
rtm_addrs |= RTA_IFP; |
rtm_addrs |= RTA_IFP; |
} |
} |
#endif /* SMALL */ |
#endif /* SMALL */ |
Line 1443 rtmsg(int cmd, int flags) |
|
Line 1455 rtmsg(int cmd, int flags) |
|
rtm.rtm_inits = rtm_inits; |
rtm.rtm_inits = rtm_inits; |
|
|
if (rtm_addrs & RTA_NETMASK) |
if (rtm_addrs & RTA_NETMASK) |
mask_addr(); |
mask_addr(soup); |
NEXTADDR(RTA_DST, so_dst); |
NEXTADDR(RTA_DST, soup->so_dst); |
NEXTADDR(RTA_GATEWAY, so_gate); |
NEXTADDR(RTA_GATEWAY, soup->so_gate); |
NEXTADDR(RTA_NETMASK, so_mask); |
NEXTADDR(RTA_NETMASK, soup->so_mask); |
NEXTADDR(RTA_GENMASK, so_genmask); |
NEXTADDR(RTA_GENMASK, soup->so_genmask); |
NEXTADDR(RTA_IFP, so_ifp); |
NEXTADDR(RTA_IFP, soup->so_ifp); |
NEXTADDR(RTA_IFA, so_ifa); |
NEXTADDR(RTA_IFA, soup->so_ifa); |
rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; |
rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; |
if (verbose && ! shortoutput) { |
if (verbose && ! shortoutput) { |
if (rtm_addrs) |
if (rtm_addrs) |
Line 1457 rtmsg(int cmd, int flags) |
|
Line 1469 rtmsg(int cmd, int flags) |
|
print_rtmsg(&rtm, l); |
print_rtmsg(&rtm, l); |
} |
} |
if (debugonly) |
if (debugonly) |
return (0); |
return 0; |
if ((rlen = write(sock, (char *)&m_rtmsg, l)) < 0) { |
if ((rlen = write(sock, (char *)&m_rtmsg, l)) < 0) { |
warnx("writing to routing socket: %s", route_strerror(errno)); |
warnx("writing to routing socket: %s", route_strerror(errno)); |
return (-1); |
return -1; |
} |
} |
if (rlen < l) { |
if (rlen < l) { |
warnx("write to routing socket, got %d for rlen", rlen); |
warnx("write to routing socket, got %d for rlen", rlen); |
Line 1474 rtmsg(int cmd, int flags) |
|
Line 1486 rtmsg(int cmd, int flags) |
|
if (l < 0) |
if (l < 0) |
err(EXIT_FAILURE, "read from routing socket"); |
err(EXIT_FAILURE, "read from routing socket"); |
else |
else |
return print_getmsg(&rtm, l); |
return print_getmsg(&rtm, l, soup); |
} |
} |
#endif /* SMALL */ |
#endif /* SMALL */ |
#undef rtm |
#undef rtm |
return (0); |
return 0; |
} |
} |
|
|
static void |
static void |
mask_addr(void) |
mask_addr(struct sou *soup) |
{ |
{ |
int olen = so_mask.sa.sa_len; |
int olen = soup->so_mask.sa.sa_len; |
char *cp1 = olen + (char *)&so_mask, *cp2; |
char *cp1 = olen + (char *)&soup->so_mask, *cp2; |
|
|
for (so_mask.sa.sa_len = 0; cp1 > (char *)&so_mask; ) |
for (soup->so_mask.sa.sa_len = 0; cp1 > (char *)&soup->so_mask; ) |
if (*--cp1 != 0) { |
if (*--cp1 != 0) { |
so_mask.sa.sa_len = 1 + cp1 - (char *)&so_mask; |
soup->so_mask.sa.sa_len = 1 + cp1 - (char *)&soup->so_mask; |
break; |
break; |
} |
} |
if ((rtm_addrs & RTA_DST) == 0) |
if ((rtm_addrs & RTA_DST) == 0) |
return; |
return; |
switch (so_dst.sa.sa_family) { |
switch (soup->so_dst.sa.sa_family) { |
case AF_INET: |
case AF_INET: |
#ifdef INET6 |
#ifdef INET6 |
case AF_INET6: |
case AF_INET6: |
Line 1506 mask_addr(void) |
|
Line 1518 mask_addr(void) |
|
return; |
return; |
#ifndef SMALL |
#ifndef SMALL |
case AF_ISO: |
case AF_ISO: |
olen = MIN(so_dst.siso.siso_nlen, |
olen = MIN(soup->so_dst.siso.siso_nlen, |
MAX(so_mask.sa.sa_len - 6, 0)); |
MAX(soup->so_mask.sa.sa_len - 6, 0)); |
break; |
break; |
#endif /* SMALL */ |
#endif /* SMALL */ |
} |
} |
cp1 = so_mask.sa.sa_len + 1 + (char *)&so_dst; |
cp1 = soup->so_mask.sa.sa_len + 1 + (char *)&soup->so_dst; |
cp2 = so_dst.sa.sa_len + 1 + (char *)&so_dst; |
cp2 = soup->so_dst.sa.sa_len + 1 + (char *)&soup->so_dst; |
while (cp2 > cp1) |
while (cp2 > cp1) |
*--cp2 = 0; |
*--cp2 = 0; |
cp2 = so_mask.sa.sa_len + 1 + (char *)&so_mask; |
cp2 = soup->so_mask.sa.sa_len + 1 + (char *)&soup->so_mask; |
while (cp1 > so_dst.sa.sa_data) |
while (cp1 > soup->so_dst.sa.sa_data) |
*--cp1 &= *--cp2; |
*--cp1 &= *--cp2; |
#ifndef SMALL |
#ifndef SMALL |
switch (so_dst.sa.sa_family) { |
switch (soup->so_dst.sa.sa_family) { |
case AF_ISO: |
case AF_ISO: |
so_dst.siso.siso_nlen = olen; |
soup->so_dst.siso.siso_nlen = olen; |
break; |
break; |
} |
} |
#endif /* SMALL */ |
#endif /* SMALL */ |
Line 1719 print_rtmsg(struct rt_msghdr *rtm, int m |
|
Line 1731 print_rtmsg(struct rt_msghdr *rtm, int m |
|
|
|
#ifndef SMALL |
#ifndef SMALL |
static int |
static int |
print_getmsg(struct rt_msghdr *rtm, int msglen) |
print_getmsg(struct rt_msghdr *rtm, int msglen, struct sou *soup) |
{ |
{ |
struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL, *ifa = NULL; |
struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL, *ifa = NULL; |
struct sockaddr_dl *ifp = NULL; |
struct sockaddr_dl *ifp = NULL; |
Line 1729 print_getmsg(struct rt_msghdr *rtm, int |
|
Line 1741 print_getmsg(struct rt_msghdr *rtm, int |
|
|
|
if (! shortoutput) |
if (! shortoutput) |
(void)printf(" route to: %s\n", |
(void)printf(" route to: %s\n", |
routename((struct sockaddr *) &so_dst, NULL, RTF_HOST)); |
routename(&soup->so_dst.sa, NULL, RTF_HOST)); |
if (rtm->rtm_version != RTM_VERSION) { |
if (rtm->rtm_version != RTM_VERSION) { |
warnx("routing message version %d not understood", |
warnx("routing message version %d not understood", |
rtm->rtm_version); |
rtm->rtm_version); |
Line 1789 print_getmsg(struct rt_msghdr *rtm, int |
|
Line 1801 print_getmsg(struct rt_msghdr *rtm, int |
|
name = routename(gate, NULL, RTF_HOST); |
name = routename(gate, NULL, RTF_HOST); |
if (shortoutput) { |
if (shortoutput) { |
if (*name == '\0') |
if (*name == '\0') |
return (1); |
return 1; |
(void)printf("%s\n", name); |
(void)printf("%s\n", name); |
} else |
} else |
(void)printf(" gateway: %s\n", name); |
(void)printf(" gateway: %s\n", name); |
Line 1827 print_getmsg(struct rt_msghdr *rtm, int |
|
Line 1839 print_getmsg(struct rt_msghdr *rtm, int |
|
#define RTA_IGN (RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD) |
#define RTA_IGN (RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD) |
|
|
if (shortoutput) |
if (shortoutput) |
return ((rtm->rtm_addrs & RTF_GATEWAY) == 0); |
return (rtm->rtm_addrs & RTF_GATEWAY) == 0; |
else if (verbose) |
else if (verbose) |
pmsg_common(rtm); |
pmsg_common(rtm); |
else if (rtm->rtm_addrs &~ RTA_IGN) { |
else if (rtm->rtm_addrs &~ RTA_IGN) { |
Line 1847 pmsg_common(struct rt_msghdr *rtm) |
|
Line 1859 pmsg_common(struct rt_msghdr *rtm) |
|
bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames); |
bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames); |
(void)printf(" inits: "); |
(void)printf(" inits: "); |
bprintf(stdout, rtm->rtm_inits, metricnames); |
bprintf(stdout, rtm->rtm_inits, metricnames); |
pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs); |
pmsg_addrs((char *)(rtm + 1), rtm->rtm_addrs); |
} |
} |
|
|
static void |
static void |
pmsg_addrs(char *cp, int addrs) |
extract_addrs(const char *cp, int addrs, const struct sockaddr *sa[], int *nmfp) |
{ |
{ |
struct sockaddr *sa[RTAX_MAX]; |
int i, nmf = -1; |
|
|
|
for (i = 0; i < RTAX_MAX; i++) { |
|
if ((1 << i) & addrs) { |
|
sa[i] = (const struct sockaddr *)cp; |
|
if ((i == RTAX_DST || i == RTAX_IFA) && |
|
nmf == -1) |
|
nmf = sa[i]->sa_family; |
|
ADVANCE(cp, sa[i]); |
|
} else |
|
sa[i] = NULL; |
|
} |
|
|
|
if (nmfp != NULL) |
|
*nmfp = nmf; |
|
} |
|
|
|
static void |
|
pmsg_addrs(const char *cp, int addrs) |
|
{ |
|
const struct sockaddr *sa[RTAX_MAX]; |
int i, nmf; |
int i, nmf; |
|
|
if (addrs != 0) { |
if (addrs != 0) { |
(void)printf("\nsockaddrs: "); |
(void)printf("\nsockaddrs: "); |
bprintf(stdout, addrs, addrnames); |
bprintf(stdout, addrs, addrnames); |
(void)putchar('\n'); |
(void)putchar('\n'); |
nmf = -1; |
extract_addrs(cp, addrs, sa, &nmf); |
for (i = 0; i < RTAX_MAX; i++) { |
|
if ((1 << i) & addrs) { |
|
sa[i] = (struct sockaddr *)cp; |
|
if ((i == RTAX_DST || i == RTAX_IFA) && |
|
nmf == -1) |
|
nmf = sa[i]->sa_family; |
|
ADVANCE(cp, sa[i]); |
|
} else |
|
sa[i] = NULL; |
|
} |
|
for (i = 0; i < RTAX_MAX; i++) { |
for (i = 0; i < RTAX_MAX; i++) { |
if (sa[i] != NULL) { |
if (sa[i] == NULL) |
if (i == RTAX_NETMASK && sa[i]->sa_len) |
continue; |
(void)printf(" %s", |
|
netmask_string(sa[i], -1, nmf)); |
if (i == RTAX_NETMASK && sa[i]->sa_len) |
else |
(void)printf(" %s", |
(void)printf(" %s", |
netmask_string(sa[i], -1, nmf)); |
routename(sa[i], NULL, RTF_HOST)); |
else |
} |
(void)printf(" %s", |
|
routename(sa[i], NULL, RTF_HOST)); |
} |
} |
} |
} |
(void)putchar('\n'); |
(void)putchar('\n'); |
Line 1914 bprintf(FILE *fp, int b, const char *f) |
|
Line 1937 bprintf(FILE *fp, int b, const char *f) |
|
} |
} |
|
|
int |
int |
keyword(char *cp) |
keyword(const char *cp) |
{ |
{ |
struct keytab *kt = keywords; |
struct keytab *kt = keywords; |
|
|
Line 1975 sodump(sup su, const char *which) |
|
Line 1998 sodump(sup su, const char *which) |
|
#define DELIM (4*2) |
#define DELIM (4*2) |
|
|
static void |
static void |
sockaddr(char *addr, struct sockaddr *sa) |
sockaddr(const char *addr, struct sockaddr *sa) |
{ |
{ |
char *cp = (char *)sa; |
char *cp = (char *)sa; |
int size = sa->sa_len; |
int size = sa->sa_len; |