FD.io VPP  v19.08-27-gf4dcae4
Vector Packet Processing
snap.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  * snap.c: snap support
17  *
18  * Copyright (c) 2010 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <vnet/vnet.h>
41 #include <vnet/snap/snap.h>
42 #include <vnet/ethernet/ethernet.h>
43 
44 /* Global main structure. */
46 
47 static u8 *
48 format_cisco_snap_protocol (u8 * s, va_list * args)
49 {
50  snap_header_t *h = va_arg (*args, snap_header_t *);
51  u16 protocol = clib_net_to_host_u16 (h->protocol);
52  char *t = 0;
53  switch (protocol)
54  {
55 #define _(n,f) case n: t = #f; break;
57 #undef _
58  default:
59  break;
60  }
61  if (t)
62  return format (s, "%s", t);
63  else
64  return format (s, "unknown 0x%x", protocol);
65 }
66 
67 u8 *
68 format_snap_protocol (u8 * s, va_list * args)
69 {
70  snap_header_t *h = va_arg (*args, snap_header_t *);
71  u32 oui = snap_header_get_oui (h);
72  u16 protocol = clib_net_to_host_u16 (h->protocol);
73 
74  switch (oui)
75  {
76  case IEEE_OUI_ethernet:
77  return format (s, "ethernet %U", format_ethernet_type, h->protocol);
78 
79  case IEEE_OUI_cisco:
80  return format (s, "cisco %U", format_cisco_snap_protocol, h);
81 
82  default:
83  return format (s, "oui 0x%06x 0x%04x", oui, protocol);
84  }
85 }
86 
87 u8 *
88 format_snap_header_with_length (u8 * s, va_list * args)
89 {
90  snap_main_t *sm = &snap_main;
91  snap_header_t *h = va_arg (*args, snap_header_t *);
93  u32 max_header_bytes = va_arg (*args, u32);
94  u32 indent, header_bytes;
95 
96  header_bytes = sizeof (h[0]);
97  if (max_header_bytes != 0 && header_bytes > max_header_bytes)
98  return format (s, "snap header truncated");
99 
100  indent = format_get_indent (s);
101 
102  s = format (s, "SNAP %U", format_snap_protocol, h);
103 
104  if (max_header_bytes != 0 && header_bytes > max_header_bytes && pi != 0)
105  {
106  vlib_node_t *node = vlib_get_node (sm->vlib_main, pi->node_index);
107  if (node->format_buffer)
108  s = format (s, "\n%U%U",
109  format_white_space, indent,
110  node->format_buffer, (void *) (h + 1),
111  max_header_bytes - header_bytes);
112  }
113 
114  return s;
115 }
116 
117 u8 *
118 format_snap_header (u8 * s, va_list * args)
119 {
120  snap_header_t *h = va_arg (*args, snap_header_t *);
121  return format (s, "%U", format_snap_header_with_length, h, 0);
122 }
123 
124 /* Returns snap protocol as an int in host byte order. */
125 uword
126 unformat_snap_protocol (unformat_input_t * input, va_list * args)
127 {
128  snap_header_t *result = va_arg (*args, snap_header_t *);
129  snap_main_t *sm = &snap_main;
131  u32 i;
132 
133  /* Numeric type. */
134  if (unformat (input, "0x%x 0x%x", &p.oui, &p.protocol))
135  {
136  if (p.oui >= (1 << 24))
137  return 0;
138  if (p.protocol >= (1 << 16))
139  return 0;
140  }
141 
142  /* Named type. */
144  sm->protocol_info_by_name, &i))
145  {
147  p = pi->oui_and_protocol;
148  }
149 
150  else
151  return 0;
152 
153  snap_header_set_protocol (result, &p);
154  return 1;
155 }
156 
157 uword
158 unformat_snap_header (unformat_input_t * input, va_list * args)
159 {
160  u8 **result = va_arg (*args, u8 **);
161  snap_header_t _h, *h = &_h;
162 
163  if (!unformat (input, "%U", unformat_snap_protocol, h))
164  return 0;
165 
166  /* Add header to result. */
167  {
168  void *p;
169  u32 n_bytes = sizeof (h[0]);
170 
171  vec_add2 (*result, p, n_bytes);
172  clib_memcpy (p, h, n_bytes);
173  }
174 
175  return 1;
176 }
177 
178 static clib_error_t *
180 {
181  snap_main_t *sm = &snap_main;
182 
183  clib_memset (sm, 0, sizeof (sm[0]));
184  sm->vlib_main = vm;
185 
186  mhash_init (&sm->protocol_hash, sizeof (uword),
187  sizeof (snap_oui_and_protocol_t));
188 
190  = hash_create_string ( /* elts */ 0, sizeof (uword));
191 
193 }
194 
196 
197 
198 /*
199  * fd.io coding-style-patch-verification: ON
200  *
201  * Local Variables:
202  * eval: (c-set-style "gnu")
203  * End:
204  */
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:560
int i
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
static u32 format_get_indent(u8 *s)
Definition: format.h:72
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
unsigned char u8
Definition: types.h:56
#define clib_memcpy(d, s, n)
Definition: string.h:180
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
static clib_error_t * snap_input_init(vlib_main_t *vm)
Definition: node.c:288
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
unsigned int u32
Definition: types.h:88
static void snap_header_set_protocol(snap_header_t *h, snap_oui_and_protocol_t *p)
Definition: snap.h:113
#define vlib_call_init_function(vm, x)
Definition: init.h:270
#define hash_create_string(elts, value_bytes)
Definition: hash.h:690
snap_oui_and_protocol_t oui_and_protocol
Definition: snap.h:103
vl_api_ip_proto_t protocol
Definition: punt.api:39
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
format_function_t * format_buffer
Definition: node.h:356
static u8 * format_cisco_snap_protocol(u8 *s, va_list *args)
Definition: snap.c:48
mhash_t protocol_hash
Definition: snap.h:143
u8 * format_ethernet_type(u8 *s, va_list *args)
Definition: format.c:64
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
Definition: mhash.c:168
vlib_main_t * vm
Definition: buffer.c:312
static snap_protocol_info_t * snap_get_protocol_info(snap_main_t *sm, snap_header_t *h)
Definition: snap.h:156
uword unformat_snap_header(unformat_input_t *input, va_list *args)
Definition: snap.c:158
uword * protocol_info_by_name
Definition: snap.h:146
static u32 snap_header_get_oui(snap_header_t *h)
Definition: snap.h:150
u8 * format_snap_protocol(u8 *s, va_list *args)
Definition: snap.c:68
snap_main_t snap_main
Definition: snap.c:45
uword unformat_vlib_number_by_name(unformat_input_t *input, va_list *args)
Definition: format.c:157
u64 uword
Definition: types.h:112
vlib_main_t * vlib_main
Definition: snap.h:137
uword unformat_snap_protocol(unformat_input_t *input, va_list *args)
Definition: snap.c:126
u8 * format_snap_header_with_length(u8 *s, va_list *args)
Definition: snap.c:88
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:59
snap_protocol_info_t * protocols
Definition: snap.h:140
u8 * format_snap_header(u8 *s, va_list *args)
Definition: snap.c:118
static clib_error_t * snap_init(vlib_main_t *vm)
Definition: snap.c:179
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978