FD.io VPP  v16.06
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 * format_cisco_snap_protocol (u8 * s, va_list * args)
48 {
49  snap_header_t * h = va_arg (*args, snap_header_t *);
50  u16 protocol = clib_net_to_host_u16 (h->protocol);
51  char * t = 0;
52  switch (protocol)
53  {
54 #define _(n,f) case n: t = #f; break;
56 #undef _
57  default: break;
58  }
59  if (t)
60  return format (s, "%s", t);
61  else
62  return format (s, "unknown 0x%x", protocol);
63 }
64 
65 u8 * format_snap_protocol (u8 * s, va_list * args)
66 {
67  snap_header_t * h = va_arg (*args, snap_header_t *);
68  u32 oui = snap_header_get_oui (h);
69  u16 protocol = clib_net_to_host_u16 (h->protocol);
70 
71  switch (oui)
72  {
73  case IEEE_OUI_ethernet:
74  return format (s, "ethernet %U", format_ethernet_type, h->protocol);
75 
76  case IEEE_OUI_cisco:
77  return format (s, "cisco %U", format_cisco_snap_protocol, h);
78 
79  default:
80  return format (s, "oui 0x%06x 0x%04x", oui, protocol);
81  }
82 }
83 
84 u8 * format_snap_header_with_length (u8 * s, va_list * args)
85 {
86  snap_main_t * sm = &snap_main;
87  snap_header_t * h = va_arg (*args, snap_header_t *);
89  u32 max_header_bytes = va_arg (*args, u32);
90  uword indent, header_bytes;
91 
92  header_bytes = sizeof (h[0]);
93  if (max_header_bytes != 0 && header_bytes > max_header_bytes)
94  return format (s, "snap header truncated");
95 
96  indent = format_get_indent (s);
97 
98  s = format (s, "SNAP %U", format_snap_protocol, h);
99 
100  if (max_header_bytes != 0 && header_bytes > max_header_bytes && pi != 0)
101  {
102  vlib_node_t * node = vlib_get_node (sm->vlib_main, pi->node_index);
103  if (node->format_buffer)
104  s = format (s, "\n%U%U",
105  format_white_space, indent,
106  node->format_buffer, (void *) (h + 1),
107  max_header_bytes - header_bytes);
108  }
109 
110  return s;
111 }
112 
113 u8 * format_snap_header (u8 * s, va_list * args)
114 {
115  snap_header_t * h = va_arg (*args, snap_header_t *);
116  return format (s, "%U", format_snap_header_with_length, h, 0);
117 }
118 
119 /* Returns snap protocol as an int in host byte order. */
120 uword
121 unformat_snap_protocol (unformat_input_t * input, va_list * args)
122 {
123  snap_header_t * result = va_arg (*args, snap_header_t *);
124  snap_main_t * sm = &snap_main;
126  u32 i;
127 
128  /* Numeric type. */
129  if (unformat (input, "0x%x 0x%x", &p.oui, &p.protocol))
130  {
131  if (p.oui >= (1 << 24))
132  return 0;
133  if (p.protocol >= (1 << 16))
134  return 0;
135  }
136 
137  /* Named type. */
139  sm->protocol_info_by_name, &i))
140  {
142  p = pi->oui_and_protocol;
143  }
144 
145  else
146  return 0;
147 
148  snap_header_set_protocol (result, &p);
149  return 1;
150 }
151 
152 uword
153 unformat_snap_header (unformat_input_t * input, va_list * args)
154 {
155  u8 ** result = va_arg (*args, u8 **);
156  snap_header_t _h, * h = &_h;
157 
158  if (! unformat (input, "%U", unformat_snap_protocol, h))
159  return 0;
160 
161  /* Add header to result. */
162  {
163  void * p;
164  u32 n_bytes = sizeof (h[0]);
165 
166  vec_add2 (*result, p, n_bytes);
167  clib_memcpy (p, h, n_bytes);
168  }
169 
170  return 1;
171 }
172 
174 {
175  snap_main_t * sm = &snap_main;
176 
177  memset (sm, 0, sizeof (sm[0]));
178  sm->vlib_main = vm;
179 
180  mhash_init (&sm->protocol_hash, sizeof (uword), sizeof (snap_oui_and_protocol_t));
181 
183  = hash_create_string (/* elts */ 0, sizeof (uword));
184 
186 }
187 
189 
always_inline snap_protocol_info_t * snap_get_protocol_info(snap_main_t *sm, snap_header_t *h)
Definition: snap.h:147
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:942
always_inline vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Definition: node_funcs.h:46
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:519
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:109
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:107
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:953
#define vlib_call_init_function(vm, x)
Definition: init.h:159
#define hash_create_string(elts, value_bytes)
Definition: hash.h:609
snap_oui_and_protocol_t oui_and_protocol
Definition: snap.h:96
format_function_t * format_buffer
Definition: node.h:277
static u8 * format_cisco_snap_protocol(u8 *s, va_list *args)
Definition: snap.c:47
mhash_t protocol_hash
Definition: snap.h:134
u8 * format_ethernet_type(u8 *s, va_list *args)
Definition: format.c:56
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
Definition: mhash.c:169
uword unformat_snap_header(unformat_input_t *input, va_list *args)
Definition: snap.c:153
uword * protocol_info_by_name
Definition: snap.h:137
#define clib_memcpy(a, b, c)
Definition: string.h:63
uword unformat_vlib_number_by_name(unformat_input_t *input, va_list *args)
Definition: format.c:139
u8 * format_snap_protocol(u8 *s, va_list *args)
Definition: snap.c:65
unsigned int u32
Definition: types.h:88
always_inline u32 snap_header_get_oui(snap_header_t *h)
Definition: snap.h:141
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
snap_main_t snap_main
Definition: snap.c:45
always_inline void snap_header_set_protocol(snap_header_t *h, snap_oui_and_protocol_t *p)
Definition: snap.h:106
always_inline uword format_get_indent(u8 *s)
Definition: format.h:72
u64 uword
Definition: types.h:112
unsigned short u16
Definition: types.h:57
unsigned char u8
Definition: types.h:56
vlib_main_t * vlib_main
Definition: snap.h:128
uword unformat_snap_protocol(unformat_input_t *input, va_list *args)
Definition: snap.c:121
u8 * format_snap_header_with_length(u8 *s, va_list *args)
Definition: snap.c:84
struct _unformat_input_t unformat_input_t
snap_protocol_info_t * protocols
Definition: snap.h:131
u8 * format_snap_header(u8 *s, va_list *args)
Definition: snap.c:113
static clib_error_t * snap_input_init(vlib_main_t *vm)
Definition: node.c:287
static clib_error_t * snap_init(vlib_main_t *vm)
Definition: snap.c:173