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