Connection to IPv6 link local address fails due to missing scope identifier

Michael Stapelberg <>
Tue Oct 12 22:41:19 CEST 2010


Hi,

the following proof of concept fails:
  -module(poc).
  -export([start/0]).
  
  start() ->
      {ok, Sock} = gen_tcp:connect("fe80::21f:16ff:fe1a:f5b8%eth0", 80, [inet6]),
      io:fwrite("connect said: ~p~n", [ok]).

If you strace it using strace -fF -etrace=network erl -s poc, you’ll see the
following:

  socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = 7
  bind(7, {sa_family=AF_INET6, sin6_port=htons(0), inet_pton(AF_INET6, "::",
    &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
  getsockname(7, {sa_family=AF_INET6, sin6_port=htons(36404),
    inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0},
    [28]) = 0
  connect(7, {sa_family=AF_INET6, sin6_port=htons(80), inet_pton(AF_INET6,
    "fe80::21f:16ff:fe1a:f5b8", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0},
    28) = -1 EINVAL (Invalid argument)

The problem is the missing scope identifier (sin6_scope_id), which should be 2
for eth0 in my case (see /proc/net/igmp6 for easily getting the scope id for
your interfaces).

To reproduce this test:
  • to test the client side, use nc -6 fe80::21f:16ff:fe1a:f5b8%eth0 80
  • to test the server side, use for example OpenSSH (listens on all
    interfaces/addresses per default) or Apache.
  • to get your link local address, use ifconfig(1) or "ip a|grep fe80"

Best regards,
Michael


More information about the erlang-bugs mailing list