Vaibhav Bajpai
Vaibhav Bajpai

Reputation: 16814

setsockopt(...) cannot recognize IP_TTL for IPPROTO_IP on Ubuntu

I have written a traceroute program written on OS X. I am trying to port it to GNU/Linux.

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

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

To make it compile on GNU/Linux, I added _GNU_SOURCE feature test macro.

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

error setting socket options: Invalid argument

The issue is at:

 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      }

Looks like setsockopt(...) cannot recognize IP_TTL as socket option.
However I see IP_TTL as a socket option for IPPROTO_IP level.

I am using SOCK_DGRAM as my sending socket to avoid preparing my own ICMP packet.

Upvotes: 2

Views: 6715

Answers (2)

Vaibhav Bajpai
Vaibhav Bajpai

Reputation: 16814

My mistake, my ttlvariable was an unsigned short.

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

UPDATE

In addition I had to option_len was different for different platforms.

-    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

UPDATE

-  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

Upvotes: 1

user529758
user529758

Reputation:

That's why you should use sizeof(variable) in lieu of sizeof(type), since if the type changes, you're screwed once again. This is strongly adviced and recommended not only in this case, but also when you use malloc(), etc.

error = setsockopt(send_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));

Upvotes: 6

Related Questions