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