nts_debug.c
Go to the documentation of this file.
1 /**
2  * @file nts_debug.c
3  * @brief Data logging functions for debugging purpose (NTS)
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 NTS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "nts/nts_debug.h"
37 #include "aead/aead_algorithms.h"
38 #include "debug.h"
39 
40 //Check TCP/IP stack configuration
41 #if (NTS_TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
42 
43 //NTS-KE record types
45 {
46  {NTS_KE_RECORD_TYPE_END_OF_MESSAGE, "End of Message"},
47  {NTS_KE_RECORD_TYPE_NTS_NEXT_PROTO_NEGO, "NTS Next Protocol Negotiation"},
48  {NTS_KE_RECORD_TYPE_ERROR, "Error"},
49  {NTS_KE_RECORD_TYPE_WARNING, "Warning"},
50  {NTS_KE_RECORD_TYPE_AEAD_ALGO_NEGO, "AEAD Algorithm Negotiation"},
51  {NTS_KE_RECORD_TYPE_NEW_COOKIE_FOR_NTPV4, "New Cookie for NTPv4"},
52  {NTS_KE_RECORD_TYPE_NTPV4_SERVER_NEGO, "NTPv4 Server Negotiation"},
53  {NTS_KE_RECORD_TYPE_NTPV4_PORT_NEGO, "NTPv4 Port Negotiation"}
54 };
55 
56 //Protocol IDs
58 {
59  {NTS_PROTOCOL_ID_NTPV4, "NTPv4"}
60 };
61 
62 //AEAD algorithms
64 {
65  {AEAD_AES_SIV_CMAC_256, "AEAD_AES_SIV_CMAC_256"}
66 };
67 
68 //Error codes
70 {
71  {NTS_ERROR_CODE_UNRECOGNIZED_CRITICAL_RECORD, "Unrecognized Critical Record"},
72  {NTS_ERROR_CODE_BAD_REQUEST, "Bad Request"},
73  {NTS_ERROR_CODE_INTERNAL_SERVER_ERROR, "Internal Server Error"}
74 };
75 
76 
77 /**
78  * @brief Dump NTS-KE records
79  * @param[in] records Pointer to the records
80  * @param[in] length Total length of the records, in bytes
81  **/
82 
83 void ntsDumpNtsKeRecords(const uint8_t *records, size_t length)
84 {
85  size_t i;
86  size_t n;
87  const NtsKeRecord *record;
88 
89  //Parse NTS-KE records
90  for(i = 0; i < length; i += sizeof(NtsKeRecord) + n)
91  {
92  //Malformed record?
93  if(length < sizeof(NtsKeRecord))
94  break;
95 
96  //Point to the current record
97  record = (NtsKeRecord *) (records + i);
98  //Retrieve the length of the record
99  n = ntohs(record->bodyLength);
100 
101  //Malformed record?
102  if((i + sizeof(NtsKeRecord) + n) > length)
103  break;
104 
105  //Debug message
106  TRACE_DEBUG(" NTS-KE Record (%" PRIu16 " bytes)\r\n",
107  sizeof(NtsKeRecord) + n);
108 
109  //Dump NTS-KE record
110  ntsDumpNtsKeRecord(record, sizeof(NtsKeRecord) + n);
111  }
112 }
113 
114 
115 /**
116  * @brief Dump NTS-KE record
117  * @param[in] record Pointer to the record
118  * @param[in] length Length of the record, in bytes
119  **/
120 
121 void ntsDumpNtsKeRecord(const NtsKeRecord *record, size_t length)
122 {
124  uint16_t recordType;
125  uint16_t bodyLen;
126  const char_t *name;
127 
128  //Malformed record?
129  if(length < sizeof(NtsKeRecord))
130  return;
131 
132  //Get critical flag
133  critical = (ntohs(record->type) & NTS_KE_CRITICAL) ? TRUE : FALSE;
134  //Get record type
135  recordType = ntohs(record->type) & NTS_KE_RECORD_TYPE_MASK;
136  //Get body length
137  bodyLen = ntohs(record->bodyLength);
138 
139  //Malformed record?
140  if(length < (sizeof(NtsKeRecord) + bodyLen))
141  return;
142 
143  //Convert the Record Type field to string representation
146 
147  //Dump record
148  TRACE_DEBUG(" Critical = %u\r\n", critical);
149  TRACE_DEBUG(" Record Type = %" PRIu16 " (%s)\r\n", recordType, name);
150  TRACE_DEBUG(" Body Length = %" PRIu16 "\r\n", bodyLen);
151 
152  //Check the length of the record body
153  if(bodyLen > 0)
154  {
155  //Debug message
156  TRACE_DEBUG(" Body (%" PRIu16 " bytes)\r\n", bodyLen);
157  }
158 
159  //Check record type
161  {
162  //Dump NTS Next Protocol Negotiation record
163  ntsDumpNtsNextProtoNegoRecord(record->body, bodyLen);
164  }
165  else if(recordType == NTS_KE_RECORD_TYPE_ERROR)
166  {
167  //Dump Error record
168  ntsDumpErrorRecord(record->body, bodyLen);
169  }
170  else if(recordType == NTS_KE_RECORD_TYPE_WARNING)
171  {
172  //Dump Warning record
173  ntsDumpWarningRecord(record->body, bodyLen);
174  }
175  else if(recordType == NTS_KE_RECORD_TYPE_AEAD_ALGO_NEGO)
176  {
177  //Dump AEAD Algorithm Negotiation record
178  ntsDumpAeadAlgoNegoRecord(record->body, bodyLen);
179  }
180  else if(recordType == NTS_KE_RECORD_TYPE_NTPV4_SERVER_NEGO)
181  {
182  //Dump NTPv4 Server Negotiation record
183  ntsDumpNtpv4ServerNegoRecord(record->body, bodyLen);
184  }
185  else if(recordType == NTS_KE_RECORD_TYPE_NTPV4_PORT_NEGO)
186  {
187  //Dump NTPv4 Port Negotiation record
188  ntsDumpNtpv4PortNegoRecord(record->body, bodyLen);
189  }
190  else
191  {
192  //Dump record body
193  TRACE_DEBUG_ARRAY(" ", record->body, bodyLen);
194  }
195 }
196 
197 
198 /**
199  * @brief Dump NTS Next Protocol Negotiation record
200  * @param[in] body Pointer to the record body
201  * @param[in] length Length of the record body, in bytes
202  **/
203 
204 void ntsDumpNtsNextProtoNegoRecord(const uint8_t *body, size_t length)
205 {
206  size_t i;
207  uint16_t protocolId;
208  const char_t *name;
209 
210  //The body consists of a sequence of 16-bit unsigned integers in network
211  //byte order (refer to RFC 8915, section 4.1.2)
212  for(i = 0; (i + 1) < length; i += sizeof(uint16_t))
213  {
214  //Each integer represents a protocol ID
215  protocolId = LOAD16BE(body + i);
216 
217  //Convert the protocol ID to string representation
220 
221  //Dump protocol ID
222  TRACE_DEBUG(" Protocol ID = %" PRIu16 " (%s)\r\n", protocolId, name);
223  }
224 }
225 
226 
227 /**
228  * @brief Dump Error record
229  * @param[in] body Pointer to the record body
230  * @param[in] length Length of the record body, in bytes
231  **/
232 
233 void ntsDumpErrorRecord(const uint8_t *body, size_t length)
234 {
235  uint16_t errorCode;
236  const char_t *name;
237 
238  //Malformed record?
239  if(length < sizeof(uint16_t))
240  return;
241 
242  //The body is exactly two octets long, consisting of an unsigned 16-bit
243  //integer in network byte order, denoting an error code (refer to RFC 8915,
244  //section 4.1.3)
246 
247  //Convert the error code to string representation
250 
251  //Dump error code
252  TRACE_DEBUG(" Error Code = %" PRIu16 " (%s)\r\n", errorCode, name);
253 }
254 
255 
256 /**
257  * @brief Dump Warning record
258  * @param[in] body Pointer to the record body
259  * @param[in] length Length of the record body, in bytes
260  **/
261 
262 void ntsDumpWarningRecord(const uint8_t *body, size_t length)
263 {
264  uint16_t warningCode;
265 
266  //Malformed record?
267  if(length < sizeof(uint16_t))
268  return;
269 
270  //The body is exactly two octets long, consisting of an unsigned 16-bit
271  //integer in network byte order, denoting an warning code (refer to RFC 8915,
272  //section 4.1.4)
273  warningCode = LOAD16BE(body);
274 
275  //Dump warning code
276  TRACE_DEBUG(" Warning Code = %" PRIu16 "\r\n", warningCode);
277 }
278 
279 
280 /**
281  * @brief Dump AEAD Algorithm Negotiation record
282  * @param[in] body Pointer to the record body
283  * @param[in] length Length of the record body, in bytes
284  **/
285 
286 void ntsDumpAeadAlgoNegoRecord(const uint8_t *body, size_t length)
287 {
288  size_t i;
289  uint16_t aeadAlgo;
290  const char_t *name;
291 
292  //The body consists of a sequence of 16-bit unsigned integers in network
293  //byte order (refer to RFC 8915, section 4.1.5)
294  for(i = 0; (i + 1) < length; i += sizeof(uint16_t))
295  {
296  //Each integer represents an AEAD algorithm
297  aeadAlgo = LOAD16BE(body + i);
298 
299  //Convert the AEAD algorithm to string representation
302 
303  //Dump AEAD algorithm
304  TRACE_DEBUG(" AEAD Algorithm = %" PRIu16 " (%s)\r\n", aeadAlgo, name);
305  }
306 }
307 
308 
309 /**
310  * @brief Dump NTPv4 Server Negotiation record
311  * @param[in] body Pointer to the record body
312  * @param[in] length Length of the record body, in bytes
313  **/
314 
315 void ntsDumpNtpv4ServerNegoRecord(const uint8_t *body, size_t length)
316 {
317  size_t i;
318 
319  //Dump NTPv4 server
320  TRACE_DEBUG(" NTPv4 Server = ");
321 
322  //The body consists of an ASCII-encoded string. The contents of the string
323  //shall be either an IPv4 address, an IPv6 address, or a fully qualified
324  //domain name (refer to RFC 8915, section 4.1.7)
325  for(i = 0; i < length; i++)
326  {
327  TRACE_DEBUG("%c", body[i]);
328  }
329 
330  //Add a line feed
331  TRACE_DEBUG("\r\n");
332 }
333 
334 
335 /**
336  * @brief Dump NTPv4 Port Negotiation record
337  * @param[in] body Pointer to the record body
338  * @param[in] length Length of the record body, in bytes
339  **/
340 
341 void ntsDumpNtpv4PortNegoRecord(const uint8_t *body, size_t length)
342 {
343  uint16_t port;
344 
345  //Malformed record?
346  if(length < sizeof(uint16_t))
347  return;
348 
349  //The body consists of a 16-bit unsigned integer in network byte order,
350  //denoting a UDP port number (refer to RFC 8915, section 4.1.8)
351  port = LOAD16BE(body);
352 
353  //Dump NTPv4 port
354  TRACE_DEBUG(" NTPv4 Port = %" PRIu16 "\r\n", port);
355 }
356 
357 
358 /**
359  * @brief Convert a parameter to string representation
360  * @param[in] value Parameter value
361  * @param[in] paramList List of acceptable parameters
362  * @param[in] paramListLen Number of entries in the list
363  * @return NULL-terminated string describing the parameter
364  **/
365 
366 const char_t *ntsGetParamName(uint_t value, const NtsParamName *paramList,
367  size_t paramListLen)
368 {
369  uint_t i;
370 
371  //Default name for unknown values
372  static const char_t defaultName[] = "Unknown";
373 
374  //Loop through the list of acceptable parameters
375  for(i = 0; i < paramListLen; i++)
376  {
377  if(paramList[i].value == value)
378  return paramList[i].name;
379  }
380 
381  //Unknown value
382  return defaultName;
383 }
384 
385 #endif
const NtsParamName ntsErrorCodeList[]
Definition: nts_debug.c:69
int bool_t
Definition: compiler_port.h:53
void ntsDumpErrorRecord(const uint8_t *body, size_t length)
Dump Error record.
Definition: nts_debug.c:233
const char_t * name
Definition: nts_debug.h:52
#define TRUE
Definition: os_port.h:50
char_t name[]
#define NTS_KE_RECORD_TYPE_MASK
Definition: nts_common.h:43
@ NTS_KE_RECORD_TYPE_NTPV4_SERVER_NEGO
NTPv4 Server Negotiation.
Definition: nts_common.h:63
uint16_t errorCode
Definition: tftp_common.h:138
@ NTS_KE_RECORD_TYPE_END_OF_MESSAGE
End of Message.
Definition: nts_common.h:57
void ntsDumpNtpv4ServerNegoRecord(const uint8_t *body, size_t length)
Dump NTPv4 Server Negotiation record.
Definition: nts_debug.c:315
@ NTS_ERROR_CODE_INTERNAL_SERVER_ERROR
Internal Server Error.
Definition: nts_common.h:86
@ NTS_KE_RECORD_TYPE_NTS_NEXT_PROTO_NEGO
NTS Next Protocol Negotiation.
Definition: nts_common.h:58
@ AEAD_AES_SIV_CMAC_256
RFC 5297.
void ntsDumpNtsKeRecords(const uint8_t *records, size_t length)
Dump NTS-KE records.
Definition: nts_debug.c:83
const NtsParamName ntsAeadAlgoList[]
Definition: nts_debug.c:63
@ NTS_ERROR_CODE_UNRECOGNIZED_CRITICAL_RECORD
Unrecognized Critical Record.
Definition: nts_common.h:84
#define FALSE
Definition: os_port.h:46
void ntsDumpNtpv4PortNegoRecord(const uint8_t *body, size_t length)
Dump NTPv4 Port Negotiation record.
Definition: nts_debug.c:341
uint8_t protocolId[]
Parameter value/name binding.
Definition: nts_debug.h:50
const char_t * ntsGetParamName(uint_t value, const NtsParamName *paramList, size_t paramListLen)
Convert a parameter to string representation.
Definition: nts_debug.c:366
@ NTS_KE_RECORD_TYPE_NEW_COOKIE_FOR_NTPV4
New Cookie for NTPv4.
Definition: nts_common.h:62
void ntsDumpWarningRecord(const uint8_t *body, size_t length)
Dump Warning record.
Definition: nts_debug.c:262
uint8_t length
Definition: tcp.h:368
@ NTS_KE_RECORD_TYPE_AEAD_ALGO_NEGO
AEAD Algorithm Negotiation.
Definition: nts_common.h:61
@ NTS_PROTOCOL_ID_NTPV4
Network Time Protocol version 4 (NTPv4)
Definition: nts_common.h:74
uint16_t port
Definition: dns_common.h:267
#define ntohs(value)
Definition: cpu_endian.h:421
#define TRACE_DEBUG(...)
Definition: debug.h:107
char char_t
Definition: compiler_port.h:48
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
@ NTS_KE_RECORD_TYPE_ERROR
Error.
Definition: nts_common.h:59
void ntsDumpNtsNextProtoNegoRecord(const uint8_t *body, size_t length)
Dump NTS Next Protocol Negotiation record.
Definition: nts_debug.c:204
uint8_t n
void ntsDumpAeadAlgoNegoRecord(const uint8_t *body, size_t length)
Dump AEAD Algorithm Negotiation record.
Definition: nts_debug.c:286
NtsKeRecord
Definition: nts_common.h:107
uint8_t value[]
Definition: tcp.h:369
uint8_t critical
Definition: ike.h:1281
@ NTS_ERROR_CODE_BAD_REQUEST
Bad Request.
Definition: nts_common.h:85
@ NTS_KE_RECORD_TYPE_WARNING
Warning.
Definition: nts_common.h:60
const NtsParamName ntsProtocolIdList[]
Definition: nts_debug.c:57
unsigned int uint_t
Definition: compiler_port.h:50
#define LOAD16BE(p)
Definition: cpu_endian.h:186
TCP/IP stack core.
uint8_t body[]
Definition: nts_common.h:106
Data logging functions for debugging purpose (NTS)
@ NTS_KE_RECORD_TYPE_NTPV4_PORT_NEGO
NTPv4 Port Negotiation.
Definition: nts_common.h:64
void ntsDumpNtsKeRecord(const NtsKeRecord *record, size_t length)
Dump NTS-KE record.
Definition: nts_debug.c:121
#define NTS_KE_CRITICAL
Definition: nts_common.h:41
Debugging facilities.
#define arraysize(a)
Definition: os_port.h:71
const NtsParamName ntsKeRecordTypeList[]
Definition: nts_debug.c:44