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;
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);
}
} 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;
}
}
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];
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)