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-2019 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 1.9.6
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  strlen(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  memcpy(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  //Encode the length of the octet string
535  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, sizeof(MacAddr));
536  //Any error to report?
537  if(error)
538  return error;
539 
540  //The address is encoded as 6 subsequent sub-identifiers
541  for(i = 0; i < sizeof(MacAddr); i++)
542  {
543  //Encode the current byte
544  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, macAddr->b[i]);
545  //Any error to report?
546  if(error)
547  return error;
548  }
549 
550  //Successful processing
551  return NO_ERROR;
552 }
553 
554 
555 /**
556  * @brief Decode instance identifier (MAC address)
557  * @param[in] oid Pointer to the object identifier
558  * @param[in] oidLen Length of the OID, in bytes
559  * @param[in,out] pos Offset where to read the instance identifier
560  * @param[out] macAddr MAC address
561  * @return Error code
562  **/
563 
564 error_t mibDecodeMacAddr(const uint8_t *oid, size_t oidLen, size_t *pos,
565  MacAddr *macAddr)
566 {
567  error_t error;
568  uint_t i;
569  uint32_t length;
570  uint32_t value;
571 
572  //Decode the length of the octet string
573  error = oidDecodeSubIdentifier(oid, oidLen, pos, &length);
574  //Any error to report?
575  if(error)
576  return error;
577 
578  //Make sure the length of the octet string is valid
579  if(length != sizeof(MacAddr))
581 
582  //The address is encoded as 6 subsequent sub-identifiers
583  for(i = 0; i < sizeof(MacAddr); i++)
584  {
585  //Decode the current sub-identifier
586  error = oidDecodeSubIdentifier(oid, oidLen, pos, &value);
587  //Invalid sub-identifier?
588  if(error)
589  return error;
590 
591  //Each byte of the MAC address must be in the range 0-255
592  if(value > 255)
594 
595  //Save the current byte
596  macAddr->b[i] = value & 0xFF;
597  }
598 
599  //Successful processing
600  return NO_ERROR;
601 }
602 
603 
604 /**
605  * @brief Encode instance identifier (IPv4 address)
606  * @param[in] oid Pointer to the object identifier
607  * @param[in] maxOidLen Maximum number of bytes the OID can hold
608  * @param[in,out] pos Offset where to write the instance identifier
609  * @param[in] ipAddr IPv4 address
610  * @return Error code
611  **/
612 
613 error_t mibEncodeIpv4Addr(uint8_t *oid, size_t maxOidLen, size_t *pos,
615 {
616  error_t error;
617  uint_t i;
618  uint8_t *p;
619 
620  //Cast the IPv4 address as a byte array
621  p = (uint8_t *) &ipAddr;
622 
623  //The address is encoded as 4 subsequent sub-identifiers
624  for(i = 0; i < sizeof(Ipv4Addr); i++)
625  {
626  //Encode the current byte
627  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, p[i]);
628  //Any error to report?
629  if(error)
630  return error;
631  }
632 
633  //Successful processing
634  return NO_ERROR;
635 }
636 
637 
638 /**
639  * @brief Decode instance identifier (IPv4 address)
640  * @param[in] oid Pointer to the object identifier
641  * @param[in] oidLen Length of the OID, in bytes
642  * @param[in,out] pos Offset where to read the instance identifier
643  * @param[out] ipAddr IPv4 address
644  * @return Error code
645  **/
646 
647 error_t mibDecodeIpv4Addr(const uint8_t *oid, size_t oidLen, size_t *pos,
648  Ipv4Addr *ipAddr)
649 {
650  error_t error;
651  uint_t i;
652  uint32_t value;
653  uint8_t *p;
654 
655  //Cast the IPv4 address as a byte array
656  p = (uint8_t *) ipAddr;
657 
658  //The address is encoded as 4 subsequent sub-identifiers
659  for(i = 0; i < sizeof(Ipv4Addr); i++)
660  {
661  //Decode the current sub-identifier
662  error = oidDecodeSubIdentifier(oid, oidLen, pos, &value);
663  //Invalid sub-identifier?
664  if(error)
665  return error;
666 
667  //Each byte of the IPv4 address must be in the range 0-255
668  if(value > 255)
670 
671  //Save the current byte
672  p[i] = value & 0xFF;
673  }
674 
675  //Successful processing
676  return NO_ERROR;
677 }
678 
679 
680 /**
681  * @brief Encode instance identifier (IPv6 address)
682  * @param[in] oid Pointer to the object identifier
683  * @param[in] maxOidLen Maximum number of bytes the OID can hold
684  * @param[in,out] pos Offset where to write the instance identifier
685  * @param[in] ipAddr IPv6 address
686  * @return Error code
687  **/
688 
689 error_t mibEncodeIpv6Addr(uint8_t *oid, size_t maxOidLen, size_t *pos,
690  const Ipv6Addr *ipAddr)
691 {
692  error_t error;
693  uint_t i;
694 
695  //The address is encoded as 16 subsequent sub-identifiers
696  for(i = 0; i < sizeof(Ipv6Addr); i++)
697  {
698  //Encode the current byte
699  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, ipAddr->b[i]);
700  //Any error to report?
701  if(error)
702  return error;
703  }
704 
705  //Successful processing
706  return NO_ERROR;
707 }
708 
709 
710 /**
711  * @brief Decode instance identifier (IPv6 address)
712  * @param[in] oid Pointer to the object identifier
713  * @param[in] oidLen Length of the OID, in bytes
714  * @param[in,out] pos Offset where to read the instance identifier
715  * @param[out] ipAddr IPv6 address
716  * @return Error code
717  **/
718 
719 error_t mibDecodeIpv6Addr(const uint8_t *oid, size_t oidLen, size_t *pos,
720  Ipv6Addr *ipAddr)
721 {
722  error_t error;
723  uint_t i;
724  uint32_t value;
725 
726  //The address is encoded as 16 subsequent sub-identifiers
727  for(i = 0; i < sizeof(Ipv6Addr); i++)
728  {
729  //Decode the current sub-identifier
730  error = oidDecodeSubIdentifier(oid, oidLen, pos, &value);
731  //Invalid sub-identifier?
732  if(error)
733  return error;
734 
735  //Each byte of the IPv6 address must be in the range 0-255
736  if(value > 255)
738 
739  //Save the current byte
740  ipAddr->b[i] = value & 0xFF;
741  }
742 
743  //Successful processing
744  return NO_ERROR;
745 }
746 
747 
748 /**
749  * @brief Encode instance identifier (IP address)
750  * @param[in] oid Pointer to the object identifier
751  * @param[in] maxOidLen Maximum number of bytes the OID can hold
752  * @param[in,out] pos Offset where to write the instance identifier
753  * @param[in] ipAddr IP address
754  * @return Error code
755  **/
756 
757 error_t mibEncodeIpAddr(uint8_t *oid, size_t maxOidLen, size_t *pos,
758  const IpAddr *ipAddr)
759 {
760  error_t error;
761 
762 #if (IPV4_SUPPORT == ENABLED)
763  //IPv4 address?
764  if(ipAddr->length == sizeof(Ipv4Addr))
765  {
766  //Encode address type (IPv4)
767  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, INET_ADDR_TYPE_IPV4);
768 
769  //Check status code
770  if(!error)
771  {
772  //Encode the length of the octet string
773  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, sizeof(Ipv4Addr));
774  }
775 
776  //Check status code
777  if(!error)
778  {
779  //Encode IPv4 address
780  error = mibEncodeIpv4Addr(oid, maxOidLen, pos, ipAddr->ipv4Addr);
781  }
782  }
783  else
784 #endif
785 #if (IPV6_SUPPORT == ENABLED)
786  //IPv6 address?
787  if(ipAddr->length == sizeof(Ipv6Addr))
788  {
789  //Encode address type (IPv6)
790  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, INET_ADDR_TYPE_IPV6);
791 
792  //Check status code
793  if(!error)
794  {
795  //Encode the length of the octet string
796  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, sizeof(Ipv6Addr));
797  }
798 
799  //Check status code
800  if(!error)
801  {
802  //Encode IPv6 address
803  error = mibEncodeIpv6Addr(oid, maxOidLen, pos, &ipAddr->ipv6Addr);
804  }
805  }
806  else
807 #endif
808  //Unknown address?
809  {
810  //Encode address type (unknown)
811  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, INET_ADDR_TYPE_UNKNOWN);
812 
813  //Check status code
814  if(!error)
815  {
816  //The unknown address is a zero-length octet string
817  error = oidEncodeSubIdentifier(oid, maxOidLen, pos, 0);
818  }
819  }
820 
821  //Return status code
822  return error;
823 }
824 
825 
826 /**
827  * @brief Decode instance identifier (IP address)
828  * @param[in] oid Pointer to the object identifier
829  * @param[in] oidLen Length of the OID, in bytes
830  * @param[in,out] pos Offset where to read the instance identifier
831  * @param[out] ipAddr IP address
832  * @return Error code
833  **/
834 
835 error_t mibDecodeIpAddr(const uint8_t *oid, size_t oidLen, size_t *pos,
836  IpAddr *ipAddr)
837 {
838  error_t error;
839  uint32_t type;
840  uint32_t length;
841 
842  //Decode address type
843  error = oidDecodeSubIdentifier(oid, oidLen, pos, &type);
844 
845  //Check status code
846  if(!error)
847  {
848  //Decode the length of the octet string
849  error = oidDecodeSubIdentifier(oid, oidLen, pos, &length);
850  }
851 
852  //Check status code
853  if(!error)
854  {
855  //Unknown address?
856  if(type == INET_ADDR_TYPE_UNKNOWN && length == 0)
857  {
858  //The unknown address is a zero-length octet string
859  *ipAddr = IP_ADDR_ANY;
860  }
861 #if (IPV4_SUPPORT == ENABLED)
862  //IPv4 address?
863  else if(type == INET_ADDR_TYPE_IPV4 && length == sizeof(Ipv4Addr))
864  {
865  //Save the length of the address
866  ipAddr->length = sizeof(Ipv4Addr);
867 
868  //Decode IPv4 address
869  error = mibDecodeIpv4Addr(oid, oidLen, pos, &ipAddr->ipv4Addr);
870  }
871 #endif
872 #if (IPV6_SUPPORT == ENABLED)
873  //IPv6 address?
874  else if(type == INET_ADDR_TYPE_IPV6 && length == sizeof(Ipv6Addr))
875  {
876  //Save the length of the address
877  ipAddr->length = sizeof(Ipv6Addr);
878 
879  //Decode IPv6 address
880  error = mibDecodeIpv6Addr(oid, oidLen, pos, &ipAddr->ipv6Addr);
881  }
882 #endif
883  //Invalid address?
884  else
885  {
886  //Report an error
887  error = ERROR_INSTANCE_NOT_FOUND;
888  }
889  }
890 
891  //Return status code
892  return error;
893 }
894 
895 
896 /**
897  * @brief Compare IP addresses
898  * @param[in] ipAddr1 First IP address
899  * @param[in] ipAddr2 Second IP address
900  * @return Comparison result
901  **/
902 
903 int_t mibCompIpAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
904 {
905  int_t res;
906 
907  //Compare length fields
908  if(ipAddr1->length < ipAddr2->length)
909  {
910  res = -1;
911  }
912  else if(ipAddr1->length > ipAddr2->length)
913  {
914  res = 1;
915  }
916  else if(ipAddr1->length == 0)
917  {
918  res = 0;
919  }
920  else
921  {
922  //Compare IP addresses
923  res = memcmp((uint8_t *) ipAddr1 + sizeof(size_t),
924  (uint8_t *) ipAddr2 + sizeof(size_t), ipAddr1->length);
925  }
926 
927  //Return comparison result
928  return res;
929 }
930 
931 
932 /**
933  * @brief Test and increment spin lock
934  * @param[in,out] spinLock Pointer to the spin lock
935  * @param[in] value New value supplied via the management protocol
936  * @param[in] commit This flag indicates the current phase (validation phase
937  * or write phase if the validation was successful)
938  * @return Comparison result
939  **/
940 
941 error_t mibTestAndIncSpinLock(int32_t *spinLock, int32_t value, bool_t commit)
942 {
943  error_t error;
944 
945  //The new value supplied via the management protocol must precisely match
946  //the value presently held by the instance
947  if(value == *spinLock)
948  {
949  //Write phase?
950  if(commit)
951  {
952  //The value held by the instance is incremented by one
953  (*spinLock)++;
954 
955  //if the current value is the maximum value of 2^31-1, then the value
956  //held by the instance is wrapped to zero
957  if(*spinLock < 0)
958  *spinLock = 0;
959  }
960 
961  //Successful operation
962  error = NO_ERROR;
963  }
964  else
965  {
966  //The management protocol set operation fails with an error of
967  //inconsistentValue
968  error = ERROR_INCONSISTENT_VALUE;
969  }
970 
971  //Return status code
972  return error;
973 }
@ INET_ADDR_TYPE_UNKNOWN
Definition: mib_common.h:132
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
uint8_t length
Definition: dtls_misc.h:149
error_t mibEncodeIpAddr(uint8_t *oid, size_t maxOidLen, size_t *pos, const IpAddr *ipAddr)
Encode instance identifier (IP address)
Definition: mib_common.c:757
int bool_t
Definition: compiler_port.h:49
signed int int_t
Definition: compiler_port.h:44
IP network address.
Definition: ip.h:71
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:140
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
OID (Object Identifier)
uint8_t p
Definition: ndp.h:298
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 mibDecodePort(const uint8_t *oid, size_t oidLen, size_t *pos, uint16_t *port)
Decode instance identifier (port number)
Definition: mib_common.c:495
@ INET_ADDR_TYPE_IPV6
Definition: mib_common.h:134
const uint8_t res[]
error_t mibDecodeIpv6Addr(const uint8_t *oid, size_t oidLen, size_t *pos, Ipv6Addr *ipAddr)
Decode instance identifier (IPv6 address)
Definition: mib_common.c:719
error_t oidEncodeSubIdentifier(uint8_t *oid, size_t maxOidLen, size_t *pos, uint32_t value)
Encode OID sub-identifier.
Definition: oid.c:314
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:239
error_t oidDecodeSubIdentifier(const uint8_t *oid, size_t oidLen, size_t *pos, uint32_t *value)
Decode OID sub-identifier.
Definition: oid.c:362
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
const IpAddr IP_ADDR_ANY
Definition: ip.c:45
int_t mibCompIpAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
Compare IP addresses.
Definition: mib_common.c:903
char_t type
error_t
Error codes.
Definition: error.h:42
@ ERROR_INSTANCE_NOT_FOUND
Definition: error.h:251
uint8_t oid[1]
Definition: mib_common.h:186
__start_packed struct @179 Ipv6Addr
IPv6 network address.
size_t length
Definition: ip.h:73
@ INET_ADDR_TYPE_IPV4
Definition: mib_common.h:133
uint16_t port
Definition: dns_common.h:223
char char_t
Definition: compiler_port.h:43
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 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 mibEncodeIpv4Addr(uint8_t *oid, size_t maxOidLen, size_t *pos, Ipv4Addr ipAddr)
Encode instance identifier (IPv4 address)
Definition: mib_common.c:613
Common definitions for MIB modules.
uint8_t n
error_t mibDecodeMacAddr(const uint8_t *oid, size_t oidLen, size_t *pos, MacAddr *macAddr)
Decode instance identifier (MAC address)
Definition: mib_common.c:564
error_t mibDecodeIpAddr(const uint8_t *oid, size_t oidLen, size_t *pos, IpAddr *ipAddr)
Decode instance identifier (IP address)
Definition: mib_common.c:835
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_INVALID_SYNTAX
Definition: error.h:68
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 mibTestAndIncSpinLock(int32_t *spinLock, int32_t value, bool_t commit)
Test and increment spin lock.
Definition: mib_common.c:941
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 mibDecodeIpv4Addr(const uint8_t *oid, size_t oidLen, size_t *pos, Ipv4Addr *ipAddr)
Decode instance identifier (IPv4 address)
Definition: mib_common.c:647
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 mibEncodeIpv6Addr(uint8_t *oid, size_t maxOidLen, size_t *pos, const Ipv6Addr *ipAddr)
Encode instance identifier (IPv6 address)
Definition: mib_common.c:689
uint8_t value[]
Definition: dtls_misc.h:150
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
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
uint8_t ipAddr[4]
Definition: mib_common.h:187
@ ERROR_INCONSISTENT_VALUE
Definition: error.h:122
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
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
__start_packed struct @108 MacAddr
MAC address.