+static int
+network_config_set_bind_address(const oconfig_item_t *ci,
+ struct sockaddr_storage **bind_address) {
+ if ((*bind_address) != NULL) {
+ ERROR("network_plugin: only a single bind address is allowed");
+ return -1;
+ }
+
+ char addr_text[256];
+
+ if (cf_util_get_string_buffer(ci, addr_text, sizeof(addr_text)) != 0)
+ return -1;
+
+ int ret;
+ struct addrinfo *res = NULL;
+ struct addrinfo ai_hints = {.ai_family = AF_UNSPEC,
+ .ai_flags = AI_NUMERICHOST,
+ .ai_protocol = IPPROTO_UDP,
+ .ai_socktype = SOCK_DGRAM};
+
+ ret = getaddrinfo(addr_text, NULL, &ai_hints, &res);
+ if (ret) {
+ ERROR("network plugin: Bind address option has invalid address set: %s",
+ gai_strerror(ret));
+ return -1;
+ }
+
+ *bind_address = malloc(sizeof(**bind_address));
+ if (*bind_address == NULL) {
+ ERROR("network plugin: network_config_set_bind_address: malloc failed.");
+ return -1;
+ }
+ (*bind_address)->ss_family = res->ai_family;
+ if (res->ai_family == AF_INET) {
+ struct sockaddr_in *addr = (struct sockaddr_in *)(*bind_address);
+ inet_pton(AF_INET, addr_text, &(addr->sin_addr));
+ } else if (res->ai_family == AF_INET6) {
+ struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(*bind_address);
+ inet_pton(AF_INET6, addr_text, &(addr->sin6_addr));
+ } else {
+ ERROR("network plugin: %s is an unknown address format %d\n", addr_text,
+ res->ai_family);
+ sfree(*bind_address);
+ freeaddrinfo(res);
+ return -1;
+ }
+
+ freeaddrinfo(res);
+ return 0;
+} /* int network_config_set_bind_address */
+