From 66eb0384be33db9da71d917d72b83f2ba2844743 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Thu, 5 Nov 2026 17:17:31 -0300 Subject: [PATCH] be more RFC4861 6.1.2 friendly --- mongoose.c | 20 ++++++++++++-------- src/net_builtin.c | 13 +++++++------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/mongoose.c b/mongoose.c index c609ae67..65ea56df 100644 --- a/mongoose.c +++ b/mongoose.c @@ -874,8 +874,11 @@ static bool bsd_run(struct mg_bsd_cmd *cmd) { cmd->op_setsockopt.optlen != sizeof(int)) { cmd->result = -1, cmd->err = EINVAL; } else if ((cmd->op_setsockopt.level == SOL_SOCKET && - (cmd->op_setsockopt.optname == SO_REUSEADDR || - cmd->op_setsockopt.optname == SO_NOSIGPIPE)) || + (cmd->op_setsockopt.optname == SO_REUSEADDR +#ifdef SO_NOSIGPIPE + || cmd->op_setsockopt.optname == SO_NOSIGPIPE +#endif + )) || (!s->is_udp && cmd->op_setsockopt.level == IPPROTO_TCP && cmd->op_setsockopt.optname == TCP_NODELAY)) { cmd->result = 0; @@ -9271,6 +9274,7 @@ static const struct mg_addr ip6_allrouters = { {{0xFF, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}}, 0, 0, true}; static const struct mg_addr ip6_allnodes = { {{0xFF, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}}, 0, 0, true}; +static const uint8_t locpx[8] = {0xfe, 0x80, 0, 0, 0, 0, 0, 0}; #define MG_IP6MATCH(a, b) (a[0] == b[0] && a[1] == b[1]) #endif @@ -9922,12 +9926,13 @@ static void rx_ndp_ra(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (pkt->pay.len < sizeof(*ra)) return; if (ifp->state6 == MG_TCPIP_STATE_UP) { - MG_DEBUG(("Received NDP RA")); // fill gw6 address + MG_DEBUG(("Received NDP RA")); // fill gw6 address if RFC 4861 6.1.2 + if (memcmp(pkt->ip6->src, locpx, 8) != 0 || pkt->ip6->hops != 255) return; // parse options while (opt_left >= 2) { uint8_t type = opts[0], len = opts[1]; size_t length = (size_t) len * 8; - if (length == 0 || length > opt_left) break; // malformed + if (length == 0 || length > opt_left) return; // RFC 4861 6.1.2 if (type == 1 && length >= 8) { // Received router's L2 address if (!mg_l2_ip6get(ifp->l2type, l2, opts + 2, len)) break; @@ -10008,7 +10013,7 @@ static void rx_icmp6(struct mg_tcpip_if *ifp, struct pkt *pkt) { } } break; case 134: // Router Advertisement - rx_ndp_ra(ifp, pkt); + if (pkt->icmp6->code == 0) rx_ndp_ra(ifp, pkt); // RFC 4861 6.1.2 break; case 135: // Neighbor Solicitation rx_ndp_ns(ifp, pkt); @@ -10993,12 +10998,11 @@ static void mg_ip6_poll(struct mg_tcpip_if *ifp, bool s1) { static void mg_ip6_link(struct mg_tcpip_if *ifp, bool drv_up, bool l2_up) { bool cur_drv = (ifp->state6 != MG_TCPIP_STATE_DOWN); bool cur_l2 = (ifp->state6 >= MG_TCPIP_STATE_UP); - const uint8_t px[8] = {0xfe, 0x80, 0, 0, 0, 0, 0, 0}; // RFC-4291 2.5.6 if (drv_up != cur_drv || l2_up != cur_l2) { // link/L2 state has changed if (ifp->l2type == MG_TCPIP_L2_ETH && l2_up && ifp->ip6ll[0] == 0 && ifp->ip6ll[1] == 0) { // gen ll address mg_l2_genip6(ifp->l2type, ifp->ip6ll, 64, ifp->mac); - memcpy(ifp->ip6ll, px, 8); // RFC-2464 5 + memcpy(ifp->ip6ll, locpx, 8); // RFC-4291 2.5.6; RFC-2464 5 } // just got our link local address if we didn't have one. // If static configuration is used, global addresses, // prefix length, and gw are already filled at this point. @@ -11018,7 +11022,7 @@ static void mg_ip6_link(struct mg_tcpip_if *ifp, bool drv_up, bool l2_up) { if ((ifp->l2type == MG_TCPIP_L2_PPP || ifp->l2type == MG_TCPIP_L2_PPPoE) && ifp->state6 == MG_TCPIP_STATE_UP && ifp->ip6ll[0] == 0 && ifp->ip6ll[1] != 0) { // IPV6CP has got an IFCID, gen ll address - memcpy(ifp->ip6ll, px, 8); // RFC-5072 5 + memcpy(ifp->ip6ll, locpx, 8); // RFC-5072 5 onstate6change(ifp); } // just got our link local address if we didn't have one. } diff --git a/src/net_builtin.c b/src/net_builtin.c index ec9882f0..51042092 100644 --- a/src/net_builtin.c +++ b/src/net_builtin.c @@ -364,6 +364,7 @@ static const struct mg_addr ip6_allrouters = { {{0xFF, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}}, 0, 0, true}; static const struct mg_addr ip6_allnodes = { {{0xFF, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}}, 0, 0, true}; +static const uint8_t locpx[8] = {0xfe, 0x80, 0, 0, 0, 0, 0, 0}; #define MG_IP6MATCH(a, b) (a[0] == b[0] && a[1] == b[1]) #endif @@ -1015,12 +1016,13 @@ static void rx_ndp_ra(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (pkt->pay.len < sizeof(*ra)) return; if (ifp->state6 == MG_TCPIP_STATE_UP) { - MG_DEBUG(("Received NDP RA")); // fill gw6 address + MG_DEBUG(("Received NDP RA")); // fill gw6 address if RFC 4861 6.1.2 + if (memcmp(pkt->ip6->src, locpx, 8) != 0 || pkt->ip6->hops != 255) return; // parse options while (opt_left >= 2) { uint8_t type = opts[0], len = opts[1]; size_t length = (size_t) len * 8; - if (length == 0 || length > opt_left) break; // malformed + if (length == 0 || length > opt_left) return; // RFC 4861 6.1.2 if (type == 1 && length >= 8) { // Received router's L2 address if (!mg_l2_ip6get(ifp->l2type, l2, opts + 2, len)) break; @@ -1101,7 +1103,7 @@ static void rx_icmp6(struct mg_tcpip_if *ifp, struct pkt *pkt) { } } break; case 134: // Router Advertisement - rx_ndp_ra(ifp, pkt); + if (pkt->icmp6->code == 0) rx_ndp_ra(ifp, pkt); // RFC 4861 6.1.2 break; case 135: // Neighbor Solicitation rx_ndp_ns(ifp, pkt); @@ -2086,12 +2088,11 @@ static void mg_ip6_poll(struct mg_tcpip_if *ifp, bool s1) { static void mg_ip6_link(struct mg_tcpip_if *ifp, bool drv_up, bool l2_up) { bool cur_drv = (ifp->state6 != MG_TCPIP_STATE_DOWN); bool cur_l2 = (ifp->state6 >= MG_TCPIP_STATE_UP); - const uint8_t px[8] = {0xfe, 0x80, 0, 0, 0, 0, 0, 0}; // RFC-4291 2.5.6 if (drv_up != cur_drv || l2_up != cur_l2) { // link/L2 state has changed if (ifp->l2type == MG_TCPIP_L2_ETH && l2_up && ifp->ip6ll[0] == 0 && ifp->ip6ll[1] == 0) { // gen ll address mg_l2_genip6(ifp->l2type, ifp->ip6ll, 64, ifp->mac); - memcpy(ifp->ip6ll, px, 8); // RFC-2464 5 + memcpy(ifp->ip6ll, locpx, 8); // RFC-4291 2.5.6; RFC-2464 5 } // just got our link local address if we didn't have one. // If static configuration is used, global addresses, // prefix length, and gw are already filled at this point. @@ -2111,7 +2112,7 @@ static void mg_ip6_link(struct mg_tcpip_if *ifp, bool drv_up, bool l2_up) { if ((ifp->l2type == MG_TCPIP_L2_PPP || ifp->l2type == MG_TCPIP_L2_PPPoE) && ifp->state6 == MG_TCPIP_STATE_UP && ifp->ip6ll[0] == 0 && ifp->ip6ll[1] != 0) { // IPV6CP has got an IFCID, gen ll address - memcpy(ifp->ip6ll, px, 8); // RFC-5072 5 + memcpy(ifp->ip6ll, locpx, 8); // RFC-5072 5 onstate6change(ifp); } // just got our link local address if we didn't have one. }