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 13struct bstr 14{ 15 char *data; 16 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) 58 return strncmp(b->data, text, len); 59 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; 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 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 180