int include, const char *route, int *v4_incs,
                                 int *v6_incs)
 {
-       struct in_addr addr;
+       struct in_addr net_addr, mask_addr;
        const char *in_ex = include ? "IN" : "EX";
-       char envname[80];
+       char envname[80], uptoslash[20];
        const char *slash;
        char *endp;
        int masklen;
 
        slash = strchr(route, '/');
-       envname[79] = 0;
+       envname[79] = uptoslash[19] = 0;
 
        if (strchr(route, ':')) {
                snprintf(envname, 79, "CISCO_IPV6_SPLIT_%sC_%d_ADDR", in_ex,
                return 0;
        }
 
+       if (!slash)
+               strncpy(uptoslash, route, sizeof(uptoslash)-1);
+       else {
+               int l = MIN(slash - route, sizeof(uptoslash)-1);
+               strncpy(uptoslash, route, l);
+               uptoslash[l] = 0;
+       }
+
+       /* Network address must be parseable */
+       if (!inet_aton(uptoslash, &net_addr)) {
+       bad:
+               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;
+       }
+
+       /* Accept netmask in several forms */
        if (!slash) {
                /* no mask (same as /32) */
                masklen = 32;
-               addr.s_addr = netmaskbits(32);
+               mask_addr.s_addr = netmaskbits(32);
        } else 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_addr.s_addr = netmaskbits(masklen);
+       } else if (inet_aton(slash+1, &mask_addr)) {
                /* mask is /A.B.C.D */
-               masklen = netmasklen(addr);
-       } else {
+               masklen = netmasklen(mask_addr);
+               /* something invalid like /255.0.0.1 */
+               if (netmaskbits(masklen) != mask_addr.s_addr)
+                       goto bad;
+       } else
+               goto bad;
+
+       /* Fix incorrectly-set host bits */
+       if (net_addr.s_addr & ~mask_addr.s_addr) {
+               net_addr.s_addr &= mask_addr.s_addr;
                if (include)
                        vpn_progress(vpninfo, PRG_ERR,
-                                        _("Discard bad split include: \"%s\"\n"),
-                                        route);
+                                    _("WARNING: Split include \"%s\" has host bits set, replacing with \"%s/%d\".\n"),
+                                    route, inet_ntoa(net_addr), masklen);
                else
                        vpn_progress(vpninfo, PRG_ERR,
-                                        _("Discard bad split exclude: \"%s\"\n"),
-                                        route);
-               return -EINVAL;
+                                    _("WARNING: Split exclude \"%s\" has host bits set, replacing with \"%s/%d\".\n"),
+                                    route, inet_ntoa(net_addr), masklen);
        }
 
        snprintf(envname, 79, "CISCO_SPLIT_%sC_%d_ADDR", in_ex, *v4_incs);
-       script_setenv(vpninfo, envname, route, slash ? slash - route : 0, 0);
+       script_setenv(vpninfo, envname, inet_ntoa(net_addr), 0, 0);
 
        snprintf(envname, 79, "CISCO_SPLIT_%sC_%d_MASK", in_ex, *v4_incs);
-       script_setenv(vpninfo, envname, inet_ntoa(addr), 0, 0);
+       script_setenv(vpninfo, envname, inet_ntoa(mask_addr), 0, 0);
 
        snprintf(envname, 79, "CISCO_SPLIT_%sC_%d_MASKLEN", in_ex, *v4_incs);
        script_setenv_int(vpninfo, envname, masklen);
                        struct in_addr addr;
                        struct in_addr mask;
 
-                       if (inet_aton(vpninfo->ip_info.addr, &addr) &&
-                           inet_aton(vpninfo->ip_info.netmask, &mask)) {
+                       if (!inet_aton(vpninfo->ip_info.addr, &addr))
+                               vpn_progress(vpninfo, PRG_ERR,
+                                            _("Ignoring legacy network because address \"%s\" is invalid.\n"),
+                                            vpninfo->ip_info.netmask);
+                       else if (!inet_aton(vpninfo->ip_info.netmask, &mask))
+                       bad_netmask:
+                               vpn_progress(vpninfo, PRG_ERR,
+                                            _("Ignoring legacy network because netmask \"%s\" is invalid.\n"),
+                                            vpninfo->ip_info.netmask);
+                       else {
                                char *netaddr;
+                               int masklen = netmasklen(mask);
 
+                               if (netmaskbits(masklen) != mask.s_addr)
+                                       goto bad_netmask;
                                addr.s_addr &= mask.s_addr;
                                netaddr = inet_ntoa(addr);
 
                                script_setenv(vpninfo, "INTERNAL_IP4_NETADDR", netaddr, 0, 0);
                                script_setenv(vpninfo, "INTERNAL_IP4_NETMASK", vpninfo->ip_info.netmask, 0, 0);
-                               script_setenv_int(vpninfo, "INTERNAL_IP4_NETMASKLEN", netmasklen(mask));
+                               script_setenv_int(vpninfo, "INTERNAL_IP4_NETMASKLEN", masklen);
                        }
                }
        }