123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- /*
- * lib/route/cls/ematch/text.c Text Search
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
- * Copyright (c) 2010-2013 Thomas Graf <tgraf@suug.ch>
- */
- /**
- * @ingroup ematch
- * @defgroup em_text Text Search
- *
- * @{
- */
- #include <netlink-private/netlink.h>
- #include <netlink-private/tc.h>
- #include <netlink/netlink.h>
- #include <netlink/route/cls/ematch.h>
- #include <netlink/route/cls/ematch/text.h>
- struct text_data
- {
- struct tcf_em_text cfg;
- char * pattern;
- };
- void rtnl_ematch_text_set_from(struct rtnl_ematch *e, uint8_t layer,
- uint16_t offset)
- {
- struct text_data *t = rtnl_ematch_data(e);
- t->cfg.from_offset = offset;
- t->cfg.from_layer = layer;
- }
- uint16_t rtnl_ematch_text_get_from_offset(struct rtnl_ematch *e)
- {
- return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_offset;
- }
- uint8_t rtnl_ematch_text_get_from_layer(struct rtnl_ematch *e)
- {
- return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_layer;
- }
- void rtnl_ematch_text_set_to(struct rtnl_ematch *e, uint8_t layer,
- uint16_t offset)
- {
- struct text_data *t = rtnl_ematch_data(e);
- t->cfg.to_offset = offset;
- t->cfg.to_layer = layer;
- }
- uint16_t rtnl_ematch_text_get_to_offset(struct rtnl_ematch *e)
- {
- return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_offset;
- }
- uint8_t rtnl_ematch_text_get_to_layer(struct rtnl_ematch *e)
- {
- return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_layer;
- }
- void rtnl_ematch_text_set_pattern(struct rtnl_ematch *e,
- char *pattern, size_t len)
- {
- struct text_data *t = rtnl_ematch_data(e);
- if (t->pattern)
- free(t->pattern);
- t->pattern = pattern;
- t->cfg.pattern_len = len;
- }
- char *rtnl_ematch_text_get_pattern(struct rtnl_ematch *e)
- {
- return ((struct text_data *) rtnl_ematch_data(e))->pattern;
- }
- size_t rtnl_ematch_text_get_len(struct rtnl_ematch *e)
- {
- return ((struct text_data *) rtnl_ematch_data(e))->cfg.pattern_len;
- }
- void rtnl_ematch_text_set_algo(struct rtnl_ematch *e, const char *algo)
- {
- struct text_data *t = rtnl_ematch_data(e);
- strncpy(t->cfg.algo, algo, sizeof(t->cfg.algo));
- }
- char *rtnl_ematch_text_get_algo(struct rtnl_ematch *e)
- {
- struct text_data *t = rtnl_ematch_data(e);
- return t->cfg.algo[0] ? t->cfg.algo : NULL;
- }
- static int text_parse(struct rtnl_ematch *e, void *data, size_t len)
- {
- struct text_data *t = rtnl_ematch_data(e);
- size_t hdrlen = sizeof(struct tcf_em_text);
- size_t plen = len - hdrlen;
- memcpy(&t->cfg, data, hdrlen);
- if (t->cfg.pattern_len > plen)
- return -NLE_INVAL;
- if (t->cfg.pattern_len > 0) {
- if (!(t->pattern = calloc(1, t->cfg.pattern_len)))
- return -NLE_NOMEM;
- memcpy(t->pattern, data + hdrlen, t->cfg.pattern_len);
- }
- return 0;
- }
- static void text_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
- {
- struct text_data *t = rtnl_ematch_data(e);
- char buf[64];
- nl_dump(p, "text(%s \"%s\"",
- t->cfg.algo[0] ? t->cfg.algo : "no-algo",
- t->pattern ? : "no-pattern");
- if (t->cfg.from_layer || t->cfg.from_offset) {
- nl_dump(p, " from %s",
- rtnl_ematch_offset2txt(t->cfg.from_layer,
- t->cfg.from_offset,
- buf, sizeof(buf)));
- }
- if (t->cfg.to_layer || t->cfg.to_offset) {
- nl_dump(p, " to %s",
- rtnl_ematch_offset2txt(t->cfg.to_layer,
- t->cfg.to_offset,
- buf, sizeof(buf)));
- }
- nl_dump(p, ")");
- }
- static int text_fill(struct rtnl_ematch *e, struct nl_msg *msg)
- {
- struct text_data *t = rtnl_ematch_data(e);
- int err;
- if ((err = nlmsg_append(msg, &t->cfg, sizeof(t->cfg), 0)) < 0)
- return err;
- return nlmsg_append(msg, t->pattern, t->cfg.pattern_len, 0);
- }
- static void text_free(struct rtnl_ematch *e)
- {
- struct text_data *t = rtnl_ematch_data(e);
- free(t->pattern);
- }
- static struct rtnl_ematch_ops text_ops = {
- .eo_kind = TCF_EM_TEXT,
- .eo_name = "text",
- .eo_minlen = sizeof(struct tcf_em_text),
- .eo_datalen = sizeof(struct text_data),
- .eo_parse = text_parse,
- .eo_dump = text_dump,
- .eo_fill = text_fill,
- .eo_free = text_free,
- };
- static void __init text_init(void)
- {
- rtnl_ematch_register(&text_ops);
- }
- /** @} */
|