add all family type addresses of interface if_name to the socket_info array * WARNING: it only works with ipv6 addresses on FreeBSD * return: -1 on error, 0 on success */
| 691 | * return: -1 on error, 0 on success |
| 692 | */ |
| 693 | static int expand_interface(const struct socket_info *si, struct socket_info_full** list) |
| 694 | { |
| 695 | int ret = -1; |
| 696 | struct ip_addr addr; |
| 697 | struct socket_id sid; |
| 698 | str orig_name = si->name; |
| 699 | |
| 700 | sid.port = si->port_no; |
| 701 | sid.proto = si->proto; |
| 702 | sid.workers = si->workers; |
| 703 | sid.tos = si->tos; |
| 704 | sid.auto_scaling_profile = si->s_profile?si->s_profile->name:NULL; |
| 705 | sid.adv_port = si->adv_port; |
| 706 | sid.adv_name = si->adv_name_str.s; /* it is NULL terminated */ |
| 707 | sid.tag = si->tag.s; /* it is NULL terminated */ |
| 708 | #ifdef HAVE_IFADDRS |
| 709 | /* use the getifaddrs interface to get all the interfaces */ |
| 710 | struct ifaddrs *addrs; |
| 711 | struct ifaddrs *it; |
| 712 | |
| 713 | if (getifaddrs(&addrs) != 0) { |
| 714 | LM_ERR("cannot get interfaces list: %s(%d)\n", strerror(errno), errno); |
| 715 | return -1; |
| 716 | } |
| 717 | |
| 718 | for (it = addrs; it; it = it->ifa_next) { |
| 719 | if (!it->ifa_addr) |
| 720 | continue; |
| 721 | |
| 722 | if (si->name.len == 0 || (strcmp(si->name.s, it->ifa_name) == 0)) { |
| 723 | if (it->ifa_addr->sa_family != AF_INET && |
| 724 | it->ifa_addr->sa_family != AF_INET6) |
| 725 | continue; |
| 726 | /* |
| 727 | * if it is ipv6, and there was no explicit interface specified, |
| 728 | * make sure we don't add any "scoped" interface |
| 729 | */ |
| 730 | if (it->ifa_addr->sa_family == AF_INET6 && |
| 731 | (((struct sockaddr_in6 *)(void *)it->ifa_addr)->sin6_scope_id != 0)) |
| 732 | |
| 733 | continue; |
| 734 | sockaddr2ip_addr(&addr, it->ifa_addr); |
| 735 | if ((sid.name = ip_addr2a(&addr)) == 0) |
| 736 | goto end; |
| 737 | sid.flags = si->flags; |
| 738 | if (it->ifa_flags & IFF_LOOPBACK) |
| 739 | sid.flags |= SI_IS_LO; |
| 740 | if (new_sock2list(&sid, &orig_name, list) != 0) { |
| 741 | LM_ERR("clone_sock2list failed\n"); |
| 742 | goto end; |
| 743 | } |
| 744 | ret = 0; |
| 745 | } |
| 746 | } |
| 747 | end: |
| 748 | freeifaddrs(addrs); |
| 749 | return ret; |
| 750 | #else |
no test coverage detected