Fix build break in 64bit architectures
[platform/upstream/iproute2.git] / tc / p_ip.c
1 /*
2  * p_ip.c               packet editor: IPV4 header
3  *
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  *
9  * Authors:  J Hadi Salim (hadi@cyberus.ca)
10  *
11  */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 #include <string.h>
21 #include "utils.h"
22 #include "tc_util.h"
23 #include "m_pedit.h"
24
25 static int
26 parse_ip(int *argc_p, char ***argv_p,
27          struct m_pedit_sel *sel, struct m_pedit_key *tkey)
28 {
29         int res = -1;
30         int argc = *argc_p;
31         char **argv = *argv_p;
32
33         if (argc < 2)
34                 return -1;
35
36         tkey->htype = sel->extended ?
37                 TCA_PEDIT_KEY_EX_HDR_TYPE_IP4 :
38                 TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK;
39
40         if (strcmp(*argv, "src") == 0) {
41                 NEXT_ARG();
42                 tkey->off = 12;
43                 res = parse_cmd(&argc, &argv, 4, TIPV4, RU32, sel, tkey);
44                 goto done;
45         }
46         if (strcmp(*argv, "dst") == 0) {
47                 NEXT_ARG();
48                 tkey->off = 16;
49                 res = parse_cmd(&argc, &argv, 4, TIPV4, RU32, sel, tkey);
50                 goto done;
51         }
52         /* jamal - look at these and make them either old or new
53         ** scheme given diffserv
54         ** don't forget the CE bit
55         */
56         if (strcmp(*argv, "tos") == 0 || matches(*argv, "dsfield") == 0) {
57                 NEXT_ARG();
58                 tkey->off = 1;
59                 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
60                 goto done;
61         }
62         if (strcmp(*argv, "ihl") == 0) {
63                 NEXT_ARG();
64                 tkey->off = 0;
65                 res = parse_cmd(&argc, &argv, 1, TU32, 0x0f, sel, tkey);
66                 goto done;
67         }
68         if (strcmp(*argv, "ttl") == 0) {
69                 NEXT_ARG();
70                 tkey->off = 8;
71                 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
72                 goto done;
73         }
74         if (strcmp(*argv, "protocol") == 0) {
75                 NEXT_ARG();
76                 tkey->off = 9;
77                 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
78                 goto done;
79         }
80         /* jamal - fix this */
81         if (matches(*argv, "precedence") == 0) {
82                 NEXT_ARG();
83                 tkey->off = 1;
84                 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
85                 goto done;
86         }
87         /* jamal - validate this at some point */
88         if (strcmp(*argv, "nofrag") == 0) {
89                 NEXT_ARG();
90                 tkey->off = 6;
91                 res = parse_cmd(&argc, &argv, 1, TU32, 0x3F, sel, tkey);
92                 goto done;
93         }
94         /* jamal - validate this at some point */
95         if (strcmp(*argv, "firstfrag") == 0) {
96                 NEXT_ARG();
97                 tkey->off = 6;
98                 res = parse_cmd(&argc, &argv, 1, TU32, 0x1F, sel, tkey);
99                 goto done;
100         }
101         if (strcmp(*argv, "ce") == 0) {
102                 NEXT_ARG();
103                 tkey->off = 6;
104                 res = parse_cmd(&argc, &argv, 1, TU32, 0x80, sel, tkey);
105                 goto done;
106         }
107         if (strcmp(*argv, "df") == 0) {
108                 NEXT_ARG();
109                 tkey->off = 6;
110                 res = parse_cmd(&argc, &argv, 1, TU32, 0x40, sel, tkey);
111                 goto done;
112         }
113         if (strcmp(*argv, "mf") == 0) {
114                 NEXT_ARG();
115                 tkey->off = 6;
116                 res = parse_cmd(&argc, &argv, 1, TU32, 0x20, sel, tkey);
117                 goto done;
118         }
119
120         if (sel->extended)
121                 return -1; /* fields located outside IP header should be
122                             * addressed using the relevant header type in
123                             * extended pedit kABI
124                             */
125
126         if (strcmp(*argv, "dport") == 0) {
127                 NEXT_ARG();
128                 tkey->off = 22;
129                 res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
130                 goto done;
131         }
132         if (strcmp(*argv, "sport") == 0) {
133                 NEXT_ARG();
134                 tkey->off = 20;
135                 res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
136                 goto done;
137         }
138         if (strcmp(*argv, "icmp_type") == 0) {
139                 NEXT_ARG();
140                 tkey->off = 20;
141                 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
142                 goto done;
143         }
144         if (strcmp(*argv, "icmp_code") == 0) {
145                 NEXT_ARG();
146                 tkey->off = 20;
147                 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
148                 goto done;
149         }
150         return -1;
151
152 done:
153         *argc_p = argc;
154         *argv_p = argv;
155         return res;
156 }
157
158 struct m_pedit_util p_pedit_ip = {
159         .id = "ip",
160         .parse_peopt = parse_ip,
161 };