0

NOTE:: Please note this is just me trying to understand unix/linux in detail. thanks

Just started reading Beej's Guide to Network Programming Using Internet Sockets, then i came across this section.

(Also, all the code written before struct addrinfo was invented we packed all this stuff by hand, so you’ll see a lot of IPv4 code out in the wild that does exactly that. You know, in old versions of this guide and so on.)

Some structs are IPv4, some are IPv6, and some are both. I’ll make notes of which are what.

Anyway, the struct sockaddr holds socket address information for many types of sockets.

struct sockaddr {
    unsigned short    sa_family;    // address family, AF_xxx
    char              sa_data[14];  // 14 bytes of protocol address
}; 

sa_family can be a variety of things, but it’ll be AF_INET (IPv4) or AF_INET6 (IPv6) for everything we do in this document. sa_data contains a destination address and port number for the socket. This is rather unwieldy since you don’t want to tediously pack the address in the sa_data by hand.

To deal with struct sockaddr, programmers created a parallel structure: struct sockaddr_in (“in” for “Internet”) to be used with IPv4.

And this is the important bit: a pointer to a struct sockaddr_in can be cast to a pointer to a struct sockaddr and vice-versa. So even though connect() wants a struct sockaddr*, you can still use a struct sockaddr_in and cast it at the last minute!

// (IPv4 only--see struct sockaddr_in6 for IPv6)

struct sockaddr_in {
    short int          sin_family;  // Address family, AF_INET
    unsigned short int sin_port;    // Port number
    struct in_addr     sin_addr;    // Internet address
    unsigned char      sin_zero[8]; // Same size as struct sockaddr
};

This structure makes it easy to reference elements of the socket address. Note that sin_zero (which is included to pad the structure to the length of a struct sockaddr) should be set to all zeros with the function memset(). Also, notice that sin_family corresponds to sa_family in a struct sockaddr and should be set to “AF_INET”. Finally, the sin_port must be in Network Byte Order (by using htons()!)

He said before the addrinfo struct was created addresses where packed manually.My question is how did programmers then and even the sockaddr_in etc author know how to interpret each address family, using AF_INET as an example, how did programmers then know to pack the AF_INET addresses this way, why not the sin_addr before sin_port like the below struct. is there a specification or guideline on how to pack sa_data for each sa_family somewhere. I searched online but could not find anything relating to my question

struct sockaddr_in {
    short int          sin_family;  // Address family, AF_INET
    struct in_addr     sin_addr;    // Internet address     <== swap
    unsigned short int sin_port;    // Port number          <== swap
    unsigned char      sin_zero[8]; // Same size as struct sockaddr
};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.