#include #include #include #include #include #include #include #include #include static void print_broad(int s, struct lifreq *p, sa_family_t fam) { char ipastr[INET6_ADDRSTRLEN]; char *if_name = p->lifr_name; void *addrp = &p->lifr_addr; if (ioctl(s, SIOCGLIFBRDADDR, p) < 0) { fprintf(stderr, "ioctl(SIOCGLIFBRDADDR) error\n"); exit(1); } if (fam == AF_INET) { struct in_addr addr = ((struct sockaddr_in *)addrp)->sin_addr; if (inet_ntop(AF_INET, &addr, ipastr, sizeof(ipastr)) != NULL) printf("\tbroad=%s\n", ipastr); } else if (fam == AF_INET6) { struct in6_addr addr = ((struct sockaddr_in6 *)addrp)->sin6_addr; if (inet_ntop(AF_INET6, &addr, ipastr, sizeof(ipastr)) != NULL) printf("\tbroad=%s\n", ipastr); } else { } } static void print_netmask(int s, struct lifreq *p, sa_family_t fam) { char ipastr[INET6_ADDRSTRLEN]; char *if_name = p->lifr_name; void *addrp = &p->lifr_addr; if (ioctl(s, SIOCGLIFNETMASK, p) < 0) { fprintf(stderr, "ioctl(SIOCGLIFSUBNET) error\n"); exit(1); } if (fam == AF_INET) { struct in_addr addr = ((struct sockaddr_in *)addrp)->sin_addr; if (inet_ntop(AF_INET, &addr, ipastr, sizeof(ipastr)) != NULL) printf("\tnetmask=%s\n", ipastr); } else if (fam == AF_INET6) { struct in6_addr addr = ((struct sockaddr_in6 *)addrp)->sin6_addr; if (inet_ntop(AF_INET6, &addr, ipastr, sizeof(ipastr)) != NULL) printf("\tnetmask=%s\n", ipastr); } else { } } static uint64_t get_flags(int s, struct lifreq *p, sa_family_t fam) { if (ioctl(s, SIOCGLIFFLAGS, p) < 0) { fprintf(stderr, "ioctl(SIOCGLIFFLAGS) error\n"); exit(1); } return (p->lifr_flags); } static sa_family_t print_addr(int s, struct lifreq *p) { char ipastr[INET6_ADDRSTRLEN]; char *if_name = p->lifr_name; void *addrp = &p->lifr_addr; if (p->lifr_addr.ss_family == AF_INET) { struct in_addr addr = ((struct sockaddr_in *)addrp)->sin_addr; printf("ifname(AF_INET) = %s\n", if_name); if (inet_ntop(AF_INET, &addr, ipastr, sizeof(ipastr)) != NULL) printf("\taddr=%s\n", ipastr); return (AF_INET); } else if (p->lifr_addr.ss_family == AF_INET6) { struct in6_addr addr = ((struct sockaddr_in6 *)addrp)->sin6_addr; printf("ifname(AF_INET6) = %s\n", if_name); if (inet_ntop(AF_INET6, &addr, ipastr, sizeof(ipastr)) != NULL) printf("\taddr=%s\n", ipastr); return (AF_INET6); } else { } } main() { int s, i; struct lifconf ifc; struct lifnum ifn; struct lifreq *p; int num_if; if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { fprintf(stderr, "socket() error\n"); exit(1); } /* Get interface number */ ifn.lifn_family = AF_UNSPEC; /* both AF_INET and AF_INET6 */ ifn.lifn_flags = 0; if (ioctl(s, SIOCGLIFNUM, &ifn) < 0) { fprintf(stderr, "ioctl(SIOCGLIFNUM) error\n"); exit(1); } num_if = ifn.lifn_count; ifc.lifc_len = num_if * sizeof (struct lifreq); if ((ifc.lifc_buf = malloc(ifc.lifc_len)) == NULL) { fprintf(stderr, "malloc() error\n"); exit(1); } /* Get interface configuration (name and address) */ ifc.lifc_family = AF_UNSPEC; ifc.lifc_flags = 0; if (ioctl(s, SIOCGLIFCONF, &ifc) < 0) { fprintf(stderr, "ioctl(SIOCGLIFCONF) error\n"); exit(1); } (void) close(s); for (i = 0, p = ifc.lifc_req ; i < num_if; i++, p++) { sa_family_t fam; uint64_t flags; if ((s = socket(p->lifr_addr.ss_family, SOCK_DGRAM, 0)) < 0) { fprintf(stderr, "socket() error\n"); exit(1); } fam = print_addr(s, p); flags = get_flags(s, p, fam); print_netmask(s, p, fam); if (flags & IFF_BROADCAST) print_broad(s, p, fam); (void) close(s); } }