mib_common.c
Go to the documentation of this file.
1 /**
2  * @file mib_common.c
3  * @brief Common definitions for MIB modules
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.0
29  **/
30 
31 //Dependencies
32 #include "core/net.h"
33 #include "mibs/mib_common.h"
34 #include "encoding/oid.h"
35 #include "debug.h"
36 
37 
38 /**
39  * @brief Encode instance identifier (index)
40  * @param[in] oid Pointer to the object identifier
41  * @param[in] maxOidLen Maximum number of bytes the OID can hold
42  * @param[in,out] pos Offset where to write the instance identifier
43  * @param[in] index Index value
44  * @return Error code
45  **/
46 
47 error_t mibEncodeIndex(uint8_t *oid, size_t maxOidLen, size_t *pos,
48  uint_t index)
49 {
50  //Encode instance identifier
51  return oidEncodeSubIdentifier(oid, maxOidLen, pos, index);
52 }
53 
54 
55 /**
56  * @brief Decode instance identifier (index)
57  * @param[in] oid Pointer to the object identifier
58  * @param[in] oidLen Length of the OID, in bytes
59  * @param[in,out] pos Offset where to read the instance identifier
60  * @param[out] index Index value
61  * @return Error code
62  **/
63 
64 error_t mibDecodeIndex(const uint8_t *oid, size_t oidLen, size_t *pos,
65  uint_t *index)
66 {
67  error_t error;
68  uint32_t value;
69 
70  //Decode instance identifier
71  error = oidDecodeSubIdentifier(oid, oidLen, pos, &value);
72 
73  //Check status code
74  if(!error)
75  {
76  //Save index value
77  *index = (uint_t) value;
78  }
79 
80  //Return status code
81  return error;
82 }
83 
84 
85 /**
86  * @brief Encode instance identifier (unsigned 32-bit integer)
87  * @param[in] oid Pointer to the object identifier
88  * @param[in] maxOidLen Maximum number of bytes the OID can hold
89  * @param[in,out] pos Offset where to write the instance identifier
90  * @param[in] value Unsigned 32-bit integer
91  * @return Error code
92  **/
93 
94 error_t mibEncodeUnsigned32(uint8_t *oid, size_t maxOidLen, size_t *pos,
95  uint32_t value)
96 {
97  //Encode instance identifier
98  return oidEncodeSubIdentifier(oid, maxOidLen, pos, value);
99 }
100 
101 
102 /**
103  * @brief Decode instance identifier (unsigned 32-bit integer)
104  * @param[in] oid Pointer to the object identifier
105  * @param[in] oidLen Length of the OID, in bytes
106  * @param[in,out] pos Offset where to read the instance identifier
107  * @param[out] value Unsigned 32-bit integer
108  * @return Error code
109  **/
110 
111 error_t mibDecodeUnsigned32(const uint8_t *oid, size_t oidLen, size_t *pos,
112  uint32_t *value)
113 {
114  //Decode instance identifier
115  return oidDecodeSubIdentifier(oid, oidLen, pos, value);
116 }
117 
118 
119 /**
120  * @brief Encode instance identifier (string)
121  * @param[in] oid Pointer to the object identifier
122  * @param[in] maxOidLen Maximum number of bytes the OID can hold
123  * @param[in,out] pos Offset where to write the instance identifier
124  * @param[in] string NULL-terminated string
125  * @param[in] implied Specifies whether the index is preceded by the IMPLIED keyword
126  * @return Error code
127  **/
128 
129 error_t mibEncodeString(uint8_t *oid, size_t maxOidLen, size_t *pos,
130  const char_t *string, bool_t implied)
131 {
132  //Encode string
133  return mibEncodeOctetString(oid, maxOidLen, pos, (const uint8_t *) string,
134  osStrlen(string), implied);
135 }
136 
137 
138 /**
139  * @brief Decode instance identifier (string)
140  * @param[in] oid Pointer to the object identifier
141  * @param[in] oidLen Length of the OID, in bytes
142  * @param[in,out] pos Offset where to read the instance identifier
143  * @param[out] string NULL-terminated string
144  * @param[in] maxStringLen Maximum number of characters the string can hold
145  * @param[in] implied Specifies whether the index is preceded by the IMPLIED keyword
146  * @return Error code
147  **/
148 
149 error_t mibDecodeString(const uint8_t *oid, size_t oidLen, size_t *pos,
150  char_t *string, size_t maxStringLen, bool_t implied)
151 {
152  error_t error;
153  size_t stringLen;
154 
155  //Decode string
156  error = mibDecodeOctetString(oid, oidLen, pos, (uint8_t *) string,
157  maxStringLen, &stringLen, implied);
158 
159  //Check status code
160  if(!error)
161  {
162  //Properly terminate the string with a NULL character
163  string[stringLen] = '\0';
164  }
165 
166  //Return status code
167  return error;
168 }
169 
170 
171 /**
172  * @brief Encode instance identifier (octet string)
173  * @param[in] oid Pointer to the object identifier
174  * @param[in] maxOidLen Maximum number of bytes the OID can hold
175  * @param[in,out] pos Offset where to write the instance identifier
176  * @param[in] data Pointer to the octet string
177  * @param[in] dataLen Length of the octet string, in bytes
178  * @param[in] implied Specifies whether the index is preceded by the IMPLIED keyword
179  * @return Error code
180  **/
181 
182 error_t mibEncodeOctetString(uint8_t *oid, size_t maxOidLen, size_t *pos,
183  const uint8_t *data, size_t dataLen, bool_t implied)
184 {
185  error_t error;
186  uint_t i;
187 
188  //Check whether the index is preceded by the IMPLIED keyword
189  if(!implied)
190  {
191  //Encode the length of the octet string
192  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, dataLen);
193  //Any error to report?
194  if(error)
195  return error;
196  }
197 
198  //Encode the octet string
199  for(i = 0; i < dataLen; i++)
200  {
201  //Encode the current byte
202  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, data[i]);
203  //Any error to report?
204  if(error)
205  return error;
206  }
207 
208  //Successful processing
209  return NO_ERROR;
210 }
211 
212 
213 /**
214  * @brief Decode instance identifier (octet string)
215  * @param[in] oid Pointer to the object identifier
216  * @param[in] oidLen Length of the OID, in bytes
217  * @param[in,out] pos Offset where to read the instance identifier
218  * @param[out] data Buffer where to store the octet string
219  * @param[in] maxDataLen Maximum number of bytes the buffer can hold
220  * @param[out] dataLen Length of the octet string, in bytes
221  * @param[in] implied Specifies whether the index is preceded by the IMPLIED keyword
222  * @return Error code
223  **/
224 
225 error_t mibDecodeOctetString(const uint8_t *oid, size_t oidLen, size_t *pos,
226  uint8_t *data, size_t maxDataLen, size_t *dataLen, bool_t implied)
227 {
228  error_t error;
229  uint_t i;
230  uint32_t n;
231  uint32_t value;
232 
233  //Check whether the index is preceded by the IMPLIED keyword
234  if(!implied)
235  {
236  //Decode the length of the octet string
237  error = oidDecodeSubIdentifier(oid, oidLen, pos, &n);
238  //Any error to report?
239  if(error)
240  return error;
241  }
242 
243  //Decode the octet string
244  for(i = 0; ; i++)
245  {
246  //Check whether the index is preceded by the IMPLIED keyword
247  if(!implied)
248  {
249  //Check loop condition
250  if(i >= n)
251  break;
252  }
253  else
254  {
255  //Check loop condition
256  if(*pos >= oidLen)
257  break;
258  }
259 
260  //Decode the current sub-identifier
261  error = oidDecodeSubIdentifier(oid, oidLen, pos, &value);
262  //Invalid sub-identifier?
263  if(error)
264  return error;
265 
266  //Each byte of the octet string must be in the range 0-255
267  if(value > UINT8_MAX)
269 
270  //Ensure the output buffer is large enough to hold of the octet string
271  if(i >= maxDataLen)
273 
274  //Save the current byte
275  data[i] = (uint8_t) value;
276  }
277 
278  //Return the length of the octet string
279  *dataLen = i;
280 
281  //Successful processing
282  return NO_ERROR;
283 }
284 
285 
286 /**
287  * @brief Encode instance identifier (object identifier)
288  * @param[in] oid Pointer to the object identifier
289  * @param[in] maxOidLen Maximum number of bytes the OID can hold
290  * @param[in,out] pos Offset where to write the instance identifier
291  * @param[in] objectId Object identifier to be encoded
292  * @param[in] objectIdLen Length of the object identifier, in bytes
293  * @param[in] implied Specifies whether the index is preceded by the IMPLIED keyword
294  * @return Error code
295  **/
296 
297 error_t mibEncodeObjectIdentifier(uint8_t *oid, size_t maxOidLen, size_t *pos,
298  const uint8_t *objectId, size_t objectIdLen, bool_t implied)
299 {
300  error_t error;
301  uint32_t n;
302  uint32_t value;
303  size_t objectIdPos;
304 
305  //Check whether the index is preceded by the IMPLIED keyword
306  if(!implied)
307  {
308  //Check the length of the object identifier
309  if(objectIdLen > 0)
310  {
311  //Calculate the number of sub-identifiers in the value
312  for(n = 2, objectIdPos = 1; objectIdPos < objectIdLen; n++)
313  {
314  //Decode the current sub-identifier
315  error = oidDecodeSubIdentifier(objectId, objectIdLen,
316  &objectIdPos, &value);
317  //Invalid sub-identifier?
318  if(error)
319  return error;
320  }
321  }
322  else
323  {
324  n = 0;
325  }
326 
327  //Encode the number of sub-identifiers in the value
328  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, n);
329  //Any error to report?
330  if(error)
331  return error;
332  }
333 
334  //Check the length of the object identifier
335  if(objectIdLen > 0)
336  {
337  //Encode the first sub-identifier
338  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, objectId[0] / 40);
339  //Any error to report?
340  if(error)
341  return error;
342 
343  //Encode the second sub-identifier
344  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, objectId[0] % 40);
345  //Any error to report?
346  if(error)
347  return error;
348 
349  //Sanity check
350  if((*pos + objectIdLen - 1) > maxOidLen)
351  return ERROR_BUFFER_OVERFLOW;
352 
353  //Encode the rest of the object identifier
354  osMemcpy(oid + *pos, objectId + 1, objectIdLen - 1);
355 
356  //Update offset value
357  *pos += objectIdLen - 1;
358  }
359 
360  //Successful processing
361  return NO_ERROR;
362 }
363 
364 
365 /**
366  * @brief Decode instance identifier (object identifier)
367  * @param[in] oid Pointer to the object identifier
368  * @param[in] oidLen Length of the OID, in bytes
369  * @param[in,out] pos Offset where to read the instance identifier
370  * @param[out] objectId Buffer where to store the object identifier
371  * @param[in] maxObjectIdLen Maximum number of bytes the buffer can hold
372  * @param[out] objectIdLen Length of the object identifier, in bytes
373  * @param[in] implied Specifies whether the index is preceded by the IMPLIED keyword
374  * @return Error code
375  **/
376 
377 error_t mibDecodeObjectIdentifier(const uint8_t *oid, size_t oidLen, size_t *pos,
378  uint8_t *objectId, size_t maxObjectIdLen, size_t *objectIdLen, bool_t implied)
379 {
380  error_t error;
381  uint32_t i;
382  uint32_t n;
383  uint32_t value;
384 
385  //Length of the object identifier, in bytes
386  *objectIdLen = 0;
387 
388  //Check whether the index is preceded by the IMPLIED keyword
389  if(!implied)
390  {
391  //Decode the number of sub-identifiers in the value
392  error = oidDecodeSubIdentifier(oid, oidLen, pos, &n);
393  //Invalid sub-identifier?
394  if(error)
395  return error;
396  }
397 
398  //Decode object identifier
399  for(i = 0; ; i++)
400  {
401  //Check whether the index is preceded by the IMPLIED keyword
402  if(!implied)
403  {
404  //Check loop condition
405  if(i >= n)
406  break;
407  }
408  else
409  {
410  //Check loop condition
411  if(*pos >= oidLen)
412  break;
413  }
414 
415  //Decode the current sub-identifier
416  error = oidDecodeSubIdentifier(oid, oidLen, pos, &value);
417  //Invalid sub-identifier?
418  if(error)
419  return error;
420 
421  //First node?
422  if(i == 0)
423  {
424  //Check the value of the first sub-identifier
425  if(value > 6)
426  return ERROR_INVALID_SYNTAX;
427 
428  //Check the length of the output buffer
429  if(maxObjectIdLen == 0)
430  return ERROR_BUFFER_OVERFLOW;
431 
432  //Encode the first sub-identifier
433  objectId[0] = value * 40;
434  //Prepare to decode the next node
435  *objectIdLen = 1;
436  }
437  //Second node?
438  else if(i == 1)
439  {
440  //Check the value of the second sub-identifier
441  if(value > 39)
442  return ERROR_INVALID_SYNTAX;
443 
444  //Check the length of the output buffer
445  if(maxObjectIdLen == 0)
446  return ERROR_BUFFER_OVERFLOW;
447 
448  //Encode the second sub-identifier
449  objectId[0] |= value;
450  //Prepare to decode the next node
451  *objectIdLen = 1;
452  }
453  else
454  {
455  //Encode the current sub-identifier
456  error = oidEncodeSubIdentifier(objectId, maxObjectIdLen,
457  objectIdLen, value);
458  //Invalid sub-identifier?
459  if(error)
460  return error;
461  }
462  }
463 
464  //Successful processing
465  return NO_ERROR;
466 }
467 
468 
469 /**
470  * @brief Encode instance identifier (port number)
471  * @param[in] oid Pointer to the object identifier
472  * @param[in] maxOidLen Maximum number of bytes the OID can hold
473  * @param[in,out] pos Offset where to write the instance identifier
474  * @param[in] port Port number
475  * @return Error code
476  **/
477 
478 error_t mibEncodePort(uint8_t *oid, size_t maxOidLen, size_t *pos,
479  uint16_t port)
480 {
481  //Encode instance identifier
482  return oidEncodeSubIdentifier(oid, maxOidLen, pos, port);
483 }
484 
485 
486 /**
487  * @brief Decode instance identifier (port number)
488  * @param[in] oid Pointer to the object identifier
489  * @param[in] oidLen Length of the OID, in bytes
490  * @param[in,out] pos Offset where to read the instance identifier
491  * @param[out] port Port number
492  * @return Error code
493  **/
494 
495 error_t mibDecodePort(const uint8_t *oid, size_t oidLen, size_t *pos,
496  uint16_t *port)
497 {
498  error_t error;
499  uint32_t value;
500 
501  //Decode instance identifier
502  error = oidDecodeSubIdentifier(oid, oidLen, pos, &value);
503  //Invalid sub-identifier?
504  if(error)
505  return error;
506 
507  //Port number must be in range 0-65535
508  if(value > 65535)
510 
511  //Save port number
512  *port = value;
513 
514  //Successful processing
515  return NO_ERROR;
516 }
517 
518 
519 /**
520  * @brief Encode instance identifier (MAC address)
521  * @param[in] oid Pointer to the object identifier
522  * @param[in] maxOidLen Maximum number of bytes the OID can hold
523  * @param[in,out] pos Offset where to write the instance identifier
524  * @param[in] macAddr MAC address
525  * @return Error code
526  **/
527 
528 error_t mibEncodeMacAddr(uint8_t *oid, size_t maxOidLen, size_t *pos,
529  const MacAddr *macAddr)
530 {
531  error_t error;
532  uint_t i;
533 
534  //The address is encoded as 6 subsequent sub-identifiers
535  for(i = 0; i < sizeof(MacAddr); i++)
536  {
537  //Encode the current byte
538  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, macAddr->b[i]);
539  //Any error to report?
540  if(error)
541  return error;
542  }
543 
544  //Successful processing
545  return NO_ERROR;
546 }
547 
548 
549 /**
550  * @brief Decode instance identifier (MAC address)
551  * @param[in] oid Pointer to the object identifier
552  * @param[in] oidLen Length of the OID, in bytes
553  * @param[in,out] pos Offset where to read the instance identifier
554  * @param[out] macAddr MAC address
555  * @return Error code
556  **/
557 
558 error_t mibDecodeMacAddr(const uint8_t *oid, size_t oidLen, size_t *pos,
559  MacAddr *macAddr)
560 {
561  error_t error;
562  uint_t i;
563  uint32_t value;
564 
565  //The address is encoded as 6 subsequent sub-identifiers
566  for(i = 0; i < sizeof(MacAddr); i++)
567  {
568  //Decode the current sub-identifier
569  error = oidDecodeSubIdentifier(oid, oidLen, pos, &value);
570  //Invalid sub-identifier?
571  if(error)
572  return error;
573 
574  //Each byte of the MAC address must be in the range 0-255
575  if(value > 255)
577 
578  //Save the current byte
579  macAddr->b[i] = value & 0xFF;
580  }
581 
582  //Successful processing
583  return NO_ERROR;
584 }
585 
586 
587 /**
588  * @brief Encode instance identifier (physical address)
589  * @param[in] oid Pointer to the object identifier
590  * @param[in] maxOidLen Maximum number of bytes the OID can hold
591  * @param[in,out] pos Offset where to write the instance identifier
592  * @param[in] macAddr MAC address
593  * @return Error code
594  **/
595 
596 error_t mibEncodePhysAddr(uint8_t *oid, size_t maxOidLen, size_t *pos,
597  const MacAddr *macAddr)
598 {
599  error_t error;
600 
601  //Encode the length of the octet string
602  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, sizeof(MacAddr));
603 
604  //Check status code
605  if(!error)
606  {
607  //The address is encoded as 6 subsequent sub-identifiers
608  error = mibEncodeMacAddr(oid, maxOidLen, pos, macAddr);
609  }
610 
611  //Return status code
612  return error;
613 }
614 
615 
616 /**
617  * @brief Decode instance identifier (physical address)
618  * @param[in] oid Pointer to the object identifier
619  * @param[in] oidLen Length of the OID, in bytes
620  * @param[in,out] pos Offset where to read the instance identifier
621  * @param[out] macAddr MAC address
622  * @return Error code
623  **/
624 
625 error_t mibDecodePhysAddr(const uint8_t *oid, size_t oidLen, size_t *pos,
626  MacAddr *macAddr)
627 {
628  error_t error;
629  uint32_t length;
630 
631  //Decode the length of the octet string
632  error = oidDecodeSubIdentifier(oid, oidLen, pos, &length);
633 
634  //Check status code
635  if(!error)
636  {
637  //Make sure the length of the octet string is valid
638  if(length == sizeof(MacAddr))
639  {
640  //The address is encoded as 6 subsequent sub-identifiers
641  error = mibDecodeMacAddr(oid, oidLen, pos, macAddr);
642  }
643  else
644  {
645  //Report an error
646  error = ERROR_INSTANCE_NOT_FOUND;
647  }
648  }
649 
650  //Return status code
651  return error;
652 }
653 
654 
655 /**
656  * @brief Encode instance identifier (IPv4 address)
657  * @param[in] oid Pointer to the object identifier
658  * @param[in] maxOidLen Maximum number of bytes the OID can hold
659  * @param[in,out] pos Offset where to write the instance identifier
660  * @param[in] ipAddr IPv4 address
661  * @return Error code
662  **/
663 
664 error_t mibEncodeIpv4Addr(uint8_t *oid, size_t maxOidLen, size_t *pos,
666 {
667  error_t error;
668  uint_t i;
669  uint8_t *p;
670 
671  //Cast the IPv4 address as a byte array
672  p = (uint8_t *) &ipAddr;
673 
674  //The address is encoded as 4 subsequent sub-identifiers
675  for(i = 0; i < sizeof(Ipv4Addr); i++)
676  {
677  //Encode the current byte
678  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, p[i]);
679  //Any error to report?
680  if(error)
681  return error;
682  }
683 
684  //Successful processing
685  return NO_ERROR;
686 }
687 
688 
689 /**
690  * @brief Decode instance identifier (IPv4 address)
691  * @param[in] oid Pointer to the object identifier
692  * @param[in] oidLen Length of the OID, in bytes
693  * @param[in,out] pos Offset where to read the instance identifier
694  * @param[out] ipAddr IPv4 address
695  * @return Error code
696  **/
697 
698 error_t mibDecodeIpv4Addr(const uint8_t *oid, size_t oidLen, size_t *pos,
699  Ipv4Addr *ipAddr)
700 {
701  error_t error;
702  uint_t i;
703  uint32_t value;
704  uint8_t *p;
705 
706  //Cast the IPv4 address as a byte array
707  p = (uint8_t *) ipAddr;
708 
709  //The address is encoded as 4 subsequent sub-identifiers
710  for(i = 0; i < sizeof(Ipv4Addr); i++)
711  {
712  //Decode the current sub-identifier
713  error = oidDecodeSubIdentifier(oid, oidLen, pos, &value);
714  //Invalid sub-identifier?
715  if(error)
716  return error;
717 
718  //Each byte of the IPv4 address must be in the range 0-255
719  if(value > 255)
721 
722  //Save the current byte
723  p[i] = value & 0xFF;
724  }
725 
726  //Successful processing
727  return NO_ERROR;
728 }
729 
730 
731 /**
732  * @brief Encode instance identifier (IPv6 address)
733  * @param[in] oid Pointer to the object identifier
734  * @param[in] maxOidLen Maximum number of bytes the OID can hold
735  * @param[in,out] pos Offset where to write the instance identifier
736  * @param[in] ipAddr IPv6 address
737  * @return Error code
738  **/
739 
740 error_t mibEncodeIpv6Addr(uint8_t *oid, size_t maxOidLen, size_t *pos,
741  const Ipv6Addr *ipAddr)
742 {
743  error_t error;
744  uint_t i;
745 
746  //The address is encoded as 16 subsequent sub-identifiers
747  for(i = 0; i < sizeof(Ipv6Addr); i++)
748  {
749  //Encode the current byte
750  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, ipAddr->b[i]);
751  //Any error to report?
752  if(error)
753  return error;
754  }
755 
756  //Successful processing
757  return NO_ERROR;
758 }
759 
760 
761 /**
762  * @brief Decode instance identifier (IPv6 address)
763  * @param[in] oid Pointer to the object identifier
764  * @param[in] oidLen Length of the OID, in bytes
765  * @param[in,out] pos Offset where to read the instance identifier
766  * @param[out] ipAddr IPv6 address
767  * @return Error code
768  **/
769 
770 error_t mibDecodeIpv6Addr(const uint8_t *oid, size_t oidLen, size_t *pos,
771  Ipv6Addr *ipAddr)
772 {
773  error_t error;
774  uint_t i;
775  uint32_t value;
776 
777  //The address is encoded as 16 subsequent sub-identifiers
778  for(i = 0; i < sizeof(Ipv6Addr); i++)
779  {
780  //Decode the current sub-identifier
781  error = oidDecodeSubIdentifier(oid, oidLen, pos, &value);
782  //Invalid sub-identifier?
783  if(error)
784  return error;
785 
786  //Each byte of the IPv6 address must be in the range 0-255
787  if(value > 255)
789 
790  //Save the current byte
791  ipAddr->b[i] = value & 0xFF;
792  }
793 
794  //Successful processing
795  return NO_ERROR;
796 }
797 
798 
799 /**
800  * @brief Encode instance identifier (IP address)
801  * @param[in] oid Pointer to the object identifier
802  * @param[in] maxOidLen Maximum number of bytes the OID can hold
803  * @param[in,out] pos Offset where to write the instance identifier
804  * @param[in] ipAddr IP address
805  * @return Error code
806  **/
807 
808 error_t mibEncodeIpAddr(uint8_t *oid, size_t maxOidLen, size_t *pos,
809  const IpAddr *ipAddr)
810 {
811  error_t error;
812 
813 #if (IPV4_SUPPORT == ENABLED)
814  //IPv4 address?
815  if(ipAddr->length == sizeof(Ipv4Addr))
816  {
817  //Encode address type (IPv4)
818  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, INET_ADDR_TYPE_IPV4);
819 
820  //Check status code
821  if(!error)
822  {
823  //Encode the length of the octet string
824  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, sizeof(Ipv4Addr));
825  }
826 
827  //Check status code
828  if(!error)
829  {
830  //Encode IPv4 address
831  error = mibEncodeIpv4Addr(oid, maxOidLen, pos, ipAddr->ipv4Addr);
832  }
833  }
834  else
835 #endif
836 #if (IPV6_SUPPORT == ENABLED)
837  //IPv6 address?
838  if(ipAddr->length == sizeof(Ipv6Addr))
839  {
840  //Encode address type (IPv6)
841  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, INET_ADDR_TYPE_IPV6);
842 
843  //Check status code
844  if(!error)
845  {
846  //Encode the length of the octet string
847  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, sizeof(Ipv6Addr));
848  }
849 
850  //Check status code
851  if(!error)
852  {
853  //Encode IPv6 address
854  error = mibEncodeIpv6Addr(oid, maxOidLen, pos, &ipAddr->ipv6Addr);
855  }
856  }
857  else
858 #endif
859  //Unknown address?
860  {
861  //Encode address type (unknown)
862  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, INET_ADDR_TYPE_UNKNOWN);
863 
864  //Check status code
865  if(!error)
866  {
867  //The unknown address is a zero-length octet string
868  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, 0);
869  }
870  }
871 
872  //Return status code
873  return error;
874 }
875 
876 
877 /**
878  * @brief Decode instance identifier (IP address)
879  * @param[in] oid Pointer to the object identifier
880  * @param[in] oidLen Length of the OID, in bytes
881  * @param[in,out] pos Offset where to read the instance identifier
882  * @param[out] ipAddr IP address
883  * @return Error code
884  **/
885 
886 error_t mibDecodeIpAddr(const uint8_t *oid, size_t oidLen, size_t *pos,
887  IpAddr *ipAddr)
888 {
889  error_t error;
890  uint32_t type;
891  uint32_t length;
892 
893  //Decode address type
894  error = oidDecodeSubIdentifier(oid, oidLen, pos, &type);
895 
896  //Check status code
897  if(!error)
898  {
899  //Decode the length of the octet string
900  error = oidDecodeSubIdentifier(oid, oidLen, pos, &length);
901  }
902 
903  //Check status code
904  if(!error)
905  {
906  //Unknown address?
907  if(type == INET_ADDR_TYPE_UNKNOWN && length == 0)
908  {
909  //The unknown address is a zero-length octet string
910  *ipAddr = IP_ADDR_ANY;
911  }
912 #if (IPV4_SUPPORT == ENABLED)
913  //IPv4 address?
914  else if(type == INET_ADDR_TYPE_IPV4 && length == sizeof(Ipv4Addr))
915  {
916  //Save the length of the address
917  ipAddr->length = sizeof(Ipv4Addr);
918 
919  //Decode IPv4 address
920  error = mibDecodeIpv4Addr(oid, oidLen, pos, &ipAddr->ipv4Addr);
921  }
922 #endif
923 #if (IPV6_SUPPORT == ENABLED)
924  //IPv6 address?
925  else if(type == INET_ADDR_TYPE_IPV6 && length == sizeof(Ipv6Addr))
926  {
927  //Save the length of the address
928  ipAddr->length = sizeof(Ipv6Addr);
929 
930  //Decode IPv6 address
931  error = mibDecodeIpv6Addr(oid, oidLen, pos, &ipAddr->ipv6Addr);
932  }
933 #endif
934  //Invalid address?
935  else
936  {
937  //Report an error
938  error = ERROR_INSTANCE_NOT_FOUND;
939  }
940  }
941 
942  //Return status code
943  return error;
944 }
945 
946 
947 /**
948  * @brief Compare MAC addresses
949  * @param[in] macAddr1 First MAC address
950  * @param[in] macAddr2 Second MAC address
951  * @return Comparison result
952  **/
953 
954 int_t mibCompMacAddr(const MacAddr *macAddr1, const MacAddr *macAddr2)
955 {
956  //Return comparison result
957  return osMemcmp(macAddr1, macAddr2, sizeof(MacAddr));
958 }
959 
960 
961 /**
962  * @brief Compare IP addresses
963  * @param[in] ipAddr1 First IP address
964  * @param[in] ipAddr2 Second IP address
965  * @return Comparison result
966  **/
967 
968 int_t mibCompIpAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
969 {
970  int_t res;
971 
972  //Compare length fields
973  if(ipAddr1->length < ipAddr2->length)
974  {
975  res = -1;
976  }
977  else if(ipAddr1->length > ipAddr2->length)
978  {
979  res = 1;
980  }
981  else if(ipAddr1->length == 0)
982  {
983  res = 0;
984  }
985  else
986  {
987  //Compare IP addresses
988  res = osMemcmp((uint8_t *) ipAddr1 + sizeof(size_t),
989  (uint8_t *) ipAddr2 + sizeof(size_t), ipAddr1->length);
990  }
991 
992  //Return comparison result
993  return res;
994 }
995 
996 
997 /**
998  * @brief Test and increment spin lock
999  * @param[in,out] spinLock Pointer to the spin lock
1000  * @param[in] value New value supplied via the management protocol
1001  * @param[in] commit This flag indicates the current phase (validation phase
1002  * or write phase if the validation was successful)
1003  * @return Comparison result
1004  **/
1005 
1006 error_t mibTestAndIncSpinLock(int32_t *spinLock, int32_t value, bool_t commit)
1007 {
1008  error_t error;
1009 
1010  //The new value supplied via the management protocol must precisely match
1011  //the value presently held by the instance
1012  if(value == *spinLock)
1013  {
1014  //Write phase?
1015  if(commit)
1016  {
1017  //The value held by the instance is incremented by one
1018  (*spinLock)++;
1019 
1020  //if the current value is the maximum value of 2^31-1, then the value
1021  //held by the instance is wrapped to zero
1022  if(*spinLock < 0)
1023  {
1024  *spinLock = 0;
1025  }
1026  }
1027 
1028  //Successful operation
1029  error = NO_ERROR;
1030  }
1031  else
1032  {
1033  //The management protocol set operation fails with an error of
1034  //inconsistentValue
1035  error = ERROR_INCONSISTENT_VALUE;
1036  }
1037 
1038  //Return status code
1039  return error;
1040 }
uint8_t type
Definition: coap_common.h:176
signed int int_t
Definition: compiler_port.h:49
unsigned int uint_t
Definition: compiler_port.h:50
char char_t
Definition: compiler_port.h:48
int bool_t
Definition: compiler_port.h:53
Debugging facilities.
uint8_t n
uint16_t port
Definition: dns_common.h:267
error_t
Error codes.
Definition: error.h:43
@ ERROR_INSTANCE_NOT_FOUND
Definition: error.h:256
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:142
@ ERROR_INCONSISTENT_VALUE
Definition: error.h:124
uint8_t data[]
Definition: ethernet.h:222
MacAddr
Definition: ethernet.h:195
const IpAddr IP_ADDR_ANY
Definition: ip.c:51
Ipv4Addr ipAddr
Definition: ipcp.h:105
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:267
Ipv6Addr
Definition: ipv6.h:251
uint8_t oid[]
Definition: lldp_tlv.h:300
uint8_t oidLen
Definition: lldp_tlv.h:299
error_t mibDecodeIpAddr(const uint8_t *oid, size_t oidLen, size_t *pos, IpAddr *ipAddr)
Decode instance identifier (IP address)
Definition: mib_common.c:886
error_t mibDecodeString(const uint8_t *oid, size_t oidLen, size_t *pos, char_t *string, size_t maxStringLen, bool_t implied)
Decode instance identifier (string)
Definition: mib_common.c:149
error_t mibDecodeObjectIdentifier(const uint8_t *oid, size_t oidLen, size_t *pos, uint8_t *objectId, size_t maxObjectIdLen, size_t *objectIdLen, bool_t implied)
Decode instance identifier (object identifier)
Definition: mib_common.c:377
error_t mibDecodeMacAddr(const uint8_t *oid, size_t oidLen, size_t *pos, MacAddr *macAddr)
Decode instance identifier (MAC address)
Definition: mib_common.c:558
error_t mibEncodePort(uint8_t *oid, size_t maxOidLen, size_t *pos, uint16_t port)
Encode instance identifier (port number)
Definition: mib_common.c:478
error_t mibDecodeOctetString(const uint8_t *oid, size_t oidLen, size_t *pos, uint8_t *data, size_t maxDataLen, size_t *dataLen, bool_t implied)
Decode instance identifier (octet string)
Definition: mib_common.c:225
error_t mibEncodeObjectIdentifier(uint8_t *oid, size_t maxOidLen, size_t *pos, const uint8_t *objectId, size_t objectIdLen, bool_t implied)
Encode instance identifier (object identifier)
Definition: mib_common.c:297
int_t mibCompIpAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
Compare IP addresses.
Definition: mib_common.c:968
error_t mibDecodeIpv6Addr(const uint8_t *oid, size_t oidLen, size_t *pos, Ipv6Addr *ipAddr)
Decode instance identifier (IPv6 address)
Definition: mib_common.c:770
error_t mibEncodePhysAddr(uint8_t *oid, size_t maxOidLen, size_t *pos, const MacAddr *macAddr)
Encode instance identifier (physical address)
Definition: mib_common.c:596
error_t mibDecodeIpv4Addr(const uint8_t *oid, size_t oidLen, size_t *pos, Ipv4Addr *ipAddr)
Decode instance identifier (IPv4 address)
Definition: mib_common.c:698
error_t mibDecodeIndex(const uint8_t *oid, size_t oidLen, size_t *pos, uint_t *index)
Decode instance identifier (index)
Definition: mib_common.c:64
error_t mibTestAndIncSpinLock(int32_t *spinLock, int32_t value, bool_t commit)
Test and increment spin lock.
Definition: mib_common.c:1006
error_t mibEncodeIpv4Addr(uint8_t *oid, size_t maxOidLen, size_t *pos, Ipv4Addr ipAddr)
Encode instance identifier (IPv4 address)
Definition: mib_common.c:664
error_t mibEncodeOctetString(uint8_t *oid, size_t maxOidLen, size_t *pos, const uint8_t *data, size_t dataLen, bool_t implied)
Encode instance identifier (octet string)
Definition: mib_common.c:182
error_t mibDecodePort(const uint8_t *oid, size_t oidLen, size_t *pos, uint16_t *port)
Decode instance identifier (port number)
Definition: mib_common.c:495
error_t mibDecodeUnsigned32(const uint8_t *oid, size_t oidLen, size_t *pos, uint32_t *value)
Decode instance identifier (unsigned 32-bit integer)
Definition: mib_common.c:111
error_t mibEncodeIpv6Addr(uint8_t *oid, size_t maxOidLen, size_t *pos, const Ipv6Addr *ipAddr)
Encode instance identifier (IPv6 address)
Definition: mib_common.c:740
error_t mibEncodeIpAddr(uint8_t *oid, size_t maxOidLen, size_t *pos, const IpAddr *ipAddr)
Encode instance identifier (IP address)
Definition: mib_common.c:808
error_t mibDecodePhysAddr(const uint8_t *oid, size_t oidLen, size_t *pos, MacAddr *macAddr)
Decode instance identifier (physical address)
Definition: mib_common.c:625
int_t mibCompMacAddr(const MacAddr *macAddr1, const MacAddr *macAddr2)
Compare MAC addresses.
Definition: mib_common.c:954
error_t mibEncodeUnsigned32(uint8_t *oid, size_t maxOidLen, size_t *pos, uint32_t value)
Encode instance identifier (unsigned 32-bit integer)
Definition: mib_common.c:94
error_t mibEncodeIndex(uint8_t *oid, size_t maxOidLen, size_t *pos, uint_t index)
Encode instance identifier (index)
Definition: mib_common.c:47
error_t mibEncodeMacAddr(uint8_t *oid, size_t maxOidLen, size_t *pos, const MacAddr *macAddr)
Encode instance identifier (MAC address)
Definition: mib_common.c:528
error_t mibEncodeString(uint8_t *oid, size_t maxOidLen, size_t *pos, const char_t *string, bool_t implied)
Encode instance identifier (string)
Definition: mib_common.c:129
Common definitions for MIB modules.
@ INET_ADDR_TYPE_UNKNOWN
Definition: mib_common.h:132
@ INET_ADDR_TYPE_IPV4
Definition: mib_common.h:133
@ INET_ADDR_TYPE_IPV6
Definition: mib_common.h:134
uint8_t p
Definition: ndp.h:300
TCP/IP stack core.
error_t oidDecodeSubIdentifier(const uint8_t *oid, size_t oidLen, size_t *pos, uint32_t *value)
Decode OID sub-identifier.
Definition: oid.c:475
error_t oidEncodeSubIdentifier(uint8_t *oid, size_t maxOidLen, size_t *pos, uint32_t value)
Encode OID sub-identifier.
Definition: oid.c:427
OID (Object Identifier)
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
#define osStrlen(s)
Definition: os_port.h:165
const uint8_t res[]
uint32_t dataLen
Definition: sftp_common.h:229
IP network address.
Definition: ip.h:79
size_t length
Definition: ip.h:80
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369