+ /*
+ * Setup addresses we listen on from "afp interfaces".
+ * We use getifaddrs() instead of if_nameindex() because the latter appears still
+ * to be unable to return ipv4 addresses
+ */
+ if (obj->options.interfaces) {
+#ifndef HAVE_GETIFADDRS
+ LOG(log_error, logtype_afpd, "option \"afp interfaces\" not supported");
+#else
+ if (getifaddrs(&ifaddr) == -1) {
+ LOG(log_error, logtype_afpd, "getinterfaddr: getifaddrs() failed: %s", strerror(errno));
+ EC_FAIL;
+ }
+
+ EC_NULL( q = p = strdup(obj->options.interfaces) );
+ EC_NULL( p = strtok_r(p, ", ", &savep) );
+ while (p) {
+ for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr == NULL)
+ continue;
+ if (STRCMP(ifa->ifa_name, !=, p))
+ continue;
+
+ family = ifa->ifa_addr->sa_family;
+ if (family == AF_INET || family == AF_INET6) {
+ if (getnameinfo(ifa->ifa_addr,
+ (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6),
+ interfaddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0) {
+ LOG(log_error, logtype_afpd, "getinterfaddr: getnameinfo() failed %s", gai_strerror(errno));
+ continue;
+ }
+
+ if ((dsi = dsi_init(obj, obj->options.hostname, interfaddr, obj->options.port)) == NULL)
+ continue;
+
+ status_init(obj, dsi);
+ *next = dsi;
+ next = &dsi->next;
+ dsi->AFPobj = obj;
+
+ LOG(log_note, logtype_afpd, "Netatalk AFP/TCP listening on interface %s with address %s:%d",
+ p,
+ getip_string((struct sockaddr *)&dsi->server),
+ getip_port((struct sockaddr *)&dsi->server));
+ } /* if (family == AF_INET || family == AF_INET6) */
+ } /* for (ifa != NULL) */
+ p = strtok_r(NULL, ", ", &savep);
+ }
+ freeifaddrs(ifaddr);
+#endif
+ }