libnl  3.5.0
nbyte.c
1 /*
2  * lib/route/cls/ematch/nbyte.c Nbyte comparison
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_nbyte N-Byte Comparison
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/nbyte.h>
24 #include <linux/tc_ematch/tc_em_nbyte.h>
25 
26 struct nbyte_data
27 {
28  struct tcf_em_nbyte cfg;
29  uint8_t * pattern;
30 };
31 
32 void rtnl_ematch_nbyte_set_offset(struct rtnl_ematch *e, uint8_t layer,
33  uint16_t offset)
34 {
35  struct nbyte_data *n = rtnl_ematch_data(e);
36  n->cfg.off = offset;
37  n->cfg.layer = layer;
38 }
39 
40 uint16_t rtnl_ematch_nbyte_get_offset(struct rtnl_ematch *e)
41 {
42  return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.off;
43 }
44 
45 uint8_t rtnl_ematch_nbyte_get_layer(struct rtnl_ematch *e)
46 {
47  return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.layer;
48 }
49 
50 void rtnl_ematch_nbyte_set_pattern(struct rtnl_ematch *e,
51  uint8_t *pattern, size_t len)
52 {
53  struct nbyte_data *n = rtnl_ematch_data(e);
54 
55  if (n->pattern)
56  free(n->pattern);
57 
58  n->pattern = pattern;
59  n->cfg.len = len;
60 }
61 
62 uint8_t *rtnl_ematch_nbyte_get_pattern(struct rtnl_ematch *e)
63 {
64  return ((struct nbyte_data *) rtnl_ematch_data(e))->pattern;
65 }
66 
67 size_t rtnl_ematch_nbyte_get_len(struct rtnl_ematch *e)
68 {
69  return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.len;
70 }
71 
72 static const char *layer_txt(struct tcf_em_nbyte *nbyte)
73 {
74  switch (nbyte->layer) {
75  case TCF_LAYER_LINK:
76  return "link";
77  case TCF_LAYER_NETWORK:
78  return "net";
79  case TCF_LAYER_TRANSPORT:
80  return "trans";
81  default:
82  return "?";
83  }
84 }
85 
86 static int nbyte_parse(struct rtnl_ematch *e, void *data, size_t len)
87 {
88  struct nbyte_data *n = rtnl_ematch_data(e);
89  size_t hdrlen = sizeof(struct tcf_em_nbyte);
90  size_t plen = len - hdrlen;
91 
92  memcpy(&n->cfg, data, hdrlen);
93  if (plen > 0) {
94  if (!(n->pattern = calloc(1, plen)))
95  return -NLE_NOMEM;
96 
97  memcpy(n->pattern, (char *) data + hdrlen, plen);
98  }
99 
100  return 0;
101 }
102 
103 static void nbyte_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
104 {
105  struct nbyte_data *n = rtnl_ematch_data(e);
106  int i;
107 
108  nl_dump(p, "pattern(%u:[", n->cfg.len);
109 
110  for (i = 0; i < n->cfg.len; i++) {
111  nl_dump(p, "%02x", n->pattern[i]);
112  if (i+1 < n->cfg.len)
113  nl_dump(p, " ");
114  }
115 
116  nl_dump(p, "] at %s+%u)", layer_txt(&n->cfg), n->cfg.off);
117 }
118 
119 static void nbyte_free(struct rtnl_ematch *e)
120 {
121  struct nbyte_data *n = rtnl_ematch_data(e);
122  free(n->pattern);
123 }
124 
125 static struct rtnl_ematch_ops nbyte_ops = {
126  .eo_kind = TCF_EM_NBYTE,
127  .eo_name = "nbyte",
128  .eo_minlen = sizeof(struct tcf_em_nbyte),
129  .eo_datalen = sizeof(struct nbyte_data),
130  .eo_parse = nbyte_parse,
131  .eo_dump = nbyte_dump,
132  .eo_free = nbyte_free,
133 };
134 
135 static void __init nbyte_init(void)
136 {
137  rtnl_ematch_register(&nbyte_ops);
138 }
139 
140 /** @} */
int rtnl_ematch_register(struct rtnl_ematch_ops *ops)
Register ematch module.
Definition: ematch.c:46
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:962
Extended Match Operations.
Definition: ematch.h:33