Search code examples
csocketsunixposix

Find out transport type for socket


I am currently struggling with finding out the ip, port and transport type of a inet/inet6 socket in C.

The problem is that I got a socket fd like

int s = socket( ... );
bind(s, soa, soa_len);

Now, I got s and want to find out which Transport/Interface/Port it is bound to. Interface and Port is easy enough via

struct sockaddr_storage sa = {};:w
getsockname(s, (struct sockaddr*) &sa, sizeof(sa));
/* parse the fields of sa depending on sa.sa_family */

However, I cannot figure out a way to find out whether s is a TCP or UDP socket - it must be somehow associated however - So:

How can I find out the transport protocol s uses?


Solution

  • Use the getsockopt(descriptor, SO_TYPE, ...) as described in the man 7 socket man page. For example:

    #include <sys/socket.h>
    #include <sys/types.h>
    #include <errno.h>
    
    int socket_type(const int fd)
    {
        int        type = -1;
        socklen_t  typelen = sizeof type;
    
        if (fd == -1) {
            errno = EINVAL;
            return -1;
        }
        if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &typelen) == -1)
            return -1;
    
        errno = 0;
        return type;
    }
    

    For TCP (AF_INET and AF_INET6 socket families), this will return SOCK_STREAM; for UDP, SOCK_DGRAM.