Reputation: 16814
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
Reputation: 16814
My mistake, my ttl
variable 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));
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
- 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
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