Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPv6 not implemented #4

Open
WhyNotHugo opened this issue May 21, 2014 · 15 comments
Open

IPv6 not implemented #4

WhyNotHugo opened this issue May 21, 2014 · 15 comments

Comments

@WhyNotHugo
Copy link

Both the responder and resolver don't seem to be working over IPv6: the responder does not respond, and the resolver won't resolv AAAA records (there's actually no way to query them via CLI).

@WhyNotHugo
Copy link
Author

Also, a lookups to FF02::FB should be sent.

@haesbaert
Copy link
Owner

I never actually got to implement ipv6, it was one of the last things in my TODO.

@WhyNotHugo
Copy link
Author

I tried to implement this, but the latest git -master won't build for me:

$ make
cc -O2 -pipe  -g -Wall -I/home/hugo/mdns/mdnsd -I../ -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare   -c log.c
In file included from log.h:24,
                 from log.c:33:
mdnsd.h:85: error: expected specifier-qualifier-list before 'RB_ENTRY'
mdnsd.h:144: error: expected specifier-qualifier-list before 'RB_ENTRY'
*** Error 1 in /home/hugo/mdns/mdnsd (<sys.mk>:87 'log.o')

@haesbaert
Copy link
Owner

Ah, people have been fixing things in the ports tree, so we need to sync the code + patches in ports in the git repo.

@WhyNotHugo
Copy link
Author

I noticed all the patches from ports have been applies to master. Maybe it's time to update the port to make is nice and clean now that the patches are upstream?

I'll see if I can do something with the IPv6 issue - no promises though (I'm not much of a C expert).

@haesbaert
Copy link
Owner

I agree, I've just released 0.6 and there should be no more need for the patches in ports.

@elad
Copy link
Contributor

elad commented Apr 19, 2016

@hobarrera if you post your code I might help you out with it. :)

@nbriggs
Copy link
Contributor

nbriggs commented Jul 25, 2017

I just had a quick look to see if it was actually easy to implement the IPv6 part, at least for collecting the information for the "face" (interface.c:if_new). It looks as though the IPv6 version of SIOCGIFADDR doesn't work, and it certainly appears to be deprecated since it can only return a single address and the IPv6 configuration may have many addresses on an interface -- though the only one you probably care about is the link-local one (and I believe there should be exactly one of those).

The only way I've found to get the IPv6 addresses that's reliable is to use SIOCGIFCONF, which returns an ifreq structure for each address for each interface -- though the documentation is wrong for it -- it doesn't return an array of ifreq objects, you have to calculate the size of each one and walk through the buffer filled with them. The sizes of the sockaddrs in them are different depending on the address family.

@nbriggs
Copy link
Contributor

nbriggs commented Jul 26, 2017

More on the SIOCGIFCONF etc. The code in kiface.c (from ripd's kroute.c) appears to predate the getifaddrs() call, which should probably replace the sysctl() calls in fetchifs(), and fetches all the addresses associated with each interface. If the addresses from that are kept, rather than trying to do SIOCGIFADDR calls then a bunch if the code in interface.c can also go away, and the addition and deletion of addresses on an interface can be handled properly. Unfortunately I discovered that the current code can't cope with an interface that has multiple IPv4 addresses.

@haesbaert
Copy link
Owner

Sadly, it's not only the kernel interface that needs to support ipv6, it needs also support for the protocol itself. Getting addresses and so on shouldn't be much work though.

@haesbaert haesbaert changed the title IPv6 not working IPv6 not implemented Nov 24, 2017
@twinshadow
Copy link

I've started work on plumbing in IPv6 at https://github.com/twinshadow/mdnsd/tree/ipv6

Right now, mdnsd will bind an IPv4 and IPv6 listening socket, but only the IPv4 is wired-up and mdnsctl can parse both IPv4 and IPv6 <address> input, but nothing resolves becuase T_AAAA packets are still a no-op in packet.c.

Feedback appreciated. I've built and tested on OpenBSD6.6 and FreeBSD-current, but I don't have a lot of interesting mdns traffic happening on my network. Next steps will be refactoring struct iface and associated code, which is the other 90% of the work :)

About all I have to show is some debug output from mdnsd in response to ./mdnsctl rlookup fe80::ba:57ff:febb:8bdc, but as I stated earlier, nothing is wired up so rlookup fails.

startup
[...]
mdns sock bound to 0.0.0.0:5353                                                                                                                                           
mdns sock bound to :::5353                                                                                                                                                
[...]
cache_insert: (new, cleaned up) (0x80078b400) C.D.B.8.B.B.E.F.F.F.7.5.A.B.0.0.0.0.0.0.0.0.0.0.1.0.0.0.0.8.E.F.ip6.arpa (PTR)
cache_insert: (new, cleaned up) (0x800767c00) 103.32.168.192.in-addr.arpa (PTR)
cache_insert: (new, cleaned up) (0x80078c000) C.D.B.8.B.B.E.F.F.F.7.5.A.B.0.0.0.0.0.0.0.0.0.0.1.0.0.0.0.8.E.F.ip6.arpa (NSEC)
cache_insert: (new, cleaned up) (0x80078bc00) 103.32.168.192.in-addr.arpa (NSEC)
[... cache_insert worked before, just showing that the
     address is advertised by another mdns server ...]
looking up C.D.B.8.B.B.E.F.F.F.7.5.A.B.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.E.F.in6.arpa (PTR 1)           
control_send_rr (PTR) C.D.B.8.B.B.E.F.F.F.7.5.A.B.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.E.F.in6.arpa                                                                            
question_remove C.D.B.8.B.B.E.F.F.F.7.5.A.B.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.E.F.in6.arpa (PTR)                                                                            

@nbriggs
Copy link
Contributor

nbriggs commented Oct 4, 2019 via email

@nbriggs
Copy link
Contributor

nbriggs commented Oct 6, 2019 via email

@twinshadow
Copy link

twinshadow commented Oct 7, 2019

The first thing I ran into was in mdnsd/mdnsd.c:155 where you are using a "struct sockaddr addr" for storage on the stack. It's not big enough (should probably be sockaddr_storage) so the stack gets corrupted. That will need a cast for the addr arg to bind(). Then you can lose the cast at 195 in the call to sstop(). It might also be clearer to throw in a "socklen_t socklen" and assign the length in the switch(af)... rather than checking af again at 178.

Thanks for catching that! Changes are now in the branch.

Once it's running... it gets a little confused when IPv6 address changes (or additions) happen: cache_insert: (new, cleaned up) (0x282f6d80) HP8D0CC5.local (A) if_fsm: interface bge0, event 'UP' not expected in state 'ACTIVE' RTM_NEWADDR when it acquired the 2602: address resulting in bge0 looking like: bge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=8009b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,LINKSTATE> ether 00:12:79:c0:c8:26 inet 192.168.42.90 netmask 0xffffff00 broadcast 192.168.42.255 inet6 fe80::212:79ff:fec0:c826%bge0 prefixlen 64 scopeid 0x1 inet6 2602:24a:de47:d2c0:212:79ff:fec0:c826 prefixlen 64 autoconf media: Ethernet autoselect (100baseTX ) status: active nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>

That may be some issue with the event code, which I plan on going into next.

As for the interface structure, struct iface, the challenge faced with changing it is that it will have to handle multiple IP addresses where it currently only handles a single IP address. I anticipate a large amount of existing code will need to be refactored to make this work, so I'm going to think about this change and take more notes before I commit anything.

edit: removed the diff and code example

@nbriggs
Copy link
Contributor

nbriggs commented Oct 13, 2019

@twinshadow -- I looked at the change you made regarding the sockaddr_storage. You left it passing sizeof(sockaddr), being the size of a generic sockaddr_storage, which results in an invalid argument error from the bind() call. The size passed must match the size of the type of sockaddr being passed in. Try:

@@ -155,18 +157,19 @@ mdns_sock(sa_family_t af)
        struct sockaddr_storage addr;
        struct sockaddr_in *sa4 = (struct sockaddr_in*)&addr;
        struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)&addr;
+       socklen_t socklen;
        char addrstr[INET6_ADDRSTRLEN];
 
        switch(af) {
        case AF_INET:
                sa4->sin_family = af;
-               sa4->sin_len = sizeof(struct sockaddr_in);
+               sa4->sin_len = socklen = sizeof(struct sockaddr_in);
                sa4->sin_port = htons(MDNS_PORT);
                sa4->sin_addr.s_addr = INADDR_ANY;
                break;
        case AF_INET6:
                sa6->sin6_family = af;
-               sa6->sin6_len = sizeof(struct sockaddr_in6);
+               sa6->sin6_len = socklen = sizeof(struct sockaddr_in6);
                sa6->sin6_port = htons(MDNS_PORT);
                memcpy(&sa6->sin6_addr.s6_addr, &in6addr_any, sizeof(in6addr_any));
                break;
@@ -175,7 +178,7 @@ mdns_sock(sa_family_t af)
        if ((sock = socket(af, SOCK_DGRAM, IPPROTO_UDP)) == -1)
                fatal("socket");
 
-       if (bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1)
+       if (bind(sock, (struct sockaddr *)&addr, socklen) == -1)
                fatal("bind");
 
        if (if_set_opt(af, sock) == -1)

@twinshadow twinshadow mentioned this issue Nov 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants