Tagging module iproute2 - iproute2-2.6.16-2
[iproute2.git] / tc / m_ematch.h
1 #ifndef __TC_EMATCH_H_
2 #define __TC_EMATCH_H_
3
4 #include <ctype.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "utils.h"
9 #include "tc_util.h"
10
11 #define EMATCHKINDSIZ 16
12
13 struct bstr
14 {
15         char    *data;
16         unsigned int    len;
17         int             quoted;
18         struct bstr     *next;
19 };
20
21 static 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
39 static 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
52 static 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)
58                 return strncmp(b->data, text, len);
59
60         return d;
61 }
62
63 static 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
79 static inline void bstr_print(FILE *fd, struct bstr *b, int ascii)
80 {
81         int i;
82         char *s = b->data;
83
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
97 static inline struct bstr *bstr_next(struct bstr *b)
98 {
99         return b->next;
100 }
101
102 struct 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
113 static 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
126 static 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
151 struct 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
162 static 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
174 extern int em_parse_error(int err, struct bstr *args, struct bstr *carg,
175                    struct ematch_util *, char *fmt, ...);
176 extern int print_ematch(FILE *, const struct rtattr *);
177 extern int parse_ematch(int *, char ***, int, struct nlmsghdr *);
178
179 #endif