2 * em_nbyte.c N-Byte Ematch
4 * This program is free software; you can distribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Thomas Graf <tgraf@suug.ch>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
24 #include <linux/tc_ematch/tc_em_nbyte.h>
26 extern struct ematch_util nbyte_ematch_util
;
28 static void nbyte_print_usage(FILE *fd
)
31 "Usage: nbyte(NEEDLE at OFFSET [layer LAYER])\n" \
32 "where: NEEDLE := { string | \"c-escape-sequence\" }\n" \
34 " LAYER := { link | network | transport | 0..%d }\n" \
36 "Example: nbyte(\"ababa\" at 12 layer 1)\n",
40 static int nbyte_parse_eopt(struct nlmsghdr
*n
, struct tcf_ematch_hdr
*hdr
,
44 struct bstr
*needle
= args
;
45 unsigned long offset
= 0, layer
= TCF_LAYER_NETWORK
;
46 int offset_present
= 0;
47 struct tcf_em_nbyte nb
;
49 memset(&nb
, 0, sizeof(nb
));
51 #define PARSE_ERR(CARG, FMT, ARGS...) \
52 em_parse_error(EINVAL, args, CARG, &nbyte_ematch_util, FMT ,##ARGS)
55 return PARSE_ERR(args
, "nbyte: missing arguments");
58 return PARSE_ERR(args
, "nbyte: needle length is 0");
60 for (a
= bstr_next(args
); a
; a
= bstr_next(a
)) {
61 if (!bstrcmp(a
, "at")) {
63 return PARSE_ERR(a
, "nbyte: missing argument");
67 if (offset
== ULONG_MAX
)
68 return PARSE_ERR(a
, "nbyte: invalid offset, " \
72 } else if (!bstrcmp(a
, "layer")) {
74 return PARSE_ERR(a
, "nbyte: missing argument");
77 layer
= parse_layer(a
);
78 if (layer
== INT_MAX
) {
80 if (layer
== ULONG_MAX
)
81 return PARSE_ERR(a
, "nbyte: invalid " \
85 if (layer
> TCF_LAYER_MAX
)
86 return PARSE_ERR(a
, "nbyte: illegal layer, " \
87 "must be in 0..%d", TCF_LAYER_MAX
);
89 return PARSE_ERR(a
, "nbyte: unknown parameter");
92 if (offset_present
== 0)
93 return PARSE_ERR(a
, "nbyte: offset required");
96 nb
.layer
= (__u8
) layer
;
97 nb
.off
= (__u16
) offset
;
99 addraw_l(n
, MAX_MSG
, hdr
, sizeof(*hdr
));
100 addraw_l(n
, MAX_MSG
, &nb
, sizeof(nb
));
101 addraw_l(n
, MAX_MSG
, needle
->data
, needle
->len
);
107 static int nbyte_print_eopt(FILE *fd
, struct tcf_ematch_hdr
*hdr
, void *data
,
111 struct tcf_em_nbyte
*nb
= data
;
114 if (data_len
< sizeof(*nb
)) {
115 fprintf(stderr
, "NByte header size mismatch\n");
119 if (data_len
< sizeof(*nb
) + nb
->len
) {
120 fprintf(stderr
, "NByte payload size mismatch\n");
124 needle
= data
+ sizeof(*nb
);
126 for (i
= 0; i
< nb
->len
; i
++)
127 fprintf(fd
, "%02x ", needle
[i
]);
130 for (i
= 0; i
< nb
->len
; i
++)
131 fprintf(fd
, "%c", isprint(needle
[i
]) ? needle
[i
] : '.');
132 fprintf(fd
, "\" at %d layer %d", nb
->off
, nb
->layer
);
137 struct ematch_util nbyte_ematch_util
= {
139 .kind_num
= TCF_EM_NBYTE
,
140 .parse_eopt
= nbyte_parse_eopt
,
141 .print_eopt
= nbyte_print_eopt
,
142 .print_usage
= nbyte_print_usage