blob: 535151e5d76682f3e5ac3b892d331eee9f2d2c6a [file] [log] [blame]
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +00001/*
Stephen Hemmingerae665a52006-12-05 10:10:22 -08002 * m_pedit.c packet editor: IPV4/6 header
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +00003 *
4 * This program is free software; you can distribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
Stephen Hemmingerae665a52006-12-05 10:10:22 -08009 * Authors: J Hadi Salim (hadi@cyberus.ca)
10 *
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +000011 */
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <unistd.h>
16#include <syslog.h>
17#include <fcntl.h>
18#include <sys/socket.h>
19#include <netinet/in.h>
20#include <arpa/inet.h>
21#include <string.h>
22#include "utils.h"
23#include "tc_util.h"
24#include "m_pedit.h"
25
26static int
Phil Sutter952f89d2016-03-22 15:16:21 +010027parse_ip(int *argc_p, char ***argv_p,
28 struct tc_pedit_sel *sel, struct tc_pedit_key *tkey)
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +000029{
30 int res = -1;
31 int argc = *argc_p;
32 char **argv = *argv_p;
33
34 if (argc < 2)
35 return -1;
36
37 if (strcmp(*argv, "src") == 0) {
38 NEXT_ARG();
39 tkey->off = 12;
Stephen Hemminger32a121c2016-03-21 11:48:36 -070040 res = parse_cmd(&argc, &argv, 4, TIPV4, RU32, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +000041 goto done;
42 }
43 if (strcmp(*argv, "dst") == 0) {
44 NEXT_ARG();
45 tkey->off = 16;
Stephen Hemminger32a121c2016-03-21 11:48:36 -070046 res = parse_cmd(&argc, &argv, 4, TIPV4, RU32, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +000047 goto done;
48 }
49 /* jamal - look at these and make them either old or new
50 ** scheme given diffserv
51 ** dont forget the CE bit
52 */
53 if (strcmp(*argv, "tos") == 0 || matches(*argv, "dsfield") == 0) {
54 NEXT_ARG();
55 tkey->off = 1;
Phil Sutter952f89d2016-03-22 15:16:21 +010056 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +000057 goto done;
58 }
59 if (strcmp(*argv, "ihl") == 0) {
60 NEXT_ARG();
61 tkey->off = 0;
Stephen Hemminger32a121c2016-03-21 11:48:36 -070062 res = parse_cmd(&argc, &argv, 1, TU32, 0x0f, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +000063 goto done;
64 }
65 if (strcmp(*argv, "protocol") == 0) {
66 NEXT_ARG();
67 tkey->off = 9;
Stephen Hemminger32a121c2016-03-21 11:48:36 -070068 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +000069 goto done;
70 }
71 /* jamal - fix this */
72 if (matches(*argv, "precedence") == 0) {
73 NEXT_ARG();
74 tkey->off = 1;
Stephen Hemminger32a121c2016-03-21 11:48:36 -070075 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +000076 goto done;
77 }
78 /* jamal - validate this at some point */
79 if (strcmp(*argv, "nofrag") == 0) {
80 NEXT_ARG();
81 tkey->off = 6;
Stephen Hemminger32a121c2016-03-21 11:48:36 -070082 res = parse_cmd(&argc, &argv, 1, TU32, 0x3F, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +000083 goto done;
84 }
85 /* jamal - validate this at some point */
86 if (strcmp(*argv, "firstfrag") == 0) {
87 NEXT_ARG();
88 tkey->off = 6;
Stephen Hemminger32a121c2016-03-21 11:48:36 -070089 res = parse_cmd(&argc, &argv, 1, TU32, 0x1F, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +000090 goto done;
91 }
92 if (strcmp(*argv, "ce") == 0) {
93 NEXT_ARG();
94 tkey->off = 6;
Stephen Hemminger32a121c2016-03-21 11:48:36 -070095 res = parse_cmd(&argc, &argv, 1, TU32, 0x80, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +000096 goto done;
97 }
98 if (strcmp(*argv, "df") == 0) {
99 NEXT_ARG();
100 tkey->off = 6;
Stephen Hemminger32a121c2016-03-21 11:48:36 -0700101 res = parse_cmd(&argc, &argv, 1, TU32, 0x40, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +0000102 goto done;
103 }
104 if (strcmp(*argv, "mf") == 0) {
105 NEXT_ARG();
106 tkey->off = 6;
Stephen Hemminger32a121c2016-03-21 11:48:36 -0700107 res = parse_cmd(&argc, &argv, 1, TU32, 0x20, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +0000108 goto done;
109 }
110 if (strcmp(*argv, "dport") == 0) {
111 NEXT_ARG();
112 tkey->off = 22;
Stephen Hemminger32a121c2016-03-21 11:48:36 -0700113 res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +0000114 goto done;
115 }
116 if (strcmp(*argv, "sport") == 0) {
117 NEXT_ARG();
118 tkey->off = 20;
Stephen Hemminger32a121c2016-03-21 11:48:36 -0700119 res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +0000120 goto done;
121 }
122 if (strcmp(*argv, "icmp_type") == 0) {
123 NEXT_ARG();
124 tkey->off = 20;
Stephen Hemminger32a121c2016-03-21 11:48:36 -0700125 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +0000126 goto done;
127 }
128 if (strcmp(*argv, "icmp_code") == 0) {
129 NEXT_ARG();
130 tkey->off = 20;
Stephen Hemminger32a121c2016-03-21 11:48:36 -0700131 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +0000132 goto done;
133 }
134 return -1;
135
Stephen Hemminger32a121c2016-03-21 11:48:36 -0700136done:
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +0000137 *argc_p = argc;
138 *argv_p = argv;
139 return res;
140}
141
142static int
Phil Sutter952f89d2016-03-22 15:16:21 +0100143parse_ip6(int *argc_p, char ***argv_p,
144 struct tc_pedit_sel *sel, struct tc_pedit_key *tkey)
net[shemminger]!shemminger7e7c7372005-01-17 23:32:51 +0000145{
146 int res = -1;
147 return res;
148}
149
150struct m_pedit_util p_pedit_ip = {
151 NULL,
152 "ip",
153 parse_ip,
154};
155
156
157struct m_pedit_util p_pedit_ip6 = {
158 NULL,
159 "ip6",
160 parse_ip6,
161};