ndp.c (287095) | ndp.c (287097) |
---|---|
1/* $FreeBSD: head/usr.sbin/ndp/ndp.c 287095 2015-08-24 05:28:23Z hrs $ */ | 1/* $FreeBSD: head/usr.sbin/ndp/ndp.c 287097 2015-08-24 05:38:05Z hrs $ */ |
2/* $KAME: ndp.c,v 1.104 2003/06/27 07:48:39 itojun Exp $ */ 3 4/* 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 106 unchanged lines hidden (view full) --- 116 117static pid_t pid; 118static int nflag; 119static int tflag; 120static int32_t thiszone; /* time difference with gmt */ 121static int s = -1; 122static int repeat = 0; 123 | 2/* $KAME: ndp.c,v 1.104 2003/06/27 07:48:39 itojun Exp $ */ 3 4/* 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 106 unchanged lines hidden (view full) --- 116 117static pid_t pid; 118static int nflag; 119static int tflag; 120static int32_t thiszone; /* time difference with gmt */ 121static int s = -1; 122static int repeat = 0; 123 |
124char ntop_buf[INET6_ADDRSTRLEN]; /* inet_ntop() */ 125char host_buf[NI_MAXHOST]; /* getnameinfo() */ 126char ifix_buf[IFNAMSIZ]; /* if_indextoname() */ | 124static char host_buf[NI_MAXHOST]; /* getnameinfo() */ 125static char ifix_buf[IFNAMSIZ]; /* if_indextoname() */ |
127 | 126 |
128int main(int, char **); | |
129static int file(char *); | 127static int file(char *); |
130void getsocket(void); 131int set(int, char **); 132void get(char *); 133int delete(char *); 134void dump(struct sockaddr_in6 *, int); | 128static void getsocket(void); 129static int set(int, char **); 130static void get(char *); 131static int delete(char *); 132static void dump(struct sockaddr_in6 *, int); |
135static struct in6_nbrinfo *getnbrinfo(struct in6_addr *, int, int); 136static char *ether_str(struct sockaddr_dl *); | 133static struct in6_nbrinfo *getnbrinfo(struct in6_addr *, int, int); 134static char *ether_str(struct sockaddr_dl *); |
137int ndp_ether_aton(char *, u_char *); 138void usage(void); 139int rtmsg(int); 140void ifinfo(char *, int, char **); 141void rtrlist(void); 142void plist(void); 143void pfx_flush(void); 144void rtr_flush(void); 145void harmonize_rtr(void); | 135static int ndp_ether_aton(char *, u_char *); 136static void usage(void); 137static int rtmsg(int); 138static void ifinfo(char *, int, char **); 139static void rtrlist(void); 140static void plist(void); 141static void pfx_flush(void); 142static void rtr_flush(void); 143static void harmonize_rtr(void); |
146#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ 147static void getdefif(void); 148static void setdefif(char *); 149#endif 150static char *sec2str(time_t); 151static void ts_print(const struct timeval *); 152 153static char *rtpref_str[] = { 154 "medium", /* 00 */ 155 "high", /* 01 */ 156 "rsv", /* 10 */ 157 "low" /* 11 */ 158}; 159 | 144#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ 145static void getdefif(void); 146static void setdefif(char *); 147#endif 148static char *sec2str(time_t); 149static void ts_print(const struct timeval *); 150 151static char *rtpref_str[] = { 152 "medium", /* 00 */ 153 "high", /* 01 */ 154 "rsv", /* 10 */ 155 "low" /* 11 */ 156}; 157 |
160int mode = 0; 161char *arg = NULL; 162 | |
163int 164main(int argc, char **argv) 165{ | 158int 159main(int argc, char **argv) 160{ |
166 int ch; | 161 int ch, mode = 0; 162 char *arg = NULL; |
167 168 pid = getpid(); 169 thiszone = gmt2local(0); 170 while ((ch = getopt(argc, argv, "acd:f:Ii:nprstA:HPR")) != -1) 171 switch (ch) { 172 case 'a': 173 case 'c': 174 case 'p': --- 166 unchanged lines hidden (view full) --- 341 } 342 if (set(i, args)) 343 retval = 1; 344 } 345 fclose(fp); 346 return (retval); 347} 348 | 163 164 pid = getpid(); 165 thiszone = gmt2local(0); 166 while ((ch = getopt(argc, argv, "acd:f:Ii:nprstA:HPR")) != -1) 167 switch (ch) { 168 case 'a': 169 case 'c': 170 case 'p': --- 166 unchanged lines hidden (view full) --- 337 } 338 if (set(i, args)) 339 retval = 1; 340 } 341 fclose(fp); 342 return (retval); 343} 344 |
349void | 345static void |
350getsocket() 351{ 352 if (s < 0) { 353 s = socket(PF_ROUTE, SOCK_RAW, 0); 354 if (s < 0) { 355 err(1, "socket"); 356 /* NOTREACHED */ 357 } 358 } 359} 360 | 346getsocket() 347{ 348 if (s < 0) { 349 s = socket(PF_ROUTE, SOCK_RAW, 0); 350 if (s < 0) { 351 err(1, "socket"); 352 /* NOTREACHED */ 353 } 354 } 355} 356 |
361struct sockaddr_in6 so_mask = {sizeof(so_mask), AF_INET6 }; 362struct sockaddr_in6 blank_sin = {sizeof(blank_sin), AF_INET6 }, sin_m; 363struct sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m; 364time_t expire_time; 365int flags, found_entry; 366struct { | 357static struct sockaddr_in6 so_mask = { 358 .sin6_len = sizeof(so_mask), 359 .sin6_family = AF_INET6 360}; 361static struct sockaddr_in6 blank_sin = { 362 .sin6_len = sizeof(blank_sin), 363 .sin6_family = AF_INET6 364}; 365static struct sockaddr_in6 sin_m; 366static struct sockaddr_dl blank_sdl = { 367 .sdl_len = sizeof(blank_sdl), 368 .sdl_family = AF_LINK 369}; 370static struct sockaddr_dl sdl_m; 371static time_t expire_time; 372static int flags, found_entry; 373static struct { |
367 struct rt_msghdr m_rtm; 368 char m_space[512]; | 374 struct rt_msghdr m_rtm; 375 char m_space[512]; |
369} m_rtmsg; | 376} m_rtmsg; |
370 371/* 372 * Set an individual neighbor cache entry 373 */ | 377 378/* 379 * Set an individual neighbor cache entry 380 */ |
374int | 381static int |
375set(int argc, char **argv) 376{ 377 register struct sockaddr_in6 *sin = &sin_m; 378 register struct sockaddr_dl *sdl; 379 register struct rt_msghdr *rtm = &(m_rtmsg.m_rtm); 380 struct addrinfo hints, *res; 381 int gai_error; 382 u_char *ea; --- 58 unchanged lines hidden (view full) --- 441 sdl_m.sdl_type = sdl->sdl_type; 442 sdl_m.sdl_index = sdl->sdl_index; 443 return (rtmsg(RTM_ADD)); 444} 445 446/* 447 * Display an individual neighbor cache entry 448 */ | 382set(int argc, char **argv) 383{ 384 register struct sockaddr_in6 *sin = &sin_m; 385 register struct sockaddr_dl *sdl; 386 register struct rt_msghdr *rtm = &(m_rtmsg.m_rtm); 387 struct addrinfo hints, *res; 388 int gai_error; 389 u_char *ea; --- 58 unchanged lines hidden (view full) --- 448 sdl_m.sdl_type = sdl->sdl_type; 449 sdl_m.sdl_index = sdl->sdl_index; 450 return (rtmsg(RTM_ADD)); 451} 452 453/* 454 * Display an individual neighbor cache entry 455 */ |
449void | 456static void |
450get(char *host) 451{ 452 struct sockaddr_in6 *sin = &sin_m; 453 struct addrinfo hints, *res; 454 int gai_error; 455 456 sin_m = blank_sin; 457 bzero(&hints, sizeof(hints)); --- 15 unchanged lines hidden (view full) --- 473 printf("%s (%s) -- no entry\n", host, host_buf); 474 exit(1); 475 } 476} 477 478/* 479 * Delete a neighbor cache entry 480 */ | 457get(char *host) 458{ 459 struct sockaddr_in6 *sin = &sin_m; 460 struct addrinfo hints, *res; 461 int gai_error; 462 463 sin_m = blank_sin; 464 bzero(&hints, sizeof(hints)); --- 15 unchanged lines hidden (view full) --- 480 printf("%s (%s) -- no entry\n", host, host_buf); 481 exit(1); 482 } 483} 484 485/* 486 * Delete a neighbor cache entry 487 */ |
481int | 488static int |
482delete(char *host) 483{ 484 struct sockaddr_in6 *sin = &sin_m; 485 register struct rt_msghdr *rtm = &m_rtmsg.m_rtm; 486 register char *cp = m_rtmsg.m_space; 487 struct sockaddr_dl *sdl; 488 struct addrinfo hints, *res; 489 int gai_error; --- 51 unchanged lines hidden (view full) --- 541 542#define W_ADDR 36 543#define W_LL 17 544#define W_IF 6 545 546/* 547 * Dump the entire neighbor cache 548 */ | 489delete(char *host) 490{ 491 struct sockaddr_in6 *sin = &sin_m; 492 register struct rt_msghdr *rtm = &m_rtmsg.m_rtm; 493 register char *cp = m_rtmsg.m_space; 494 struct sockaddr_dl *sdl; 495 struct addrinfo hints, *res; 496 int gai_error; --- 51 unchanged lines hidden (view full) --- 548 549#define W_ADDR 36 550#define W_LL 17 551#define W_IF 6 552 553/* 554 * Dump the entire neighbor cache 555 */ |
549void | 556static void |
550dump(struct sockaddr_in6 *addr, int cflag) 551{ 552 int mib[6]; 553 size_t needed; 554 char *lim, *buf, *next; 555 struct rt_msghdr *rtm; 556 struct sockaddr_in6 *sin; 557 struct sockaddr_dl *sdl; --- 217 unchanged lines hidden (view full) --- 775 close(s); 776 return(&nbi); 777} 778 779static char * 780ether_str(struct sockaddr_dl *sdl) 781{ 782 static char hbuf[NI_MAXHOST]; | 557dump(struct sockaddr_in6 *addr, int cflag) 558{ 559 int mib[6]; 560 size_t needed; 561 char *lim, *buf, *next; 562 struct rt_msghdr *rtm; 563 struct sockaddr_in6 *sin; 564 struct sockaddr_dl *sdl; --- 217 unchanged lines hidden (view full) --- 782 close(s); 783 return(&nbi); 784} 785 786static char * 787ether_str(struct sockaddr_dl *sdl) 788{ 789 static char hbuf[NI_MAXHOST]; |
783 char *cp; | |
784 785 if (sdl->sdl_alen == ETHER_ADDR_LEN) { 786 strlcpy(hbuf, ether_ntoa((struct ether_addr *)LLADDR(sdl)), 787 sizeof(hbuf)); 788 } else if (sdl->sdl_alen) { 789 int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; 790 snprintf(hbuf, sizeof(hbuf), "%s", link_ntoa(sdl) + n); 791 } else 792 snprintf(hbuf, sizeof(hbuf), "(incomplete)"); 793 794 return(hbuf); 795} 796 | 790 791 if (sdl->sdl_alen == ETHER_ADDR_LEN) { 792 strlcpy(hbuf, ether_ntoa((struct ether_addr *)LLADDR(sdl)), 793 sizeof(hbuf)); 794 } else if (sdl->sdl_alen) { 795 int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; 796 snprintf(hbuf, sizeof(hbuf), "%s", link_ntoa(sdl) + n); 797 } else 798 snprintf(hbuf, sizeof(hbuf), "(incomplete)"); 799 800 return(hbuf); 801} 802 |
797int | 803static int |
798ndp_ether_aton(char *a, u_char *n) 799{ 800 int i, o[6]; 801 802 i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o[0], &o[1], &o[2], 803 &o[3], &o[4], &o[5]); 804 if (i != 6) { 805 fprintf(stderr, "ndp: invalid Ethernet address '%s'\n", a); 806 return (1); 807 } 808 for (i = 0; i < 6; i++) 809 n[i] = o[i]; 810 return (0); 811} 812 | 804ndp_ether_aton(char *a, u_char *n) 805{ 806 int i, o[6]; 807 808 i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o[0], &o[1], &o[2], 809 &o[3], &o[4], &o[5]); 810 if (i != 6) { 811 fprintf(stderr, "ndp: invalid Ethernet address '%s'\n", a); 812 return (1); 813 } 814 for (i = 0; i < 6; i++) 815 n[i] = o[i]; 816 return (0); 817} 818 |
813void | 819static void |
814usage() 815{ 816 printf("usage: ndp [-nt] hostname\n"); 817 printf(" ndp [-nt] -a | -c | -p | -r | -H | -P | -R\n"); 818 printf(" ndp [-nt] -A wait\n"); 819 printf(" ndp [-nt] -d hostname\n"); 820 printf(" ndp [-nt] -f filename\n"); 821 printf(" ndp [-nt] -i interface [flags...]\n"); 822#ifdef SIOCSDEFIFACE_IN6 823 printf(" ndp [-nt] -I [interface|delete]\n"); 824#endif 825 printf(" ndp [-nt] -s nodename etheraddr [temp] [proxy]\n"); 826 exit(1); 827} 828 | 820usage() 821{ 822 printf("usage: ndp [-nt] hostname\n"); 823 printf(" ndp [-nt] -a | -c | -p | -r | -H | -P | -R\n"); 824 printf(" ndp [-nt] -A wait\n"); 825 printf(" ndp [-nt] -d hostname\n"); 826 printf(" ndp [-nt] -f filename\n"); 827 printf(" ndp [-nt] -i interface [flags...]\n"); 828#ifdef SIOCSDEFIFACE_IN6 829 printf(" ndp [-nt] -I [interface|delete]\n"); 830#endif 831 printf(" ndp [-nt] -s nodename etheraddr [temp] [proxy]\n"); 832 exit(1); 833} 834 |
829int | 835static int |
830rtmsg(int cmd) 831{ 832 static int seq; 833 int rlen; 834 register struct rt_msghdr *rtm = &m_rtmsg.m_rtm; 835 register char *cp = m_rtmsg.m_space; 836 register int l; 837 --- 48 unchanged lines hidden (view full) --- 886 l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); 887 } while (l > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid)); 888 if (l < 0) 889 (void) fprintf(stderr, "ndp: read from routing socket: %s\n", 890 strerror(errno)); 891 return (0); 892} 893 | 836rtmsg(int cmd) 837{ 838 static int seq; 839 int rlen; 840 register struct rt_msghdr *rtm = &m_rtmsg.m_rtm; 841 register char *cp = m_rtmsg.m_space; 842 register int l; 843 --- 48 unchanged lines hidden (view full) --- 892 l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); 893 } while (l > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid)); 894 if (l < 0) 895 (void) fprintf(stderr, "ndp: read from routing socket: %s\n", 896 strerror(errno)); 897 return (0); 898} 899 |
894void | 900static void |
895ifinfo(char *ifname, int argc, char **argv) 896{ 897 struct in6_ndireq nd; 898 int i, s; 899 u_int32_t newflags; 900#ifdef IPV6CTL_USETEMPADDR 901 u_int8_t nullbuf[8]; 902#endif --- 143 unchanged lines hidden (view full) --- 1046 1047 close(s); 1048} 1049 1050#ifndef ND_RA_FLAG_RTPREF_MASK /* XXX: just for compilation on *BSD release */ 1051#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */ 1052#endif 1053 | 901ifinfo(char *ifname, int argc, char **argv) 902{ 903 struct in6_ndireq nd; 904 int i, s; 905 u_int32_t newflags; 906#ifdef IPV6CTL_USETEMPADDR 907 u_int8_t nullbuf[8]; 908#endif --- 143 unchanged lines hidden (view full) --- 1052 1053 close(s); 1054} 1055 1056#ifndef ND_RA_FLAG_RTPREF_MASK /* XXX: just for compilation on *BSD release */ 1057#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */ 1058#endif 1059 |
1054void | 1060static void |
1055rtrlist() 1056{ 1057 int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_ND6_DRLIST }; 1058 char *buf; 1059 struct in6_defrouter *p, *ep; 1060 size_t l; 1061 struct timeval now; 1062 --- 35 unchanged lines hidden (view full) --- 1098 printf(", expire=Never\n"); 1099 else 1100 printf(", expire=%s\n", 1101 sec2str(p->expire - now.tv_sec)); 1102 } 1103 free(buf); 1104} 1105 | 1061rtrlist() 1062{ 1063 int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_ND6_DRLIST }; 1064 char *buf; 1065 struct in6_defrouter *p, *ep; 1066 size_t l; 1067 struct timeval now; 1068 --- 35 unchanged lines hidden (view full) --- 1104 printf(", expire=Never\n"); 1105 else 1106 printf(", expire=%s\n", 1107 sec2str(p->expire - now.tv_sec)); 1108 } 1109 free(buf); 1110} 1111 |
1106void | 1112static void |
1107plist() 1108{ 1109 int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_ND6_PRLIST }; 1110 char *buf; 1111 struct in6_prefix *p, *ep, *n; 1112 struct sockaddr_in6 *advrtr; 1113 size_t l; 1114 struct timeval now; --- 97 unchanged lines hidden (view full) --- 1212 sin6++; 1213 } 1214 } else 1215 printf(" No advertising router\n"); 1216 } 1217 free(buf); 1218} 1219 | 1113plist() 1114{ 1115 int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_ND6_PRLIST }; 1116 char *buf; 1117 struct in6_prefix *p, *ep, *n; 1118 struct sockaddr_in6 *advrtr; 1119 size_t l; 1120 struct timeval now; --- 97 unchanged lines hidden (view full) --- 1218 sin6++; 1219 } 1220 } else 1221 printf(" No advertising router\n"); 1222 } 1223 free(buf); 1224} 1225 |
1220void | 1226static void |
1221pfx_flush() 1222{ 1223 char dummyif[IFNAMSIZ+8]; 1224 int s; 1225 1226 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 1227 err(1, "socket"); 1228 strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ 1229 if (ioctl(s, SIOCSPFXFLUSH_IN6, (caddr_t)&dummyif) < 0) 1230 err(1, "ioctl(SIOCSPFXFLUSH_IN6)"); 1231} 1232 | 1227pfx_flush() 1228{ 1229 char dummyif[IFNAMSIZ+8]; 1230 int s; 1231 1232 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 1233 err(1, "socket"); 1234 strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ 1235 if (ioctl(s, SIOCSPFXFLUSH_IN6, (caddr_t)&dummyif) < 0) 1236 err(1, "ioctl(SIOCSPFXFLUSH_IN6)"); 1237} 1238 |
1233void | 1239static void |
1234rtr_flush() 1235{ 1236 char dummyif[IFNAMSIZ+8]; 1237 int s; 1238 1239 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 1240 err(1, "socket"); 1241 strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ 1242 if (ioctl(s, SIOCSRTRFLUSH_IN6, (caddr_t)&dummyif) < 0) 1243 err(1, "ioctl(SIOCSRTRFLUSH_IN6)"); 1244 1245 close(s); 1246} 1247 | 1240rtr_flush() 1241{ 1242 char dummyif[IFNAMSIZ+8]; 1243 int s; 1244 1245 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 1246 err(1, "socket"); 1247 strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ 1248 if (ioctl(s, SIOCSRTRFLUSH_IN6, (caddr_t)&dummyif) < 0) 1249 err(1, "ioctl(SIOCSRTRFLUSH_IN6)"); 1250 1251 close(s); 1252} 1253 |
1248void | 1254static void |
1249harmonize_rtr() 1250{ 1251 char dummyif[IFNAMSIZ+8]; 1252 int s; 1253 1254 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 1255 err(1, "socket"); 1256 strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ --- 117 unchanged lines hidden --- | 1255harmonize_rtr() 1256{ 1257 char dummyif[IFNAMSIZ+8]; 1258 int s; 1259 1260 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 1261 err(1, "socket"); 1262 strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ --- 117 unchanged lines hidden --- |