17e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger/*
2ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger * m_pedit.c		packet editor: IPV4/6 header
37e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger *
47e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger *		This program is free software; you can distribute it and/or
57e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger *		modify it under the terms of the GNU General Public License
67e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger *		as published by the Free Software Foundation; either version
77e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger *		2 of the License, or (at your option) any later version.
87e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger *
9ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger * Authors:  J Hadi Salim (hadi@cyberus.ca)
10ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *
117e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger */
127e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger
137e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include <stdio.h>
147e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include <stdlib.h>
157e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include <unistd.h>
167e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include <syslog.h>
177e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include <fcntl.h>
187e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include <sys/socket.h>
197e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include <netinet/in.h>
207e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include <arpa/inet.h>
217e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include <string.h>
227e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include "utils.h"
237e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include "tc_util.h"
247e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger#include "m_pedit.h"
257e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger
267e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemmingerstatic int
277e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemmingerparse_ip(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey)
287e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger{
297e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	int res = -1;
307e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	int argc = *argc_p;
317e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	char **argv = *argv_p;
327e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger
337e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (argc < 2)
347e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		return -1;
357e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger
367e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "src") == 0) {
377e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
387e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 12;
397e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 4, TIPV4,RU32,sel,tkey);
407e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
417e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
427e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "dst") == 0) {
437e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
447e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 16;
457e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 4, TIPV4,RU32,sel,tkey);
467e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
477e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
487e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	/* jamal - look at these and make them either old or new
497e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	** scheme given diffserv
507e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	** dont forget the CE bit
517e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	*/
527e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "tos") == 0 || matches(*argv, "dsfield") == 0) {
537e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
547e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 1;
557e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv,  1, TU32,RU8,sel,tkey);
567e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
577e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
587e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "ihl") == 0) {
597e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
607e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 0;
617e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 1, TU32,RU8,sel,tkey);
627e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
637e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
647e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "protocol") == 0) {
657e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
667e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 9;
677e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 1, TU32,RU8,sel,tkey);
687e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
697e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
707e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	/* jamal - fix this */
717e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (matches(*argv, "precedence") == 0) {
727e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
737e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 1;
747e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 1, TU32,RU8,sel,tkey);
757e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
767e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
777e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	/* jamal - validate this at some point */
787e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "nofrag") == 0) {
797e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
807e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 6;
817e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 1, TU32,0x3F,sel,tkey);
827e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
837e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
847e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	/* jamal - validate this at some point */
857e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "firstfrag") == 0) {
867e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
877e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 6;
887e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 1, TU32,0x1F,sel,tkey);
897e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
907e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
917e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "ce") == 0) {
927e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
937e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 6;
947e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 1, TU32,0x80,sel,tkey);
957e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
967e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
977e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "df") == 0) {
987e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
997e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 6;
1007e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 1, TU32,0x40,sel,tkey);
1017e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
1027e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
1037e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "mf") == 0) {
1047e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
1057e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 6;
1067e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 1, TU32,0x20,sel,tkey);
1077e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
1087e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
1097e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "dport") == 0) {
1107e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
1117e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 22;
1127e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 2, TU32,RU16,sel,tkey);
1137e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
1147e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
1157e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "sport") == 0) {
1167e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
1177e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 20;
1187e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 2, TU32,RU16,sel,tkey);
1197e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
1207e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
1217e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "icmp_type") == 0) {
1227e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
1237e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 20;
1247e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 1, TU32,RU8,sel,tkey);
1257e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
1267e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
1277e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	if (strcmp(*argv, "icmp_code") == 0) {
1287e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		NEXT_ARG();
1297e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		tkey->off = 20;
1307e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		res = parse_cmd(&argc, &argv, 1, TU32,RU8,sel,tkey);
1317e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger		goto done;
1327e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	}
1337e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	return -1;
1347e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger
1357e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger      done:
1367e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	*argc_p = argc;
1377e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	*argv_p = argv;
1387e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	return res;
1397e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger}
1407e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger
1417e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemmingerstatic int
1427e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemmingerparse_ip6(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey)
1437e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger{
1447e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	int res = -1;
1457e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	return res;
1467e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger}
1477e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger
1487e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemmingerstruct m_pedit_util p_pedit_ip = {
1497e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	NULL,
1507e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	"ip",
1517e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	parse_ip,
1527e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger};
1537e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger
1547e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger
1557e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemmingerstruct m_pedit_util p_pedit_ip6 = {
1567e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	NULL,
1577e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	"ip6",
1587e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger	parse_ip6,
1597e7c737245a48cac0c9386b4cab6c35622fde629net[shemminger]!shemminger};
160