Thread: Sockaddress struct confusion

  1. #1
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629

    Sockaddress struct confusion

    Hi,
    Can someone explain what's happening here, apparently it is over the internet, but no good explanation

    Code:
    struct in_addr {
      in_addr_t   s_addr;           /* 32-bit IPv4 address */
                                    /* network byte ordered */
    };
    
    struct sockaddr_in {
      uint8_t         sin_len;      /* length of structure (16) */
      sa_family_t     sin_family;   /* AF_INET */
      in_port_t       sin_port;     /* 16-bit TCP or UDP port number */
                                    /* network byte ordered */
      struct in_addr  sin_addr;     /* 32-bit IPv4 address */
                                    /* network byte ordered */
      char            sin_zero[8];  /* unused */
    };
    struct sockaddr {
      uint8_t      sa_len;
      sa_family_t  sa_family;    /* address family: AF_xxx value */
      char         sa_data[14];  /* protocol-specific address */
    };
    From what I understand sockaddr and sockaddr_in have 2 fields in common the length and the family. struct sockaddr is some kind of base class.
    What I don't understand is this notation.
    Code:
    bind(sockfd, (struct sockaddr *) &serv, sizeof(serv));
    A pointer to sockaddr_in is treated a pointer to sockaddr. I understand that the pointer can fill in the length and family with no problems...but I don't understand how it would do so?

    If sockAddr was the variable that holds the serv struct in bind how would it access the family and length
    would it be sockAddr->sa_len or sockAddr->sin_len? If you have happened to use BSD api it'd be nice if you clarify what's happening thanks.
    You ended that sentence with a preposition...Bastard!

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Down in the OS, the bind() call will examine the sa_family field, see that it is AF_INET, and recast the pointer to a sockaddr_in pointer to access the INET specific fields. What you're asking about is just a bit of type casting used to placate the compiler, because C doesn't have "real" classes.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by brewbuck View Post
    Down in the OS, the bind() call will examine the sa_family field, see that it is AF_INET, and recast the pointer to a sockaddr_in pointer to access the INET specific fields. What you're asking about is just a bit of type casting used to placate the compiler, because C doesn't have "real" classes.
    Finally an answer, thanks.
    Right I think I see what's happening. It's a way of passing sockets that use different types of family UNIX, Internet with one kind of structure.
    It's some kind of twisted polymorphism then....
    How is char sa_data[14] filled in then? sockaddr_in holds an integer address.
    You ended that sentence with a preposition...Bastard!

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Eman View Post
    Finally an answer, thanks.
    Right I think I see what's happening. It's a way of passing sockets that use different types of family UNIX, Internet with one kind of structure.
    It's some kind of twisted polymorphism then....
    How is char sa_data[14] filled in then? sockaddr_in holds an integer address.
    Nobody fills in sa_data. It is just a placeholder for other data which may or may not be present, depending on the address family. It's just casting one pointer type to another so the compiler doesn't complain. Nothing is being converted or translated. You're passing a pointer to a sockaddr_in structure, it's just the type of that pointer happens to be sockaddr, not sockaddr_in.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    I don't understand, what is the point then?
    The socket must hold the family, length (which I don't know its use for yet), ip address and port number. The iport I assume must be in sa_data because a socket structure needs that. I don't see why it might be empty. Unless some other family doesn't require iport...
    You ended that sentence with a preposition...Bastard!

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Eman View Post
    I don't understand, what is the point then?
    The socket must hold the family, length (which I don't know its use for yet), ip address and port number. The iport I assume must be in sa_data because a socket structure needs that. I don't see why it might be empty. Unless some other family doesn't require iport...
    Internet addresses are only meaningful for Internet sockets, obviously. Other kinds of sockets can exist. The whole point of this interface is to allow for multiple address families.

    The point of the length is so the kernel knows how much data needs to be copied from user space to kernel space. It's also a kind of sanity check.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    The same generic socket is used for another though, like struct sockaddr_un (couldn't find the template). Does that mean it doesn't use iport addresses? How does it transfer data.
    You ended that sentence with a preposition...Bastard!

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Eman View Post
    The same generic socket is used for another though, like struct sockaddr_un (couldn't find the template). Does that mean it doesn't use iport addresses? How does it transfer data.
    IP == "Internet Protocol," why would a non-Internet socket have an IP address?

    UNIX sockets are special objects which have names in the filesystem -- the "address" of a UNIX socket is a path.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  9. #9
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Yeah... I think I get the gist of it. I need to do some more coding to understand. But thanks a lot.
    You ended that sentence with a preposition...Bastard!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. struct tm confusion?
    By deadrabbit in forum C Programming
    Replies: 4
    Last Post: 08-11-2011, 06:35 PM
  2. Struct and array! confusion
    By ronrardin in forum C Programming
    Replies: 5
    Last Post: 04-05-2010, 12:09 PM
  3. C struct / pointer confusion
    By ChipsHandon in forum C Programming
    Replies: 5
    Last Post: 02-26-2010, 02:08 AM
  4. struct holding data inside a linked list struct
    By icestorm in forum C Programming
    Replies: 2
    Last Post: 10-06-2009, 12:49 PM
  5. Pointer + struct w/arrays confusion
    By Viper187 in forum C Programming
    Replies: 1
    Last Post: 07-23-2009, 09:37 AM