c - understanding the protocol family argument of socket() and result list of getaddrinfo() -


i had started network programming days ago there confusion need clear. have not studied networking or tcp/ip protocol before.

socket function argument:

the protocol family argument socket function denote set of protocols or protocol suite used communication.

  1. is above interpretation correct?

    if yes, means pf/af_inet , pf/af_inet6 2 different protocol suites. right? reason creating 2 different protocol suites , not 1 tcp/ip protocol suite 2 address families?

    if not, protocol family denote function argument?

    edit: don't have enough reputation answer own question editing

    from unix network programming vol. 1, 3rd edition - section 4.2 socket function, sub-section - af_xxx verseus pf_xxx

    the "af_" prefix stands "address family" , "pf_" prefix stands "protocol family". historically, intent single protocol family might support multiple address families , pf_ value used create socket , af_ value used in socket addresses structures. in actually, protocol family supporting multiple address families has never been supported , sys/socket.h header defines pf_ value given protocol equal af_ value protocol. while there no guarantee equality between 2 true, should change existing protocols, lots of existing code break.

    so guess reason not creating 1 pf_inet protocol family 2 address families af_inet , af_inet6 backward compatibility.

getaddrinfo:

the following code prints information each ip address returned getaddrinfo.

#define _posix_c_source 201112l  #include <stdio.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h>  void print_family(struct addrinfo *aip) {     printf(" family ");     switch (aip->ai_family)     {         case af_inet:             printf("inet");             break;         case af_inet6:             printf("inet6");             break;     } } void print_type(struct addrinfo *aip) {     printf(" type ");     switch (aip->ai_socktype)     {         case sock_stream:             printf("stream");             break;         case sock_dgram:             printf("datagram");             break;         case sock_seqpacket:             printf("seqpacket");             break;         case sock_raw:             printf("raw");             break;         default:             printf("unknown %d", aip->ai_socktype);     } } void print_protocol(struct addrinfo *aip) {     printf(" protocol ");     switch (aip->ai_protocol)     {         case 0:             printf("0");             break;         case ipproto_tcp:             printf("tcp");             break;         case ipproto_udp:             printf("udp");             break;         case ipproto_raw:             printf("raw");         case ipproto_sctp:             printf("sctp");             break;         default:             printf("unknown %d", aip->ai_protocol);     } } int main(int argc, char **argv) {     struct addrinfo *ailist, *aip, hint;     int err;      if (argc != 3)     {         printf("usage: %s <hostname> <service>\n", argv[0]);         printf("if 1 not applicable, provide null in place.\n");         return 1;     }     if (strcmp(argv[1], "null") == 0)         argv[1] = null;     if (strcmp(argv[2], "null") == 0)         argv[2] = null;     hint.ai_flags = 0;     hint.ai_family = 0;     hint.ai_socktype = 0;     hint.ai_protocol = 0;     hint.ai_addrlen = 0;     hint.ai_canonname = null;     hint.ai_addr = null;     hint.ai_next = null;     if ((err = getaddrinfo(argv[1], argv[2], &hint, &ailist)) != 0)     {         printf("getaddrinfo error: %s", gai_strerror(err));         return 2;     }      (aip = ailist; aip != null; aip = aip->ai_next)     {         struct sockaddr_in *sinp;         struct sockaddr_in6 *sinp6;         char buf[inet_addrstrlen];         const char *addr;          print_family(aip);         print_type(aip);         print_protocol(aip);         printf("\n\thost %s", aip->ai_canonname ? aip->ai_canonname : "-");         if (aip->ai_family == af_inet)         {             sinp = (struct sockaddr_in *) aip->ai_addr;             addr = inet_ntop(af_inet, &sinp->sin_addr, buf, inet_addrstrlen);             printf(" address %s", addr ? addr : "unknown");             printf(" port %d ", ntohs(sinp->sin_port));         }         else if (aip->ai_family == af_inet6)         {             sinp6 = (struct sockaddr_in6 *) aip->ai_addr;             addr = inet_ntop(af_inet6, &sinp6->sin6_addr, buf, inet6_addrstrlen);             printf(" address %s", addr ? addr : "unknown");             printf(" port %d ", ntohs(sinp6->sin6_port));         }         printf("\n");     }     return 0; } 

compiling , running above program on arch linux 4.4.11-1-lts x86-64.

running program as: ./prg localhost http gives following result (for ipv4 addresses):-

family inet type stream protocol tcp         host - address 127.0.0.1 port 80  family inet type datagram protocol udp         host - address 127.0.0.1 port 80  family inet type stream protocol sctp         host - address 127.0.0.1 port 80  family inet type seqpacket protocol sctp         host - address 127.0.0.1 port 80 

and command ./prg localhost null result is:-

family inet type stream protocol tcp         host - address 127.0.0.1 port 0  family inet type datagram protocol udp         host - address 127.0.0.1 port 0  family inet type raw protocol 0         host - address 127.0.0.1 port 0  
  1. my question how return result when service null? man page says port left uninitialized there nothing number of structures returned. why give addrinfo structure tcp , udp when service null , not sctp? sctp not in default list of protocols return structures when service null, if there such default?

from unix network programming vol. 1 3rd edition w. richard stevens

it acceptable getaddrinfo return ai_protocol of 0 2 sock_stream structures if sufficient specify tcp (it not sufficient if system implements sctp, example), , ai_protocol of 0 2 sock_dgram structures if system doesn't implement other sock_dgram protocols ip.

  1. as understood above line, getaddrinfo can return 0 protocol if there 1 protocol specified socket type. this acceptable. system implements sctp , maybe other protocols sock_dgram socket types cannot return 0 protocol value tcp , udp? why return protocol value of 0 sock_raw socket type there many protocols supported raw sockets under af_inet family?

the man page says

there several reasons why linked list may have more 1 addrinfo structure, including: network host multihomed, accessible on multiple protocols (e.g., both af_inet , af_inet6); or same service available multiple socket types (one sock_stream address , sock_dgram address, example).

  1. is saying "service available multiple socket types" same saying "service supported or available multiple protocols"?

changing line of code hint.ai_socktype=0 hint.ai_socktype=sock_stream , running ./prg localhost http gives following result:

family inet type stream protocol tcp         host - address 127.0.0.1 port 80 
  1. why did not give 1 structure sctp supported sock_stream socket type following result shows.

changing line in modified program hint.ai_protocol=0 tohint.ai_protocol=ipproto_sctp , running ./prg localhost http gives following result:

family inet type stream protocol sctp         host - address 127.0.0.1 port 80  


Comments

Popular posts from this blog

wordpress - (T_ENDFOREACH) php error -

Export Excel workseet into txt file using vba - (text and numbers with formulas) -

Using django-mptt to get only the categories that have items -