FD.io VPP  v18.10-34-gcce845e
Vector Packet Processing
igmp_format.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2018 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 
18 #include <igmp/igmp.h>
19 #include <vnet/ip/ip.h>
20 
21 u8 *
22 format_igmp_type (u8 * s, va_list * args)
23 {
24  igmp_type_t type = va_arg (*args, int);
25 
26  switch (type)
27  {
28 #define _(n,f) case IGMP_TYPE_##f: return (format (s, "%s", #f));
30 #undef _
31  }
32  return format (s, "unknown:%d", type);
33 }
34 
35 u8 *
37 {
38  igmp_membership_group_v3_type_t type = va_arg (*args, int);
39 
40  switch (type)
41  {
42 #define _(n,f) case IGMP_MEMBERSHIP_GROUP_##f: return (format (s, "%s", #f));
44 #undef _
45  }
46  return (format (s, "unknown:%d", type));
47 }
48 
49 u8 *
50 format_igmp_filter_mode (u8 * s, va_list * args)
51 {
52  igmp_filter_mode_t mode = va_arg (*args, igmp_filter_mode_t);
53 
54  switch (mode)
55  {
56 #define _(n,f) case IGMP_FILTER_MODE_##f: return (format (s, "%s", #f));
58 #undef _
59  }
60  return (format (s, "unknown:%d", mode));
61 
62 }
63 
64 u8 *
65 format_igmp_mode (u8 * s, va_list * args)
66 {
67  igmp_mode_t mode = va_arg (*args, igmp_mode_t);
68 
69  switch (mode)
70  {
71 #define _(n,f) case IGMP_MODE_##f: return (format (s, "%s", #f));
73 #undef _
74  }
75  return (format (s, "unknown:%d", mode));
76 
77 }
78 
79 u8 *
80 format_igmp_header (u8 * s, va_list * args)
81 {
82  igmp_header_t *hdr = va_arg (*args, igmp_header_t *);
83  u32 max_header_bytes = va_arg (*args, u32);
84  u32 indent;
85 
86  if (max_header_bytes < sizeof (hdr[0]))
87  return format (s, "IGMP header truncated");
88 
89  indent = format_get_indent (s);
90  indent += 2;
91 
92  s =
93  format (s, "%U%U: code %u, checksum 0x%04x", format_white_space, indent,
94  format_igmp_type, hdr->type, hdr->code,
95  clib_net_to_host_u16 (hdr->checksum));
96  return s;
97 }
98 
99 u8 *
100 format_igmp_report_v3 (u8 * s, va_list * args)
101 {
103  va_arg (*args, igmp_membership_report_v3_t *);
104  u32 max_header_bytes = va_arg (*args, u32);
106 
107  u32 len = sizeof (igmp_membership_report_v3_t);
108  u32 indent;
109 
110  if (max_header_bytes < sizeof (igmp[0]))
111  return format (s, "IGMP report truncated");
112 
113  indent = format_get_indent (s);
114  indent += 2;
115 
116  s =
117  format (s, "%Un_groups %u", format_white_space, indent,
118  clib_net_to_host_u16 (igmp->n_groups));
119  indent += 2;
120  int i, j = 0;
121  for (i = 0; i < clib_net_to_host_u16 (igmp->n_groups); i++)
122  {
123  group = group_ptr (igmp, len);
124  s =
125  format (s, "\n%U%U: %U, sources %u", format_white_space, indent,
128  clib_net_to_host_u16 (group->n_src_addresses));
129  indent += 2;
130  for (j = 0; j < clib_net_to_host_u16 (group->n_src_addresses); j++)
131  {
132  s =
133  format (s, "\n%U%U", format_white_space, indent,
134  format_ip4_address, &group->src_addresses[j]);
135  }
136  indent -= 2;
137  len +=
138  sizeof (igmp_membership_group_v3_t) +
139  (sizeof (ip4_address_t) *
140  clib_net_to_host_u16 (group->n_src_addresses));
141  }
142  return s;
143 }
144 
145 u8 *
146 format_igmp_query_v3 (u8 * s, va_list * args)
147 {
149  va_arg (*args, igmp_membership_query_v3_t *);
150  u32 max_header_bytes = va_arg (*args, u32);
151  u32 indent;
152  int i;
153 
154  if (max_header_bytes < sizeof (igmp[0]))
155  return format (s, "IGMP query truncated");
156 
157  indent = format_get_indent (s);
158  indent += 2;
159 
160  ip4_address_t tmp;
161  tmp.as_u32 = 0;
162 
163  if ((!ip4_address_compare (&igmp->group_address, &tmp))
164  && (igmp->n_src_addresses == 0))
165  s = format (s, "%UGeneral Query", format_white_space, indent);
166  else if (igmp->n_src_addresses == 0)
167  s = format (s, "%UGroup-Specific Query: %U", format_white_space, indent,
169  else
170  {
171  s =
172  format (s, "%UGroup-and-Source-Specific Query: %U",
174  &igmp->group_address);
175  indent += 2;
176  for (i = 0; i < clib_net_to_host_u16 (igmp->n_src_addresses); i++)
177  {
178  s = format (s, "\n%U%U", format_white_space, indent,
179  format_ip4_address, &igmp->src_addresses[i]);
180  }
181  }
182  return s;
183 }
184 
185 u8 *
186 format_igmp_src_addr_list (u8 * s, va_list * args)
187 {
188  ip46_address_t *ss, *srcs;
189 
190  srcs = va_arg (*args, ip46_address_t *);
191 
192  s = format (s, "[");
193  vec_foreach (ss, srcs)
194  {
195  s = format (s, "%U ", format_ip46_address, ss, IP46_TYPE_ANY);
196  }
197  s = format (s, "]");
198 
199  return (s);
200 }
201 
202 u8 *
203 format_igmp_key (u8 * s, va_list * args)
204 {
205  const igmp_key_t *key = va_arg (*args, const igmp_key_t *);
206 
207  s = format (s, "%U", format_ip46_address, key, IP46_TYPE_ANY);
208 
209  return (s);
210 }
211 
212 /*
213  * fd.io coding-style-patch-verification: ON
214  *
215  * Local Variables:
216  * eval: (c-set-style "gnu")
217  * End:
218  */
u8 * format_igmp_src_addr_list(u8 *s, va_list *args)
Definition: igmp_format.c:186
igmp_membership_group_v3_type_t type
Definition: igmp_packet.h:149
u8 * format_igmp_key(u8 *s, va_list *args)
Definition: igmp_format.c:203
ip4_address_t src_addresses[0]
Definition: igmp_packet.h:115
igmp_membership_group_v3_type_t
Definition: igmp_packet.h:140
int i
format_function_t format_ip46_address
Definition: format.h:61
static u32 format_get_indent(u8 *s)
Definition: format.h:72
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
u8 * format_igmp_report_v3(u8 *s, va_list *args)
Definition: igmp_format.c:100
unsigned char u8
Definition: types.h:56
format_function_t format_ip4_address
Definition: format.h:75
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
unsigned int u32
Definition: types.h:88
u8 * format_igmp_header(u8 *s, va_list *args)
Definition: igmp_format.c:80
igmp_type_t type
Definition: igmp_packet.h:70
int ip4_address_compare(ip4_address_t *a1, ip4_address_t *a2)
Definition: ip46_cli.c:53
enum igmp_filter_mode_t_ igmp_filter_mode_t
u8 * format_igmp_mode(u8 *s, va_list *args)
Definition: igmp_format.c:65
u8 * format_igmp_filter_mode(u8 *s, va_list *args)
Definition: igmp_format.c:50
ip4_address_t group_address
Definition: igmp_packet.h:158
ip46_address_t igmp_key_t
IGMP Key Used to index groups within an interface config and sources within a list.
Definition: igmp_types.h:49
u8 * format_igmp_query_v3(u8 *s, va_list *args)
Definition: igmp_format.c:146
enum igmp_mode_t_ igmp_mode_t
ip4_address_t src_addresses[0]
Definition: igmp_packet.h:160
#define vec_foreach(var, vec)
Vector iterator.
u8 * format_igmp_type(u8 *s, va_list *args)
Definition: igmp_format.c:22
#define group_ptr(p, l)
helper macro to get igmp membership group from pointer plus offset
Definition: igmp.h:56
igmp_type_t
Definition: igmp_packet.h:61
u8 * format_igmp_membership_group_type(u8 *s, va_list *args)
Definition: igmp_format.c:36
ip4_address_t group_address
Definition: igmp_packet.h:105