Vorac
Vorac

Reputation: 9124

Read source address for UDP broadcast

My goal is to listen on broadcast address range ff05:e671:2015::1 for udp datagrams. When such is received, the concrete server ip shall be recovered.

Currently, I am receiving valid packets. However, when I check the source address, here are a couple of outputs:

fd01:e671:2015:5c01::
fd01:e671:2015:d101::

Here is the relevant part of my code:

std::array<char, 1024> _buff;
sockaddr a {};
socklen_t s = sizeof( a );
auto bytes = recvfrom( _fd, _buff.data(), _buff.size(), MSG_DONTWAIT | MSG_TRUNC, &a, &s );
...
// reuse the buffer
sockaddr_in6 *sin = reinterpret_cast<sockaddr_in6*>( &a );
inet_ntop( AF_INET6, &sin->sin6_addr, _buff.data(), INET6_ADDRSTRLEN );

Finally, here is some of the output of tcpdump | grep fd01:e671:2015:5c01:

10:07:31.452905 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 120
10:07:31.453122 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 161
10:07:31.453128 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 202
10:07:31.453130 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 80
10:07:31.453131 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 121
10:07:31.453133 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 162

How do I get the full and concrete datagram source ip?

Upvotes: 0

Views: 84

Answers (1)

David Schwartz
David Schwartz

Reputation: 182837

Your sockaddr is too small to hold an IPv6 address. You should allocate the type you intend to hold and cast in the call to recvfrom. You can't do it the other way around because you don't actually have a sockaddr_in6 that way.

Upvotes: 1

Related Questions