2
votes

I have a C++ application that uses the same IPv6 UDP socket to send to IPv6 or IPv4 destinations.

sockfd = socket(PF_INET6, SOCK_DGRAM, 0);
dest_addr.sin6_family = AF_INET;
dest_addr.sin6_port = htons(dest_port);
inet_pton ("192.168.1.33",  &dest_addr.sin6_addr);
sendto (sockfd, message, strlen(message)+1, 0, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in6));

On Linux this works fine, but on FreeBSD I get an error Address family not supported by protocol family when I send to IPv4 addresses.

Is there a way to configure FreeBSD to accept this? Maybe similar to ipv6_ipv4mapping="YES" for listening to IPv4 clients?

1
Wouldn't be better to have a socket for ipv4 and one for ipv6? - Paolo
@Paolo: Two reasons a.) it fits the existing (IPv4 based) program structure well and b.) the application already uses many hundreds of sockets and I'd prefer not to double it. - Gene Vincent
in C++ you only need (sockaddr *), not (struct sockaddr *) - phuclv

1 Answers

3
votes

You are creating an IPv6 socket, so you have to use IPv6 addresses. However, if your OS supports dual-stack sockets (ie, natively supports both IPv4 and IPv6 on a single socket), then use an IPv4-mapped IPv6 address to send to an IPv4 address (if the OS allows it, some do not). Otherwise, you have to use separate sockets for IPv4 annd IPv6.