+ /* To determine the local subnet, we need to know the local IP address.
+ Do this by looking at the IPs of every network interface.
+ */
+ struct in_addr in = { 0, };
+ struct ifaddrs *all = 0, *ifa;
+
+ if (pd->debug_p)
+ fprintf (stderr, "%s: listing network interfaces\n", progname);
+
+ getifaddrs (&all);
+ for (ifa = all; ifa; ifa = ifa->ifa_next)
+ {
+ struct in_addr in2;
+ unsigned long mask;
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ {
+ if (pd->debug_p)
+ fprintf (stderr, "%s: if: %4s: %s\n", progname,
+ ifa->ifa_name,
+ (ifa->ifa_addr->sa_family == AF_UNIX ? "local" :
+ ifa->ifa_addr->sa_family == AF_LINK ? "link" :
+ ifa->ifa_addr->sa_family == AF_INET6 ? "ipv6" :
+ "other"));
+ continue;
+ }
+ in2 = ((struct sockaddr_in *) ifa->ifa_addr)->sin_addr;
+ mask = ntohl (((struct sockaddr_in *) ifa->ifa_netmask)
+ ->sin_addr.s_addr);
+ if (pd->debug_p)
+ fprintf (stderr, "%s: if: %4s: inet = %s /%d 0x%08lx\n",
+ progname,
+ ifa->ifa_name,
+ inet_ntoa (in2),
+ mask_width (mask),
+ mask);
+ if (in2.s_addr == 0x0100007f || /* 127.0.0.1 in network order */
+ mask == 0)
+ continue;
+
+ /* At least on the AT&T 3G network, pinging either of the two
+ hosts on a /31 network doesn't work, so don't try.
+ */
+ if (mask_width (mask) == 31)
+ {
+ char buf[255];
+ sprintf (buf,
+ "Can't ping subnet:\n"
+ "local network is\n"
+ "%s/%d,\n"
+ "a p2p bridge\n"
+ "on if %s.",
+ inet_ntoa (in2), mask_width (mask), ifa->ifa_name);
+ if (*error_ret) free (*error_ret);
+ *error_ret = strdup (buf);
+ continue;
+ }
+
+ in = in2;
+ subnet_width = mask_width (mask);
+ }
+
+ if (in.s_addr)
+ {
+ if (*error_ret) free (*error_ret);
+ *error_ret = 0;
+ n_base = in.s_addr; /* already in network order, I think? */
+ }
+ else if (!*error_ret)
+ *error_ret = strdup ("Unable to determine\nlocal IP address\n");
+
+ if (all)
+ freeifaddrs (all);
+
+ if (*error_ret)
+ return 0;
+
+# else /* !HAVE_GETIFADDRS */
+
+ /* If we can't walk the list of network interfaces to figure out
+ our local IP address, try to do it by finding the local host
+ name, then resolving that.
+ */
+ char hostname[BUFSIZ];
+ struct hostent *hent = 0;
+
+ if (gethostname(hostname, BUFSIZ))
+ {
+ *error_ret = strdup ("Unable to determine\n"
+ "local host name!");
+ return 0;
+ }
+
+ /* Get our IP address and convert it to a string */