From d621b76fe0ba4ec07b51f5676e2f23f3b42ec602 Mon Sep 17 00:00:00 2001 From: Daniel Lenski Date: Sun, 17 May 2020 16:27:52 -0700 Subject: [PATCH] Need to handle case where rejected protocol was sent as only 1 byte MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit … as well as the admittedly-unlikely case where the rejected protocol is larger than peer's MRU (which we've already accepted as our MTU). Signed-off-by: Daniel Lenski --- ppp.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ppp.c b/ppp.c index 1a2a6b4f..c1846aa2 100644 --- a/ppp.c +++ b/ppp.c @@ -1084,12 +1084,23 @@ int ppp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable) default: vpn_progress(vpninfo, PRG_ERR, - _("PPP packet with unknown protocol 0x%04x. Payload:\n"), + _("Sending Protocol-Reject for unknown protocol 0x%04x. Payload:\n"), proto); dump_buf_hex(vpninfo, PRG_ERR, '<', pp, payload_len); - if (queue_config_packet(vpninfo, PPP_LCP, ++ppp->lcp.id, PROTREJ, payload_len + (pp - ph), ph)) - vpn_progress(vpninfo, PRG_ERR, - _("Failed queuing Protocol-Reject for unknown protocol 0x%04x.\n"), proto); + + /* The rejected protocol MUST occupy 2 bytes prior to the rejected packet contents. + * (https://tools.ietf.org/html/rfc1661#section-5.7). We can clobber these bytes + * because we are throwing out this packet anyway. + * + * The rejected packet body is fully included, unless it must be truncated to the + * peer's MRU (taking into account the preceding 4 bytes for PPP header, 4 for LCP + * config header, and 2 for rejected proto. + */ + store_be16(pp - 2, proto); + if ((ret = queue_config_packet(vpninfo, PPP_LCP, ++ppp->lcp.id, PROTREJ, + MIN(payload_len + 2, vpninfo->ip_info.mtu - 10), + pp - 2)) < 0) + return ret; } if (next_len) { -- 2.49.0