Reputation: 9124
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
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