]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Fortinet does not use HDLC framing
authorDaniel Lenski <dlenski@gmail.com>
Thu, 4 Feb 2021 20:38:49 +0000 (12:38 -0800)
committerDaniel Lenski <dlenski@gmail.com>
Mon, 29 Mar 2021 03:13:30 +0000 (20:13 -0700)
It uses non-HDLC framing with a 6-byte header.

Signed-off-by: Daniel Lenski <dlenski@gmail.com>
fortinet.c
openconnect-internal.h
ppp.c

index f5e1e0c884842fdb043d06e0baad745bd9639dac..97ecabade7538a579805464ed980912d06218631 100644 (file)
@@ -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)
index 63a0eefe3d74481d2c3e61d589e02b7ba0f64d02..5e92e56e054dd2808ae1c702682e513183cdc274 100644 (file)
@@ -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 e452caee2c1af52d1b3746c406da0e0308127ebe..c9f7b4f1ed538ec2001586fdda9cd1f0008fb284 100644 (file)
--- 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;