1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2010-2013 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker */
5*4dc78e53SAndroid Build Coastguard Worker
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker * @ingroup ematch
8*4dc78e53SAndroid Build Coastguard Worker * @defgroup em_text Text Search
9*4dc78e53SAndroid Build Coastguard Worker *
10*4dc78e53SAndroid Build Coastguard Worker * @{
11*4dc78e53SAndroid Build Coastguard Worker */
12*4dc78e53SAndroid Build Coastguard Worker
13*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
14*4dc78e53SAndroid Build Coastguard Worker
15*4dc78e53SAndroid Build Coastguard Worker #include <linux/tc_ematch/tc_em_text.h>
16*4dc78e53SAndroid Build Coastguard Worker
17*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
18*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/cls/ematch.h>
19*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/cls/ematch/text.h>
20*4dc78e53SAndroid Build Coastguard Worker
21*4dc78e53SAndroid Build Coastguard Worker struct text_data
22*4dc78e53SAndroid Build Coastguard Worker {
23*4dc78e53SAndroid Build Coastguard Worker struct tcf_em_text cfg;
24*4dc78e53SAndroid Build Coastguard Worker char * pattern;
25*4dc78e53SAndroid Build Coastguard Worker };
26*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_text_set_from(struct rtnl_ematch * e,uint8_t layer,uint16_t offset)27*4dc78e53SAndroid Build Coastguard Worker void rtnl_ematch_text_set_from(struct rtnl_ematch *e, uint8_t layer,
28*4dc78e53SAndroid Build Coastguard Worker uint16_t offset)
29*4dc78e53SAndroid Build Coastguard Worker {
30*4dc78e53SAndroid Build Coastguard Worker struct text_data *t = rtnl_ematch_data(e);
31*4dc78e53SAndroid Build Coastguard Worker t->cfg.from_offset = offset;
32*4dc78e53SAndroid Build Coastguard Worker t->cfg.from_layer = layer;
33*4dc78e53SAndroid Build Coastguard Worker }
34*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_text_get_from_offset(struct rtnl_ematch * e)35*4dc78e53SAndroid Build Coastguard Worker uint16_t rtnl_ematch_text_get_from_offset(struct rtnl_ematch *e)
36*4dc78e53SAndroid Build Coastguard Worker {
37*4dc78e53SAndroid Build Coastguard Worker return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_offset;
38*4dc78e53SAndroid Build Coastguard Worker }
39*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_text_get_from_layer(struct rtnl_ematch * e)40*4dc78e53SAndroid Build Coastguard Worker uint8_t rtnl_ematch_text_get_from_layer(struct rtnl_ematch *e)
41*4dc78e53SAndroid Build Coastguard Worker {
42*4dc78e53SAndroid Build Coastguard Worker return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_layer;
43*4dc78e53SAndroid Build Coastguard Worker }
44*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_text_set_to(struct rtnl_ematch * e,uint8_t layer,uint16_t offset)45*4dc78e53SAndroid Build Coastguard Worker void rtnl_ematch_text_set_to(struct rtnl_ematch *e, uint8_t layer,
46*4dc78e53SAndroid Build Coastguard Worker uint16_t offset)
47*4dc78e53SAndroid Build Coastguard Worker {
48*4dc78e53SAndroid Build Coastguard Worker struct text_data *t = rtnl_ematch_data(e);
49*4dc78e53SAndroid Build Coastguard Worker t->cfg.to_offset = offset;
50*4dc78e53SAndroid Build Coastguard Worker t->cfg.to_layer = layer;
51*4dc78e53SAndroid Build Coastguard Worker }
52*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_text_get_to_offset(struct rtnl_ematch * e)53*4dc78e53SAndroid Build Coastguard Worker uint16_t rtnl_ematch_text_get_to_offset(struct rtnl_ematch *e)
54*4dc78e53SAndroid Build Coastguard Worker {
55*4dc78e53SAndroid Build Coastguard Worker return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_offset;
56*4dc78e53SAndroid Build Coastguard Worker }
57*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_text_get_to_layer(struct rtnl_ematch * e)58*4dc78e53SAndroid Build Coastguard Worker uint8_t rtnl_ematch_text_get_to_layer(struct rtnl_ematch *e)
59*4dc78e53SAndroid Build Coastguard Worker {
60*4dc78e53SAndroid Build Coastguard Worker return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_layer;
61*4dc78e53SAndroid Build Coastguard Worker }
62*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_text_set_pattern(struct rtnl_ematch * e,char * pattern,size_t len)63*4dc78e53SAndroid Build Coastguard Worker void rtnl_ematch_text_set_pattern(struct rtnl_ematch *e,
64*4dc78e53SAndroid Build Coastguard Worker char *pattern, size_t len)
65*4dc78e53SAndroid Build Coastguard Worker {
66*4dc78e53SAndroid Build Coastguard Worker struct text_data *t = rtnl_ematch_data(e);
67*4dc78e53SAndroid Build Coastguard Worker
68*4dc78e53SAndroid Build Coastguard Worker if (t->pattern)
69*4dc78e53SAndroid Build Coastguard Worker free(t->pattern);
70*4dc78e53SAndroid Build Coastguard Worker
71*4dc78e53SAndroid Build Coastguard Worker t->pattern = pattern;
72*4dc78e53SAndroid Build Coastguard Worker t->cfg.pattern_len = len;
73*4dc78e53SAndroid Build Coastguard Worker }
74*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_text_get_pattern(struct rtnl_ematch * e)75*4dc78e53SAndroid Build Coastguard Worker char *rtnl_ematch_text_get_pattern(struct rtnl_ematch *e)
76*4dc78e53SAndroid Build Coastguard Worker {
77*4dc78e53SAndroid Build Coastguard Worker return ((struct text_data *) rtnl_ematch_data(e))->pattern;
78*4dc78e53SAndroid Build Coastguard Worker }
79*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_text_get_len(struct rtnl_ematch * e)80*4dc78e53SAndroid Build Coastguard Worker size_t rtnl_ematch_text_get_len(struct rtnl_ematch *e)
81*4dc78e53SAndroid Build Coastguard Worker {
82*4dc78e53SAndroid Build Coastguard Worker return ((struct text_data *) rtnl_ematch_data(e))->cfg.pattern_len;
83*4dc78e53SAndroid Build Coastguard Worker }
84*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_text_set_algo(struct rtnl_ematch * e,const char * algo)85*4dc78e53SAndroid Build Coastguard Worker void rtnl_ematch_text_set_algo(struct rtnl_ematch *e, const char *algo)
86*4dc78e53SAndroid Build Coastguard Worker {
87*4dc78e53SAndroid Build Coastguard Worker struct text_data *t = rtnl_ematch_data(e);
88*4dc78e53SAndroid Build Coastguard Worker
89*4dc78e53SAndroid Build Coastguard Worker _nl_strncpy_trunc(t->cfg.algo, algo, sizeof(t->cfg.algo));
90*4dc78e53SAndroid Build Coastguard Worker }
91*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_text_get_algo(struct rtnl_ematch * e)92*4dc78e53SAndroid Build Coastguard Worker char *rtnl_ematch_text_get_algo(struct rtnl_ematch *e)
93*4dc78e53SAndroid Build Coastguard Worker {
94*4dc78e53SAndroid Build Coastguard Worker struct text_data *t = rtnl_ematch_data(e);
95*4dc78e53SAndroid Build Coastguard Worker
96*4dc78e53SAndroid Build Coastguard Worker return t->cfg.algo[0] ? t->cfg.algo : NULL;
97*4dc78e53SAndroid Build Coastguard Worker }
98*4dc78e53SAndroid Build Coastguard Worker
text_parse(struct rtnl_ematch * e,void * data,size_t len)99*4dc78e53SAndroid Build Coastguard Worker static int text_parse(struct rtnl_ematch *e, void *data, size_t len)
100*4dc78e53SAndroid Build Coastguard Worker {
101*4dc78e53SAndroid Build Coastguard Worker struct text_data *t = rtnl_ematch_data(e);
102*4dc78e53SAndroid Build Coastguard Worker size_t hdrlen = sizeof(struct tcf_em_text);
103*4dc78e53SAndroid Build Coastguard Worker size_t plen = len - hdrlen;
104*4dc78e53SAndroid Build Coastguard Worker
105*4dc78e53SAndroid Build Coastguard Worker memcpy(&t->cfg, data, hdrlen);
106*4dc78e53SAndroid Build Coastguard Worker
107*4dc78e53SAndroid Build Coastguard Worker if (t->cfg.pattern_len > plen)
108*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
109*4dc78e53SAndroid Build Coastguard Worker
110*4dc78e53SAndroid Build Coastguard Worker if (t->cfg.pattern_len > 0) {
111*4dc78e53SAndroid Build Coastguard Worker if (!(t->pattern = calloc(1, t->cfg.pattern_len)))
112*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
113*4dc78e53SAndroid Build Coastguard Worker
114*4dc78e53SAndroid Build Coastguard Worker memcpy(t->pattern, (char *) data + hdrlen, t->cfg.pattern_len);
115*4dc78e53SAndroid Build Coastguard Worker }
116*4dc78e53SAndroid Build Coastguard Worker
117*4dc78e53SAndroid Build Coastguard Worker return 0;
118*4dc78e53SAndroid Build Coastguard Worker }
119*4dc78e53SAndroid Build Coastguard Worker
text_dump(struct rtnl_ematch * e,struct nl_dump_params * p)120*4dc78e53SAndroid Build Coastguard Worker static void text_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
121*4dc78e53SAndroid Build Coastguard Worker {
122*4dc78e53SAndroid Build Coastguard Worker struct text_data *t = rtnl_ematch_data(e);
123*4dc78e53SAndroid Build Coastguard Worker char buf[64];
124*4dc78e53SAndroid Build Coastguard Worker
125*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "text(%s \"%s\"",
126*4dc78e53SAndroid Build Coastguard Worker t->cfg.algo[0] ? t->cfg.algo : "no-algo",
127*4dc78e53SAndroid Build Coastguard Worker t->pattern ? t->pattern : "no-pattern");
128*4dc78e53SAndroid Build Coastguard Worker
129*4dc78e53SAndroid Build Coastguard Worker if (t->cfg.from_layer || t->cfg.from_offset) {
130*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " from %s",
131*4dc78e53SAndroid Build Coastguard Worker rtnl_ematch_offset2txt(t->cfg.from_layer,
132*4dc78e53SAndroid Build Coastguard Worker t->cfg.from_offset,
133*4dc78e53SAndroid Build Coastguard Worker buf, sizeof(buf)));
134*4dc78e53SAndroid Build Coastguard Worker }
135*4dc78e53SAndroid Build Coastguard Worker
136*4dc78e53SAndroid Build Coastguard Worker if (t->cfg.to_layer || t->cfg.to_offset) {
137*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " to %s",
138*4dc78e53SAndroid Build Coastguard Worker rtnl_ematch_offset2txt(t->cfg.to_layer,
139*4dc78e53SAndroid Build Coastguard Worker t->cfg.to_offset,
140*4dc78e53SAndroid Build Coastguard Worker buf, sizeof(buf)));
141*4dc78e53SAndroid Build Coastguard Worker }
142*4dc78e53SAndroid Build Coastguard Worker
143*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, ")");
144*4dc78e53SAndroid Build Coastguard Worker }
145*4dc78e53SAndroid Build Coastguard Worker
text_fill(struct rtnl_ematch * e,struct nl_msg * msg)146*4dc78e53SAndroid Build Coastguard Worker static int text_fill(struct rtnl_ematch *e, struct nl_msg *msg)
147*4dc78e53SAndroid Build Coastguard Worker {
148*4dc78e53SAndroid Build Coastguard Worker struct text_data *t = rtnl_ematch_data(e);
149*4dc78e53SAndroid Build Coastguard Worker int err;
150*4dc78e53SAndroid Build Coastguard Worker
151*4dc78e53SAndroid Build Coastguard Worker if ((err = nlmsg_append(msg, &t->cfg, sizeof(t->cfg), 0)) < 0)
152*4dc78e53SAndroid Build Coastguard Worker return err;
153*4dc78e53SAndroid Build Coastguard Worker
154*4dc78e53SAndroid Build Coastguard Worker return nlmsg_append(msg, t->pattern, t->cfg.pattern_len, 0);
155*4dc78e53SAndroid Build Coastguard Worker }
156*4dc78e53SAndroid Build Coastguard Worker
text_free(struct rtnl_ematch * e)157*4dc78e53SAndroid Build Coastguard Worker static void text_free(struct rtnl_ematch *e)
158*4dc78e53SAndroid Build Coastguard Worker {
159*4dc78e53SAndroid Build Coastguard Worker struct text_data *t = rtnl_ematch_data(e);
160*4dc78e53SAndroid Build Coastguard Worker free(t->pattern);
161*4dc78e53SAndroid Build Coastguard Worker }
162*4dc78e53SAndroid Build Coastguard Worker
163*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_ematch_ops text_ops = {
164*4dc78e53SAndroid Build Coastguard Worker .eo_kind = TCF_EM_TEXT,
165*4dc78e53SAndroid Build Coastguard Worker .eo_name = "text",
166*4dc78e53SAndroid Build Coastguard Worker .eo_minlen = sizeof(struct tcf_em_text),
167*4dc78e53SAndroid Build Coastguard Worker .eo_datalen = sizeof(struct text_data),
168*4dc78e53SAndroid Build Coastguard Worker .eo_parse = text_parse,
169*4dc78e53SAndroid Build Coastguard Worker .eo_dump = text_dump,
170*4dc78e53SAndroid Build Coastguard Worker .eo_fill = text_fill,
171*4dc78e53SAndroid Build Coastguard Worker .eo_free = text_free,
172*4dc78e53SAndroid Build Coastguard Worker };
173*4dc78e53SAndroid Build Coastguard Worker
text_init(void)174*4dc78e53SAndroid Build Coastguard Worker static void _nl_init text_init(void)
175*4dc78e53SAndroid Build Coastguard Worker {
176*4dc78e53SAndroid Build Coastguard Worker rtnl_ematch_register(&text_ops);
177*4dc78e53SAndroid Build Coastguard Worker }
178*4dc78e53SAndroid Build Coastguard Worker
179*4dc78e53SAndroid Build Coastguard Worker /** @} */
180