setsockopt fails for IPPROTO_TCP IP_TOS in C
13,665
Solution 1
IP_TOS
has level IPPROTO_IP
, not IPPROTO_TCP
.
See the documentation.
This affects both setting and getting the option.
Also, what Seth said about initializing the length parameter, which affects only getsockopt
.
Solution 2
When calling getsockopt, you pass in the size of the memory pointed to by &tos. In other words initialize toslen to sizeof(tos).
Comments
-
cateof almost 2 years
My code fails. I am running as root (same behavior as normal user)
First I want to set the TOS and then get the value.
int tos_local = 0x28; if (setsockopt(sockfd, IPPROTO_TCP, IP_TOS, &tos_local, sizeof(tos_local))) { error("error at socket option"); } else { int tos=0; int toslen=0; if (getsockopt(sockfd, IPPROTO_TCP, IP_TOS, &tos, &toslen) < 0) { error("error to get option"); }else { printf ("changing tos opt = %d\n",tos); } }
the printf prints
changing tos opt = 0
I would expect to print 0x28 (40).
What is the problem?
The correct answer:
if (setsockopt(sockfd, **IPPROTO_IP**, IP_TOS, &tos_local, sizeof(tos_local))) { int tos=0; int toslen=sizeof(tos); //that line here if (getsockopt(sockfd, IPPROTO_IP, IP_TOS, &tos, &toslen) < 0) {
-
cateof almost 13 yearsI get compiler warning error: warning: passing argument 5 of getsockopt makes pointer from integer without a cast when I pass sizeof(tos). Additionally the getsockoption fails with "Bad Address"
-
Nemo almost 13 yearsIndeed. And IP_TOS happens to equal 1, as does TCP_NODELAY, so this code actually does something... Just not what was intended.
-
Ben Voigt almost 13 years@cateof: passing
&tos_len
as the parameter is correct, but you need to declare it asint tos_len = sizeof (tos);
and not0
. -
Seth Robertson almost 13 years@cateof: @Ben Voight: I think you mean, passing &tos_len as the parameter is correct, but you need to initialize it to sizeof(tos) and not 0.
-
Ben Voigt almost 13 years@Nemo: Yeah, they should have designed these as bitfields instead of separate parameters. But that's water under the bridge.