libnl  3.3.0
text.c
1 /*
2  * lib/route/cls/ematch/text.c Text Search
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation version 2.1
7  * of the License.
8  *
9  * Copyright (c) 2010-2013 Thomas Graf <tgraf@suug.ch>
10  */
11 
12 /**
13  * @ingroup ematch
14  * @defgroup em_text Text Search
15  *
16  * @{
17  */
18 
19 #include <netlink-private/netlink.h>
20 #include <netlink-private/tc.h>
21 #include <netlink/netlink.h>
22 #include <netlink/route/cls/ematch.h>
23 #include <netlink/route/cls/ematch/text.h>
24 #include <linux/tc_ematch/tc_em_text.h>
25 
26 struct text_data
27 {
28  struct tcf_em_text cfg;
29  char * pattern;
30 };
31 
32 void rtnl_ematch_text_set_from(struct rtnl_ematch *e, uint8_t layer,
33  uint16_t offset)
34 {
35  struct text_data *t = rtnl_ematch_data(e);
36  t->cfg.from_offset = offset;
37  t->cfg.from_layer = layer;
38 }
39 
40 uint16_t rtnl_ematch_text_get_from_offset(struct rtnl_ematch *e)
41 {
42  return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_offset;
43 }
44 
45 uint8_t rtnl_ematch_text_get_from_layer(struct rtnl_ematch *e)
46 {
47  return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_layer;
48 }
49 
50 void rtnl_ematch_text_set_to(struct rtnl_ematch *e, uint8_t layer,
51  uint16_t offset)
52 {
53  struct text_data *t = rtnl_ematch_data(e);
54  t->cfg.to_offset = offset;
55  t->cfg.to_layer = layer;
56 }
57 
58 uint16_t rtnl_ematch_text_get_to_offset(struct rtnl_ematch *e)
59 {
60  return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_offset;
61 }
62 
63 uint8_t rtnl_ematch_text_get_to_layer(struct rtnl_ematch *e)
64 {
65  return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_layer;
66 }
67 
68 void rtnl_ematch_text_set_pattern(struct rtnl_ematch *e,
69  char *pattern, size_t len)
70 {
71  struct text_data *t = rtnl_ematch_data(e);
72 
73  if (t->pattern)
74  free(t->pattern);
75 
76  t->pattern = pattern;
77  t->cfg.pattern_len = len;
78 }
79 
80 char *rtnl_ematch_text_get_pattern(struct rtnl_ematch *e)
81 {
82  return ((struct text_data *) rtnl_ematch_data(e))->pattern;
83 }
84 
85 size_t rtnl_ematch_text_get_len(struct rtnl_ematch *e)
86 {
87  return ((struct text_data *) rtnl_ematch_data(e))->cfg.pattern_len;
88 }
89 
90 void rtnl_ematch_text_set_algo(struct rtnl_ematch *e, const char *algo)
91 {
92  struct text_data *t = rtnl_ematch_data(e);
93 
94  strncpy(t->cfg.algo, algo, sizeof(t->cfg.algo));
95 }
96 
97 char *rtnl_ematch_text_get_algo(struct rtnl_ematch *e)
98 {
99  struct text_data *t = rtnl_ematch_data(e);
100 
101  return t->cfg.algo[0] ? t->cfg.algo : NULL;
102 }
103 
104 static int text_parse(struct rtnl_ematch *e, void *data, size_t len)
105 {
106  struct text_data *t = rtnl_ematch_data(e);
107  size_t hdrlen = sizeof(struct tcf_em_text);
108  size_t plen = len - hdrlen;
109 
110  memcpy(&t->cfg, data, hdrlen);
111 
112  if (t->cfg.pattern_len > plen)
113  return -NLE_INVAL;
114 
115  if (t->cfg.pattern_len > 0) {
116  if (!(t->pattern = calloc(1, t->cfg.pattern_len)))
117  return -NLE_NOMEM;
118 
119  memcpy(t->pattern, data + hdrlen, t->cfg.pattern_len);
120  }
121 
122  return 0;
123 }
124 
125 static void text_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
126 {
127  struct text_data *t = rtnl_ematch_data(e);
128  char buf[64];
129 
130  nl_dump(p, "text(%s \"%s\"",
131  t->cfg.algo[0] ? t->cfg.algo : "no-algo",
132  t->pattern ? : "no-pattern");
133 
134  if (t->cfg.from_layer || t->cfg.from_offset) {
135  nl_dump(p, " from %s",
136  rtnl_ematch_offset2txt(t->cfg.from_layer,
137  t->cfg.from_offset,
138  buf, sizeof(buf)));
139  }
140 
141  if (t->cfg.to_layer || t->cfg.to_offset) {
142  nl_dump(p, " to %s",
143  rtnl_ematch_offset2txt(t->cfg.to_layer,
144  t->cfg.to_offset,
145  buf, sizeof(buf)));
146  }
147 
148  nl_dump(p, ")");
149 }
150 
151 static int text_fill(struct rtnl_ematch *e, struct nl_msg *msg)
152 {
153  struct text_data *t = rtnl_ematch_data(e);
154  int err;
155 
156  if ((err = nlmsg_append(msg, &t->cfg, sizeof(t->cfg), 0)) < 0)
157  return err;
158 
159  return nlmsg_append(msg, t->pattern, t->cfg.pattern_len, 0);
160 }
161 
162 static void text_free(struct rtnl_ematch *e)
163 {
164  struct text_data *t = rtnl_ematch_data(e);
165  free(t->pattern);
166 }
167 
168 static struct rtnl_ematch_ops text_ops = {
169  .eo_kind = TCF_EM_TEXT,
170  .eo_name = "text",
171  .eo_minlen = sizeof(struct tcf_em_text),
172  .eo_datalen = sizeof(struct text_data),
173  .eo_parse = text_parse,
174  .eo_dump = text_dump,
175  .eo_fill = text_fill,
176  .eo_free = text_free,
177 };
178 
179 static void __init text_init(void)
180 {
181  rtnl_ematch_register(&text_ops);
182 }
183 
184 /** @} */
Definition: text.c:26
int rtnl_ematch_register(struct rtnl_ematch_ops *ops)
Register ematch module.
Definition: ematch.c:46
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
Definition: msg.c:446
Dumping parameters.
Definition: types.h:33
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:961
Extended Match Operations.
Definition: ematch.h:33