in source/linux/network.c [329:430]
int get_network_config_and_transfer(struct aws_iotdevice_network_ifconfig *ifconfig, struct aws_allocator *allocator) {
if (aws_hash_table_init(
&ifconfig->iface_name_to_info,
allocator,
sizeof(struct aws_iotdevice_network_iface),
aws_hash_c_string,
aws_hash_callback_c_str_eq,
NULL,
s_network_iface_destroy)) {
return AWS_OP_ERR;
}
int result = AWS_OP_ERR;
int fd = -1;
struct ifaddrs *address_info = NULL;
if (getifaddrs(&address_info)) {
AWS_LOGF_ERROR(
AWS_LS_IOTDEVICE_NETWORK_CONFIG, "id=%p: getifaddrs() failed: %s", (void *)ifconfig, strerror(errno));
result = AWS_OP_ERR;
goto cleanup;
}
struct ifaddrs *address = address_info;
while (address) {
if (address->ifa_addr == NULL || address->ifa_data == NULL) {
goto next_interface;
}
struct ifreq ifr;
AWS_ZERO_STRUCT(ifr);
strncpy(ifr.ifr_name, address->ifa_name, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ - 1] = 0;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1) {
AWS_LOGF_ERROR(
AWS_LS_IOTDEVICE_NETWORK_CONFIG,
"id=%p: socket(AF_INET, SOCK_DGRAM, 0) failed: %s",
(void *)ifconfig,
strerror(errno));
result = AWS_OP_ERR;
goto cleanup;
}
if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) {
AWS_LOGF_WARN(
AWS_LS_IOTDEVICE_NETWORK_CONFIG,
"id=%p: iotctl(fd, SIOCGIFADDR, ...) failed to get interface address: %s",
(void *)ifconfig,
strerror(errno));
goto next_interface;
}
struct aws_iotdevice_network_iface *iface =
aws_mem_calloc(allocator, 1, sizeof(struct aws_iotdevice_network_iface));
if (iface == NULL) {
goto cleanup;
}
iface->allocator = allocator;
if (ifr.ifr_addr.sa_family == AF_INET) {
inet_ntop(AF_INET, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr, iface->ipv4_addr_str, 16);
}
strncpy(iface->iface_name, ifr.ifr_name, IFACE_NAME_SIZE);
iface->iface_name[IFACE_NAME_SIZE - 1] = 0;
if (address->ifa_data) {
struct rtnl_link_stats *stats = address->ifa_data;
iface->metrics.bytes_in = stats->rx_bytes;
iface->metrics.bytes_out = stats->tx_bytes;
iface->metrics.packets_in = stats->rx_packets;
iface->metrics.packets_out = stats->tx_packets;
}
if ((result = aws_hash_table_put(&ifconfig->iface_name_to_info, iface->ipv4_addr_str, iface, NULL))) {
AWS_LOGF_ERROR(
AWS_LS_IOTDEVICE_NETWORK_CONFIG,
"id=%p: network interface address to interface info add to map failed: %s",
(void *)ifconfig,
aws_error_name(result));
result = AWS_OP_ERR;
aws_mem_release(allocator, iface);
goto cleanup;
}
next_interface:
if (fd != -1) {
close(fd);
fd = -1;
}
address = address->ifa_next;
} /* while */
result = AWS_OP_SUCCESS;
cleanup:
if (result != AWS_OP_SUCCESS) {
aws_hash_table_clean_up(&ifconfig->iface_name_to_info);
}
if (address_info) {
freeifaddrs(address_info);
}
if (fd != -1) {
close(fd);
}
return result;
}