mld_debug.c
Go to the documentation of this file.
1 /**
2  * @file mld_debug.c
3  * @brief Data logging functions for debugging purpose (MLD)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL MLD_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "ipv6/icmpv6.h"
37 #include "mld/mld_debug.h"
38 #include "debug.h"
39 
40 //Check TCP/IP stack configuration
41 #if (IPV6_SUPPORT == ENABLED && MLD_TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
42 
43 //MLD message types
45 {
46  {ICMPV6_TYPE_MCAST_LISTENER_QUERY, "Multicast Listener Query"},
47  {ICMPV6_TYPE_MCAST_LISTENER_REPORT_V1, "Version 1 Multicast Listener Report"},
48  {ICMPV6_TYPE_MCAST_LISTENER_DONE_V1, "Version 1 Multicast Listener Done"},
49  {ICMPV6_TYPE_MCAST_LISTENER_REPORT_V2, "Version 2 Multicast Listener Report"}
50 };
51 
52 //MLDv2 multicast address record types
54 {
55  {MLD_MCAST_ADDR_RECORD_TYPE_IS_IN, "MODE_IS_INCLUDE"},
56  {MLD_MCAST_ADDR_RECORD_TYPE_IS_EX, "MODE_IS_EXCLUDE"},
57  {MLD_MCAST_ADDR_RECORD_TYPE_TO_IN, "CHANGE_TO_INCLUDE_MODE"},
58  {MLD_MCAST_ADDR_RECORD_TYPE_TO_EX, "CHANGE_TO_EXCLUDE_MODE"},
59  {MLD_MCAST_ADDR_RECORD_TYPE_ALLOW, "ALLOW_NEW_SOURCES"},
60  {MLD_MCAST_ADDR_RECORD_TYPE_BLOCK, "BLOCK_OLD_SOURCES"}
61 };
62 
63 
64 /**
65  * @brief Dump MLD message for debugging purpose
66  * @param[in] message Pointer to the MLD message to dump
67  * @param[in] length Length of the MLD message, in bytes
68  **/
69 
71 {
73  const char_t *name;
74 
75  //Malformed message?
76  if(length < sizeof(MldMessage))
77  return;
78 
79  //Convert the Type field to string representation
82 
83  //Dump Type field
84  TRACE_DEBUG(" Type = %" PRIu8 " (%s)\r\n", message->type, name);
85 
86  //Check message type
88  length == sizeof(MldMessage))
89  {
90  //Dump Code field
91  TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
92 
93  //The Maximum Response Delay field is meaningful only in Query messages,
94  //and specifies the maximum allowed delay before sending a responding
95  //report, in units of milliseconds
96  maxRespDelay = ntohs(message->maxRespDelay);
97 
98  //Dump Maximum Response Delay field
99  TRACE_DEBUG(" Maximum Response Delay = %" PRIu8 " (%u.%03us)\r\n",
100  maxRespDelay, maxRespDelay / 1000, maxRespDelay % 1000);
101 
102  //Dump Checksum field
103  TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
104 
105  //Dump Multicast Address field
106  TRACE_DEBUG(" Multicast Address = %s\r\n",
107  ipv6AddrToString(&message->multicastAddr, NULL));
108  }
109  else if(message->type == ICMPV6_TYPE_MCAST_LISTENER_QUERY &&
110  length >= sizeof(MldListenerQueryV2))
111  {
112  //Dump Version 2 Multicast Listener Query message
114  }
116  {
117  //Dump Version 2 Multicast Listener Report message
119  }
120  else
121  {
122  //Dump Code field
123  TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
124 
125  //Dump Checksum field
126  TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
127 
128  //Dump Multicast Address field
129  TRACE_DEBUG(" Multicast Address = %s\r\n",
130  ipv6AddrToString(&message->multicastAddr, NULL));
131  }
132 }
133 
134 
135 /**
136  * @brief Dump MLDv2 Query message for debugging purpose
137  * @param[in] message Pointer to the MLD message to dump
138  * @param[in] length Length of the MLD message, in bytes
139  **/
140 
142 {
143  uint_t i;
144  uint_t n;
145  uint_t qqic;
146  uint16_t maxRespCode;
148 
149  //Malformed message?
150  if(length < sizeof(MldListenerQueryV2))
151  return;
152 
153  //Dump Code field
154  TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
155 
156  //The Maximum Response Code field specifies the maximum time allowed before
157  //sending a responding report
158  maxRespCode = ntohs(message->maxRespCode);
159 
160  //The Maximum Response Delay is is derived from the Maximum Response Code as
161  //follows
162  if(maxRespCode < 32768)
163  {
164  //The time is represented in units of milliseconds
166  }
167  else
168  {
169  //Maximum Response Code represents a floating-point value
171  }
172 
173  //Dump Maximum Response Code field
174  TRACE_DEBUG(" Maximum Response Code = %" PRIu16 " (%u.%03us)\r\n",
175  message->maxRespCode, maxRespDelay / 1000, maxRespDelay % 1000);
176 
177  //Dump Checksum field
178  TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
179 
180  //Dump Multicast Address field
181  TRACE_DEBUG(" Multicast Address = %s\r\n",
182  ipv6AddrToString(&message->multicastAddr, NULL));
183 
184  //Dump S field
185  TRACE_DEBUG(" S = %" PRIu8 "\r\n", message->s);
186 
187  //The Querier's Query Interval Code field specifies the [Query Interval]
188  //used by the querier
189  if(message->qqic < 128)
190  {
191  //The time is represented in units of seconds
192  qqic = message->qqic;
193  }
194  else
195  {
196  //Max Resp Code represents a floating-point value
197  qqic = mldDecodeFloatingPointValue8(message->maxRespCode);
198  }
199 
200  //Dump QRV field
201  TRACE_DEBUG(" QRV = %" PRIu8 " (%us)\r\n", message->qrv, qqic);
202 
203  //Dump QQIC field
204  TRACE_DEBUG(" QQIC = %" PRIu8 "\r\n", message->qqic);
205 
206  //The Number of Sources field specifies how many source addresses are
207  //present in the Query
208  n = ntohs(message->numOfSources);
209 
210  //Malformed message?
211  if(length < (sizeof(MldListenerQueryV2) + n * sizeof(Ipv6Addr)))
212  return;
213 
214  //Dump Number of Sources field
215  TRACE_DEBUG(" Number of Sources = %u\r\n", n);
216 
217  //Dump Source Address field
218  for(i = 0; i < n; i++)
219  {
220  TRACE_DEBUG(" Source Address %u = %s\r\n", i + 1,
221  ipv6AddrToString(&message->srcAddr[i], NULL));
222  }
223 }
224 
225 
226 /**
227  * @brief Dump MLDv2 Report message for debugging purpose
228  * @param[in] message Pointer to the MLD message to dump
229  * @param[in] length Length of the MLD message, in bytes
230  **/
231 
233 {
234  size_t i;
235  size_t n;
236  uint_t k;
237  uint_t numRecords;
238  const MldMcastAddrRecord *record;
239 
240  //Malformed message?
241  if(length < sizeof(MldListenerReportV2))
242  return;
243 
244  //Get the length occupied by the multicast address records
245  length -= sizeof(MldListenerReportV2);
246 
247  //Dump Checksum field
248  TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
249 
250  //The Nr of Mcast Address Records field specifies how many Group Records are
251  //present in this Report
252  numRecords = ntohs(message->numOfMcastAddrRecords);
253 
254  //Dump Nr of Mcast Address Records field
255  TRACE_DEBUG(" Nr of Mcast Address Records = %u\r\n", numRecords);
256 
257  //Loop through the multicast address records
258  for(i = 0, k = 0; i < length && k < numRecords; i += n, k++)
259  {
260  //Malformed message?
261  if((i + sizeof(MldMcastAddrRecord)) > length)
262  break;
263 
264  //Point to the current multicast address record
265  record = (MldMcastAddrRecord *) (message->mcastAddrRecords + i);
266 
267  //Determine the length of the multicast address record
268  n = sizeof(MldMcastAddrRecord) + record->auxDataLen +
269  ntohs(record->numOfSources) * sizeof(Ipv6Addr);
270 
271  //Malformed message?
272  if((i + n) > length)
273  break;
274 
275  //Debug message
276  TRACE_DEBUG(" Multicast Address Record %u\r\n", k + 1);
277 
278  //Dump current multicast address record
279  mldDumpMulticastAddrRecord(record, n);
280  }
281 }
282 
283 
284 /**
285  * @brief Dump multicast address record for debugging purpose
286  * @param[in] record Pointer to the multicast address record to dump
287  * @param[in] length Length of the multicast address record, in bytes
288  **/
289 
291  size_t length)
292 {
293  uint_t i;
294  uint_t n;
295  const char_t *name;
296 
297  //Malformed multicast address record?
298  if(length < sizeof(MldMcastAddrRecord))
299  return;
300 
301  //Convert the Record Type field to string representation
304 
305  //Dump Record Type field
306  TRACE_DEBUG(" Record Type = 0x%02" PRIX8 " (%s)\r\n", record->recordType,
307  name);
308 
309  //Dump Aux Data Len field
310  TRACE_DEBUG(" Aux Data Len = %" PRIu8 "\r\n", record->auxDataLen);
311 
312  //The Number of Sources field specifies how many source addresses are
313  //present in this Group Record
314  n = htons(record->numOfSources);
315 
316  //Malformed group record?
317  if(length < (sizeof(MldMcastAddrRecord) + n * sizeof(Ipv6Addr)))
318  return;
319 
320  //Dump Number of Sources field
321  TRACE_DEBUG(" Number of Sources = %u\r\n", n);
322 
323  //Dump Multicast Address field
324  TRACE_DEBUG(" Multicast Address = %s\r\n",
325  ipv6AddrToString(&record->multicastAddr, NULL));
326 
327  //Dump Source Address field
328  for(i = 0; i < n; i++)
329  {
330  TRACE_DEBUG(" Source Address %u = %s\r\n", i + 1,
331  ipv6AddrToString(&record->srcAddr[i], NULL));
332  }
333 }
334 
335 
336 /**
337  * @brief Convert a parameter to string representation
338  * @param[in] value Parameter value
339  * @param[in] paramList List of acceptable parameters
340  * @param[in] paramListLen Number of entries in the list
341  * @return NULL-terminated string describing the parameter
342  **/
343 
344 const char_t *mldGetParamName(uint_t value, const MldParamName *paramList,
345  size_t paramListLen)
346 {
347  uint_t i;
348 
349  //Default name for unknown values
350  static const char_t defaultName[] = "Unknown";
351 
352  //Loop through the list of acceptable parameters
353  for(i = 0; i < paramListLen; i++)
354  {
355  if(paramList[i].value == value)
356  return paramList[i].name;
357  }
358 
359  //Unknown value
360  return defaultName;
361 }
362 
363 #endif
char_t * ipv6AddrToString(const Ipv6Addr *ipAddr, char_t *str)
Convert a binary IPv6 address to a string representation.
Definition: ipv6.c:2329
#define htons(value)
Definition: cpu_endian.h:413
Parameter value/name binding.
Definition: mld_debug.h:50
void mldDumpQueryV2(const MldListenerQueryV2 *message, size_t length)
Dump MLDv2 Query message for debugging purpose.
Definition: mld_debug.c:141
uint32_t mldDecodeFloatingPointValue8(uint8_t code)
Decode a floating-point value (8-bit code)
Definition: mld_common.c:294
void mldDumpReportV2(const MldListenerReportV2 *message, size_t length)
Dump MLDv2 Report message for debugging purpose.
Definition: mld_debug.c:232
uint8_t message[]
Definition: chap.h:154
MldMessage
Definition: mld_common.h:134
Ipv6Addr
Definition: ipv6.h:260
@ MLD_MCAST_ADDR_RECORD_TYPE_IS_EX
Definition: mld_common.h:106
char_t name[]
@ MLD_MCAST_ADDR_RECORD_TYPE_IS_IN
Definition: mld_common.h:105
@ ICMPV6_TYPE_MCAST_LISTENER_QUERY
Definition: icmpv6.h:59
MldMcastAddrRecord
Definition: mld_common.h:190
@ MLD_MCAST_ADDR_RECORD_TYPE_TO_IN
Definition: mld_common.h:107
ICMPv6 (Internet Control Message Protocol Version 6)
uint16_t maxRespDelay
Definition: mld_common.h:131
Data logging functions for debugging purpose (MLD)
@ ICMPV6_TYPE_MCAST_LISTENER_REPORT_V1
Definition: icmpv6.h:60
uint8_t length
Definition: tcp.h:368
MldListenerReportV2
Definition: mld_common.h:176
uint8_t qqic
Definition: igmp_common.h:237
#define ntohs(value)
Definition: cpu_endian.h:421
const char_t * mldGetParamName(uint_t value, const MldParamName *paramList, size_t paramListLen)
Convert a parameter to string representation.
Definition: mld_debug.c:344
#define TRACE_DEBUG(...)
Definition: debug.h:107
char char_t
Definition: compiler_port.h:48
const MldParamName mldMulticastAddrRecordTypeList[]
Definition: mld_debug.c:53
uint8_t n
@ MLD_MCAST_ADDR_RECORD_TYPE_TO_EX
Definition: mld_common.h:108
uint32_t mldDecodeFloatingPointValue16(uint16_t code)
Decode a floating-point value (16-bit code)
Definition: mld_common.c:315
uint8_t value[]
Definition: tcp.h:369
@ ICMPV6_TYPE_MCAST_LISTENER_DONE_V1
Definition: icmpv6.h:61
@ MLD_MCAST_ADDR_RECORD_TYPE_BLOCK
Definition: mld_common.h:110
const char_t * name
Definition: mld_debug.h:52
void mldDumpMulticastAddrRecord(const MldMcastAddrRecord *record, size_t length)
Dump multicast address record for debugging purpose.
Definition: mld_debug.c:290
MldListenerQueryV2
Definition: mld_common.h:161
@ ICMPV6_TYPE_MCAST_LISTENER_REPORT_V2
Definition: icmpv6.h:67
unsigned int uint_t
Definition: compiler_port.h:50
TCP/IP stack core.
@ MLD_MCAST_ADDR_RECORD_TYPE_ALLOW
Definition: mld_common.h:109
void mldDumpMessage(const MldMessage *message, size_t length)
Dump MLD message for debugging purpose.
Definition: mld_debug.c:70
const MldParamName mldMessageTypeList[]
Definition: mld_debug.c:44
uint8_t maxRespCode
Definition: igmp_common.h:225
Debugging facilities.
#define arraysize(a)
Definition: os_port.h:71