From 1d4ef08e6a3d09627cb5fd12e07a14e688b9e9f6 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Fri, 13 Mar 2026 08:53:36 -0300 Subject: [PATCH] Add L2 PPP and PPPoE --- mongoose.c | 57 ++++++++++++++++++++++++++++++++++++++++++ mongoose.h | 70 ++++++++++++++++++++++++++-------------------------- src/l2_ppp.c | 41 ++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 35 deletions(-) diff --git a/mongoose.c b/mongoose.c index e6a72f8d..cd7287b3 100644 --- a/mongoose.c +++ b/mongoose.c @@ -3746,6 +3746,7 @@ struct pppoe { // RFC-2516, "A Method for Transmitting PPP Over Ethernet #define MG_PPPoE_PADS 0x65 #define MG_PPPoE_PADT 0xa7 +<<<<<<< HEAD #define MG_PPPoE_ST_DISC 0 // Discovery phase, see what servers are out there #define MG_PPPoE_ST_REQ 1 // Chose a server, request a session and wait #define MG_PPPoE_ST_SESS 2 // Session established, PPP traffic is exchanged @@ -3754,6 +3755,12 @@ struct pppoe { // RFC-2516, "A Method for Transmitting PPP Over Ethernet static bool s_link = false; // ************ THESE SHOULD MOVE TO A struct mg_l2data ******************************* static uint8_t s_state = MG_PPPoE_ST_DISC; +======= +#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a)))) + +static bool s_link = false; // ******************************************* +static uint8_t s_state = 0; +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) static uint16_t s_id; void mg_l2_ppp_init(struct mg_tcpip_if *ifp) { @@ -3770,7 +3777,12 @@ void mg_l2_pppoe_init(struct mg_tcpip_if *ifp) { } bool mg_l2_ppp_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) { +<<<<<<< HEAD if (expired_1000ms && ifp->state == MG_TCPIP_STATE_DOWN) s_link = false; +======= + (void) ifp; + (void) expired_1000ms; +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) return s_link; } @@ -4180,17 +4192,26 @@ static size_t pppoe_tx_frame(struct mg_tcpip_if *ifp, uint8_t code, uint16_t id, } bool mg_l2_pppoe_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) { +<<<<<<< HEAD if (expired_1000ms && s_state == MG_PPPoE_ST_DISC && ifp->state == MG_TCPIP_STATE_LINK_UP) { +======= + if (expired_1000ms && s_state == 0 && ifp->driver_up) { +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) uint16_t tags[2]; tags[0] = mg_htons(0x0101); // Service Request tags[1] = mg_htons(0x0000); // Any pppoe_tx_frame(ifp, MG_PPPoE_PADI, 0, (uint8_t *) tags, sizeof(tags), mg_l2_eth_mapip(MG_TCPIP_L2ADDR_BCAST, NULL)); MG_DEBUG(("Sent PADI")); +<<<<<<< HEAD } else if (expired_1000ms && (s_state != MG_PPPoE_ST_SESS || ifp->state == MG_TCPIP_STATE_DOWN)) { s_state = MG_PPPoE_ST_DISC; +======= + } else if (expired_1000ms && (s_state != 2 || !ifp->driver_up)) { + s_state = 0; +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) } return mg_l2_ppp_poll(ifp, expired_1000ms); } @@ -4208,8 +4229,12 @@ bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto, if (pay->len < sizeof(*pppoe)) return false; // Truncated if (eth_proto == MG_TCPIP_L2PROTO_PPPoE_DISC) { MG_VERBOSE(("PPPoE_DISC")); +<<<<<<< HEAD if (s_state == MG_PPPoE_ST_DISC && pppoe->code == MG_PPPoE_PADO && pppoe->id == 0) { +======= + if (s_state == 0 && pppoe->code == MG_PPPoE_PADO && pppoe->id == 0) { +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) uint16_t tags[2]; bool has_cookie = false; size_t len = pay->len - sizeof(*pppoe); @@ -4238,6 +4263,7 @@ bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto, pppoe_tx_frame(ifp, MG_PPPoE_PADR, 0, p, taglen, mg_l2_eth_getaddr((uint8_t *) raw->buf)); MG_DEBUG(("Sent PADR")); +<<<<<<< HEAD s_state = MG_PPPoE_ST_REQ; } else if (s_state == MG_PPPoE_ST_REQ && pppoe->code == MG_PPPoE_PADS) { s_id = pppoe->id; @@ -4245,14 +4271,29 @@ bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto, MG_DEBUG(("PPPoE session 0x%04x started", mg_ntohs(s_id))); s_state = MG_PPPoE_ST_SESS; } else if (s_state == MG_PPPoE_ST_SESS && pppoe->code == MG_PPPoE_PADT && +======= + s_state = 1; + } else if (s_state == 1 && pppoe->code == MG_PPPoE_PADS) { + s_id = pppoe->id; + memcpy(&ifp->gwmac, mg_l2_eth_getaddr((uint8_t *) raw->buf)->addr.mac, 6); + MG_DEBUG(("PPPoE session 0x%04x started", mg_ntohs(s_id))); + s_state = 2; + } else if (s_state == 2 && pppoe->code == MG_PPPoE_PADT && +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) pppoe->id == s_id) { MG_ERROR(("Got PADT")); s_id = 0; s_link = false; +<<<<<<< HEAD s_state = MG_PPPoE_ST_DISC; } } else if (eth_proto == MG_TCPIP_L2PROTO_PPPoE_SESS && s_state == MG_PPPoE_ST_SESS) { +======= + s_state = 0; + } + } else if (eth_proto == MG_TCPIP_L2PROTO_PPPoE_SESS && s_state == 2) { +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) pay->buf = (char *) (pppoe + 1); pay->len = pay->len - sizeof(*pppoe); return ppp_rx(ifp, proto, pay, raw); @@ -7275,7 +7316,11 @@ static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) { pkt.raw.len = len; pkt.l2 = (uint8_t *) pkt.raw.buf; if (!mg_l2_rx(ifp, &proto, &pkt.pay, &pkt.raw)) return; +<<<<<<< HEAD if (ifp->state < MG_TCPIP_STATE_UP) return; // discard while L2 is not up +======= + if (ifp->state == MG_TCPIP_STATE_DOWN) return; // discard while L2 is not up +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) if (proto == MG_TCPIP_L2PROTO_ARP) { pkt.arp = (struct arp *) (pkt.pay.buf); if (pkt.pay.len < sizeof(*pkt.arp)) return; // Truncated @@ -7409,9 +7454,17 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) { drv_up = ifp->driver->poll ? ifp->driver->poll(ifp, expired_1000ms) : true; l2_up = mg_l2_poll(ifp, expired_1000ms); // Handle L2 up/down link status; if (expired_1000ms) { // ifp->state rules over state6 +<<<<<<< HEAD mg_ip_link(ifp, drv_up, l2_up); // Handle IPv4 mg_ip6_link(ifp, drv_up, l2_up); // Handle IPv6 if (ifp->state < MG_TCPIP_STATE_UP) MG_ERROR(("Network is down")); +======= + bool up = drv_up & l2_up; + ifp->driver_up = drv_up; // update physical link state + mg_ip_link(ifp, up); // Handle IPv4 + mg_ip6_link(ifp, up); // Handle IPv6 + if (ifp->state == MG_TCPIP_STATE_DOWN) MG_ERROR(("Network is down")); +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) mg_tcpip_call(ifp, MG_TCPIP_EV_TIMER_1S, NULL); } } @@ -7435,7 +7488,11 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) { mg_queue_del(&ifp->recv_queue, len); } } +<<<<<<< HEAD if (ifp->state < MG_TCPIP_STATE_UP) return; // need to let L2 do its job +======= + if (ifp->state == MG_TCPIP_STATE_DOWN) return; // need to let L2 do its job +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) // Process timeouts for (c = ifp->mgr->conns; c != NULL; c = c->next) { diff --git a/mongoose.h b/mongoose.h index 1cb8a05e..070a23cd 100644 --- a/mongoose.h +++ b/mongoose.h @@ -4034,6 +4034,41 @@ struct mg_tcpip_driver_tms570_data { +#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7 + +struct mg_tcpip_driver_xmc7_data { + int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5 + uint8_t phy_addr; +}; + +#ifndef MG_TCPIP_PHY_ADDR +#define MG_TCPIP_PHY_ADDR 0 +#endif + +#ifndef MG_DRIVER_MDC_CR +#define MG_DRIVER_MDC_CR 3 +#endif + +#define MG_TCPIP_DRIVER_INIT(mgr) \ + do { \ + static struct mg_tcpip_driver_xmc7_data driver_data_; \ + static struct mg_tcpip_if mif_; \ + driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \ + driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \ + mif_.ip = MG_TCPIP_IP; \ + mif_.mask = MG_TCPIP_MASK; \ + mif_.gw = MG_TCPIP_GW; \ + mif_.driver = &mg_tcpip_driver_xmc7; \ + mif_.driver_data = &driver_data_; \ + MG_SET_MAC_ADDRESS(mif_.mac); \ + mg_tcpip_init(mgr, &mif_); \ + MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \ + } while (0) + +#endif + + + #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC struct mg_tcpip_driver_xmc_data { @@ -4080,41 +4115,6 @@ struct mg_tcpip_driver_xmc_data { #endif - -#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7 - -struct mg_tcpip_driver_xmc7_data { - int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5 - uint8_t phy_addr; -}; - -#ifndef MG_TCPIP_PHY_ADDR -#define MG_TCPIP_PHY_ADDR 0 -#endif - -#ifndef MG_DRIVER_MDC_CR -#define MG_DRIVER_MDC_CR 3 -#endif - -#define MG_TCPIP_DRIVER_INIT(mgr) \ - do { \ - static struct mg_tcpip_driver_xmc7_data driver_data_; \ - static struct mg_tcpip_if mif_; \ - driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \ - driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \ - mif_.ip = MG_TCPIP_IP; \ - mif_.mask = MG_TCPIP_MASK; \ - mif_.gw = MG_TCPIP_GW; \ - mif_.driver = &mg_tcpip_driver_xmc7; \ - mif_.driver_data = &driver_data_; \ - MG_SET_MAC_ADDRESS(mif_.mac); \ - mg_tcpip_init(mgr, &mif_); \ - MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \ - } while (0) - -#endif - - #ifdef __cplusplus } #endif diff --git a/src/l2_ppp.c b/src/l2_ppp.c index f8172fca..2f708177 100644 --- a/src/l2_ppp.c +++ b/src/l2_ppp.c @@ -88,6 +88,7 @@ struct pppoe { // RFC-2516, "A Method for Transmitting PPP Over Ethernet #define MG_PPPoE_PADS 0x65 #define MG_PPPoE_PADT 0xa7 +<<<<<<< HEAD #define MG_PPPoE_ST_DISC 0 // Discovery phase, see what servers are out there #define MG_PPPoE_ST_REQ 1 // Chose a server, request a session and wait #define MG_PPPoE_ST_SESS 2 // Session established, PPP traffic is exchanged @@ -96,6 +97,12 @@ struct pppoe { // RFC-2516, "A Method for Transmitting PPP Over Ethernet static bool s_link = false; // ************ THESE SHOULD MOVE TO A struct mg_l2data ******************************* static uint8_t s_state = MG_PPPoE_ST_DISC; +======= +#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a)))) + +static bool s_link = false; // ******************************************* +static uint8_t s_state = 0; +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) static uint16_t s_id; void mg_l2_ppp_init(struct mg_tcpip_if *ifp) { @@ -112,7 +119,12 @@ void mg_l2_pppoe_init(struct mg_tcpip_if *ifp) { } bool mg_l2_ppp_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) { +<<<<<<< HEAD if (expired_1000ms && ifp->state == MG_TCPIP_STATE_DOWN) s_link = false; +======= + (void) ifp; + (void) expired_1000ms; +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) return s_link; } @@ -522,17 +534,26 @@ static size_t pppoe_tx_frame(struct mg_tcpip_if *ifp, uint8_t code, uint16_t id, } bool mg_l2_pppoe_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) { +<<<<<<< HEAD if (expired_1000ms && s_state == MG_PPPoE_ST_DISC && ifp->state == MG_TCPIP_STATE_LINK_UP) { +======= + if (expired_1000ms && s_state == 0 && ifp->driver_up) { +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) uint16_t tags[2]; tags[0] = mg_htons(0x0101); // Service Request tags[1] = mg_htons(0x0000); // Any pppoe_tx_frame(ifp, MG_PPPoE_PADI, 0, (uint8_t *) tags, sizeof(tags), mg_l2_eth_mapip(MG_TCPIP_L2ADDR_BCAST, NULL)); MG_DEBUG(("Sent PADI")); +<<<<<<< HEAD } else if (expired_1000ms && (s_state != MG_PPPoE_ST_SESS || ifp->state == MG_TCPIP_STATE_DOWN)) { s_state = MG_PPPoE_ST_DISC; +======= + } else if (expired_1000ms && (s_state != 2 || !ifp->driver_up)) { + s_state = 0; +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) } return mg_l2_ppp_poll(ifp, expired_1000ms); } @@ -550,8 +571,12 @@ bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto, if (pay->len < sizeof(*pppoe)) return false; // Truncated if (eth_proto == MG_TCPIP_L2PROTO_PPPoE_DISC) { MG_VERBOSE(("PPPoE_DISC")); +<<<<<<< HEAD if (s_state == MG_PPPoE_ST_DISC && pppoe->code == MG_PPPoE_PADO && pppoe->id == 0) { +======= + if (s_state == 0 && pppoe->code == MG_PPPoE_PADO && pppoe->id == 0) { +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) uint16_t tags[2]; bool has_cookie = false; size_t len = pay->len - sizeof(*pppoe); @@ -580,6 +605,7 @@ bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto, pppoe_tx_frame(ifp, MG_PPPoE_PADR, 0, p, taglen, mg_l2_eth_getaddr((uint8_t *) raw->buf)); MG_DEBUG(("Sent PADR")); +<<<<<<< HEAD s_state = MG_PPPoE_ST_REQ; } else if (s_state == MG_PPPoE_ST_REQ && pppoe->code == MG_PPPoE_PADS) { s_id = pppoe->id; @@ -587,14 +613,29 @@ bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto, MG_DEBUG(("PPPoE session 0x%04x started", mg_ntohs(s_id))); s_state = MG_PPPoE_ST_SESS; } else if (s_state == MG_PPPoE_ST_SESS && pppoe->code == MG_PPPoE_PADT && +======= + s_state = 1; + } else if (s_state == 1 && pppoe->code == MG_PPPoE_PADS) { + s_id = pppoe->id; + memcpy(&ifp->gwmac, mg_l2_eth_getaddr((uint8_t *) raw->buf)->addr.mac, 6); + MG_DEBUG(("PPPoE session 0x%04x started", mg_ntohs(s_id))); + s_state = 2; + } else if (s_state == 2 && pppoe->code == MG_PPPoE_PADT && +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) pppoe->id == s_id) { MG_ERROR(("Got PADT")); s_id = 0; s_link = false; +<<<<<<< HEAD s_state = MG_PPPoE_ST_DISC; } } else if (eth_proto == MG_TCPIP_L2PROTO_PPPoE_SESS && s_state == MG_PPPoE_ST_SESS) { +======= + s_state = 0; + } + } else if (eth_proto == MG_TCPIP_L2PROTO_PPPoE_SESS && s_state == 2) { +>>>>>>> 3b7ca757 (Add L2 PPP and PPPoE) pay->buf = (char *) (pppoe + 1); pay->len = pay->len - sizeof(*pppoe); return ppp_rx(ifp, proto, pay, raw);