Exemple #1
0
static int parse_selector(int *argc_p, char ***argv_p,
			  struct tc_u32_sel *sel, struct nlmsghdr *n)
{
	int argc = *argc_p;
	char **argv = *argv_p;
	int res = -1;

	if (argc <= 0)
		return -1;

	if (matches(*argv, "u32") == 0) {
		NEXT_ARG();
		res = parse_u32(&argc, &argv, sel, 0, 0);
	} else if (matches(*argv, "u16") == 0) {
		NEXT_ARG();
		res = parse_u16(&argc, &argv, sel, 0, 0);
	} else if (matches(*argv, "u8") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 0, 0);
	} else if (matches(*argv, "ip") == 0) {
		NEXT_ARG();
		res = parse_ip(&argc, &argv, sel);
	} else 	if (matches(*argv, "ip6") == 0) {
		NEXT_ARG();
		res = parse_ip6(&argc, &argv, sel);
	} else if (matches(*argv, "udp") == 0) {
		NEXT_ARG();
		res = parse_udp(&argc, &argv, sel);
	} else if (matches(*argv, "tcp") == 0) {
		NEXT_ARG();
		res = parse_tcp(&argc, &argv, sel);
	} else if (matches(*argv, "icmp") == 0) {
		NEXT_ARG();
		res = parse_icmp(&argc, &argv, sel);
	} else if (matches(*argv, "mark") == 0) {
		NEXT_ARG();
		res = parse_mark(&argc, &argv, n);
	} else if (matches(*argv, "ether") == 0) {
		NEXT_ARG();
		res = parse_ether(&argc, &argv, sel);
	} else 
		return -1;

	*argc_p = argc;
	*argv_p = argv;
	return res;
}
static int parse_ip6(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
{
	int res = -1;
	int argc = *argc_p;
	char **argv = *argv_p;

	if (argc < 2)
		return -1;

	if (strcmp(*argv, "src") == 0) {
		NEXT_ARG();
		res = parse_ip6_addr(&argc, &argv, sel, 8);
		goto done;
	}
	if (strcmp(*argv, "dst") == 0) {
		NEXT_ARG();
		res = parse_ip6_addr(&argc, &argv, sel, 24);
		goto done;
	}
	if (strcmp(*argv, "priority") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 0, 0);
		goto done;
	}
	if (strcmp(*argv, "protocol") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 6, 0);
		goto done;
	}
	if (strcmp(*argv, "flowlabel") == 0) {
		NEXT_ARG();
		res = parse_u32(&argc, &argv, sel, 0, 0);
		goto done;
	}
	if (strcmp(*argv, "dport") == 0) {
		NEXT_ARG();
		res = parse_u16(&argc, &argv, sel, 42, 0);
		goto done;
	}
	if (strcmp(*argv, "sport") == 0) {
		NEXT_ARG();
		res = parse_u16(&argc, &argv, sel, 40, 0);
		goto done;
	}
	if (strcmp(*argv, "icmp_type") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 40, 0);
		goto done;
	}
	if (strcmp(*argv, "icmp_code") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 41, 1);
		goto done;
	}
	return -1;

done:
	*argc_p = argc;
	*argv_p = argv;
	return res;
}
static int parse_ip(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
{
	int res = -1;
	int argc = *argc_p;
	char **argv = *argv_p;

	if (argc < 2)
		return -1;

	if (strcmp(*argv, "src") == 0) {
		NEXT_ARG();
		res = parse_ip_addr(&argc, &argv, sel, 12);
		goto done;
	}
	if (strcmp(*argv, "dst") == 0) {
		NEXT_ARG();
		res = parse_ip_addr(&argc, &argv, sel, 16);
		goto done;
	}
	if (strcmp(*argv, "tos") == 0 ||
	    matches(*argv, "dsfield") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 1, 0);
		goto done;
	}
    if (strcmp(*argv, "mport") == 0)
    {
    	NEXT_ARG();
        res = parse_u8(&argc, &argv, sel, 10, 0);   
        goto done;
    }
	if (strcmp(*argv, "ihl") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 0, 0);
		goto done;
	}
	if (strcmp(*argv, "protocol") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 9, 0);
		goto done;
	}
	if (matches(*argv, "precedence") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 1, 0);
		goto done;
	}
	if (strcmp(*argv, "nofrag") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0, 0x3FFF, 6, 0);
		goto done;
	}
	if (strcmp(*argv, "firstfrag") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0, 0x1FFF, 6, 0);
		goto done;
	}
	if (strcmp(*argv, "df") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0x4000, 0x4000, 6, 0);
		goto done;
	}
	if (strcmp(*argv, "mf") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0x2000, 0x2000, 6, 0);
		goto done;
	}
	if (strcmp(*argv, "dport") == 0) {
		NEXT_ARG();
		//res = parse_u16(&argc, &argv, sel, 22, 0);
		res = parse_port(&argc, &argv, sel, 22, 0);
		goto done;
	}
	if (strcmp(*argv, "sport") == 0) {
		NEXT_ARG();
		//res = parse_u16(&argc, &argv, sel, 20, 0);
		res = parse_port(&argc, &argv, sel, 20, 0);
		goto done;
	}
	if (strcmp(*argv, "icmp_type") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 20, 0);
		goto done;
	}
	if (strcmp(*argv, "icmp_code") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 20, 1);
		goto done;
	}
	return -1;

done:
	*argc_p = argc;
	*argv_p = argv;
	return res;
}
static int parse_ip(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
{
	int res = -1;
	int argc = *argc_p;
	char **argv = *argv_p;

	if (argc < 2)
		return -1;

	if (strcmp(*argv, "src") == 0) {
		NEXT_ARG();
		res = parse_ip_addr(&argc, &argv, sel, 12);
		goto done;
	}
	if (strcmp(*argv, "dst") == 0) {
		NEXT_ARG();
		res = parse_ip_addr(&argc, &argv, sel, 16);
		goto done;
	}
	//------------->richie: add to parse ip range
	if (strcmp(*argv, "ssrc") == 0) {
		//fprintf(stderr, "enter ssrc\n");
		NEXT_ARG();
		res = nk_parse_ip_addr(&argc, &argv, sel, 12, TC_SSRC_IP);
		goto done;
	}
	if (strcmp(*argv, "esrc") == 0) {
		//fprintf(stderr, "enter esrc\n");
		NEXT_ARG();
		res = nk_parse_ip_addr(&argc, &argv, sel, 12, TC_ESRC_IP);
		goto done;
	}
	if (strcmp(*argv, "sdst") == 0) {
		//fprintf(stderr, "enter sdst\n");
		NEXT_ARG();
		res = nk_parse_ip_addr(&argc, &argv, sel, 16, TC_SDST_IP);
		goto done;
	}
	if (strcmp(*argv, "edst") == 0) {
		//fprintf(stderr, "enter edst\n");
		NEXT_ARG();
		res = nk_parse_ip_addr(&argc, &argv, sel, 16, TC_EDST_IP);
		goto done;
	}
	//<--------------------
	if (strcmp(*argv, "tos") == 0 ||
	    matches(*argv, "dsfield") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 1, 0);
		goto done;
	}
	if (strcmp(*argv, "ihl") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 0, 0);
		goto done;
	}
	if (strcmp(*argv, "protocol") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 9, 0);
		goto done;
	}
	if (matches(*argv, "precedence") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 1, 0);
		goto done;
	}
	if (strcmp(*argv, "nofrag") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0, 0x3FFF, 6, 0);
		goto done;
	}
	if (strcmp(*argv, "firstfrag") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0, 0x1FFF, 6, 0);
		goto done;
	}
	if (strcmp(*argv, "df") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0x4000, 0x4000, 6, 0);
		goto done;
	}
	if (strcmp(*argv, "mf") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0x2000, 0x2000, 6, 0);
		goto done;
	}
	if (strcmp(*argv, "dport") == 0) {
		NEXT_ARG();
		res = parse_u16(&argc, &argv, sel, 22, 0);
		goto done;
	}
	if (strcmp(*argv, "sport") == 0) {
		NEXT_ARG();
		res = parse_u16(&argc, &argv, sel, 20, 0);
		goto done;
	}
	// 2004/05/12 Ryan : added to support QoS for port range setting
	// -->
	if (strcmp(*argv, "ssport") == 0) {
		NEXT_ARG();
		//printf("enter ssport\n");
//fprintf(stderr, "enter ssport!!!!!!!!!!!\n");

		res = nk_parse_u16(&argc, &argv, sel, 20, 0 , TC_SSRC_PORT);
		goto done;
	}
	if (strcmp(*argv, "esport") == 0) {
		NEXT_ARG();
		//printf("enter esport\n");
//fprintf(stderr, "enter esport!!!!!!!!!!!\n");
		res = nk_parse_u16(&argc, &argv, sel, 20, 0 , TC_ESRC_PORT);
		goto done;
	}
	if (strcmp(*argv, "sdport") == 0) {
		NEXT_ARG();
		//printf("enter sdport\n");
//fprintf(stderr, "enter sdport!!!!!!!!!!!\n");
		res = nk_parse_u16(&argc, &argv, sel, 22, 0 , TC_SDST_PORT);
		goto done;
	}
	if (strcmp(*argv, "edport") == 0) {
		NEXT_ARG();
		//printf("enter edport\n");
//fprintf(stderr, "enter edport!!!!!!!!!!!\n");
		res = nk_parse_u16(&argc, &argv, sel, 22, 0 , TC_EDST_PORT);
		goto done;
	}
	// <--

	//2004/09/29 richie: add to support inbound QoS by interface
	if (strcmp(*argv, "wanif") == 0) {
		NEXT_ARG();
		//printf("enter wanif!!!!!!!!!!!!!!!!!!!!!!!!!!11");
		res = nk_parse_u16(&argc, &argv, sel, 100, 0 , TC_WANIF);
		goto done;
	}
	//
	//2004/09/29 richie: add to support inbound QoS by ALG type
	if (strcmp(*argv, "ap_type") == 0) {
		NEXT_ARG();
		//printf("enter ap_type!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
		res = nk_parse_u16(&argc, &argv, sel, 120, 0 , TC_AP_TYPE);
		goto done;
	}
	//

	if (strcmp(*argv, "icmp_type") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 20, 0);
		goto done;
	}
	if (strcmp(*argv, "icmp_code") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 20, 1);
		goto done;
	}
	return -1;

done:
	*argc_p = argc;
	*argv_p = argv;
	return res;
}