Line data Source code
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 4 : format_igmp_type (u8 * s, va_list * args)
23 : {
24 4 : igmp_type_t type = va_arg (*args, int);
25 :
26 4 : switch (type)
27 : {
28 : #define _(n,f) case IGMP_TYPE_##f: return (format (s, "%s", #f));
29 4 : foreach_igmp_type
30 : #undef _
31 : }
32 0 : return format (s, "unknown:%d", type);
33 : }
34 :
35 : u8 *
36 2 : format_igmp_membership_group_type (u8 * s, va_list * args)
37 : {
38 2 : igmp_membership_group_v3_type_t type = va_arg (*args, int);
39 :
40 2 : switch (type)
41 : {
42 : #define _(n,f) case IGMP_MEMBERSHIP_GROUP_##f: return (format (s, "%s", #f));
43 2 : foreach_igmp_membership_group_v3_type
44 : #undef _
45 : }
46 0 : return (format (s, "unknown:%d", type));
47 : }
48 :
49 : u8 *
50 2 : format_igmp_filter_mode (u8 * s, va_list * args)
51 : {
52 2 : igmp_filter_mode_t mode = va_arg (*args, igmp_filter_mode_t);
53 :
54 2 : switch (mode)
55 : {
56 : #define _(n,f) case IGMP_FILTER_MODE_##f: return (format (s, "%s", #f));
57 2 : foreach_igmp_filter_mode
58 : #undef _
59 : }
60 0 : return (format (s, "unknown:%d", mode));
61 :
62 : }
63 :
64 : u8 *
65 1 : format_igmp_mode (u8 * s, va_list * args)
66 : {
67 1 : igmp_mode_t mode = va_arg (*args, igmp_mode_t);
68 :
69 1 : switch (mode)
70 : {
71 : #define _(n,f) case IGMP_MODE_##f: return (format (s, "%s", #f));
72 1 : foreach_igmp_mode
73 : #undef _
74 : }
75 0 : return (format (s, "unknown:%d", mode));
76 :
77 : }
78 :
79 : u8 *
80 4 : format_igmp_header (u8 * s, va_list * args)
81 : {
82 4 : igmp_header_t *hdr = va_arg (*args, igmp_header_t *);
83 4 : u32 max_header_bytes = va_arg (*args, u32);
84 : u32 indent;
85 :
86 4 : if (max_header_bytes < sizeof (hdr[0]))
87 0 : return format (s, "IGMP header truncated");
88 :
89 4 : indent = format_get_indent (s);
90 4 : indent += 2;
91 :
92 : s =
93 4 : format (s, "%U%U: code %u, checksum 0x%04x", format_white_space, indent,
94 4 : format_igmp_type, hdr->type, hdr->code,
95 4 : clib_net_to_host_u16 (hdr->checksum));
96 4 : return s;
97 : }
98 :
99 : u8 *
100 2 : format_igmp_report_v3 (u8 * s, va_list * args)
101 : {
102 2 : igmp_membership_report_v3_t *igmp =
103 : va_arg (*args, igmp_membership_report_v3_t *);
104 2 : u32 max_header_bytes = va_arg (*args, u32);
105 : igmp_membership_group_v3_t *group;
106 :
107 2 : u32 len = sizeof (igmp_membership_report_v3_t);
108 : u32 indent;
109 :
110 2 : if (max_header_bytes < sizeof (igmp[0]))
111 0 : return format (s, "IGMP report truncated");
112 :
113 2 : indent = format_get_indent (s);
114 2 : indent += 2;
115 :
116 : s =
117 2 : format (s, "%Un_groups %u", format_white_space, indent,
118 2 : clib_net_to_host_u16 (igmp->n_groups));
119 2 : indent += 2;
120 2 : int i, j = 0;
121 4 : for (i = 0; i < clib_net_to_host_u16 (igmp->n_groups); i++)
122 : {
123 2 : group = group_ptr (igmp, len);
124 : s =
125 2 : format (s, "\n%U%U: %U, sources %u", format_white_space, indent,
126 2 : format_igmp_membership_group_type, group->type,
127 : format_ip4_address, &group->group_address,
128 2 : clib_net_to_host_u16 (group->n_src_addresses));
129 2 : indent += 2;
130 3 : for (j = 0; j < clib_net_to_host_u16 (group->n_src_addresses); j++)
131 : {
132 : s =
133 1 : format (s, "\n%U%U", format_white_space, indent,
134 : format_ip4_address, &group->src_addresses[j]);
135 : }
136 2 : indent -= 2;
137 2 : len +=
138 2 : sizeof (igmp_membership_group_v3_t) +
139 : (sizeof (ip4_address_t) *
140 2 : clib_net_to_host_u16 (group->n_src_addresses));
141 : }
142 2 : return s;
143 : }
144 :
145 : u8 *
146 2 : format_igmp_query_v3 (u8 * s, va_list * args)
147 : {
148 2 : igmp_membership_query_v3_t *igmp =
149 : va_arg (*args, igmp_membership_query_v3_t *);
150 2 : u32 max_header_bytes = va_arg (*args, u32);
151 : u32 indent;
152 : int i;
153 :
154 2 : if (max_header_bytes < sizeof (igmp[0]))
155 0 : return format (s, "IGMP query truncated");
156 :
157 2 : indent = format_get_indent (s);
158 2 : indent += 2;
159 :
160 : ip4_address_t tmp;
161 2 : tmp.as_u32 = 0;
162 :
163 2 : if ((!ip4_address_compare (&igmp->group_address, &tmp))
164 0 : && (igmp->n_src_addresses == 0))
165 0 : s = format (s, "%UGeneral Query", format_white_space, indent);
166 2 : else if (igmp->n_src_addresses == 0)
167 0 : s = format (s, "%UGroup-Specific Query: %U", format_white_space, indent,
168 : format_ip4_address, &igmp->group_address);
169 : else
170 : {
171 : s =
172 2 : format (s, "%UGroup-and-Source-Specific Query: %U",
173 : format_white_space, indent, format_ip4_address,
174 : &igmp->group_address);
175 2 : indent += 2;
176 7 : for (i = 0; i < clib_net_to_host_u16 (igmp->n_src_addresses); i++)
177 : {
178 5 : s = format (s, "\n%U%U", format_white_space, indent,
179 : format_ip4_address, &igmp->src_addresses[i]);
180 : }
181 : }
182 2 : return s;
183 : }
184 :
185 : u8 *
186 2 : format_igmp_src_addr_list (u8 * s, va_list * args)
187 : {
188 : ip46_address_t *ss, *srcs;
189 :
190 2 : srcs = va_arg (*args, ip46_address_t *);
191 :
192 2 : s = format (s, "[");
193 4 : vec_foreach (ss, srcs)
194 : {
195 2 : s = format (s, "%U ", format_ip46_address, ss, IP46_TYPE_ANY);
196 : }
197 2 : s = format (s, "]");
198 :
199 2 : return (s);
200 : }
201 :
202 : u8 *
203 10 : format_igmp_key (u8 * s, va_list * args)
204 : {
205 10 : const igmp_key_t *key = va_arg (*args, const igmp_key_t *);
206 :
207 10 : s = format (s, "%U", format_ip46_address, key, IP46_TYPE_ANY);
208 :
209 10 : return (s);
210 : }
211 :
212 : u8 *
213 1 : format_igmp_proxy_device_id (u8 * s, va_list * args)
214 : {
215 1 : u32 id = va_arg (*args, u32);
216 :
217 1 : s = (id == ~0) ? s : format (s, "proxy device: %u", id);
218 :
219 1 : return (s);
220 : }
221 :
222 : /*
223 : * fd.io coding-style-patch-verification: ON
224 : *
225 : * Local Variables:
226 : * eval: (c-set-style "gnu")
227 : * End:
228 : */
|