static int process_split_xxclude(struct openconnect_info *vpninfo, int include, const char *route, int *v4_incs, int *v6_incs) { struct in_addr addr; const char *in_ex = include ? "IN" : "EX"; char envname[80]; char *slash, *endp; int masklen; slash = strchr(route, '/'); if (!slash) { badinc: if (include) vpn_progress(vpninfo, PRG_ERR, _("Discard bad split include: \"%s\"\n"), route); else vpn_progress(vpninfo, PRG_ERR, _("Discard bad split exclude: \"%s\"\n"), route); return -EINVAL; } *slash = 0; if (strchr(route, ':')) { snprintf(envname, 79, "CISCO_IPV6_SPLIT_%sC_%d_ADDR", in_ex, *v6_incs); script_setenv(vpninfo, envname, route, 0); snprintf(envname, 79, "CISCO_IPV6_SPLIT_%sC_%d_MASKLEN", in_ex, *v6_incs); script_setenv(vpninfo, envname, slash+1, 0); (*v6_incs)++; return 0; } if (!inet_aton(route, &addr)) { *slash = '/'; goto badinc; } envname[79] = 0; snprintf(envname, 79, "CISCO_SPLIT_%sC_%d_ADDR", in_ex, *v4_incs); script_setenv(vpninfo, envname, route, 0); /* Put it back how we found it */ *slash = '/'; if ((masklen = strtol(slash+1, &endp, 10))<=32 && *endp!='.') { /* mask is /N */ addr.s_addr = netmaskbits(masklen); } else if (inet_aton(slash+1, &addr)) { /* mask is /A.B.C.D */ masklen = netmasklen(addr); } else { goto badinc; } snprintf(envname, 79, "CISCO_SPLIT_%sC_%d_MASK", in_ex, *v4_incs); script_setenv(vpninfo, envname, inet_ntoa(addr), 0); snprintf(envname, 79, "CISCO_SPLIT_%sC_%d_MASKLEN", in_ex, *v4_incs); script_setenv_int(vpninfo, envname, masklen); (*v4_incs)++; return 0; }
static int process_split_xxclude(struct openconnect_info *vpninfo, int include, const char *route, int *v4_incs, int *v6_incs) { struct in_addr addr; const char *in_ex = include ? "IN" : "EX"; char envname[80]; char *slash; slash = strchr(route, '/'); if (!slash) { badinc: if (include) vpn_progress(vpninfo, PRG_ERR, _("Discard bad split include: \"%s\"\n"), route); else vpn_progress(vpninfo, PRG_ERR, _("Discard bad split exclude: \"%s\"\n"), route); return -EINVAL; } *slash = 0; if (strchr(route, ':')) { snprintf(envname, 79, "CISCO_IPV6_SPLIT_%sC_%d_ADDR", in_ex, *v6_incs); setenv(envname, route, 1); snprintf(envname, 79, "CISCO_IPV6_SPLIT_%sC_%d_MASKLEN", in_ex, *v6_incs); setenv(envname, slash+1, 1); (*v6_incs)++; return 0; } if (!inet_aton(route, &addr)) { *slash = '/'; goto badinc; } envname[79] = 0; snprintf(envname, 79, "CISCO_SPLIT_%sC_%d_ADDR", in_ex, *v4_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_%sC_%d_MASK", in_ex, *v4_incs); setenv(envname, slash+1, 1); snprintf(envname, 79, "CISCO_SPLIT_%sC_%d_MASKLEN", in_ex, *v4_incs); setenv_int(envname, netmasklen(addr)); (*v4_incs)++; return 0; }
void prepare_script_env(struct openconnect_info *vpninfo) { if (vpninfo->ip_info.gateway_addr) script_setenv(vpninfo, "VPNGATEWAY", vpninfo->ip_info.gateway_addr, 0); set_banner(vpninfo); script_setenv(vpninfo, "CISCO_SPLIT_INC", NULL, 0); script_setenv(vpninfo, "CISCO_SPLIT_EXC", NULL, 0); script_setenv_int(vpninfo, "INTERNAL_IP4_MTU", vpninfo->ip_info.mtu); if (vpninfo->ip_info.addr) { script_setenv(vpninfo, "INTERNAL_IP4_ADDRESS", vpninfo->ip_info.addr, 0); if (vpninfo->ip_info.netmask) { struct in_addr addr; struct in_addr mask; if (inet_aton(vpninfo->ip_info.addr, &addr) && inet_aton(vpninfo->ip_info.netmask, &mask)) { char *netaddr; addr.s_addr &= mask.s_addr; netaddr = inet_ntoa(addr); script_setenv(vpninfo, "INTERNAL_IP4_NETADDR", netaddr, 0); script_setenv(vpninfo, "INTERNAL_IP4_NETMASK", vpninfo->ip_info.netmask, 0); script_setenv_int(vpninfo, "INTERNAL_IP4_NETMASKLEN", netmasklen(mask)); } } } if (vpninfo->ip_info.addr6) { script_setenv(vpninfo, "INTERNAL_IP6_ADDRESS", vpninfo->ip_info.addr6, 0); script_setenv(vpninfo, "INTERNAL_IP6_NETMASK", vpninfo->ip_info.netmask6, 0); } else if (vpninfo->ip_info.netmask6) { char *slash = strchr(vpninfo->ip_info.netmask6, '/'); script_setenv(vpninfo, "INTERNAL_IP6_NETMASK", vpninfo->ip_info.netmask6, 0); if (slash) { *slash = 0; script_setenv(vpninfo, "INTERNAL_IP6_ADDRESS", vpninfo->ip_info.netmask6, 0); *slash = '/'; } } if (vpninfo->ip_info.dns[0]) script_setenv(vpninfo, "INTERNAL_IP4_DNS", vpninfo->ip_info.dns[0], 0); else script_setenv(vpninfo, "INTERNAL_IP4_DNS", NULL, 0); if (vpninfo->ip_info.dns[1]) script_setenv(vpninfo, "INTERNAL_IP4_DNS", vpninfo->ip_info.dns[1], 1); if (vpninfo->ip_info.dns[2]) script_setenv(vpninfo, "INTERNAL_IP4_DNS", vpninfo->ip_info.dns[2], 1); if (vpninfo->ip_info.nbns[0]) script_setenv(vpninfo, "INTERNAL_IP4_NBNS", vpninfo->ip_info.nbns[0], 0); else script_setenv(vpninfo, "INTERNAL_IP4_NBNS", NULL, 0); if (vpninfo->ip_info.nbns[1]) script_setenv(vpninfo, "INTERNAL_IP4_NBNS", vpninfo->ip_info.nbns[1], 1); if (vpninfo->ip_info.nbns[2]) script_setenv(vpninfo, "INTERNAL_IP4_NBNS", vpninfo->ip_info.nbns[2], 1); if (vpninfo->ip_info.domain) script_setenv(vpninfo, "CISCO_DEF_DOMAIN", vpninfo->ip_info.domain, 0); else script_setenv(vpninfo, "CISCO_DEF_DOMAIN", NULL, 0); if (vpninfo->ip_info.proxy_pac) script_setenv(vpninfo, "CISCO_PROXY_PAC", vpninfo->ip_info.proxy_pac, 0); if (vpninfo->ip_info.split_dns) { char *list; int len = 0; struct oc_split_include *dns = vpninfo->ip_info.split_dns; while (dns) { len += strlen(dns->route) + 1; dns = dns->next; } list = malloc(len); if (list) { char *p = list; dns = vpninfo->ip_info.split_dns; while (1) { strcpy(p, dns->route); p += strlen(p); dns = dns->next; if (!dns) break; *(p++) = ','; } script_setenv(vpninfo, "CISCO_SPLIT_DNS", list, 0); free(list); } } if (vpninfo->ip_info.split_includes) { struct oc_split_include *this = vpninfo->ip_info.split_includes; int nr_split_includes = 0; int nr_v6_split_includes = 0; while (this) { process_split_xxclude(vpninfo, 1, this->route, &nr_split_includes, &nr_v6_split_includes); this = this->next; } if (nr_split_includes) script_setenv_int(vpninfo, "CISCO_SPLIT_INC", nr_split_includes); if (nr_v6_split_includes) script_setenv_int(vpninfo, "CISCO_IPV6_SPLIT_INC", nr_v6_split_includes); } if (vpninfo->ip_info.split_excludes) { struct oc_split_include *this = vpninfo->ip_info.split_excludes; int nr_split_excludes = 0; int nr_v6_split_excludes = 0; while (this) { process_split_xxclude(vpninfo, 0, this->route, &nr_split_excludes, &nr_v6_split_excludes); this = this->next; } if (nr_split_excludes) script_setenv_int(vpninfo, "CISCO_SPLIT_EXC", nr_split_excludes); if (nr_v6_split_excludes) script_setenv_int(vpninfo, "CISCO_IPV6_SPLIT_EXC", nr_v6_split_excludes); } setenv_cstp_opts(vpninfo); }