Can't bind ipv4-mapped ipv6 address

Aleksej Lebedev root at zta.lk
Tue Feb 21 14:09:26 PST 2023


Hi,

I think I found a bug in bind(2) or at least the behavior that differs from Linux and is expected to like in Linux.
On linux instead of creating a PF_INET UDP socket and assigning an ipv4 address I can create PF_INET6 UDP socket and assigning it an ipv4-mapped ipv6 address (i.e. ::ffff:x.x.x.x).
On DragonFly the first way works (of course) but the second option doesn't seem to:

$ cat test_bind.c 
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

void die(const char *s) { perror(s); exit(1); }

int main()
{
  struct sockaddr_in sa;
  int s, r;

  s = socket(PF_INET, SOCK_DGRAM, 0);

  r = inet_pton(AF_INET, "176.9.104.141", &sa.sin_addr);
  if (r == INADDR_NONE) die("inet_pton");

  sa.sin_family = AF_INET;
  sa.sin_port = 53;

  r = bind(s, (const struct sockaddr *)&sa, sizeof sa);
  if (r != 0) die("bind");

}
$ cc test_bind.c && a.out
$ echo $?
0

$ cat test_bind6.c 
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

void die(const char *s) { perror(s); exit(1); }

int main()
{
  struct sockaddr_in6 sa;
  int s, r;

  s = socket(PF_INET6, SOCK_DGRAM, 0);

  r = inet_pton(AF_INET6, "::ffff:176.9.104.141", &sa.sin6_addr);
  if (r == INADDR_NONE) die("inet_pton");

  sa.sin6_family = AF_INET6;
  sa.sin6_port = 53;

  r = bind(s, (const struct sockaddr *)&sa, sizeof sa);
  if (r != 0) die("bind");

}
$ cc test_bind6.c && ./a.out
bind: Can't assign requested address
$ echo $?
1

On Linux both versions work.

--
Aleksej Lebedev


More information about the Users mailing list