|
@@ -34,7 +34,7 @@ static struct filter_actions_map action_tokens[] = {
|
34
|
34
|
{ NULL, true, FILTER_NO_MATCH },
|
35
|
35
|
};
|
36
|
36
|
|
37
|
|
-enum filter_token { T_UNKNOWN, T_NAME, T_OFFSET, T_DATA, T_MATCH, T_MASK };
|
|
37
|
+enum filter_token { T_UNKNOWN, T_NAME, T_OFFSET, T_DATA, T_MATCH, T_MASK, T_LENGTH };
|
38
|
38
|
|
39
|
39
|
struct filter_data_map {
|
40
|
40
|
const char *token;
|
|
@@ -48,6 +48,7 @@ static struct filter_data_map data_tokens[] = {
|
48
|
48
|
{ "data", T_DATA },
|
49
|
49
|
{ "match", T_MATCH },
|
50
|
50
|
{ "mask", T_MASK },
|
|
51
|
+ { "length", T_LENGTH },
|
51
|
52
|
{ NULL, T_UNKNOWN },
|
52
|
53
|
};
|
53
|
54
|
|
|
@@ -144,9 +145,22 @@ int filter_parse(char *filter_def, struct filter *filter) {
|
144
|
145
|
filter->type = FILTER_TYPE_MASK;
|
145
|
146
|
ret = parse_hex(tokdata, filter->mask, NULL, MAX_FILTER_LEN);
|
146
|
147
|
break;
|
147
|
|
- default:
|
|
148
|
+ case T_LENGTH: {
|
|
149
|
+ filter->type = FILTER_TYPE_LENGTH;
|
|
150
|
+ int i;
|
|
151
|
+ char *ptr, *saveptr3 = NULL;
|
|
152
|
+ for (i = 0, ptr = strtok_r(tokdata, " ", &saveptr3);
|
|
153
|
+ i < MAX_FILTER_LEN && ptr;
|
|
154
|
+ i++ , ptr = strtok_r(NULL, " ", &saveptr3))
|
|
155
|
+ {
|
|
156
|
+ filter->data[i] = strtoul(ptr, NULL, 0);
|
|
157
|
+ }
|
|
158
|
+ filter->filter_len = i;
|
|
159
|
+ break;
|
|
160
|
+ }
|
|
161
|
+ case T_UNKNOWN:
|
148
|
162
|
fprintf(stderr, "WARN : Unknown filter setting: %s\n", token2);
|
149
|
|
- }
|
|
163
|
+ } // switch (data_type)
|
150
|
164
|
}
|
151
|
165
|
}
|
152
|
166
|
}
|
|
@@ -157,7 +171,7 @@ OUT:
|
157
|
171
|
}
|
158
|
172
|
|
159
|
173
|
void filter_dump(struct filter *filter, char *buffer, unsigned int buf_len) {
|
160
|
|
- unsigned int pos = 0;
|
|
174
|
+ unsigned int i, pos = 0;
|
161
|
175
|
memset(buffer, 0, buf_len);
|
162
|
176
|
pos += snprintf(buffer + pos, buf_len - pos, "Action: %s",
|
163
|
177
|
filter->action == FILTER_ACCEPT_ALL ? "ACCEPT_ALL (default)" :
|
|
@@ -177,11 +191,17 @@ void filter_dump(struct filter *filter, char *buffer, unsigned int buf_len) {
|
177
|
191
|
ts_hex_dump_buf(tmp_mask, sizeof(tmp_mask), filter->mask, filter->filter_len, 0);
|
178
|
192
|
pos += snprintf(buffer + pos, buf_len - pos, " Match: %s Mask: %s", tmp_data, tmp_mask);
|
179
|
193
|
break;
|
|
194
|
+ case FILTER_TYPE_LENGTH:
|
|
195
|
+ pos += snprintf(buffer + pos, buf_len - pos, " Length:");
|
|
196
|
+ for (i = 0; i < filter->filter_len; i++)
|
|
197
|
+ pos += snprintf(buffer + pos, buf_len - pos, " 0x%02x", filter->data[i]);
|
|
198
|
+ break;
|
180
|
199
|
} // switch (filter->type)
|
181
|
200
|
}
|
182
|
201
|
}
|
183
|
202
|
|
184
|
203
|
static enum filter_action filter_match(uint8_t *data, unsigned int data_len, struct filter *filter) {
|
|
204
|
+ int i;
|
185
|
205
|
if (filter->action == FILTER_ACCEPT_ALL || filter->action == FILTER_REJECT_ALL)
|
186
|
206
|
return filter->action;
|
187
|
207
|
if (filter->action == FILTER_ACCEPT || filter->action == FILTER_REJECT) {
|
|
@@ -200,7 +220,6 @@ static enum filter_action filter_match(uint8_t *data, unsigned int data_len, str
|
200
|
220
|
// Check data[0] against filter->data[0]
|
201
|
221
|
if ((data[0] & filter->mask[0]) == (filter->data[0] & filter->mask[0])) {
|
202
|
222
|
matched++;
|
203
|
|
- int i;
|
204
|
223
|
for (i = 1; i < filter->filter_len; i++) {
|
205
|
224
|
// Check data[3...] against filter->data[1...]
|
206
|
225
|
if ((data[i + 2] & filter->mask[i]) == (filter->data[i] & filter->mask[i]))
|
|
@@ -211,6 +230,16 @@ static enum filter_action filter_match(uint8_t *data, unsigned int data_len, str
|
211
|
230
|
return filter->action;
|
212
|
231
|
break;
|
213
|
232
|
}
|
|
233
|
+ case FILTER_TYPE_LENGTH: {
|
|
234
|
+ if (data_len < 3)
|
|
235
|
+ return FILTER_NO_MATCH;
|
|
236
|
+ for (i = 0; i < filter->filter_len; i++) {
|
|
237
|
+ // data[2] holds the section length (not quite, but close to what
|
|
238
|
+ // we need, because length= can contain sizes > 255)
|
|
239
|
+ if (data[2] == filter->data[i])
|
|
240
|
+ return filter->action;
|
|
241
|
+ }
|
|
242
|
+ }
|
214
|
243
|
} // switch (filter->type)
|
215
|
244
|
}
|
216
|
245
|
return FILTER_NO_MATCH;
|