--- embedaddon/mpd/src/pppoe.c 2021/03/17 00:39:23 1.1.1.5 +++ embedaddon/mpd/src/pppoe.c 2023/09/27 11:08:01 1.1.1.5.2.1 @@ -29,6 +29,7 @@ * DEFINITIONS */ +#define PPPOE_MTU_MAX (ETHER_MAX_LEN_JUMBO - 8) #define PPPOE_MTU 1492 /* allow room for PPPoE overhead */ #define PPPOE_MRU 1492 @@ -178,7 +179,7 @@ static void PppoeDoClose(Link l); const struct phystype gPppoePhysType = { .name = "pppoe", .descr = "PPP over Ethernet", - .mtu = PPPOE_MTU, + .mtu = PPPOE_MTU_MAX, .mru = PPPOE_MRU, .tmpl = 1, .init = PppoeInit, @@ -407,6 +408,10 @@ PppoeOpen(Link l) &cn, sizeof(cn)) < 0) { Perror("[%s] PPPoE: can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"", l->name, path, cn.ourhook, cn.path, cn.peerhook); + if (errno == ENOENT) { + PppoeReleaseNode(l); + goto fail; + } goto fail2; } @@ -615,7 +620,7 @@ PppoeCtrlReadEvent(int type, void *arg) switch (u.resp.header.cmd) { case NGM_PPPOE_SESSIONID: /* XXX: I do not know what to do with this? */ Log(LG_PHYS3, ("PPPoE: rec'd SESSIONID %u from \"%s\"", - ntohs((uint16_t)u.resp.data), path)); + ntohs(*(uint16_t*)u.resp.data), path)); break; case NGM_PPPOE_SUCCESS: Log(LG_PHYS, ("[%s] PPPoE: connection successful", l->name)); @@ -875,7 +880,7 @@ PppoeGetMtu(Link l, int conf) if (conf == 0) return (l->type->mtu); else - return (l->conf.mtu); + return (l->conf.mtu ? l->conf.mtu : PPPOE_MTU); } static u_short @@ -1252,6 +1257,8 @@ PppoeListenEvent(int type, void *arg) const struct pppoe_hdr *ph; const struct pppoe_tag *tag; + u_int16_t length; + union { u_char buf[sizeof(struct ngpppoe_init_data) + MAX_SESSION]; struct ngpppoe_init_data poeid; @@ -1283,6 +1290,20 @@ PppoeListenEvent(int type, void *arg) wh = (struct pppoe_full_hdr *)response; ph = &wh->ph; + + /* Sanity check */ + length = ntohs(ph->length); + if (length > (size_t)sz - sizeof(struct pppoe_full_hdr)) { + Log(LG_PHYS, ("Ignored incoming PPPoE connection request " + "via %s for service \"%s\" from %s " + "due to bad length %hu > %u", + PIf->ifnodepath, session, + ether_ntoa((const struct ether_addr *)&wh->eh.ether_shost), + length, + (unsigned)((size_t)sz - sizeof(struct pppoe_full_hdr)))); + return; + } + if ((tag = get_tag(ph, PTT_SRV_NAME))) { size_t len = ntohs(tag->tag_len); if (len >= sizeof(real_session)) @@ -1684,6 +1705,7 @@ PppoeSetCommand(Context ctx, int ac, const char *const int i; #ifdef NGM_PPPOE_SETMAXP_COOKIE int ap; + uint16_t mtu; #endif switch ((intptr_t)arg) { case SET_IFACE: @@ -1704,6 +1726,20 @@ PppoeSetCommand(Context ctx, int ac, const char *const } } strlcpy(pi->hook, hookname, sizeof(pi->hook)); + +#ifdef NGM_PPPOE_SETMAXP_COOKIE + if (pi->max_payload > 0) { + mtu = GetSystemIfaceMTU(pi->iface); + if (mtu == 0) + mtu = ETHER_MAX_LEN; + if (pi->max_payload > mtu - 8) { + pi->max_payload = mtu - 8; + Perror("[%s] PPPoE: PPP-Max-Payload" + " value reduced to %hu", + pi->iface, pi->max_payload); + } + } +#endif break; default: return(-1); @@ -1734,8 +1770,18 @@ PppoeSetCommand(Context ctx, int ac, const char *const if (ac != 1) return(-1); ap = atoi(av[0]); - if (ap < PPPOE_MRU || ap > ETHER_MAX_LEN - 8) - Error("PPP-Max-Payload value \"%s\"", av[0]); + if (pi->iface[0] == '\0') { + if (ap < PPPOE_MRU) /* postpone check for MTU */ + Error("PPP-Max-Payload value \"%s\" less than %d", + av[0], PPPOE_MRU); + } else { + mtu = GetSystemIfaceMTU(pi->iface); + if (mtu == 0) + mtu = ETHER_MAX_LEN; + if (ap < PPPOE_MRU || ap > mtu - 8) + Error("PPP-Max-Payload value \"%s\" not in a range of %d..%hu", + av[0], PPPOE_MRU, mtu); + } pi->max_payload = ap; break; #endif