blob: 72437caad25143cbe9e41d0903813d68dd00695d [file] [log] [blame]
shemminger6a805a62005-06-23 20:27:02 +00001#ifndef __TC_EMATCH_H_
2#define __TC_EMATCH_H_
3
4#include <ctype.h>
5
6#include "utils.h"
7#include "tc_util.h"
8
9#define EMATCHKINDSIZ 16
10
11struct bstr
12{
13 unsigned char *data;
14 unsigned int len;
15 int quoted;
16 struct bstr *next;
17};
18
19static inline struct bstr * bstr_alloc(const char *text)
20{
21 struct bstr *b = calloc(1, sizeof(*b));
22
23 if (b == NULL)
24 return NULL;
25
26 b->data = strdup(text);
27 if (b->data == NULL) {
28 free(b);
29 return NULL;
30 }
31
32 b->len = strlen(text);
33
34 return b;
35}
36
37static inline struct bstr * bstr_new(char *data, unsigned int len)
38{
39 struct bstr *b = calloc(1, sizeof(*b));
40
41 if (b == NULL)
42 return NULL;
43
44 b->data = data;
45 b->len = len;
46
47 return b;
48}
49
50static inline int bstrcmp(struct bstr *b, const char *text)
51{
52 int len = strlen(text);
53 int d = b->len - len;
54
55 if (d == 0)
56 return strncmp((char *) b->data, text, len);
57
58 return d;
59}
60
61static inline unsigned long bstrtoul(struct bstr *b)
62{
63 char *inv = NULL;
64 unsigned long l;
65 char buf[b->len+1];
66
67 memcpy(buf, b->data, b->len);
68 buf[b->len] = '\0';
69
70 l = strtol(buf, &inv, 0);
71 if (l == ULONG_MAX || inv == buf)
72 return LONG_MAX;
73
74 return l;
75}
76
77static inline void bstr_print(FILE *fd, struct bstr *b, int ascii)
78{
79 int i;
80 char *s = (char *) b->data;
81
82 if (ascii)
83 for (i = 0; i < b->len; i++)
84 fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
85 else {
86 for (i = 0; i < b->len; i++)
87 fprintf(fd, "%02x", s[i]);
88 fprintf(fd, "\"");
89 for (i = 0; i < b->len; i++)
90 fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
91 fprintf(fd, "\"");
92 }
93}
94
95static inline struct bstr *bstr_next(struct bstr *b)
96{
97 return b->next;
98}
99
100struct ematch
101{
102 struct bstr *args;
103 int index;
104 int inverted;
105 int relation;
106 int child_ref;
107 struct ematch *child;
108 struct ematch *next;
109};
110
111static inline struct ematch * new_ematch(struct bstr *args, int inverted)
112{
113 struct ematch *e = calloc(1, sizeof(*e));
114
115 if (e == NULL)
116 return NULL;
117
118 e->args = args;
119 e->inverted = inverted;
120
121 return e;
122}
123
124static inline void print_ematch_tree(struct ematch *tree)
125{
126 struct ematch *t;
127
128 for (t = tree; t; t = t->next) {
129 if (t->inverted)
130 printf("NOT ");
131
132 if (t->child) {
133 printf("(");
134 print_ematch_tree(t->child);
135 printf(")");
136 } else {
137 struct bstr *b;
138 for (b = t->args; b; b = b->next)
139 printf("%s%s", b->data, b->next ? " " : "");
140 }
141
142 if (t->relation == TCF_EM_REL_AND)
143 printf(" AND ");
144 else if (t->relation == TCF_EM_REL_OR)
145 printf(" OR ");
146 }
147}
148
149struct ematch_util
150{
151 char kind[EMATCHKINDSIZ];
152 int kind_num;
153 int (*parse_eopt)(struct nlmsghdr *,struct tcf_ematch_hdr *,
154 struct bstr *);
155 int (*print_eopt)(FILE *, struct tcf_ematch_hdr *, void *, int);
156 void (*print_usage)(FILE *);
157 struct ematch_util *next;
158};
159
160static inline int parse_layer(struct bstr *b)
161{
162 if (*((char *) b->data) == 'l')
163 return TCF_LAYER_LINK;
164 else if (*((char *) b->data) == 'n')
165 return TCF_LAYER_NETWORK;
166 else if (*((char *) b->data) == 't')
167 return TCF_LAYER_TRANSPORT;
168 else
169 return INT_MAX;
170}
171
172extern int em_parse_error(int err, struct bstr *args, struct bstr *carg,
173 struct ematch_util *, char *fmt, ...);
174extern int print_ematch(FILE *, const struct rtattr *);
175extern int parse_ematch(int *, char ***, int, struct nlmsghdr *);
176
177#endif