From: Daniel Lenski Date: Thu, 4 Feb 2021 20:38:49 +0000 (-0800) Subject: Fortinet does not use HDLC framing X-Git-Tag: v8.20~325^2~25 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=7b1bd66e077590f9c8ae9e0b46dbebdd558efa85;p=users%2Fdwmw2%2Fopenconnect.git Fortinet does not use HDLC framing It uses non-HDLC framing with a 6-byte header. Signed-off-by: Daniel Lenski --- diff --git a/fortinet.c b/fortinet.c index f5e1e0c8..97ecabad 100644 --- a/fortinet.c +++ b/fortinet.c @@ -339,7 +339,7 @@ int fortinet_connect(struct openconnect_info *vpninfo) * Don't blame me. I didn't design this. */ - ret = openconnect_ppp_new(vpninfo, PPP_ENCAP_FORTINET_HDLC, ipv4, ipv6); + ret = openconnect_ppp_new(vpninfo, PPP_ENCAP_FORTINET, ipv4, ipv6); out: if (ret) diff --git a/openconnect-internal.h b/openconnect-internal.h index 63a0eefe..5e92e56e 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -190,8 +190,8 @@ struct pkt { #define PPP_ENCAP_RFC1662_HDLC 2 /* PPP with HDLC-like framing (RFC1662) */ #define PPP_ENCAP_F5 3 /* F5 BigIP no HDLC */ #define PPP_ENCAP_F5_HDLC 4 /* F5 BigIP HDLC */ -#define PPP_ENCAP_FORTINET_HDLC 5 /* Fortinet HDLC */ -#define PPP_ENCAP_MAX PPP_ENCAP_FORTINET_HDLC +#define PPP_ENCAP_FORTINET 5 /* Fortinet no HDLC */ +#define PPP_ENCAP_MAX PPP_ENCAP_FORTINET #define COMPR_DEFLATE (1<<0) #define COMPR_LZS (1<<1) diff --git a/ppp.c b/ppp.c index e452caee..c9f7b4f1 100644 --- a/ppp.c +++ b/ppp.c @@ -172,7 +172,7 @@ static const char *encap_names[PPP_ENCAP_MAX+1] = { "RFC1662 HDLC", "F5", "F5 HDLC", - "FORTINET HDLC", + "FORTINET", }; static const char *lcp_names[] = { @@ -248,9 +248,10 @@ int openconnect_ppp_new(struct openconnect_info *vpninfo, ppp->encap_len = 4; break; - case PPP_ENCAP_FORTINET_HDLC: + case PPP_ENCAP_FORTINET: + ppp->encap_len = 6; ppp->check_http_response = 1; - /* fall through */ + break; case PPP_ENCAP_F5_HDLC: /* XX: F5 server cancels our IP address allocation if we PPP-terminate */ @@ -1081,6 +1082,17 @@ int ppp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable) } break; + case PPP_ENCAP_FORTINET: + payload_len = load_be16(eh + 4); + magic = load_be16(eh + 2); + next = eh + 6 + payload_len; + + if (magic != 0x5050 || (load_be16(eh) != payload_len + 6)) + goto bad_encap_header; + if (len < 6 + payload_len) + goto incomplete_pkt; + break; + case PPP_ENCAP_F5_HDLC: case PPP_ENCAP_RFC1662_HDLC: payload_len = unhdlc_in_place(vpninfo, eh + ppp->encap_len, len - ppp->encap_len, &next); @@ -1342,6 +1354,12 @@ int ppp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable) store_be16(eh, 0xf500); store_be16(eh + 2, this->len + this->ppp.hlen); break; + case PPP_ENCAP_FORTINET: + /* XX: header contains both TOTAL bytes-on-wire, and (bytes-on-wire excluding this header) */ + store_be16(eh, this->len + this->ppp.hlen + 6); + store_be16(eh + 2, 0x5050); + store_be16(eh + 4, this->len + this->ppp.hlen); + break; } this->ppp.hlen += ppp->encap_len;