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>
25 #include <linux/tc_ematch/tc_em_nbyte.h>
27 extern struct ematch_util nbyte_ematch_util
;
29 static void nbyte_print_usage(FILE *fd
)
32 "Usage: nbyte(NEEDLE at OFFSET [layer LAYER])\n" \
33 "where: NEEDLE := { string | \"c-escape-sequence\" }\n" \
35 " LAYER := { link | header | next-header | 0..%d }\n" \
37 "Example: nbyte(\"ababa\" at 12 layer 1)\n",
41 static int nbyte_parse_eopt(struct nlmsghdr
*n
, struct tcf_ematch_hdr
*hdr
,
45 struct bstr
*needle
= args
;
46 unsigned long offset
= 0, layer
= TCF_LAYER_NETWORK
;
47 int offset_present
= 0;
48 struct tcf_em_nbyte nb
;
50 memset(&nb
, 0, sizeof(nb
));
52 #define PARSE_ERR(CARG, FMT, ARGS...) \
53 em_parse_error(EINVAL, args, CARG, &nbyte_ematch_util, FMT ,##ARGS)
56 return PARSE_ERR(args
, "nbyte: missing arguments");
59 return PARSE_ERR(args
, "nbyte: needle length is 0");
61 for (a
= bstr_next(args
); a
; a
= bstr_next(a
)) {
62 if (!bstrcmp(a
, "at")) {
64 return PARSE_ERR(a
, "nbyte: missing argument");
68 if (offset
== ULONG_MAX
)
69 return PARSE_ERR(a
, "nbyte: invalid offset, " \
73 } else if (!bstrcmp(a
, "layer")) {
75 return PARSE_ERR(a
, "nbyte: missing argument");
78 layer
= parse_layer(a
);
79 if (layer
== INT_MAX
) {
81 if (layer
== ULONG_MAX
)
82 return PARSE_ERR(a
, "nbyte: invalid " \
86 if (layer
> TCF_LAYER_MAX
)
87 return PARSE_ERR(a
, "nbyte: illegal layer, " \
88 "must be in 0..%d", TCF_LAYER_MAX
);
90 return PARSE_ERR(a
, "nbyte: unknown parameter");
93 if (offset_present
== 0)
94 return PARSE_ERR(a
, "nbyte: offset required");
97 nb
.layer
= (__u8
) layer
;
98 nb
.off
= (__u16
) offset
;
100 addraw_l(n
, MAX_MSG
, hdr
, sizeof(*hdr
));
101 addraw_l(n
, MAX_MSG
, &nb
, sizeof(nb
));
102 addraw_l(n
, MAX_MSG
, needle
->data
, needle
->len
);
108 static int nbyte_print_eopt(FILE *fd
, struct tcf_ematch_hdr
*hdr
, void *data
,
112 struct tcf_em_nbyte
*nb
= data
;
115 if (data_len
< sizeof(*nb
)) {
116 fprintf(stderr
, "NByte header size mismatch\n");
120 if (data_len
< sizeof(*nb
) + nb
->len
) {
121 fprintf(stderr
, "NByte payload size mismatch\n");
125 needle
= data
+ sizeof(*nb
);
127 for (i
= 0; i
< nb
->len
; i
++)
128 fprintf(fd
, "%02x ", needle
[i
]);
131 for (i
= 0; i
< nb
->len
; i
++)
132 fprintf(fd
, "%c", isprint(needle
[i
]) ? needle
[i
] : '.');
133 fprintf(fd
, "\" at %d layer %d", nb
->off
, nb
->layer
);
138 struct ematch_util nbyte_ematch_util
= {
140 .kind_num
= TCF_EM_NBYTE
,
141 .parse_eopt
= nbyte_parse_eopt
,
142 .print_eopt
= nbyte_print_eopt
,
143 .print_usage
= nbyte_print_usage