Ejemplo n.º 1
0
static int geo_parse_cidr(geo_t *g, char *cidr, char *value) {
    struct in_addr  in;
    int             i;
    uint32_t        addr;
    uint32_t        mask;
    uint32_t        ip_addr;
    uint32_t        old;

    if (strcmp(cidr, "default") == 0) {
        if (inet_aton(value, &in) == 0) {
            return -1;
        }
        ip_addr = ntohl(in.s_addr);
        addr = 0;
        mask = 0;
    } else if (strcmp(cidr, "delete") == 0) {
        if (parse_cidr(value, &addr, &mask) != 0) {
            return -1;
        }
        if (radix32tree_delete(g->u.tree, addr, mask) != 0) {
            return -1;
        }
        return 0;
    } 
 
    if (parse_cidr(cidr, &addr, &mask) != 0) {
        return -1;
    }

    if (inet_aton(value, &in) == 0) {
        return -1;
    }
    ip_addr = ntohl(in.s_addr);

    /* Retry 3 times */
    for (i = 3; i; --i) {
        if (radix32tree_insert(g->u.tree, addr, mask, ip_addr) == 0) {
            return 0;
        }

        old = radix32tree_find(g->u.tree, addr & mask);
        /* TODO log */
        if (radix32tree_delete(g->u.tree, addr, mask) != 0) {
            return -1;
        }
    }

    return -1;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
	struct netent *netent;
	ipaddr_t gateway, destination, netmask, defaultmask=0;
	u8_t high_byte;
	nwio_route_t route;
	int ip_fd, itab;
	int r;
	int metric;
	char *check;
	char *ip_device;
	char *netmask_str, *metric_str, *destination_str, *gateway_str;
	int c;
	char *d_arg, *g_arg, *m_arg, *n_arg, *I_arg;
	int i_flag, o_flag, D_flag, v_flag;
	int cidr;

	prog_name= strrchr(argv[0], '/');
	if (prog_name == NULL) prog_name= argv[0]; else prog_name++;

	if (strcmp(prog_name, "add_route") == 0)
		action= ADD;
	else if (strcmp(prog_name, "del_route") == 0)
		action= DEL;
	else
	{
		fprintf(stderr, "Don't know what to do when named '%s'\n",
			prog_name);
		exit(1);
	}

	i_flag= 0;
	o_flag= 0;
	D_flag= 0;
	v_flag= 0;
	g_arg= NULL;
	d_arg= NULL;
	m_arg= NULL;
	n_arg= NULL;
	I_arg= NULL;
	while ((c= getopt(argc, argv, "iovDg:d:m:n:I:?")) != -1)
	{
		switch(c)
		{
		case 'i':
			if (i_flag)
				usage();
			i_flag= 1;
			break;
		case 'o':
			if (o_flag)
				usage();
			o_flag= 1;
			break;
		case 'v':
			if (v_flag)
				usage();
			v_flag= 1;
			break;
		case 'D':
			if (D_flag)
				usage();
			D_flag= 1;
			break;
		case 'g':
			if (g_arg)
				usage();
			g_arg= optarg;
			break;
		case 'd':
			if (d_arg)
				usage();
			d_arg= optarg;
			break;
		case 'm':
			if (m_arg)
				usage();
			m_arg= optarg;
			break;
		case 'n':
			if (n_arg)
				usage();
			n_arg= optarg;
			break;
		case 'I':
			if (I_arg)
				usage();
			I_arg= optarg;
			break;
		case '?':
			usage();
		default:
			fprintf(stderr, "%s: getopt failed\n", prog_name);
			exit(1);
		}
	}
	if (optind != argc)
		usage();
	if (i_flag && o_flag)
		usage();
	itab= i_flag;

	if (i_flag)
	{
		if (g_arg == NULL || d_arg == NULL || m_arg == NULL)
			usage();
	}
	else
	{
		if (g_arg == NULL || (d_arg == NULL && n_arg != NULL))
		{
			usage();
		}
	}
		
	gateway_str= g_arg;
	destination_str= d_arg;
	metric_str= m_arg;
	netmask_str= n_arg;
	ip_device= I_arg;

	if (!name_to_ip(gateway_str, &gateway))
	{
		fprintf(stderr, "%s: unknown host '%s'\n", prog_name,
								gateway_str);
		exit(1);
	}

	destination= 0;
	netmask= 0;
	cidr= 0;

	if (destination_str)
	{
		if (parse_cidr(destination_str, &destination, &netmask))
			cidr= 1;
		else if (inet_aton(destination_str, &destination))
			;
		else if ((netent= getnetbyname(destination_str)) != NULL)
			destination= netent->n_net;
		else if (!name_to_ip(destination_str, &destination))
		{
			fprintf(stderr, "%s: unknown network/host '%s'\n",
				prog_name, destination_str);
			exit(1);
		}
		high_byte= *(u8_t *)&destination;
		if (!(high_byte & 0x80))	/* class A or 0 */
		{
			if (destination)
				defaultmask= HTONL(0xff000000);
		}
		else if (!(high_byte & 0x40))	/* class B */
		{
			defaultmask= HTONL(0xffff0000);
		}
		else if (!(high_byte & 0x20))	/* class C */
		{
			defaultmask= HTONL(0xffffff00);
		}
		else				/* class D is multicast ... */
		{
			fprintf(stderr, "%s: Warning: Martian address '%s'\n",
				prog_name, inet_ntoa(destination));
			defaultmask= HTONL(0xffffffff);
		}
		if (destination & ~defaultmask)
		{
			/* host route */
			defaultmask= HTONL(0xffffffff);
		}
		if (!cidr)
			netmask= defaultmask;
	}

	if (netmask_str)
	{
		if (cidr)
			usage();
		if (inet_aton(netmask_str, &netmask) == 0)
		{
			fprintf(stderr, "%s: illegal netmask'%s'\n", prog_name,
				netmask_str);
			exit(1);
		}
	}

	if (metric_str)
	{
		metric= strtol(metric_str, &check, 0);
		if (check[0] != '\0' || metric < 1)
		{
			fprintf(stderr, "%s: illegal metric %s\n",
				prog_name, metric_str);
		}
	}
	else
		metric= 1;
		
	if (!ip_device)
		ip_device= getenv("IP_DEVICE");
	if (!ip_device)
		ip_device= IP_DEVICE;

	ip_fd= open(ip_device, O_RDWR);
	if (ip_fd == -1)
	{
		fprintf(stderr, "%s: unable to open('%s'): %s\n",
			prog_name, ip_device, strerror(errno));
		exit(1);
	}

	if (v_flag)
	{
		printf("%s %s route to %s ",
			action == ADD ? "adding" : "deleting",
			itab ? "input" : "output",
			inet_ntoa(destination));
		printf("with netmask %s ", inet_ntoa(netmask));
		printf("using gateway %s", inet_ntoa(gateway));
		if (itab && action == ADD)
			printf(" at distance %d", metric);
		printf("\n");
	}

	route.nwr_ent_no= 0;
	route.nwr_dest= destination;
	route.nwr_netmask= netmask;
	route.nwr_gateway= gateway;
	route.nwr_dist= action == ADD ? metric : 0;
	route.nwr_flags= (action == DEL && D_flag) ? 0 : NWRF_STATIC;
	route.nwr_pref= 0;
	route.nwr_mtu= 0;

	if (action == ADD)
		r= ioctl(ip_fd, itab ? NWIOSIPIROUTE : NWIOSIPOROUTE, &route);
	else
		r= ioctl(ip_fd, itab ? NWIODIPIROUTE : NWIODIPOROUTE, &route);
	if (r == -1)
	{
		fprintf(stderr, "%s: NWIO%cIP%cROUTE: %s\n",
			prog_name,
			action == ADD ? 'S' : 'D',
			itab ? 'I' : 'O',
			strerror(errno));
		exit(1);
	}
	return(0);
}
Ejemplo n.º 3
0
/**
 * returns the include_exclude_mode on success placing the CIDR or LIST in mybuf
 * but on failure, returns xXError
 */
int
parse_xX_str(tcpr_xX_t *xX, char *str, tcpr_bpf_t *bpf)
{
    int out = 0;

    dbgx(1, "Parsing string: %s", str);
    dbgx(1, "Switching on: %c", str[0]);

    switch (str[0]) {
    case 'B':                  /* both ip's */
        str = str + 2;
        out = xXBoth;
        if (!parse_cidr(&(xX->cidr), str, ","))
            return xXError;
        break;

    case 'D':                  /* dst ip */
        str = str + 2;
        out = xXDest;
        if (!parse_cidr(&(xX->cidr), str, ","))
            return xXError;
        break;

    case 'E':                  /* either ip */
        str = str + 2;
        out = xXEither;
        if (!parse_cidr(&(xX->cidr), str, ","))
            return xXError;
        break;
        
    case 'F':                  /* bpf filter */
        str = str + 2;
        out = xXBPF;
        bpf->filter = safe_strdup(str);
        /* 
         * note: it's temping to compile the BPF here, but we don't
         * yet know what the link type is for the file, so we have 
         * to compile the BPF once we open the pcap file
         */
        break;
        
    case 'P':                  /* packet id */
        str = str + 2;
        out = xXPacket;
        if (!parse_list(&(xX->list), str))
            return xXError;
        break;

    case 'S':                  /* source ip */
        str = str + 2;
        out = xXSource;
        if (!parse_cidr(&(xX->cidr), str, ","))
            return xXError;
        break;

    default:
        errx(-1, "Invalid -%c option: %c", xX->mode, *str);
        break;
    }

    if (xX->mode == 'X') {          /* run in exclude mode */
        out += xXExclude;
        if (bpf->filter != NULL)
            err(-1, "Using a BPF filter with -X doesn't work.\n"
                "Try using -xF:\"not <filter>\" instead");
    }

    xX->mode = out;
    return xX->mode;
}