On Sun, Dec 23, 2018 at 10:05:01AM +0000, Jason McIntyre wrote: > unless you're trying somehow to emphasise that both types of address are > supported, you could simplify the text to just: > > The > .Ar dest-address > is used to find ... >
Thank you for your input. Index: ifconfig.8 =================================================================== RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v retrieving revision 1.324 diff -u -p -r1.324 ifconfig.8 --- ifconfig.8 16 Nov 2018 12:25:29 -0000 1.324 +++ ifconfig.8 23 Dec 2018 10:22:56 -0000 @@ -1344,8 +1344,7 @@ is another 20-bit number which will be u Sets the destination address where this mpw should output. The .Ar dest-address -is an IPv4 address that will be used to find the nexthop in the MPLS -network. +is used to find the nexthop in the MPLS network. .El .Sh PAIR .nr nS 1 Index: ifconfig.c =================================================================== RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v retrieving revision 1.387 diff -u -p -r1.387 ifconfig.c --- ifconfig.c 29 Nov 2018 00:12:34 -0000 1.387 +++ ifconfig.c 23 Dec 2018 10:22:57 -0000 @@ -3802,8 +3802,9 @@ mpe_status(void) void mpw_status(void) { - struct sockaddr_in *sin; - struct ifmpwreq imr; + struct sockaddr_storage *ss; + struct ifmpwreq imr; + char hbuf[NI_MAXHOST]; bzero(&imr, sizeof(imr)); ifr.ifr_data = (caddr_t) &imr; @@ -3842,11 +3843,19 @@ mpw_status(void) else printf("remote %u\n", imr.imr_rshim.shim_label); - sin = (struct sockaddr_in *) &imr.imr_nexthop; - if (sin->sin_addr.s_addr == 0) - printf("\tneighbor: none\n"); - else - printf("\tneighbor: %s\n", inet_ntoa(sin->sin_addr)); + printf("\tneighbor: "); + switch (imr.imr_nexthop.ss_family) { + case AF_INET6: + case AF_INET: + ss = (struct sockaddr_storage *) &imr.imr_nexthop; + if (getnameinfo((struct sockaddr *)ss, ss->ss_len, hbuf, + sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) + strlcpy(hbuf, "???", sizeof(hbuf)); + printf("%s\n", hbuf); + break; + default: + printf("none\n"); + } } /* ARGSUSED */ @@ -3870,6 +3879,7 @@ void process_mpw_commands(void) { struct sockaddr_in *sin, *sinn; + struct sockaddr_in6 *sin6, *sin6n; struct ifmpwreq imr; if (wconfig == 0) @@ -3899,14 +3909,29 @@ process_mpw_commands(void) imrsave.imr_rshim.shim_label = imr.imr_rshim.shim_label; } - sin = (struct sockaddr_in *) &imrsave.imr_nexthop; - sinn = (struct sockaddr_in *) &imr.imr_nexthop; - if (sin->sin_addr.s_addr == 0) { - if (sinn->sin_addr.s_addr == 0) + switch (imrsave.imr_nexthop.ss_family) { + case AF_INET6: + case AF_INET: + /* neighbor was set earlier, nothing to do */ + break; + default: + switch (imr.imr_nexthop.ss_family) { + case AF_INET6: + sin6 = (struct sockaddr_in6 *) &imrsave.imr_nexthop; + sin6n = (struct sockaddr_in6 *) &imr.imr_nexthop; + sin6->sin6_family = sin6n->sin6_family; + memcpy(&sin6->sin6_addr, &sin6n->sin6_addr, + sizeof(struct in6_addr)); + break; + case AF_INET: + sin = (struct sockaddr_in *) &imrsave.imr_nexthop; + sinn = (struct sockaddr_in *) &imr.imr_nexthop; + sin->sin_family = sinn->sin_family; + sin->sin_addr.s_addr = sinn->sin_addr.s_addr; + break; + default: errx(1, "mpw neighbor address not specified"); - - sin->sin_family = sinn->sin_family; - sin->sin_addr.s_addr = sinn->sin_addr.s_addr; + } } ifr.ifr_data = (caddr_t) &imrsave; @@ -3949,14 +3974,41 @@ void setmpwneighbor(const char *value, int d) { struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + struct addrinfo hints, *res; + int rv; wconfig = 1; - sin = (struct sockaddr_in *) &imrsave.imr_nexthop; - if (inet_aton(value, &sin->sin_addr) == 0) + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = 0; + hints.ai_flags = AI_PASSIVE; + + rv = getaddrinfo(value, NULL, &hints, &res); + if (rv != 0) + errx(1, "neighbor %s: %s", value, gai_strerror(rv)); + + switch (res->ai_family) { + case AF_INET: + sin = (struct sockaddr_in *) &imrsave.imr_nexthop; + sin->sin_family = res->ai_family; + sin->sin_addr.s_addr = + ((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr; + break; + case AF_INET6: + sin6 = (struct sockaddr_in6 *) &imrsave.imr_nexthop; + sin6->sin6_family = res->ai_family; + memcpy(&sin6->sin6_addr, + &((struct sockaddr_in6*)res->ai_addr)->sin6_addr, + sizeof(struct in6_addr)); + break; + default: errx(1, "invalid neighbor addresses"); + } - sin->sin_family = AF_INET; + freeaddrinfo(res); } void