udhcpc6 kernel listen mode is broken

Danomi Manchego danomimanchego123 at gmail.com
Sat Jun 4 00:57:38 UTC 2022


Sorry all, I did not realize that there was a function called
d6_listen_socket() in d6_socket.c - so no new function is needed to
fix DHCPv6 Renew reply processing.  The correct message ID is needed
and use of d6_listen_socket() rather than udhcp_listen_socket().

Regards,
Danomi -

On Tue, May 10, 2022 at 9:34 PM Danomi Manchego
<danomimanchego123 at gmail.com> wrote:
>
> Hello,
>
> On April 1, I sent "udhcpc6 renew message copy/paste error" email
> about udhcpc6 sends the wrong message ID for Renew message due to
> copy/paste error from IPv4 dhcpc.c.  (Was DHCPREQUEST, should be
> D6_MSG_RENEW.)  After fixing that, I found that the Renew is sent
> correctly, and the DHCPv6 server replies, but udhcpc6 fails to get the
> reply.  Because there is no reply, the lease does not get extended by
> Renew.  I found that the issue is that the udhcp_listen_socket() in
> socket.c (used for kernel listen mode in d6_dhcpc.c) is somewhat
> hard-coded for IPv4.  I was able to get kernel listen mode to work by
> adding a new function like this to socket.c and using it in d6_dhcp.c.
> My udhcp6_listen_socket() differs from udhcp_listen_socket() as
> follows:
>
> * Use PF_INET6 instead of PF_INET.
>
> * Set IPPROTO_IPV6 / IPV6_V6ONLY socket option rather than broadcast option.
>
> * Use `struct sockaddr_in6` instead of `struct sockaddr_in`.
>
> * Use AF_INET6 instead of AF_INET.
>
> (Maybe SOCK_CLOEXEC should also be set in *both* functions when
> calling xsocket since udhcpc/udhcpc6 invoke external udhcpc.script,
> but I did not try it.)
>
> My function is pasted below.
>
> int FAST_FUNC udhcp6_listen_socket(/*uint32_t ip,*/ int port, const char *inf)
> {
>     int fd;
>     struct sockaddr_in6 addr;
>     char *colon;
>
>     log2("opening listen socket on *:%d %s", port, inf);
>     fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
>
>     setsockopt_reuseaddr(fd);
>
>     if (setsockopt_1(fd, IPPROTO_IPV6, IPV6_V6ONLY) < 0)
>         bb_simple_perror_msg_and_die("IPPROTO_IPV6");
>
>     /* SO_BINDTODEVICE doesn't work on ethernet aliases (ethN:M) */
>     colon = strrchr(inf, ':');
>     if (colon)
>         *colon = '\0';
>
>     if (setsockopt_bindtodevice(fd, inf))
>         xfunc_die(); /* warning is already printed */
>
>     if (colon)
>         *colon = ':';
>
>     memset(&addr, 0, sizeof(addr));
>     addr.sin6_family = AF_INET6;
>     addr.sin6_port = htons(port);
>     /* addr.sin_addr.s_addr = ip; - all-zeros is INADDR_ANY */
>     xbind(fd, (struct sockaddr *)&addr, sizeof(addr));
>
>     return fd;
> }
>
> Regards,
> Danomi -


More information about the busybox mailing list