| 993 | } |
| 994 | |
| 995 | static void |
| 996 | ifinfo(char *ifname, int argc, char **argv) |
| 997 | { |
| 998 | struct in6_ndireq nd; |
| 999 | int i, sock; |
| 1000 | u_int32_t newflags; |
| 1001 | #ifdef IPV6CTL_USETEMPADDR |
| 1002 | u_int8_t nullbuf[8]; |
| 1003 | #endif |
| 1004 | |
| 1005 | if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { |
| 1006 | err(1, "socket"); |
| 1007 | /* NOTREACHED */ |
| 1008 | } |
| 1009 | bzero(&nd, sizeof(nd)); |
| 1010 | strlcpy(nd.ifname, ifname, sizeof(nd.ifname)); |
| 1011 | if (ioctl(sock, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) { |
| 1012 | err(1, "ioctl(SIOCGIFINFO_IN6)"); |
| 1013 | /* NOTREACHED */ |
| 1014 | } |
| 1015 | #define ND nd.ndi |
| 1016 | newflags = ND.flags; |
| 1017 | for (i = 0; i < argc; i++) { |
| 1018 | int clear = 0; |
| 1019 | char *cp = argv[i]; |
| 1020 | |
| 1021 | if (*cp == '-') { |
| 1022 | clear = 1; |
| 1023 | cp++; |
| 1024 | } |
| 1025 | |
| 1026 | #define SETFLAG(s, f) do { \ |
| 1027 | if (strcmp(cp, (s)) == 0) { \ |
| 1028 | if (clear) \ |
| 1029 | newflags &= ~(f); \ |
| 1030 | else \ |
| 1031 | newflags |= (f); \ |
| 1032 | } \ |
| 1033 | } while (0) |
| 1034 | /* |
| 1035 | * XXX: this macro is not 100% correct, in that it matches "nud" against |
| 1036 | * "nudbogus". But we just let it go since this is minor. |
| 1037 | */ |
| 1038 | #define SETVALUE(f, v) do { \ |
| 1039 | char *valptr; \ |
| 1040 | unsigned long newval; \ |
| 1041 | v = 0; /* unspecified */ \ |
| 1042 | if (strncmp(cp, f, strlen(f)) == 0) { \ |
| 1043 | valptr = strchr(cp, '='); \ |
| 1044 | if (valptr == NULL) \ |
| 1045 | err(1, "syntax error in %s field", (f)); \ |
| 1046 | errno = 0; \ |
| 1047 | newval = strtoul(++valptr, NULL, 0); \ |
| 1048 | if (errno) \ |
| 1049 | err(1, "syntax error in %s's value", (f)); \ |
| 1050 | v = newval; \ |
| 1051 | } \ |
| 1052 | } while (0) |