+ case PING_OPT_SOURCE:
+ {
+ char *hostname = (char *) 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 = AF_UNSPEC;
+#if defined(AI_ADDRCONFIG)
+ ai_hints.ai_flags = AI_ADDRCONFIG;
+#endif
+ status = getaddrinfo (hostname, NULL, &ai_hints, &ai_list);
+ if (status != 0)
+ {
+#if defined(EAI_SYSTEM)
+ char errbuf[PING_ERRMSG_LEN];
+#endif
+ ping_set_error (obj, "getaddrinfo",
+#if defined(EAI_SYSTEM)
+ (status == EAI_SYSTEM)
+ ? sstrerror (errno, errbuf, sizeof (errbuf)) :
+#endif
+ gai_strerror (status));
+ ret = -1;
+ break;
+ }
+#if WITH_DEBUG
+ if (ai_list->ai_next != NULL)
+ {
+ dprintf ("hostname = `%s' is ambiguous.\n", hostname);
+ }
+#endif
+ if (obj->srcaddr == NULL)
+ {
+ obj->srcaddrlen = 0;
+ obj->srcaddr = malloc (sizeof (struct sockaddr_storage));
+ if (obj->srcaddr == NULL)
+ {
+ ping_set_errno (obj, errno);
+ ret = -1;
+ freeaddrinfo (ai_list);
+ break;
+ }
+ }
+ memset ((void *) obj->srcaddr, 0, sizeof (struct sockaddr_storage));
+ assert (ai_list->ai_addrlen <= sizeof (struct sockaddr_storage));
+ 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 */
+ break;
+
+ case PING_OPT_DEVICE:
+ {
+#ifdef SO_BINDTODEVICE
+ char *device = strdup ((char *) value);
+
+ if (device == NULL)
+ {
+ ping_set_errno (obj, errno);
+ ret = -1;
+ break;
+ }
+
+ if (obj->device != NULL)
+ free (obj->device);
+ obj->device = device;
+#else /* ! SO_BINDTODEVICE */
+ ping_set_errno (obj, ENOTSUP);
+ ret = -1;
+#endif /* ! SO_BINDTODEVICE */
+ } /* case PING_OPT_DEVICE */
+ break;
+
+ case PING_OPT_MARK:
+ {
+#ifdef SO_MARK
+ obj->mark = *(int*)(value);
+ obj->set_mark = 1;
+#else /* SO_MARK */
+ ping_set_errno (obj, ENOTSUP);
+ ret = -1;
+#endif /* !SO_MARK */
+
+ } /* case PING_OPT_MARK */
+ break;
+