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-2025 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.5.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 Flags field
185  TRACE_DEBUG(" Flags = 0x%" PRIX8 "\r\n", message->flags);
186  //Dump S field
187  TRACE_DEBUG(" S = %" PRIu8 "\r\n", message->s);
188  //Dump QRV field
189  TRACE_DEBUG(" QRV = %" PRIu8 "\r\n", message->qrv);
190 
191  //The Querier's Query Interval Code field specifies the [Query Interval]
192  //used by the querier
193  if(message->qqic < 128)
194  {
195  //The time is represented in units of seconds
196  qqic = message->qqic;
197  }
198  else
199  {
200  //Max Resp Code represents a floating-point value
201  qqic = mldDecodeFloatingPointValue8(message->maxRespCode);
202  }
203 
204  //Dump QQIC field
205  TRACE_DEBUG(" QQIC = %" PRIu8 " (%us)\r\n", message->qqic, qqic);
206 
207  //The Number of Sources field specifies how many source addresses are
208  //present in the Query
209  n = ntohs(message->numOfSources);
210 
211  //Malformed message?
212  if(length < (sizeof(MldListenerQueryV2) + n * sizeof(Ipv6Addr)))
213  return;
214 
215  //Dump Number of Sources field
216  TRACE_DEBUG(" Number of Sources = %u\r\n", n);
217 
218  //Dump Source Address field
219  for(i = 0; i < n; i++)
220  {
221  TRACE_DEBUG(" Source Address %u = %s\r\n", i + 1,
222  ipv6AddrToString(&message->srcAddr[i], NULL));
223  }
224 }
225 
226 
227 /**
228  * @brief Dump MLDv2 Report message for debugging purpose
229  * @param[in] message Pointer to the MLD message to dump
230  * @param[in] length Length of the MLD message, in bytes
231  **/
232 
234 {
235  size_t i;
236  size_t n;
237  uint_t k;
238  uint_t numRecords;
239  const MldMcastAddrRecord *record;
240 
241  //Malformed message?
242  if(length < sizeof(MldListenerReportV2))
243  return;
244 
245  //Get the length occupied by the multicast address records
246  length -= sizeof(MldListenerReportV2);
247 
248  //Dump Checksum field
249  TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
250  //Dump Flags field
251  TRACE_DEBUG(" Flags = 0x%04" PRIX16 "\r\n", ntohs(message->flags));
252 
253  //The Nr of Mcast Address Records field specifies how many Group Records are
254  //present in this Report
255  numRecords = ntohs(message->numOfMcastAddrRecords);
256 
257  //Dump Nr of Mcast Address Records field
258  TRACE_DEBUG(" Nr of Mcast Address Records = %u\r\n", numRecords);
259 
260  //Loop through the multicast address records
261  for(i = 0, k = 0; i < length && k < numRecords; i += n, k++)
262  {
263  //Malformed message?
264  if((i + sizeof(MldMcastAddrRecord)) > length)
265  break;
266 
267  //Point to the current multicast address record
268  record = (MldMcastAddrRecord *) (message->mcastAddrRecords + i);
269 
270  //Determine the length of the multicast address record
271  n = sizeof(MldMcastAddrRecord) + record->auxDataLen +
272  ntohs(record->numOfSources) * sizeof(Ipv6Addr);
273 
274  //Malformed message?
275  if((i + n) > length)
276  break;
277 
278  //Debug message
279  TRACE_DEBUG(" Multicast Address Record %u\r\n", k + 1);
280 
281  //Dump current multicast address record
282  mldDumpMulticastAddrRecord(record, n);
283  }
284 }
285 
286 
287 /**
288  * @brief Dump multicast address record for debugging purpose
289  * @param[in] record Pointer to the multicast address record to dump
290  * @param[in] length Length of the multicast address record, in bytes
291  **/
292 
294  size_t length)
295 {
296  uint_t i;
297  uint_t n;
298  const char_t *name;
299 
300  //Malformed multicast address record?
301  if(length < sizeof(MldMcastAddrRecord))
302  return;
303 
304  //Convert the Record Type field to string representation
307 
308  //Dump Record Type field
309  TRACE_DEBUG(" Record Type = 0x%02" PRIX8 " (%s)\r\n", record->recordType,
310  name);
311 
312  //Dump Aux Data Len field
313  TRACE_DEBUG(" Aux Data Len = %" PRIu8 "\r\n", record->auxDataLen);
314 
315  //The Number of Sources field specifies how many source addresses are
316  //present in this Group Record
317  n = htons(record->numOfSources);
318 
319  //Malformed group record?
320  if(length < (sizeof(MldMcastAddrRecord) + n * sizeof(Ipv6Addr)))
321  return;
322 
323  //Dump Number of Sources field
324  TRACE_DEBUG(" Number of Sources = %u\r\n", n);
325 
326  //Dump Multicast Address field
327  TRACE_DEBUG(" Multicast Address = %s\r\n",
328  ipv6AddrToString(&record->multicastAddr, NULL));
329 
330  //Dump Source Address field
331  for(i = 0; i < n; i++)
332  {
333  TRACE_DEBUG(" Source Address %u = %s\r\n", i + 1,
334  ipv6AddrToString(&record->srcAddr[i], NULL));
335  }
336 }
337 
338 
339 /**
340  * @brief Convert a parameter to string representation
341  * @param[in] value Parameter value
342  * @param[in] paramList List of acceptable parameters
343  * @param[in] paramListLen Number of entries in the list
344  * @return NULL-terminated string describing the parameter
345  **/
346 
347 const char_t *mldGetParamName(uint_t value, const MldParamName *paramList,
348  size_t paramListLen)
349 {
350  uint_t i;
351 
352  //Default name for unknown values
353  static const char_t defaultName[] = "Unknown";
354 
355  //Loop through the list of acceptable parameters
356  for(i = 0; i < paramListLen; i++)
357  {
358  if(paramList[i].value == value)
359  return paramList[i].name;
360  }
361 
362  //Unknown value
363  return defaultName;
364 }
365 
366 #endif
char_t * ipv6AddrToString(const Ipv6Addr *ipAddr, char_t *str)
Convert a binary IPv6 address to a string representation.
Definition: ipv6.c:2339
#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:295
void mldDumpReportV2(const MldListenerReportV2 *message, size_t length)
Dump MLDv2 Report message for debugging purpose.
Definition: mld_debug.c:233
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:375
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:347
#define TRACE_DEBUG(...)
Definition: debug.h:119
char char_t
Definition: compiler_port.h:55
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:316
uint8_t value[]
Definition: tcp.h:376
@ 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:293
MldListenerQueryV2
Definition: mld_common.h:161
@ ICMPV6_TYPE_MCAST_LISTENER_REPORT_V2
Definition: icmpv6.h:67
unsigned int uint_t
Definition: compiler_port.h:57
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