Which protocol values are compatible with which combinations of domain and type in socket()?

354 Views Asked by At

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:

  1. why is the need of this 3rd parameter in socket() call, if we have
    already specified SOCK_STREAM(TCP) as protocol in 2nd parameter i.e. what is the reason of existence of this protocol (3rd parameter) ?

  2. If the protocol(3rd argument) is necessary then what all values can it take
    with all possible combinations of domain(1st argument) and type(2nd argument) ?

It would be very helpful, if someone can explain this with examples ,otherwise too it would be fine. Thanks

1

There are 1 best solutions below

12
Louis P. Dartez On
  1. from my experience, the protocol field is usually only used when you use SOCK_RAW instead of SOCK_DGRAM or SOCK_STREAM.
  2. the values that protocol can 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 the protocol field:
   The protocol specifies a particular protocol to be used with the
   socket.  Normally only a single protocol exists to support a
   particular socket type within a given protocol family, in which case
   protocol can be specified as 0.  However, it is possible that many
   protocols may exist, in which case a particular protocol must be
   specified in this manner.  The protocol number to use is specific to
   the “communication domain” in which communication is to take place;
   see protocols(5).  See getprotoent(3) on how to map protocol name
   strings to protocol numbers.

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

sock = socket(AF_INET, SOCK_DGRAM, 0);

or

sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);

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.