CPIInterfaceSet * cpiInterfaceSet_FromJson(PARCJSON *json) { assertNotNull(json, "Parameter must be non-null"); PARCJSONValue *value = parcJSON_GetValueByName(json, cpi_InterfaceList); assertNotNull(value, "JSON key not found %s: %s", cpi_InterfaceList, parcJSON_ToString(json)); PARCJSONArray *ifaceSetJson = parcJSONValue_GetArray(value); CPIInterfaceSet *set = cpiInterfaceSet_Create(); size_t length = parcJSONArray_GetLength(ifaceSetJson); for (size_t i = 0; i < length; i++) { value = parcJSONArray_GetValue(ifaceSetJson, i); PARCJSON *ifaceJson = parcJSONValue_GetJSON(value); CPIInterface *iface = cpiInterface_FromJson(ifaceJson); cpiInterfaceSet_Add(set, iface); } return set; }
CPIInterfaceSet * metisSystem_Interfaces(MetisForwarder *metis) { CPIInterfaceSet *set = cpiInterfaceSet_Create(); // this is the dynamically allocated head of the list struct ifaddrs *ifaddr; int failure = getifaddrs(&ifaddr); assertFalse(failure, "Error getifaddrs: (%d) %s", errno, strerror(errno)); struct ifaddrs *next; for (next = ifaddr; next != NULL; next = next->ifa_next) { if ((next->ifa_addr == NULL) || ((next->ifa_flags & IFF_UP) == 0)) { continue; } // This assumes the LINK address comes first so we can get the MTU // when the interface is created. CPIInterface *iface = cpiInterfaceSet_GetByName(set, next->ifa_name); if (iface == NULL) { unsigned mtu = 0; if (next->ifa_data != NULL) { struct if_data *ifdata = (struct if_data *) next->ifa_data; mtu = ifdata->ifi_mtu; } iface = cpiInterface_Create(next->ifa_name, metisForwarder_GetNextConnectionId(metis), next->ifa_flags & IFF_LOOPBACK, next->ifa_flags & IFF_MULTICAST, mtu); cpiInterfaceSet_Add(set, iface); } int family = next->ifa_addr->sa_family; switch (family) { case AF_INET: { CPIAddress *address = cpiAddress_CreateFromInet((struct sockaddr_in *) next->ifa_addr); cpiInterface_AddAddress(iface, address); break; } case AF_INET6: { CPIAddress *address = cpiAddress_CreateFromInet6((struct sockaddr_in6 *) next->ifa_addr); cpiInterface_AddAddress(iface, address); break; } case AF_LINK: { struct sockaddr_dl *addr_dl = (struct sockaddr_dl *) next->ifa_addr; // skip links with 0-length address if (addr_dl->sdl_alen > 0) { // addr_dl->sdl_data[12] contains the interface name followed by the MAC address, so // need to offset in to the array past the interface name. CPIAddress *address = cpiAddress_CreateFromLink((uint8_t *) &addr_dl->sdl_data[ addr_dl->sdl_nlen], addr_dl->sdl_alen); cpiInterface_AddAddress(iface, address); } break; } } } freeifaddrs(ifaddr); return set; }