| 650 | }; |
| 651 | |
| 652 | static const char * |
| 653 | netname6(struct sockaddr_in6 *sa6, struct sockaddr_in6 *mask) |
| 654 | { |
| 655 | static char line[NI_MAXHOST + sizeof("/xxx") - 1]; |
| 656 | struct sockaddr_in6 addr; |
| 657 | char nline[NI_MAXHOST]; |
| 658 | char maskbuf[sizeof("/xxx")]; |
| 659 | u_char *p, *lim; |
| 660 | u_char masklen; |
| 661 | int i; |
| 662 | bool illegal = false; |
| 663 | |
| 664 | if (mask) { |
| 665 | p = (u_char *)&mask->sin6_addr; |
| 666 | for (masklen = 0, lim = p + 16; p < lim; p++) { |
| 667 | if (masktolen[*p] > 0) { |
| 668 | /* -1 is required. */ |
| 669 | masklen += (masktolen[*p] - 1); |
| 670 | } else |
| 671 | illegal = true; |
| 672 | } |
| 673 | if (illegal) |
| 674 | xo_error("illegal prefixlen\n"); |
| 675 | |
| 676 | memcpy(&addr, sa6, sizeof(addr)); |
| 677 | for (i = 0; i < 16; ++i) |
| 678 | addr.sin6_addr.s6_addr[i] &= |
| 679 | mask->sin6_addr.s6_addr[i]; |
| 680 | sa6 = &addr; |
| 681 | } |
| 682 | else |
| 683 | masklen = 128; |
| 684 | |
| 685 | if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sa6->sin6_addr)) |
| 686 | return("default"); |
| 687 | |
| 688 | getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, nline, sizeof(nline), |
| 689 | NULL, 0, NI_NUMERICHOST); |
| 690 | if (numeric_addr) |
| 691 | strlcpy(line, nline, sizeof(line)); |
| 692 | else |
| 693 | getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, line, |
| 694 | sizeof(line), NULL, 0, 0); |
| 695 | if (numeric_addr || strcmp(line, nline) == 0) { |
| 696 | snprintf(maskbuf, sizeof(maskbuf), "/%d", masklen); |
| 697 | strlcat(line, maskbuf, sizeof(line)); |
| 698 | } |
| 699 | |
| 700 | return (line); |
| 701 | } |
| 702 | #endif /*INET6*/ |
| 703 | |
| 704 | /* |