Handle split-includes
authorDavid Woodhouse <David.Woodhouse@intel.com>
Fri, 24 Oct 2008 10:49:45 +0000 (11:49 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Fri, 24 Oct 2008 10:49:45 +0000 (11:49 +0100)
cstp.c
openconnect.h
tun.c

diff --git a/cstp.c b/cstp.c
index 4a190b7..5e3c3be 100644 (file)
--- a/cstp.c
+++ b/cstp.c
@@ -71,6 +71,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
        struct vpn_option *old_dtls_opts = vpninfo->dtls_options;
        const char *old_addr = vpninfo->vpn_addr;
        const char *old_netmask = vpninfo->vpn_netmask;
+       struct split_include *inc;
 
        /* Clear old options which will be overwritten */
        vpninfo->vpn_addr = vpninfo->vpn_netmask = NULL;
@@ -78,6 +79,11 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
        for (i=0; i<3; i++)
                vpninfo->vpn_dns[i] = vpninfo->vpn_nbns[i] = NULL;
 
+       for (inc = vpninfo->split_includes; inc; inc = inc->next) {
+               struct split_include *next = inc->next;
+               free(inc);
+               inc = next;
+       }
  retry:
        openconnect_SSL_printf(vpninfo->https_ssl, "CONNECT /CSCOSSLC/tunnel HTTP/1.1\r\n");
        openconnect_SSL_printf(vpninfo->https_ssl, "Host: %s\r\n", vpninfo->hostname);
@@ -207,6 +213,13 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
                        }
                } else if (!strcmp(buf + 7, "Default-Domain")) {
                        vpninfo->vpn_domain = new_option->value;
+               } else if (!strcmp(buf + 7, "Split-Include")) {
+                       struct split_include *inc = malloc(sizeof(*inc));
+                       if (!inc)
+                               continue;
+                       inc->route = new_option->value;
+                       inc->next = vpninfo->split_includes;
+                       vpninfo->split_includes = inc;
                }
        }
 
index 4d85ffd..1a252e2 100644 (file)
@@ -63,6 +63,11 @@ struct keepalive_info {
        time_t last_dpd;
 };
 
+struct split_include {
+       char *route;
+       struct split_include *next;
+};
+
 struct openconnect_info {
        char *redirect_url;
        
@@ -115,6 +120,7 @@ struct openconnect_info {
        const char *vpn_dns[3];
        const char *vpn_nbns[3];
        const char *vpn_domain;
+       struct split_include *split_includes;
 
        int select_nfds;
        fd_set select_rfds;
diff --git a/tun.c b/tun.c
index f2c63a5..83ba6a0 100644 (file)
--- a/tun.c
+++ b/tun.c
@@ -83,6 +83,55 @@ static int setenv_int(const char *opt, int value)
        return setenv(opt, buf, 1);
 }
 
+static int process_split_include(struct openconnect_info *vpninfo,
+                                char *route, int *nr_incs)
+{
+       struct in_addr addr;
+       int masklen;
+       char envname[80];
+       char *slash;
+
+       slash = strchr(route, '/');
+       if (!slash) {
+       badinc:
+               vpninfo->progress(vpninfo, PRG_ERR,
+                                 "Discard bad split include: \"%s\"\n",
+                                 route);
+               return -EINVAL;
+       }
+
+       *slash = 0;
+       if (!inet_aton(route, &addr)) {
+               *slash = '/';
+               goto badinc;
+       }
+
+       envname[79] = 0;
+       snprintf(envname, 79, "CISCO_SPLIT_INC_%d_ADDR", *nr_incs);
+       setenv(envname, route, 1);
+
+       /* Put it back how we found it */
+       *slash = '/';
+
+       if (!inet_aton(slash+1, &addr))
+               goto badinc;
+
+       snprintf(envname, 79, "CISCO_SPLIT_INC_%d_MASK", *nr_incs);
+       setenv(envname, slash+1, 1);
+
+       for (masklen = 0; masklen < 32; masklen++) {
+               if (ntohl(addr.s_addr) >= (0xffffffff << masklen))
+                       break;
+       }
+       masklen = 32 - masklen;
+                   
+       snprintf(envname, 79, "CISCO_SPLIT_INC_%d_MASKLEN", *nr_incs);
+       setenv_int(envname, masklen);
+
+       (*nr_incs)++;
+       return 0;
+}
+
 static int appendenv(const char *opt, const char *new)
 {
        char buf[1024];
@@ -133,6 +182,20 @@ static void set_script_env(struct openconnect_info *vpninfo)
        if (vpninfo->vpn_domain)
                setenv("CISCO_DEF_DOMAIN", vpninfo->vpn_domain, 1);
        else unsetenv ("CISCO_DEF_DOMAIN");
+
+       if (vpninfo->split_includes) {
+               struct split_include *this = vpninfo->split_includes;
+               int nr_split_includes = 0;
+
+               while (this) {
+                       process_split_include(vpninfo, this->route,
+                                             &nr_split_includes);
+                       this = this->next;
+               }
+               setenv_int("CISCO_SPLIT_INC", nr_split_includes);
+       }                       
+                       
+                       
 }
 
 static int script_config_tun(struct openconnect_info *vpninfo)