tcpdump mailing list archives

Re: ipv6 addresses in pcap_addr


From: Guy Harris <guy () alum mit edu>
Date: Thu, 22 Jan 2009 16:59:39 -0800


On Jan 22, 2009, at 4:05 PM, Chris Morgan wrote:

Hello.

I wasn't sure if this question was answered anywhere, I've searched
via google and looked on the mailing lists but haven't seen any
answers.

How does one get a ipv6 address from the sockaddr struct pointed to by
pcap_addr?

Welcome to the wonderful world of C, the programming language that combines the power of assembly language with the convenience of assembly language....

"struct sockaddr" is a sort of place-holder structure. There are few, if any, real "struct sockaddr" structures out there; instead, there are "struct sockaddr_XXX" structures, for various values of XXX. "struct sockaddr" is an abstraction that covers all of them; all "struct sockaddr_XXX" structures begin with members that are the same as the non-"sa_data" members of "struct sockaddr", and with the same structure offsets as those members, and have, following that, the address-type-specific data, starting at the same offset as the "sa_data" member of "struct sockaddr", but not necessarily having the same *length* as the "sa_data" member of that structure - it could be longer (and possibly shorter).

Once you've determined the address family of an address structure by dereferencing a "struct sockaddr *" that you've been handed, you should cast the "struct sockaddr *" to the appropriate "struct sockaddr_XXX *" type - "struct sockaddr_un" for UNIX-domain socket addresses, "struct sockaddr_in" for IPv4 addresses, "struct sockaddr_in6" for IPv6 addresses, etc. - and get the address family- specific information from the "struct sockaddr_XXX" pointed to by the result of that cast.

I have devices with addresses of type AF_INET6 but since
the sockaddr struct is defined to have only 14 bytes of protocol
address how does one get a 16 byte ipv6 address out of this 14 byte
structure?

By realizing that, in fact, what you've been handed is a pointer to a "struct sockaddr_in6", cast to a pointer to a "struct sockaddr", because the address family is AF_INET6.

For a bit more detailed discussion of this, go to

        http://www.unix.org/

go to the Single UNIX Specification Version 3 (you'll have to register, but don't worry about it - it's free, just a nuisance), and go to the page for <sys/sockets.h>, which says:

The <sys/socket.h> header shall define the unsigned integer type sa_family_t.

The <sys/socket.h> header shall define the sockaddr structure that includes at least the following members:

        sa_family_t  sa_family  Address family.
        char         sa_data[]  Socket address (variable-length data).

The sockaddr structure is used to define a socket address which is used in the bind(), connect(), getpeername(), getsockname(), recvfrom(), and sendto() functions.

The <sys/socket.h> header shall define the sockaddr_storage structure. This structure shall be:

o Large enough to accommodate all supported protocol-specific address structures

o Aligned at an appropriate boundary so that pointers to it can be cast as pointers to protocol-specific address structures and used to access the fields of those structures without alignment problems

The sockaddr_storage structure shall contain at least the following members:

        sa_family_t   ss_family

When a sockaddr_storage structure is cast as a sockaddr structure, the ss_family field of the sockaddr_storage structure shall map onto the sa_family field of the sockaddr structure. When a sockaddr_storage structure is cast as a protocol-specific address structure, the ss_family field shall map onto a field of that structure that is of type sa_family_t and that identifies the protocol's address family.

These conventions aren't libpcap-isms; other APIs, such as getaddrinfo(), use those conventions - for example, the "struct addrinfo"s handed back by getaddrinfo() have "struct sockaddr *" pointers in them.
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: