Exemple #1
0
static int pack_mac(struct m_pedit_sel *sel, struct m_pedit_key *tkey,
		    __u8 *mac)
{
	int ret = 0;

	if (!(tkey->off & 0x3)) {
		tkey->mask = 0;
		tkey->val = ntohl(*((__u32 *)mac));
		ret |= pack_key32(~0, sel, tkey);

		tkey->off += 4;
		tkey->mask = 0;
		tkey->val = ntohs(*((__u16 *)&mac[4]));
		ret |= pack_key16(~0, sel, tkey);
	} else if (!(tkey->off & 0x1)) {
		tkey->mask = 0;
		tkey->val = ntohs(*((__u16 *)mac));
		ret |= pack_key16(~0, sel, tkey);

		tkey->off += 4;
		tkey->mask = 0;
		tkey->val = ntohl(*((__u32 *)(mac + 2)));
		ret |= pack_key32(~0, sel, tkey);
	} else {
		fprintf(stderr,
			"pack_mac: mac offsets must begin in 32bit or 16bit boundaries\n");
		return -1;
	}

	return ret;
}
Exemple #2
0
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);
	} else if (strcmp(*argv, "dst") == 0) {
		NEXT_ARG();
		res = parse_ip_addr(&argc, &argv, sel, 16);
	} else if (strcmp(*argv, "tos") == 0 ||
	    matches(*argv, "dsfield") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 1, 0);
	} else if (strcmp(*argv, "ihl") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 0, 0);
	} else if (strcmp(*argv, "protocol") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 9, 0);
	} else if (matches(*argv, "precedence") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 1, 0);
	} else if (strcmp(*argv, "nofrag") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0, 0x3FFF, 6, 0);
	} else if (strcmp(*argv, "firstfrag") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0x2000, 0x3FFF, 6, 0);
	} else if (strcmp(*argv, "df") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0x4000, 0x4000, 6, 0);
	} else if (strcmp(*argv, "mf") == 0) {
		argc--; argv++;
		res = pack_key16(sel, 0x2000, 0x2000, 6, 0);
	} else if (strcmp(*argv, "dport") == 0) {
		NEXT_ARG();
		res = parse_u16(&argc, &argv, sel, 22, 0);
	} else if (strcmp(*argv, "sport") == 0) {
		NEXT_ARG();
		res = parse_u16(&argc, &argv, sel, 20, 0);
	} else if (strcmp(*argv, "icmp_type") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 20, 0);
	} else if (strcmp(*argv, "icmp_code") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 21, 0);
	} else
		return -1;

	*argc_p = argc;
	*argv_p = argv;
	return res;
}
Exemple #3
0
static int parse_u16(int *argc_p, char ***argv_p, struct tc_u32_sel *sel,
		     int off, int offmask)
{
	int res = -1;
	int argc = *argc_p;
	char **argv = *argv_p;
	__u32 key;
	__u32 mask;

	if (argc < 2)
		return -1;

	if (get_u32(&key, *argv, 0))
		return -1;
	argc--; argv++;

	if (get_u32(&mask, *argv, 16))
		return -1;
	argc--; argv++;

	if (argc > 0 && strcmp(argv[0], "at") == 0) {
		NEXT_ARG();
		if (parse_at(&argc, &argv, &off, &offmask))
			return -1;
	}
	res = pack_key16(sel, key, mask, off, offmask);
	*argc_p = argc;
	*argv_p = argv;
	return res;
}
Exemple #4
0
int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain,
	      struct m_pedit_sel *sel, struct m_pedit_key *tkey)
{
	__u32 mask[4] = { 0 };
	__u32 val[4] = { 0 };
	__u32 *m = &mask[0];
	__u32 *v = &val[0];
	__u32 o = 0xFF;
	int res = -1;
	int argc = *argc_p;
	char **argv = *argv_p;

	if (argc <= 0)
		return -1;

	if (pedit_debug)
		printf("parse_cmd argc %d %s offset %d length %d\n",
		       argc, *argv, tkey->off, len);

	if (len == 2)
		o = 0xFFFF;
	if (len == 4)
		o = 0xFFFFFFFF;

	if (matches(*argv, "invert") == 0) {
		*v = *m = o;
	} else if (matches(*argv, "set") == 0 ||
		   matches(*argv, "add") == 0) {
		if (matches(*argv, "add") == 0)
			tkey->cmd = TCA_PEDIT_KEY_EX_CMD_ADD;

		if (!sel->extended && tkey->cmd) {
			fprintf(stderr,
				"Non extended mode. only 'set' command is supported\n");
			return -1;
		}

		NEXT_ARG();
		if (parse_val(&argc, &argv, val, type))
			return -1;
	} else if (matches(*argv, "preserve") == 0) {
		retain = 0;
	} else {
		if (matches(*argv, "clear") != 0)
			return -1;
	}

	argc--;
	argv++;

	if (argc && matches(*argv, "retain") == 0) {
		NEXT_ARG();
		if (parse_val(&argc, &argv, &retain, TU32))
			return -1;
		argc--;
		argv++;
	}

	if (len > 4 && retain != ~0) {
		fprintf(stderr,
			"retain is not supported for fields longer the 32 bits\n");
		return -1;
	}

	if (type == TMAC) {
		res = pack_mac(sel, tkey, (__u8 *)val);
		goto done;
	}

	if (type == TIPV6) {
		res = pack_ipv6(sel, tkey, val);
		goto done;
	}

	tkey->val = *v;
	tkey->mask = *m;

	if (type == TIPV4)
		tkey->val = ntohl(tkey->val);

	if (len == 1) {
		res = pack_key8(retain, sel, tkey);
		goto done;
	}
	if (len == 2) {
		res = pack_key16(retain, sel, tkey);
		goto done;
	}
	if (len == 4) {
		res = pack_key32(retain, sel, tkey);
		goto done;
	}

	return -1;
done:
	if (pedit_debug)
		printf("parse_cmd done argc %d %s offset %d length %d\n",
		       argc, *argv, tkey->off, len);
	*argc_p = argc;
	*argv_p = argv;
	return res;

}
Exemple #5
0
int
parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey)
{
	__u32 mask = 0, val = 0;
	__u32 o = 0xFF;
	int res = -1;
	int argc = *argc_p;
	char **argv = *argv_p;

	if (argc <= 0)
		return -1;

	if (pedit_debug)
		printf("parse_cmd argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len);

	if (len == 2)
		o = 0xFFFF;
	if (len == 4)
		o = 0xFFFFFFFF;

	if (matches(*argv, "invert") == 0) {
		retain = val = mask = o;
	} else if (matches(*argv, "set") == 0) {
		NEXT_ARG();
		if (parse_val(&argc, &argv, &val, type))
			return -1;
	} else if (matches(*argv, "preserve") == 0) {
		retain = mask = o;
	} else {
		if (matches(*argv, "clear") != 0)
			return -1;
	}

	argc--; argv++;

	if (argc && matches(*argv, "retain") == 0) {
		NEXT_ARG();
		if (parse_val(&argc, &argv, &retain, TU32))
			return -1;
		argc--; argv++;
	}

	tkey->val = val;

	if (len == 1) {
		tkey->mask = 0xFF;
		res = pack_key8(retain,sel,tkey);
		goto done;
	}
	if (len == 2) {
		tkey->mask = mask;
		res = pack_key16(retain,sel,tkey);
		goto done;
	}
	if (len == 4) {
		tkey->mask = mask;
		res = pack_key32(retain,sel,tkey);
		goto done;
	}

	return -1;
done:
	if (pedit_debug)
		printf("parse_cmd done argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len);
	*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;
}