Actually bind to the configured address.
[liboping.git] / src / liboping.c
index d74659f..21855e1 100644 (file)
@@ -890,9 +890,14 @@ int ping_setopt (pingobj_t *obj, int option, void *value)
                        struct addrinfo  ai_hints;
                        struct addrinfo *ai_list;
                        int              status;
-
+#if WITH_DEBUG
+                       if (obj->addrfamily != AF_UNSPEC)
+                       {
+                               dprintf ("Resetting obj->addrfamily to AF_UNSPEC.\n");
+                       }
+#endif
                        memset ((void *) &ai_hints, '\0', sizeof (ai_hints));
-                       ai_hints.ai_family = obj->addrfamily;
+                       ai_hints.ai_family = obj->addrfamily = AF_UNSPEC;
 #if defined(AI_ADDRCONFIG)
                        ai_hints.ai_flags = AI_ADDRCONFIG;
 #endif
@@ -930,6 +935,7 @@ int ping_setopt (pingobj_t *obj, int option, void *value)
                        memcpy ((void *) obj->srcaddr, (const void *) ai_list->ai_addr,
                                        ai_list->ai_addrlen);
                        obj->srcaddrlen = ai_list->ai_addrlen;
+                       obj->addrfamily = ai_list->ai_family;
 
                        freeaddrinfo (ai_list);
                } /* case PING_OPT_SOURCE */
@@ -1086,21 +1092,20 @@ int ping_host_add (pingobj_t *obj, const char *host)
                        continue;
                }
 
-/*
- * The majority vote of operating systems has decided that you don't need to
- * bind here. This code should be reactivated to bind to a specific address,
- * though. See the `-I' option of `ping(1)' (GNU).  -octo
- */
-#if 0
-               if (bind (ph->fd, (struct sockaddr *) &sockaddr, sockaddr_len) == -1)
+               if (obj->srcaddr != NULL)
                {
-                       dprintf ("bind: %s\n", strerror (errno));
-                       ping_set_error (obj, "bind", strerror (errno));
-                       close (ph->fd);
-                       ph->fd = -1;
-                       continue;
+                       assert (obj->srcaddrlen > 0);
+                       assert (obj->srcaddrlen <= sizeof (struct sockaddr_storage));
+
+                       if (bind (ph->fd, (struct sockaddr *) obj->srcaddr, obj->srcaddrlen) == -1)
+                       {
+                               dprintf ("bind: %s\n", strerror (errno));
+                               ping_set_error (obj, "bind", strerror (errno));
+                               close (ph->fd);
+                               ph->fd = -1;
+                               continue;
+                       }
                }
-#endif
 
                assert (sizeof (struct sockaddr_storage) >= ai_ptr->ai_addrlen);
                memset (ph->addr, '\0', sizeof (struct sockaddr_storage));