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