xref: /aosp_15_r20/external/libnl/lib/route/cls/ematch/text.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
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