Changeset View
Changeset View
Standalone View
Standalone View
head/usr.sbin/ndp/ndp.c
Show First 20 Lines • Show All 145 Lines • ▼ Show 20 Lines | |||||
static void harmonize_rtr(void); | static void harmonize_rtr(void); | ||||
#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ | #ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ | ||||
static void getdefif(void); | static void getdefif(void); | ||||
static void setdefif(char *); | static void setdefif(char *); | ||||
#endif | #endif | ||||
static char *sec2str(time_t); | static char *sec2str(time_t); | ||||
static void ts_print(const struct timeval *); | static void ts_print(const struct timeval *); | ||||
static char *rtpref_str[] = { | static const char *rtpref_str[] = { | ||||
"medium", /* 00 */ | "medium", /* 00 */ | ||||
"high", /* 01 */ | "high", /* 01 */ | ||||
"rsv", /* 10 */ | "rsv", /* 10 */ | ||||
"low" /* 11 */ | "low" /* 11 */ | ||||
}; | }; | ||||
int | int | ||||
main(int argc, char **argv) | main(int argc, char **argv) | ||||
▲ Show 20 Lines • Show All 397 Lines • ▼ Show 20 Lines | |||||
dump(struct sockaddr_in6 *addr, int cflag) | dump(struct sockaddr_in6 *addr, int cflag) | ||||
{ | { | ||||
int mib[6]; | int mib[6]; | ||||
size_t needed; | size_t needed; | ||||
char *lim, *buf, *next; | char *lim, *buf, *next; | ||||
struct rt_msghdr *rtm; | struct rt_msghdr *rtm; | ||||
struct sockaddr_in6 *sin; | struct sockaddr_in6 *sin; | ||||
struct sockaddr_dl *sdl; | struct sockaddr_dl *sdl; | ||||
extern int h_errno; | |||||
struct timeval now; | struct timeval now; | ||||
u_long expire; | time_t expire; | ||||
int addrwidth; | int addrwidth; | ||||
int llwidth; | int llwidth; | ||||
int ifwidth; | int ifwidth; | ||||
char flgbuf[8]; | char flgbuf[8]; | ||||
char *ifname; | char *ifname; | ||||
/* Print header */ | /* Print header */ | ||||
if (!tflag && !cflag) | if (!tflag && !cflag) | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | #endif | ||||
addrwidth = strlen(host_buf); | addrwidth = strlen(host_buf); | ||||
if (addrwidth < W_ADDR) | if (addrwidth < W_ADDR) | ||||
addrwidth = W_ADDR; | addrwidth = W_ADDR; | ||||
llwidth = strlen(ether_str(sdl)); | llwidth = strlen(ether_str(sdl)); | ||||
if (W_ADDR + W_LL - addrwidth > llwidth) | if (W_ADDR + W_LL - addrwidth > llwidth) | ||||
llwidth = W_ADDR + W_LL - addrwidth; | llwidth = W_ADDR + W_LL - addrwidth; | ||||
ifname = if_indextoname(sdl->sdl_index, ifix_buf); | ifname = if_indextoname(sdl->sdl_index, ifix_buf); | ||||
if (!ifname) | if (ifname == NULL) { | ||||
ifname = "?"; | strlcpy(ifix_buf, "?", sizeof(ifix_buf)); | ||||
ifname = ifix_buf; | |||||
} | |||||
ifwidth = strlen(ifname); | ifwidth = strlen(ifname); | ||||
if (W_ADDR + W_LL + W_IF - addrwidth - llwidth > ifwidth) | if (W_ADDR + W_LL + W_IF - addrwidth - llwidth > ifwidth) | ||||
ifwidth = W_ADDR + W_LL + W_IF - addrwidth - llwidth; | ifwidth = W_ADDR + W_LL + W_IF - addrwidth - llwidth; | ||||
printf("%-*.*s %-*.*s %*.*s", addrwidth, addrwidth, host_buf, | printf("%-*.*s %-*.*s %*.*s", addrwidth, addrwidth, host_buf, | ||||
llwidth, llwidth, ether_str(sdl), ifwidth, ifwidth, ifname); | llwidth, llwidth, ether_str(sdl), ifwidth, ifwidth, ifname); | ||||
/* Print neighbor discovery specific information */ | /* Print neighbor discovery specific information */ | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | if (repeat) { | ||||
goto again; | goto again; | ||||
} | } | ||||
} | } | ||||
static struct in6_nbrinfo * | static struct in6_nbrinfo * | ||||
getnbrinfo(struct in6_addr *addr, int ifindex, int warning) | getnbrinfo(struct in6_addr *addr, int ifindex, int warning) | ||||
{ | { | ||||
static struct in6_nbrinfo nbi; | static struct in6_nbrinfo nbi; | ||||
int s; | int sock; | ||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | ||||
err(1, "socket"); | err(1, "socket"); | ||||
bzero(&nbi, sizeof(nbi)); | bzero(&nbi, sizeof(nbi)); | ||||
if_indextoname(ifindex, nbi.ifname); | if_indextoname(ifindex, nbi.ifname); | ||||
nbi.addr = *addr; | nbi.addr = *addr; | ||||
if (ioctl(s, SIOCGNBRINFO_IN6, (caddr_t)&nbi) < 0) { | if (ioctl(sock, SIOCGNBRINFO_IN6, (caddr_t)&nbi) < 0) { | ||||
if (warning) | if (warning) | ||||
warn("ioctl(SIOCGNBRINFO_IN6)"); | warn("ioctl(SIOCGNBRINFO_IN6)"); | ||||
close(s); | close(sock); | ||||
return(NULL); | return(NULL); | ||||
} | } | ||||
close(s); | close(sock); | ||||
return(&nbi); | return(&nbi); | ||||
} | } | ||||
static char * | static char * | ||||
ether_str(struct sockaddr_dl *sdl) | ether_str(struct sockaddr_dl *sdl) | ||||
{ | { | ||||
static char hbuf[NI_MAXHOST]; | static char hbuf[NI_MAXHOST]; | ||||
▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | (void) fprintf(stderr, "ndp: read from routing socket: %s\n", | ||||
strerror(errno)); | strerror(errno)); | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
ifinfo(char *ifname, int argc, char **argv) | ifinfo(char *ifname, int argc, char **argv) | ||||
{ | { | ||||
struct in6_ndireq nd; | struct in6_ndireq nd; | ||||
int i, s; | int i, sock; | ||||
u_int32_t newflags; | u_int32_t newflags; | ||||
#ifdef IPV6CTL_USETEMPADDR | #ifdef IPV6CTL_USETEMPADDR | ||||
u_int8_t nullbuf[8]; | u_int8_t nullbuf[8]; | ||||
#endif | #endif | ||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { | if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { | ||||
err(1, "socket"); | err(1, "socket"); | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
} | } | ||||
bzero(&nd, sizeof(nd)); | bzero(&nd, sizeof(nd)); | ||||
strlcpy(nd.ifname, ifname, sizeof(nd.ifname)); | strlcpy(nd.ifname, ifname, sizeof(nd.ifname)); | ||||
if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) { | if (ioctl(sock, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) { | ||||
err(1, "ioctl(SIOCGIFINFO_IN6)"); | err(1, "ioctl(SIOCGIFINFO_IN6)"); | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
} | } | ||||
#define ND nd.ndi | #define ND nd.ndi | ||||
newflags = ND.flags; | newflags = ND.flags; | ||||
for (i = 0; i < argc; i++) { | for (i = 0; i < argc; i++) { | ||||
int clear = 0; | int clear = 0; | ||||
char *cp = argv[i]; | char *cp = argv[i]; | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
#ifdef ND6_IFF_NO_PREFER_IFACE | #ifdef ND6_IFF_NO_PREFER_IFACE | ||||
SETFLAG("no_prefer_iface", ND6_IFF_NO_PREFER_IFACE); | SETFLAG("no_prefer_iface", ND6_IFF_NO_PREFER_IFACE); | ||||
#endif | #endif | ||||
SETVALUE("basereachable", ND.basereachable); | SETVALUE("basereachable", ND.basereachable); | ||||
SETVALUE("retrans", ND.retrans); | SETVALUE("retrans", ND.retrans); | ||||
SETVALUE("curhlim", ND.chlim); | SETVALUE("curhlim", ND.chlim); | ||||
ND.flags = newflags; | ND.flags = newflags; | ||||
if (ioctl(s, SIOCSIFINFO_IN6, (caddr_t)&nd) < 0) { | if (ioctl(sock, SIOCSIFINFO_IN6, (caddr_t)&nd) < 0) { | ||||
err(1, "ioctl(SIOCSIFINFO_IN6)"); | err(1, "ioctl(SIOCSIFINFO_IN6)"); | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
} | } | ||||
#undef SETFLAG | #undef SETFLAG | ||||
#undef SETVALUE | #undef SETVALUE | ||||
} | } | ||||
if (!ND.initialized) { | if (!ND.initialized) { | ||||
errx(1, "%s: not initialized yet", ifname); | errx(1, "%s: not initialized yet", ifname); | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
} | } | ||||
if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) { | if (ioctl(sock, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) { | ||||
err(1, "ioctl(SIOCGIFINFO_IN6)"); | err(1, "ioctl(SIOCGIFINFO_IN6)"); | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
} | } | ||||
printf("linkmtu=%d", ND.linkmtu); | printf("linkmtu=%d", ND.linkmtu); | ||||
printf(", maxmtu=%d", ND.maxmtu); | printf(", maxmtu=%d", ND.maxmtu); | ||||
printf(", curhlim=%d", ND.chlim); | printf(", curhlim=%d", ND.chlim); | ||||
printf(", basereachable=%ds%dms", | printf(", basereachable=%ds%dms", | ||||
ND.basereachable / 1000, ND.basereachable % 1000); | ND.basereachable / 1000, ND.basereachable % 1000); | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
#ifdef ND6_IFF_NO_PREFER_IFACE | #ifdef ND6_IFF_NO_PREFER_IFACE | ||||
if ((ND.flags & ND6_IFF_NO_PREFER_IFACE)) | if ((ND.flags & ND6_IFF_NO_PREFER_IFACE)) | ||||
printf("no_prefer_iface "); | printf("no_prefer_iface "); | ||||
#endif | #endif | ||||
} | } | ||||
putc('\n', stdout); | putc('\n', stdout); | ||||
#undef ND | #undef ND | ||||
close(s); | close(sock); | ||||
} | } | ||||
#ifndef ND_RA_FLAG_RTPREF_MASK /* XXX: just for compilation on *BSD release */ | #ifndef ND_RA_FLAG_RTPREF_MASK /* XXX: just for compilation on *BSD release */ | ||||
#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */ | #define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */ | ||||
#endif | #endif | ||||
static void | static void | ||||
rtrlist() | rtrlist() | ||||
▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
free(buf); | free(buf); | ||||
} | } | ||||
static void | static void | ||||
pfx_flush() | pfx_flush() | ||||
{ | { | ||||
char dummyif[IFNAMSIZ+8]; | char dummyif[IFNAMSIZ+8]; | ||||
int s; | int sock; | ||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | ||||
err(1, "socket"); | err(1, "socket"); | ||||
strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ | strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ | ||||
if (ioctl(s, SIOCSPFXFLUSH_IN6, (caddr_t)&dummyif) < 0) | if (ioctl(sock, SIOCSPFXFLUSH_IN6, (caddr_t)&dummyif) < 0) | ||||
err(1, "ioctl(SIOCSPFXFLUSH_IN6)"); | err(1, "ioctl(SIOCSPFXFLUSH_IN6)"); | ||||
close(sock); | |||||
} | } | ||||
static void | static void | ||||
rtr_flush() | rtr_flush() | ||||
{ | { | ||||
char dummyif[IFNAMSIZ+8]; | char dummyif[IFNAMSIZ+8]; | ||||
int s; | int sock; | ||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | ||||
err(1, "socket"); | err(1, "socket"); | ||||
strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ | strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ | ||||
if (ioctl(s, SIOCSRTRFLUSH_IN6, (caddr_t)&dummyif) < 0) | if (ioctl(sock, SIOCSRTRFLUSH_IN6, (caddr_t)&dummyif) < 0) | ||||
err(1, "ioctl(SIOCSRTRFLUSH_IN6)"); | err(1, "ioctl(SIOCSRTRFLUSH_IN6)"); | ||||
close(s); | close(sock); | ||||
} | } | ||||
static void | static void | ||||
harmonize_rtr() | harmonize_rtr() | ||||
{ | { | ||||
char dummyif[IFNAMSIZ+8]; | char dummyif[IFNAMSIZ+8]; | ||||
int s; | int sock; | ||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | ||||
err(1, "socket"); | err(1, "socket"); | ||||
strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ | strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ | ||||
if (ioctl(s, SIOCSNDFLUSH_IN6, (caddr_t)&dummyif) < 0) | if (ioctl(sock, SIOCSNDFLUSH_IN6, (caddr_t)&dummyif) < 0) | ||||
err(1, "ioctl(SIOCSNDFLUSH_IN6)"); | err(1, "ioctl(SIOCSNDFLUSH_IN6)"); | ||||
close(s); | close(sock); | ||||
} | } | ||||
#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ | #ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ | ||||
static void | static void | ||||
setdefif(char *ifname) | setdefif(char *ifname) | ||||
{ | { | ||||
struct in6_ndifreq ndifreq; | struct in6_ndifreq ndifreq; | ||||
unsigned int ifindex; | unsigned int ifindex; | ||||
int sock; | |||||
if (strcasecmp(ifname, "delete") == 0) | if (strcasecmp(ifname, "delete") == 0) | ||||
ifindex = 0; | ifindex = 0; | ||||
else { | else { | ||||
if ((ifindex = if_nametoindex(ifname)) == 0) | if ((ifindex = if_nametoindex(ifname)) == 0) | ||||
err(1, "failed to resolve i/f index for %s", ifname); | err(1, "failed to resolve i/f index for %s", ifname); | ||||
} | } | ||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | ||||
err(1, "socket"); | err(1, "socket"); | ||||
strlcpy(ndifreq.ifname, "lo0", sizeof(ndifreq.ifname)); /* dummy */ | strlcpy(ndifreq.ifname, "lo0", sizeof(ndifreq.ifname)); /* dummy */ | ||||
ndifreq.ifindex = ifindex; | ndifreq.ifindex = ifindex; | ||||
if (ioctl(s, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq) < 0) | if (ioctl(sock, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq) < 0) | ||||
err(1, "ioctl(SIOCSDEFIFACE_IN6)"); | err(1, "ioctl(SIOCSDEFIFACE_IN6)"); | ||||
close(s); | close(sock); | ||||
} | } | ||||
static void | static void | ||||
getdefif() | getdefif() | ||||
{ | { | ||||
struct in6_ndifreq ndifreq; | struct in6_ndifreq ndifreq; | ||||
char ifname[IFNAMSIZ+8]; | char ifname[IFNAMSIZ+8]; | ||||
int sock; | |||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | ||||
err(1, "socket"); | err(1, "socket"); | ||||
memset(&ndifreq, 0, sizeof(ndifreq)); | memset(&ndifreq, 0, sizeof(ndifreq)); | ||||
strlcpy(ndifreq.ifname, "lo0", sizeof(ndifreq.ifname)); /* dummy */ | strlcpy(ndifreq.ifname, "lo0", sizeof(ndifreq.ifname)); /* dummy */ | ||||
if (ioctl(s, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq) < 0) | if (ioctl(sock, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq) < 0) | ||||
err(1, "ioctl(SIOCGDEFIFACE_IN6)"); | err(1, "ioctl(SIOCGDEFIFACE_IN6)"); | ||||
if (ndifreq.ifindex == 0) | if (ndifreq.ifindex == 0) | ||||
printf("No default interface.\n"); | printf("No default interface.\n"); | ||||
else { | else { | ||||
if ((if_indextoname(ndifreq.ifindex, ifname)) == NULL) | if ((if_indextoname(ndifreq.ifindex, ifname)) == NULL) | ||||
err(1, "failed to resolve ifname for index %lu", | err(1, "failed to resolve ifname for index %lu", | ||||
ndifreq.ifindex); | ndifreq.ifindex); | ||||
printf("ND default interface = %s\n", ifname); | printf("ND default interface = %s\n", ifname); | ||||
} | } | ||||
close(s); | close(sock); | ||||
} | } | ||||
#endif /* SIOCSDEFIFACE_IN6 */ | #endif /* SIOCSDEFIFACE_IN6 */ | ||||
static char * | static char * | ||||
sec2str(time_t total) | sec2str(time_t total) | ||||
{ | { | ||||
static char result[256]; | static char result[256]; | ||||
int days, hours, mins, secs; | int days, hours, mins, secs; | ||||
Show All 35 Lines | |||||
/* | /* | ||||
* Print the timestamp | * Print the timestamp | ||||
* from tcpdump/util.c | * from tcpdump/util.c | ||||
*/ | */ | ||||
static void | static void | ||||
ts_print(const struct timeval *tvp) | ts_print(const struct timeval *tvp) | ||||
{ | { | ||||
int s; | int sec; | ||||
/* Default */ | /* Default */ | ||||
s = (tvp->tv_sec + thiszone) % 86400; | sec = (tvp->tv_sec + thiszone) % 86400; | ||||
(void)printf("%02d:%02d:%02d.%06u ", | (void)printf("%02d:%02d:%02d.%06u ", | ||||
s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec); | sec / 3600, (sec % 3600) / 60, sec % 60, (u_int32_t)tvp->tv_usec); | ||||
} | } | ||||
#undef NEXTADDR | #undef NEXTADDR |