I was playing around with Berkeley sockets, and then I did this:
#include <iostream>
#include <sys/socket.h>
#include <cstring>
int main()
{
auto res = socket(AF_INET6, SOCK_STREAM, 58);
if (res < 0) {
std::cout << " Error in creating socket: " << strerror(errno) << '\n';
}
return 0;
}
And the output was: Error in creating socket: Protocol not supported. I chose 58 as I wanted to try out as an example a ICMP IPv6 socket, and using the contents of /etc/protocols I got this:
ipv6-icmp 58 IPv6-ICMP # ICMP for IPv6.
Then I tried 0 in place of 58 in the code above and the program ran fine.
So my questions are:
why is the need of this 3rd parameter in socket() call, if we have
already specifiedSOCK_STREAM(TCP) as protocol in 2nd parameter i.e. what is the reason of existence of thisprotocol(3rd parameter) ?If the
protocol(3rd argument) is necessary then what all values can it take
with all possible combinations ofdomain(1st argument) andtype(2nd argument) ?
It would be very helpful, if someone can explain this with examples ,otherwise too it would be fine. Thanks
protocolcan accept depend on the values of the first two arguments. The domains and types that are available are listed here. The same page says the following about theprotocolfield:Here is a link to a page listing the available protocols and their associated values. The ICMP protocol value is 1.
To setup for ICMP packets you could do the following: sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
to setup for UDP packets you would use
or
Also check out this answer to another question. It's talking about normal ICMPv4 sockets but it should still be helpful and some parts may be applicable.