gln
gln

Reputation: 1031

sockaddr - print all information which sa_data holds - c++

in my c++ application I' using sockaddr. I want to see all the infarmation which sockaddr.sa_data[14] holds. for now I just print the ip from sa_data[2].sa_data[3].sa_data[4].sa_data[5].

I want to print in a way that I can understand (and please explain) all the information in the sa_data 14 bytes.

any help?

thanks!

Upvotes: 4

Views: 14376

Answers (6)

user3731622
user3731622

Reputation: 5095

To get and print the sa_data member of the struct sockaddr please refer to John's answer at Getting IPV4 address from a sockaddr structure

Upvotes: 0

hailelil
hailelil

Reputation: 11

the value of the sa_data which is 14 bytes is changed(are different) based on the address family : sa_family.

  1. if the the address family is AF_INET the first two bytes are port number and the next 4 bytes will be the source ip address.

  2. if the the address family is PF_PACKET the first two bytes tells the Ethernet type(wither 0800--> IP, 0806 --> ARP etc..) and the next 4 bytes (actually the first one is enough) it tells the source interface. if the value is:

    • 02 00 00 00 = eth0,
    • 03 00 00 00 = eth1,
    • 04 00 00 00 = eth2 etc ... and the last 8 bytes are unused in AF_INET family but in the PF_PACKET i didn't find out.

Upvotes: 1

Steve Hibbert
Steve Hibbert

Reputation: 2175

In the sa_data member, for IPv4 on Windows, I have found that the first two bytes hold the port number, and the next four hold the IP address.

For example, if I resolve the address 228.0.0.1:9995, the sa_data member is...

27 0b e4 00 00 01 00 00 00 00 00 00 00 00

Here, 270b is the Hex value representation of 9995 in the first two bytes. The next four bytes are the IP address, where 0xe4 is 228, then two zeros, then 0x01, or 228 0 0 1.
The last eight bytes are unused, which tallies with the comment above about only the first six bytes being used.

Note that sa_data will vary in format with the protocol being used.

Upvotes: 5

Mark Wilkins
Mark Wilkins

Reputation: 41262

One possibility would be to use inet_ntop which should be able to handle IPv4 and IPv6 addresses. It will produce a human-readable string with the address.

Upvotes: 2

Jason Orendorff
Jason Orendorff

Reputation: 45116

The information in sockaddr depends on what socket family and protocol you're using.

If you're using IPv4, the right thing is to cast the sockaddr pointer to sockaddr_in *. Only the first 6 bytes of the address are meaningful when you're using IPv4. The rest should just be ignored.

Upvotes: 0

CashCow
CashCow

Reputation: 31445

std::copy( &sa_data[0], &sa_data[0]+sizeof(sa_data)/sizeof(sa_data[0]), 
             std::ostream_iterator<int>(std::cout, " "));

will print each element as an int with a space separating. You can also use unsigned int if you don't want negative values and you can iomanip your stream to print hex if you prefer that.

Upvotes: 0

Related Questions