2

我在 OS X 上编写了一个 traceroute 程序。我正在尝试将它移植到 GNU/Linux。

[@osx]
>> sudo bin/traceroute www.google.com

Warning: www.google.com has multiple addresses; using 173.194.69.99
...

为了让它在 GNU/Linux 上编译,我添加了_GNU_SOURCE特性测试宏。

[@ubuntu]
>> sudo bin/traceroute www.google.com

error setting socket options: Invalid argument

问题在:

 85     send_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 86     if(send_socket == -1){
 87        fprintf(stderr, "\ncannot create send socket");
 88        freeaddrinfo(dest_addrinfo_collection);
 89        return EXIT_FAILURE;
 90      }
 91     error = setsockopt(send_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(int));
 92     if(error != 0){
 93        perror("\nerror setting socket options");
 94        freeaddrinfo(dest_addrinfo_collection);
 95        return EXIT_FAILURE;
 96      }

看起来setsockopt(...)无法识别IP_TTL为套接字选项。
但是,我将IP_TTL其视为IPPROTO_IP级别的套接字选项。

SOCK_DGRAM用作我的发送套接字以避免准备我自己的ICMP数据包。

4

2 回答 2

6

这就是为什么你应该使用 sizeof(variable) 来代替 sizeof(type),因为如果类型改变了,你又被搞砸了。强烈建议这样做,不仅在这种情况下,而且在您使用 malloc() 等时也是如此。

error = setsockopt(send_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
于 2012-05-20T18:03:28.933 回答
1

我的错误,我的ttl变量是无符号短。

-    error = setsockopt(send_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(int));
+    error = setsockopt(send_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(unsigned short));

更新

此外,option_len对于不同的平台,我必须有所不同。

-    error = setsockopt(send_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(unsigned short));
+#if defined(__APPLE__)
+    error = setsockopt(send_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(&ttl));
+#elif defined(__linux)
+    error = setsockopt(send_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
+#endif

更新

-  unsigned short          ttl = 1;
+  socklen_t               ttl = 1;

-#if defined(__APPLE__)
-    error = setsockopt(send_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(&ttl));
-#elif defined(__linux)
     error = setsockopt(send_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
-#endif
于 2012-05-20T17:30:17.097 回答