snmp_agent.c
Go to the documentation of this file.
1 /**
2  * @file snmp_agent.c
3  * @brief SNMP agent (Simple Network Management Protocol)
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  * @section Description
28  *
29  * SNMP is a simple protocol by which management information for a network
30  * element may be inspected or altered by logically remote users. Refer
31  * to the following RFCs for complete details:
32  * - RFC 1157: A Simple Network Management Protocol (SNMP)
33  * - RFC 1905: Protocol Operations for Version 2 of the Simple Network
34  * Management Protocol (SNMPv2)
35  * - RFC 3410: Introduction and Applicability Statements for Internet
36  * Standard Management Framework
37  * - RFC 3411: An Architecture for Describing SNMP Management Frameworks
38  * - RFC 3412: Message Processing and Dispatching for the SNMP
39  * - RFC 3413: Simple Network Management Protocol (SNMP) Applications
40  * - RFC 3584: Coexistence between Version 1, Version 2, and Version 3 of
41  * SNMP Framework
42  *
43  * @author Oryx Embedded SARL (www.oryx-embedded.com)
44  * @version 1.9.6
45  **/
46 
47 //Switch to the appropriate trace level
48 #define TRACE_LEVEL SNMP_TRACE_LEVEL
49 
50 //Dependencies
51 #include "core/net.h"
52 #include "snmp/snmp_agent.h"
54 #include "snmp/snmp_agent_pdu.h"
55 #include "snmp/snmp_agent_misc.h"
56 #include "snmp/snmp_agent_trap.h"
57 #include "snmp/snmp_agent_inform.h"
58 #include "mibs/mib2_module.h"
59 #include "core/crypto.h"
60 #include "encoding/asn1.h"
61 #include "encoding/oid.h"
62 #include "debug.h"
63 
64 //Check TCP/IP stack configuration
65 #if (SNMP_AGENT_SUPPORT == ENABLED)
66 
67 
68 /**
69  * @brief Initialize settings with default values
70  * @param[out] settings Structure that contains SNMP agent settings
71  **/
72 
74 {
75  //The SNMP agent is not bound to any interface
76  settings->interface = NULL;
77 
78  //Minimum version accepted by the SNMP agent
79  settings->versionMin = SNMP_VERSION_1;
80  //Maximum version accepted by the SNMP agent
81  settings->versionMax = SNMP_VERSION_3;
82 
83  //SNMP port number
84  settings->port = SNMP_PORT;
85  //SNMP trap port number
86  settings->trapPort = SNMP_TRAP_PORT;
87 
88  //Random data generation callback function
89  settings->randCallback = NULL;
90 }
91 
92 
93 /**
94  * @brief SNMP agent initialization
95  * @param[in] context Pointer to the SNMP agent context
96  * @param[in] settings SNMP agent specific settings
97  * @return Error code
98  **/
99 
101 {
102  error_t error;
103 
104  //Debug message
105  TRACE_INFO("Initializing SNMP agent...\r\n");
106 
107  //Ensure the parameters are valid
108  if(context == NULL || settings == NULL)
110 
111  //Check minimum and maximum SNMP versions
112  if(settings->versionMin > settings->versionMax)
114 
115  //Clear the SNMP agent context
116  memset(context, 0, sizeof(SnmpAgentContext));
117 
118  //Save user settings
119  context->settings = *settings;
120 
121  //Initialize request identifier
122  context->requestId = netGetRandRange(1, INT32_MAX);
123 
124 #if (SNMP_V3_SUPPORT == ENABLED)
125  //Get current time
126  context->systemTime = osGetSystemTime();
127 
128  //Each SNMP engine maintains two values, snmpEngineBoots and snmpEngineTime,
129  //which taken together provide an indication of time at that SNMP engine
130  context->engineBoots = 1;
131  context->engineTime = 0;
132 
133  //Initialize message identifier
134  context->msgId = netGetRandRange(1, INT32_MAX);
135 
136  //Check whether SNMPv3 is supported
137  if(settings->versionMin <= SNMP_VERSION_3 &&
138  settings->versionMax >= SNMP_VERSION_3)
139  {
140  //Make sure a random number generator has been registered
141  if(settings->randCallback == NULL)
143 
144  //The salt integer is initialized to an arbitrary value at boot time
145  error = settings->randCallback((uint8_t *) &context->salt, sizeof(context->salt));
146  //Any error to report?
147  if(error)
148  return error;
149  }
150 #endif
151 
152  //Create a mutex to prevent simultaneous access to SNMP agent context
153  if(!osCreateMutex(&context->mutex))
154  {
155  //Failed to create mutex
156  return ERROR_OUT_OF_RESOURCES;
157  }
158 
159 #if (SNMP_AGENT_INFORM_SUPPORT == ENABLED)
160  //Create an event object to manage inform request retransmissions
161  if(!osCreateEvent(&context->informEvent))
162  {
163  //Clean up side effects
164  osDeleteMutex(&context->mutex);
165  //Failed to event object
166  return ERROR_OUT_OF_RESOURCES;
167  }
168 #endif
169 
170  //Open a UDP socket
172 
173  //Failed to open socket?
174  if(context->socket == NULL)
175  {
176  //Clean up side effects
177  osDeleteMutex(&context->mutex);
178 #if (SNMP_AGENT_INFORM_SUPPORT == ENABLED)
179  osDeleteMutex(&context->informEvent);
180 #endif
181  //Report an error
182  return ERROR_OPEN_FAILED;
183  }
184 
185  //Start of exception handling block
186  do
187  {
188  //Explicitly associate the socket with the relevant interface
189  error = socketBindToInterface(context->socket, settings->interface);
190  //Unable to bind the socket to the desired interface?
191  if(error)
192  break;
193 
194  //The SNMP agent listens for messages on port 161
195  error = socketBind(context->socket, &IP_ADDR_ANY, settings->port);
196  //Unable to bind the socket to the desired port?
197  if(error)
198  break;
199 
200  //End of exception handling block
201  } while(0);
202 
203  //Any error to report?
204  if(error)
205  {
206  //Clean up side effects
207  osDeleteMutex(&context->mutex);
208 #if (SNMP_AGENT_INFORM_SUPPORT == ENABLED)
209  osDeleteMutex(&context->informEvent);
210 #endif
211  //Close underlying socket
212  socketClose(context->socket);
213  }
214 
215  //Return status code
216  return error;
217 }
218 
219 
220 /**
221  * @brief Start SNMP agent
222  * @param[in] context Pointer to the SNMP agent context
223  * @return Error code
224  **/
225 
227 {
228  OsTask *task;
229 
230  //Debug message
231  TRACE_INFO("Starting SNMP agent...\r\n");
232 
233  //Make sure the SNMP agent context is valid
234  if(context == NULL)
236 
237  //Start the SNMP agent service
238  task = osCreateTask("SNMP Agent", (OsTaskCode) snmpAgentTask,
240 
241  //Unable to create the task?
242  if(task == OS_INVALID_HANDLE)
243  return ERROR_OUT_OF_RESOURCES;
244 
245  //The SNMP agent has successfully started
246  return NO_ERROR;
247 }
248 
249 
250 /**
251  * @brief Load a MIB module
252  * @param[in] context Pointer to the SNMP agent context
253  * @param[in] module Pointer the MIB module to be loaded
254  * @return Error code
255  **/
256 
258 {
259  error_t error;
260  uint_t i;
261 
262  //Check parameters
263  if(context == NULL || module == NULL)
265  if(module->numObjects < 1)
267 
268  //Acquire exclusive access to the SNMP agent context
269  osAcquireMutex(&context->mutex);
270 
271  //Loop through existing MIBs
272  for(i = 0; i < SNMP_AGENT_MAX_MIBS; i++)
273  {
274  //Check whether the specified MIB module is already loaded
275  if(context->mibTable[i] == module)
276  break;
277  }
278 
279  //MIB module found?
280  if(i < SNMP_AGENT_MAX_MIBS)
281  {
282  //Prevent the SNMP agent from loading the same MIB multiple times
283  error = NO_ERROR;
284  }
285  else
286  {
287  //Loop through existing MIBs
288  for(i = 0; i < SNMP_AGENT_MAX_MIBS; i++)
289  {
290  //Check if the current entry is available
291  if(context->mibTable[i] == NULL)
292  break;
293  }
294 
295  //Make sure there is enough room to add the specified MIB
296  if(i < SNMP_AGENT_MAX_MIBS)
297  {
298  //Invoke user callback, if any
299  if(module->load != NULL)
300  error = module->load(context);
301  else
302  error = NO_ERROR;
303 
304  //Check status code
305  if(!error)
306  {
307  //Add the MIB to the list
308  context->mibTable[i] = module;
309  }
310  }
311  else
312  {
313  //Failed to load the specified MIB
314  error = ERROR_OUT_OF_RESOURCES;
315  }
316  }
317 
318  //Release exclusive access to the SNMP agent context
319  osReleaseMutex(&context->mutex);
320 
321  //Return status code
322  return error;
323 }
324 
325 
326 /**
327  * @brief Unload a MIB module
328  * @param[in] context Pointer to the SNMP agent context
329  * @param[in] module Pointer the MIB module to be unloaded
330  * @return Error code
331  **/
332 
334 {
335  error_t error;
336  uint_t i;
337 
338  //Check parameters
339  if(context == NULL || module == NULL)
341 
342  //Acquire exclusive access to the SNMP agent context
343  osAcquireMutex(&context->mutex);
344 
345  //Loop through existing MIBs
346  for(i = 0; i < SNMP_AGENT_MAX_MIBS; i++)
347  {
348  //Check whether the specified MIB module is already loaded
349  if(context->mibTable[i] == module)
350  break;
351  }
352 
353  //MIB module found?
354  if(i < SNMP_AGENT_MAX_MIBS)
355  {
356  //Any registered callback?
357  if(context->mibTable[i]->unload != NULL)
358  {
359  //Invoke user callback function
360  context->mibTable[i]->unload(context);
361  }
362 
363  //Remove the MIB from the list
364  context->mibTable[i] = NULL;
365 
366  //Successful processing
367  error = NO_ERROR;
368  }
369  else
370  {
371  //Failed to unload the specified MIB
372  error = ERROR_NOT_FOUND;
373  }
374 
375  //Release exclusive access to the SNMP agent context
376  osReleaseMutex(&context->mutex);
377 
378  //Return status code
379  return error;
380 }
381 
382 
383 /**
384  * @brief Set minimum and maximum versions permitted
385  * @param[in] context Pointer to the SNMP agent context
386  * @param[in] versionMin Minimum version accepted by the SNMP agent
387  * @param[in] versionMax Maximum version accepted by the SNMP agent
388  * @return Error code
389  **/
390 
392  SnmpVersion versionMin, SnmpVersion versionMax)
393 {
394  //Check parameters
395  if(context == NULL)
397  if(versionMin > versionMax)
399 
400  //Acquire exclusive access to the SNMP agent context
401  osAcquireMutex(&context->mutex);
402 
403  //Set minimum and maximum versions permitted
404  context->settings.versionMin = versionMin;
405  context->settings.versionMax = versionMax;
406 
407  //Release exclusive access to the SNMP agent context
408  osReleaseMutex(&context->mutex);
409 
410  //Successful processing
411  return NO_ERROR;
412 }
413 
414 
415 /**
416  * @brief Set the value of the snmpEngineBoots variable
417  * @param[in] context Pointer to the SNMP agent context
418  * @param[in] engineBoots Number of times the SNMP engine has re-booted
419  * @return Error code
420  **/
421 
422 error_t snmpAgentSetEngineBoots(SnmpAgentContext *context, int32_t engineBoots)
423 {
424 #if (SNMP_V3_SUPPORT == ENABLED)
425  //Check parameters
426  if(context == NULL)
428  if(engineBoots < 0)
429  return ERROR_OUT_OF_RANGE;
430 
431  //Acquire exclusive access to the SNMP agent context
432  osAcquireMutex(&context->mutex);
433 
434  //Get current time
435  context->systemTime = osGetSystemTime();
436 
437  //Set the value of the snmpEngineBoots
438  context->engineBoots = engineBoots;
439  //The snmpEngineTime is reset to zero
440  context->engineTime = 0;
441 
442  //Release exclusive access to the SNMP agent context
443  osReleaseMutex(&context->mutex);
444 
445  //Successful processing
446  return NO_ERROR;
447 #else
448  //Not implemented
449  return ERROR_NOT_IMPLEMENTED;
450 #endif
451 }
452 
453 
454 /**
455  * @brief Get the value of the snmpEngineBoots variable
456  * @param[in] context Pointer to the SNMP agent context
457  * @param[out] engineBoots Number of times the SNMP engine has re-booted
458  * @return Error code
459  **/
460 
461 error_t snmpAgentGetEngineBoots(SnmpAgentContext *context, int32_t *engineBoots)
462 {
463 #if (SNMP_V3_SUPPORT == ENABLED)
464  //Check parameters
465  if(context == NULL || engineBoots == NULL)
467 
468  //Acquire exclusive access to the SNMP agent context
469  osAcquireMutex(&context->mutex);
470  //Get the current value of the snmpEngineBoots
471  *engineBoots = context->engineBoots;
472  //Release exclusive access to the SNMP agent context
473  osReleaseMutex(&context->mutex);
474 
475  //Successful processing
476  return NO_ERROR;
477 #else
478  //Not implemented
479  return ERROR_NOT_IMPLEMENTED;
480 #endif
481 }
482 
483 
484 /**
485  * @brief Set enterprise OID
486  * @param[in] context Pointer to the SNMP agent context
487  * @param[in] enterpriseOid Pointer to the enterprise OID
488  * @param[in] enterpriseOidLen Length of the enterprise OID
489  * @return Error code
490  **/
491 
493  const uint8_t *enterpriseOid, size_t enterpriseOidLen)
494 {
495  //Check parameters
496  if(context == NULL || enterpriseOid == NULL)
498  if(enterpriseOidLen > SNMP_MAX_OID_SIZE)
500 
501  //Acquire exclusive access to the SNMP agent context
502  osAcquireMutex(&context->mutex);
503 
504  //Set enterprise OID
505  memcpy(context->enterpriseOid, enterpriseOid, enterpriseOidLen);
506  //Save the length of the enterprise OID
507  context->enterpriseOidLen = enterpriseOidLen;
508 
509  //Release exclusive access to the SNMP agent context
510  osReleaseMutex(&context->mutex);
511 
512  //Successful processing
513  return NO_ERROR;
514 }
515 
516 
517 /**
518  * @brief Set context engine identifier
519  * @param[in] context Pointer to the SNMP agent context
520  * @param[in] contextEngine Pointer to the context engine identifier
521  * @param[in] contextEngineLen Length of the context engine identifier
522  * @return Error code
523  **/
524 
526  const void *contextEngine, size_t contextEngineLen)
527 {
528 #if (SNMP_V3_SUPPORT == ENABLED)
529  //Check parameters
530  if(context == NULL || contextEngine == NULL)
532  if(contextEngineLen > SNMP_MAX_CONTEXT_ENGINE_SIZE)
534 
535  //Acquire exclusive access to the SNMP agent context
536  osAcquireMutex(&context->mutex);
537 
538  //Set context engine identifier
539  memcpy(context->contextEngine, contextEngine, contextEngineLen);
540  //Save the length of the context engine identifier
541  context->contextEngineLen = contextEngineLen;
542 
543  //Release exclusive access to the SNMP agent context
544  osReleaseMutex(&context->mutex);
545 
546  //Successful processing
547  return NO_ERROR;
548 #else
549  //Not implemented
550  return ERROR_NOT_IMPLEMENTED;
551 #endif
552 }
553 
554 
555 /**
556  * @brief Set context name
557  * @param[in] context Pointer to the SNMP agent context
558  * @param[in] contextName NULL-terminated string that contains the context name
559  * @return Error code
560  **/
561 
563  const char_t *contextName)
564 {
565 #if (SNMP_V3_SUPPORT == ENABLED)
566  size_t n;
567 
568  //Check parameters
569  if(context == NULL || contextName == NULL)
571 
572  //Retrieve the length of the context name
573  n = strlen(contextName);
574 
575  //Make sure the context name is valid
577  return ERROR_INVALID_LENGTH;
578 
579  //Acquire exclusive access to the SNMP agent context
580  osAcquireMutex(&context->mutex);
581  //Set context name
582  strcpy(context->contextName, contextName);
583  //Release exclusive access to the SNMP agent context
584  osReleaseMutex(&context->mutex);
585 
586  //Successful processing
587  return NO_ERROR;
588 #else
589  //Not implemented
590  return ERROR_NOT_IMPLEMENTED;
591 #endif
592 }
593 
594 
595 /**
596  * @brief Create a new community string
597  * @param[in] context Pointer to the SNMP agent context
598  * @param[in] community NULL-terminated string that contains the community name
599  * @param[in] mode Access rights
600  * @return Error code
601  **/
602 
604  const char_t *community, SnmpAccess mode)
605 {
606 #if (SNMP_V1_SUPPORT == ENABLED || SNMP_V2C_SUPPORT == ENABLED)
607  error_t error;
608  size_t n;
609  SnmpUserEntry *entry;
610 
611  //Check parameters
612  if(context == NULL || community == NULL)
614 
615  //Retrieve the length of the community string
616  n = strlen(community);
617 
618  //Make sure the community string is valid
619  if(n == 0 || n > SNMP_MAX_USER_NAME_LEN)
620  return ERROR_INVALID_LENGTH;
621 
622  //Acquire exclusive access to the SNMP agent context
623  osAcquireMutex(&context->mutex);
624 
625  //Check whether the community string already exists
626  entry = snmpFindCommunityEntry(context, community, strlen(community));
627 
628  //If the specified community string does not exist, then a new entry
629  //should be created
630  if(entry == NULL)
631  {
632  //Create a new entry
633  entry = snmpCreateCommunityEntry(context);
634  }
635 
636  //Any entry available?
637  if(entry != NULL)
638  {
639  //Clear the contents
640  memset(entry, 0, sizeof(SnmpUserEntry));
641 
642  //Save community string
643  strcpy(entry->name, community);
644  //Set access rights
645  entry->mode = mode;
646  //The entry is now available for use
647  entry->status = MIB_ROW_STATUS_ACTIVE;
648 
649  //Successful processing
650  error = NO_ERROR;
651  }
652  else
653  {
654  //The table runs out of space
655  error = ERROR_OUT_OF_RESOURCES;
656  }
657 
658  //Release exclusive access to the SNMP agent context
659  osReleaseMutex(&context->mutex);
660 
661  //Return error code
662  return error;
663 #else
664  //Not implemented
665  return ERROR_NOT_IMPLEMENTED;
666 #endif
667 }
668 
669 
670 /**
671  * @brief Remove a community string
672  * @param[in] context Pointer to the SNMP agent context
673  * @param[in] community NULL-terminated string that contains the community name
674  * @return Error code
675  **/
676 
678 {
679 #if (SNMP_V1_SUPPORT == ENABLED || SNMP_V2C_SUPPORT == ENABLED)
680  error_t error;
681  SnmpUserEntry *entry;
682 
683  //Check parameters
684  if(context == NULL || community == NULL)
686 
687  //Acquire exclusive access to the SNMP agent context
688  osAcquireMutex(&context->mutex);
689 
690  //Search the community table for the specified community string
691  entry = snmpFindCommunityEntry(context, community, strlen(community));
692 
693  //Any matching entry found?
694  if(entry != NULL)
695  {
696  //Clear the contents
697  memset(entry, 0, sizeof(SnmpUserEntry));
698  //Now mark the entry as free
699  entry->status = MIB_ROW_STATUS_UNUSED;
700 
701  //Successful processing
702  error = NO_ERROR;
703  }
704  else
705  {
706  //The specified community string does not exist
707  error = ERROR_NOT_FOUND;
708  }
709 
710  //Release exclusive access to the SNMP agent context
711  osReleaseMutex(&context->mutex);
712 
713  //Return status code
714  return error;
715 #else
716  //Not implemented
717  return ERROR_NOT_IMPLEMENTED;
718 #endif
719 }
720 
721 
722 /**
723  * @brief Create a new user
724  * @param[in] context Pointer to the SNMP agent context
725  * @param[in] userName NULL-terminated string that contains the user name
726  * @param[in] mode Access rights
727  * @param[in] keyFormat Key format (ASCII password or raw key)
728  * @param[in] authProtocol Authentication type
729  * @param[in] authKey Key to be used for data authentication
730  * @param[in] privProtocol Privacy type
731  * @param[in] privKey Key to be used for data encryption
732  * @return Error code
733  **/
734 
736  const char_t *userName, SnmpAccess mode, SnmpKeyFormat keyFormat,
737  SnmpAuthProtocol authProtocol, const void *authKey,
738  SnmpPrivProtocol privProtocol, const void *privKey)
739 {
740 #if (SNMP_V3_SUPPORT == ENABLED)
741  error_t error;
742  size_t n;
743  SnmpUserEntry *entry;
744 
745  //Check parameters
746  if(context == NULL || userName == NULL)
748 
749  //Data authentication?
750  if(authProtocol != SNMP_AUTH_PROTOCOL_NONE)
751  {
752  //Check key format
753  if(keyFormat != SNMP_KEY_FORMAT_TEXT &&
754  keyFormat != SNMP_KEY_FORMAT_RAW &&
755  keyFormat != SNMP_KEY_FORMAT_LOCALIZED)
756  {
758  }
759 
760  //Data authentication requires a key
761  if(authKey == NULL)
763  }
764 
765  //Data confidentiality?
766  if(privProtocol != SNMP_PRIV_PROTOCOL_NONE)
767  {
768  //Check key format
769  if(keyFormat != SNMP_KEY_FORMAT_TEXT && keyFormat != SNMP_KEY_FORMAT_RAW)
771 
772  //Data confidentiality requires a key
773  if(privKey == NULL)
775 
776  //There is no provision for data confidentiality without data authentication
777  if(authProtocol == SNMP_AUTH_PROTOCOL_NONE)
779  }
780 
781  //Retrieve the length of the user name
782  n = strlen(userName);
783 
784  //Make sure the user name is valid
785  if(n == 0 || n > SNMP_MAX_USER_NAME_LEN)
786  return ERROR_INVALID_LENGTH;
787 
788  //Acquire exclusive access to the SNMP agent context
789  osAcquireMutex(&context->mutex);
790 
791  //Check whether the user name already exists
792  entry = snmpFindUserEntry(context, userName, strlen(userName));
793 
794  //If the specified user name does not exist, then a new entry
795  //should be created
796  if(entry == NULL)
797  {
798  //Create a security profile for the new user
799  entry = snmpCreateUserEntry(context);
800  }
801 
802  //Any entry available?
803  if(entry != NULL)
804  {
805  //Clear the security profile of the user
806  memset(entry, 0, sizeof(SnmpUserEntry));
807 
808  //Save user name
809  strcpy(entry->name, userName);
810  //Access rights
811  entry->mode = mode;
812  //Authentication protocol
813  entry->authProtocol = authProtocol;
814  //Privacy protocol
815  entry->privProtocol = privProtocol;
816 
817  //Initialize status code
818  error = NO_ERROR;
819 
820  //Data authentication?
821  if(authProtocol != SNMP_AUTH_PROTOCOL_NONE)
822  {
823  //ASCII password or raw key?
824  if(keyFormat == SNMP_KEY_FORMAT_TEXT)
825  {
826  //Generate the authentication key from the provided password
827  error = snmpGenerateKey(authProtocol, authKey, &entry->rawAuthKey);
828 
829  //Check status code
830  if(!error)
831  {
832  //Localize the key with the engine ID
833  error = snmpLocalizeKey(authProtocol,
834  context->contextEngine, context->contextEngineLen,
835  &entry->rawAuthKey, &entry->localizedAuthKey);
836  }
837  }
838  else if(keyFormat == SNMP_KEY_FORMAT_RAW)
839  {
840  //Save the authentication key
841  memcpy(&entry->rawAuthKey, authKey, sizeof(SnmpKey));
842 
843  //Now localize the key with the engine ID
844  error = snmpLocalizeKey(authProtocol,
845  context->contextEngine, context->contextEngineLen,
846  &entry->rawAuthKey, &entry->localizedAuthKey);
847  }
848  else
849  {
850  //The authentication key is already localized
851  memcpy(&entry->localizedAuthKey, authKey, sizeof(SnmpKey));
852  }
853  }
854 
855  //Check status code
856  if(!error)
857  {
858  //Data confidentiality?
859  if(privProtocol != SNMP_PRIV_PROTOCOL_NONE)
860  {
861  //ASCII password or raw key?
862  if(keyFormat == SNMP_KEY_FORMAT_TEXT)
863  {
864  //Generate the privacy key from the provided password
865  error = snmpGenerateKey(authProtocol, privKey, &entry->rawPrivKey);
866 
867  //Check status code
868  if(!error)
869  {
870  //Localize the key with the engine ID
871  error = snmpLocalizeKey(authProtocol,
872  context->contextEngine, context->contextEngineLen,
873  &entry->rawPrivKey, &entry->localizedPrivKey);
874  }
875  }
876  else if(keyFormat == SNMP_KEY_FORMAT_RAW)
877  {
878  //Save the privacy key
879  memcpy(&entry->rawPrivKey, privKey, sizeof(SnmpKey));
880 
881  //Now localize the key with the engine ID
882  error = snmpLocalizeKey(authProtocol,
883  context->contextEngine, context->contextEngineLen,
884  &entry->rawPrivKey, &entry->localizedPrivKey);
885  }
886  else
887  {
888  //The privacy key is already localized
889  memcpy(&entry->localizedPrivKey, privKey, sizeof(SnmpKey));
890  }
891  }
892  }
893 
894  //Check status code
895  if(!error)
896  {
897  //The entry is now available for use
898  entry->status = MIB_ROW_STATUS_ACTIVE;
899  }
900  else
901  {
902  //Clean up side effects
903  memset(entry, 0, sizeof(SnmpUserEntry));
904  //Now mark the entry as free
905  entry->status = MIB_ROW_STATUS_UNUSED;
906  }
907  }
908  else
909  {
910  //The user table runs out of space
911  error = ERROR_OUT_OF_RESOURCES;
912  }
913 
914  //Release exclusive access to the SNMP agent context
915  osReleaseMutex(&context->mutex);
916 
917  //Return error code
918  return error;
919 #else
920  //Not implemented
921  return ERROR_NOT_IMPLEMENTED;
922 #endif
923 }
924 
925 
926 /**
927  * @brief Remove existing user
928  * @param[in] context Pointer to the SNMP agent context
929  * @param[in] userName NULL-terminated string that contains the user name
930  * @return Error code
931  **/
932 
934 {
935 #if (SNMP_V3_SUPPORT == ENABLED)
936  error_t error;
937  SnmpUserEntry *entry;
938 
939  //Check parameters
940  if(context == NULL || userName == NULL)
942 
943  //Acquire exclusive access to the SNMP agent context
944  osAcquireMutex(&context->mutex);
945 
946  //Search the user table for the specified user name
947  entry = snmpFindUserEntry(context, userName, strlen(userName));
948 
949  //Any matching entry found?
950  if(entry != NULL)
951  {
952  //Clear the security profile of the user
953  memset(entry, 0, sizeof(SnmpUserEntry));
954  //Now mark the entry as free
955  entry->status = MIB_ROW_STATUS_UNUSED;
956 
957  //Successful processing
958  error = NO_ERROR;
959  }
960  else
961  {
962  //The specified user name does not exist
963  error = ERROR_NOT_FOUND;
964  }
965 
966  //Release exclusive access to the SNMP agent context
967  osReleaseMutex(&context->mutex);
968 
969  //Return status code
970  return error;
971 #else
972  //Not implemented
973  return ERROR_NOT_IMPLEMENTED;
974 #endif
975 }
976 
977 
978 /**
979  * @brief Join a group of users
980  * @param[in] context Pointer to the SNMP agent context
981  * @param[in] userName NULL-terminated string that contains the user name
982  * @param[in] securityModel Security model
983  * @param[in] groupName NULL-terminated string that contains the group name
984  * @return Error code
985  **/
986 
988  SnmpSecurityModel securityModel, const char_t *groupName)
989 {
990 #if (SNMP_AGENT_VACM_SUPPORT == ENABLED)
991  error_t error;
992  size_t n;
993  SnmpGroupEntry *entry;
994 
995  //Check parameters
996  if(context == NULL || userName == NULL || groupName == NULL)
998 
999  //Check security model
1000  if(securityModel != SNMP_SECURITY_MODEL_V1 &&
1001  securityModel != SNMP_SECURITY_MODEL_V2C &&
1002  securityModel != SNMP_SECURITY_MODEL_USM)
1003  {
1004  return ERROR_INVALID_PARAMETER;
1005  }
1006 
1007  //Retrieve the length of the user name
1008  n = strlen(userName);
1009 
1010  //Make sure the user name is valid
1011  if(n == 0 || n > SNMP_MAX_USER_NAME_LEN)
1012  return ERROR_INVALID_LENGTH;
1013 
1014  //Retrieve the length of the group name
1015  n = strlen(groupName);
1016 
1017  //Make sure the group name is valid
1018  if(n == 0 || n > SNMP_MAX_GROUP_NAME_LEN)
1019  return ERROR_INVALID_LENGTH;
1020 
1021  //Acquire exclusive access to the SNMP agent context
1022  osAcquireMutex(&context->mutex);
1023 
1024  //Search the group table for a matching entry
1025  entry = snmpFindGroupEntry(context, securityModel, userName,
1026  strlen(userName));
1027 
1028  //No matching entry found?
1029  if(entry == NULL)
1030  {
1031  //Create a new entry in the group table
1032  entry = snmpCreateGroupEntry(context);
1033  }
1034 
1035  //Any entry available?
1036  if(entry != NULL)
1037  {
1038  //Clear entry
1039  memset(entry, 0, sizeof(SnmpGroupEntry));
1040 
1041  //Save security model
1042  entry->securityModel = securityModel;
1043  //Save user name
1044  strcpy(entry->securityName, userName);
1045  //Save group name
1046  strcpy(entry->groupName, groupName);
1047 
1048  //The entry is now available for use
1049  entry->status = MIB_ROW_STATUS_ACTIVE;
1050 
1051  //Successful processing
1052  error = NO_ERROR;
1053  }
1054  else
1055  {
1056  //The group table runs out of space
1057  error = ERROR_OUT_OF_RESOURCES;
1058  }
1059 
1060  //Release exclusive access to the SNMP agent context
1061  osReleaseMutex(&context->mutex);
1062 
1063  //Return status code
1064  return error;
1065 #else
1066  //Not implemented
1067  return ERROR_NOT_IMPLEMENTED;
1068 #endif
1069 }
1070 
1071 
1072 /**
1073  * @brief Leave a group of users
1074  * @param[in] context Pointer to the SNMP agent context
1075  * @param[in] userName NULL-terminated string that contains the user name
1076  * @param[in] securityModel Security model
1077  * @return Error code
1078  **/
1079 
1081  const char_t *userName, SnmpSecurityModel securityModel)
1082 {
1083 #if (SNMP_AGENT_VACM_SUPPORT == ENABLED)
1084  error_t error;
1085  SnmpGroupEntry *entry;
1086 
1087  //Check parameters
1088  if(context == NULL || userName == NULL)
1089  return ERROR_INVALID_PARAMETER;
1090 
1091  //Acquire exclusive access to the SNMP agent context
1092  osAcquireMutex(&context->mutex);
1093 
1094  //Search the group table for a matching entry
1095  entry = snmpFindGroupEntry(context, securityModel, userName,
1096  strlen(userName));
1097 
1098  //Any matching entry found?
1099  if(entry != NULL)
1100  {
1101  //Clear the entry
1102  memset(entry, 0, sizeof(SnmpGroupEntry));
1103  //Now mark the entry as free
1104  entry->status = MIB_ROW_STATUS_UNUSED;
1105 
1106  //Successful processing
1107  error = NO_ERROR;
1108  }
1109  else
1110  {
1111  //The specified entry does not exist
1112  error = ERROR_NOT_FOUND;
1113  }
1114 
1115  //Release exclusive access to the SNMP agent context
1116  osReleaseMutex(&context->mutex);
1117 
1118  //Return status code
1119  return error;
1120 #else
1121  //Not implemented
1122  return ERROR_NOT_IMPLEMENTED;
1123 #endif
1124 }
1125 
1126 
1127 /**
1128  * @brief Create access policy for the specified group name
1129  * @param[in] context Pointer to the SNMP agent context
1130  * @param[in] groupName NULL-terminated string that contains the group name
1131  * @param[in] securityModel Security model
1132  * @param[in] securityLevel Security level
1133  * @param[in] contextPrefix NULL-terminated string that contains the context name prefix
1134  * @param[in] contextMatch Context match
1135  * @param[in] readViewName NULL-terminated string that contains the read view name
1136  * @param[in] writeViewName NULL-terminated string that contains the write view name
1137  * @param[in] notifyViewName NULL-terminated string that contains the notify view name
1138  * @return Error code
1139  **/
1140 
1142  const char_t *groupName, SnmpSecurityModel securityModel,
1143  SnmpSecurityLevel securityLevel, const char_t *contextPrefix,
1144  SnmpContextMatch contextMatch, const char_t *readViewName,
1145  const char_t *writeViewName, const char_t *notifyViewName)
1146 {
1147 #if (SNMP_AGENT_VACM_SUPPORT == ENABLED)
1148  error_t error;
1149  size_t n;
1150  SnmpAccessEntry *entry;
1151 
1152  //Check parameters
1153  if(context == NULL || groupName == NULL || contextPrefix == NULL)
1154  return ERROR_INVALID_PARAMETER;
1155  if(readViewName == NULL || writeViewName == NULL || notifyViewName == NULL)
1156  return ERROR_INVALID_PARAMETER;
1157 
1158  //Check security model
1159  if(securityModel != SNMP_SECURITY_MODEL_ANY &&
1160  securityModel != SNMP_SECURITY_MODEL_V1 &&
1161  securityModel != SNMP_SECURITY_MODEL_V2C &&
1162  securityModel != SNMP_SECURITY_MODEL_USM)
1163  {
1164  return ERROR_INVALID_PARAMETER;
1165  }
1166 
1167  //Check security level
1168  if(securityLevel != SNMP_SECURITY_LEVEL_NO_AUTH_NO_PRIV &&
1169  securityLevel != SNMP_SECURITY_LEVEL_AUTH_NO_PRIV &&
1170  securityLevel != SNMP_SECURITY_LEVEL_AUTH_PRIV)
1171  {
1172  return ERROR_INVALID_PARAMETER;
1173  }
1174 
1175  //Check context match
1176  if(contextMatch != SNMP_CONTEXT_MATCH_EXACT &&
1177  contextMatch != SNMP_CONTEXT_MATCH_PREFIX)
1178  {
1179  return ERROR_INVALID_PARAMETER;
1180  }
1181 
1182  //Retrieve the length of the group name
1183  n = strlen(groupName);
1184 
1185  //Make sure the group name is valid
1186  if(n == 0 || n > SNMP_MAX_GROUP_NAME_LEN)
1187  return ERROR_INVALID_LENGTH;
1188 
1189  //Make sure the context name prefix is valid
1191  return ERROR_INVALID_LENGTH;
1192 
1193  //Make sure the read view name is valid
1194  if(strlen(readViewName) > SNMP_MAX_VIEW_NAME_LEN)
1195  return ERROR_INVALID_LENGTH;
1196 
1197  //Make sure the write view name is valid
1198  if(strlen(writeViewName) > SNMP_MAX_VIEW_NAME_LEN)
1199  return ERROR_INVALID_LENGTH;
1200 
1201  //Make sure the notify view name is valid
1202  if(strlen(notifyViewName) > SNMP_MAX_VIEW_NAME_LEN)
1203  return ERROR_INVALID_LENGTH;
1204 
1205  //Acquire exclusive access to the SNMP agent context
1206  osAcquireMutex(&context->mutex);
1207 
1208  //Search the access table for a matching entry
1209  entry = snmpFindAccessEntry(context, groupName, contextPrefix,
1210  securityModel, securityLevel);
1211 
1212  //No matching entry found?
1213  if(entry == NULL)
1214  {
1215  //Create a new entry in the access table
1216  entry = snmpCreateAccessEntry(context);
1217  }
1218 
1219  //Any entry available?
1220  if(entry != NULL)
1221  {
1222  //Clear entry
1223  memset(entry, 0, sizeof(SnmpAccessEntry));
1224 
1225  //Save group name
1226  strcpy(entry->groupName, groupName);
1227  //Save context name prefix
1228  strcpy(entry->contextPrefix, contextPrefix);
1229  //Save security model
1230  entry->securityModel = securityModel;
1231  //Save security level
1232  entry->securityLevel = securityLevel;
1233  //Save context match
1234  entry->contextMatch = contextMatch;
1235  //Save read view name
1236  strcpy(entry->readViewName, readViewName);
1237  //Save write view name
1238  strcpy(entry->writeViewName, writeViewName);
1239  //Save notify view name
1240  strcpy(entry->notifyViewName, notifyViewName);
1241 
1242  //The entry is now available for use
1243  entry->status = MIB_ROW_STATUS_ACTIVE;
1244 
1245  //Successful processing
1246  error = NO_ERROR;
1247  }
1248  else
1249  {
1250  //The access table runs out of space
1251  error = ERROR_OUT_OF_RESOURCES;
1252  }
1253 
1254  //Release exclusive access to the SNMP agent context
1255  osReleaseMutex(&context->mutex);
1256 
1257  //Return status code
1258  return error;
1259 #else
1260  //Not implemented
1261  return ERROR_NOT_IMPLEMENTED;
1262 #endif
1263 }
1264 
1265 
1266 /**
1267  * @brief Delete an existing access policy
1268  * @param[in] context Pointer to the SNMP agent context
1269  * @param[in] groupName NULL-terminated string that contains the group name
1270  * @param[in] securityModel Security model
1271  * @param[in] securityLevel Security level
1272  * @param[in] contextPrefix NULL-terminated string that contains the context name prefix
1273  * @return Error code
1274  **/
1275 
1277  const char_t *groupName, SnmpSecurityModel securityModel,
1278  SnmpSecurityLevel securityLevel, const char_t *contextPrefix)
1279 {
1280 #if (SNMP_AGENT_VACM_SUPPORT == ENABLED)
1281  error_t error;
1282  SnmpAccessEntry *entry;
1283 
1284  //Check parameters
1285  if(context == NULL || groupName == NULL || contextPrefix == NULL)
1286  return ERROR_INVALID_PARAMETER;
1287 
1288  //Acquire exclusive access to the SNMP agent context
1289  osAcquireMutex(&context->mutex);
1290 
1291  //Search the access table for a matching entry
1292  entry = snmpFindAccessEntry(context, groupName, contextPrefix,
1293  securityModel, securityLevel);
1294 
1295  //Any matching entry found?
1296  if(entry != NULL)
1297  {
1298  //Clear the entry
1299  memset(entry, 0, sizeof(SnmpAccessEntry));
1300  //Now mark the entry as free
1301  entry->status = MIB_ROW_STATUS_UNUSED;
1302 
1303  //Successful processing
1304  error = NO_ERROR;
1305  }
1306  else
1307  {
1308  //The specified entry does not exist
1309  error = ERROR_NOT_FOUND;
1310  }
1311 
1312  //Release exclusive access to the SNMP agent context
1313  osReleaseMutex(&context->mutex);
1314 
1315  //Return status code
1316  return error;
1317 #else
1318  //Not implemented
1319  return ERROR_NOT_IMPLEMENTED;
1320 #endif
1321 }
1322 
1323 
1324 /**
1325  * @brief Create a new MIB view
1326  * @param[in] context Pointer to the SNMP agent context
1327  * @param[in] viewName NULL-terminated string that contains the view name
1328  * @param[in] subtree Pointer to the subtree
1329  * @param[in] subtreeLen Length of the subtree, in bytes
1330  * @param[in] mask Pointer to the bit mask
1331  * @param[in] maskLen Length of the bit mask
1332  * @param[in] type View type
1333  * @return Error code
1334  **/
1335 
1337  const char_t *viewName, const uint8_t *subtree, size_t subtreeLen,
1338  const uint8_t *mask, size_t maskLen, SnmpViewType type)
1339 {
1340 #if (SNMP_AGENT_VACM_SUPPORT == ENABLED)
1341  error_t error;
1342  size_t n;
1343  SnmpViewEntry *entry;
1344 
1345  //Check parameters
1346  if(context == NULL || viewName == NULL || subtree == NULL)
1347  return ERROR_INVALID_PARAMETER;
1348 
1349  //Check view type
1350  if(type != SNMP_VIEW_TYPE_INCLUDED &&
1352  {
1353  return ERROR_INVALID_PARAMETER;
1354  }
1355 
1356  //Retrieve the length of the view name
1357  n = strlen(viewName);
1358 
1359  //Make sure the view name is valid
1360  if(n == 0 || n > SNMP_MAX_VIEW_NAME_LEN)
1361  return ERROR_INVALID_LENGTH;
1362 
1363  //Make sure the subtree is valid
1364  if(subtreeLen == 0 || subtreeLen > MIB_MAX_OID_SIZE)
1365  return ERROR_INVALID_PARAMETER;
1366 
1367  //Make sure the bit mask is valid
1368  if(maskLen > 0 && mask == NULL)
1369  return ERROR_INVALID_PARAMETER;
1370  if(maskLen > SNMP_MAX_BIT_MASK_SIZE)
1371  return ERROR_INVALID_PARAMETER;
1372 
1373  //Acquire exclusive access to the SNMP agent context
1374  osAcquireMutex(&context->mutex);
1375 
1376  //Search the view table for a matching entry
1377  entry = snmpFindViewEntry(context, viewName, subtree, subtreeLen);
1378 
1379  //No matching entry found?
1380  if(entry == NULL)
1381  {
1382  //Create a new entry in the view table
1383  entry = snmpCreateViewEntry(context);
1384  }
1385 
1386  //Any entry available?
1387  if(entry != NULL)
1388  {
1389  //Clear entry
1390  memset(entry, 0, sizeof(SnmpViewEntry));
1391 
1392  //Save view name
1393  strcpy(entry->viewName, viewName);
1394  //Save subtree
1395  memcpy(entry->subtree, subtree, subtreeLen);
1396  //Save the length of the subtree
1397  entry->subtreeLen = subtreeLen;
1398  //Save bit mask
1399  memcpy(entry->mask, mask, maskLen);
1400  //Save the length of the bit mask
1401  entry->maskLen = maskLen;
1402  //Save type
1403  entry->type = type;
1404 
1405  //The entry is now available for use
1406  entry->status = MIB_ROW_STATUS_ACTIVE;
1407 
1408  //Successful processing
1409  error = NO_ERROR;
1410  }
1411  else
1412  {
1413  //The view table runs out of space
1414  error = ERROR_OUT_OF_RESOURCES;
1415  }
1416 
1417  //Release exclusive access to the SNMP agent context
1418  osReleaseMutex(&context->mutex);
1419 
1420  //Return status code
1421  return error;
1422 #else
1423  //Not implemented
1424  return ERROR_NOT_IMPLEMENTED;
1425 #endif
1426 }
1427 
1428 
1429 /**
1430  * @brief Delete an existing MIB view
1431  * @param[in] context Pointer to the SNMP agent context
1432  * @param[in] viewName NULL-terminated string that contains the view name
1433  * @param[in] subtree Pointer to the subtree
1434  * @param[in] subtreeLen Length of the subtree, in bytes
1435  * @return Error code
1436  **/
1437 
1439  const char_t *viewName, const uint8_t *subtree, size_t subtreeLen)
1440 {
1441 #if (SNMP_AGENT_VACM_SUPPORT == ENABLED)
1442  error_t error;
1443  SnmpViewEntry *entry;
1444 
1445  //Check parameters
1446  if(context == NULL || viewName == NULL || subtree == NULL)
1447  return ERROR_INVALID_PARAMETER;
1448 
1449  //Acquire exclusive access to the SNMP agent context
1450  osAcquireMutex(&context->mutex);
1451 
1452  //Search the view table for a matching entry
1453  entry = snmpFindViewEntry(context, viewName, subtree, subtreeLen);
1454 
1455  //Any matching entry found?
1456  if(entry != NULL)
1457  {
1458  //Clear the entry
1459  memset(entry, 0, sizeof(SnmpViewEntry));
1460  //Now mark the entry as free
1461  entry->status = MIB_ROW_STATUS_UNUSED;
1462 
1463  //Successful processing
1464  error = NO_ERROR;
1465  }
1466  else
1467  {
1468  //The specified entry does not exist
1469  error = ERROR_NOT_FOUND;
1470  }
1471 
1472  //Release exclusive access to the SNMP agent context
1473  osReleaseMutex(&context->mutex);
1474 
1475  //Return status code
1476  return error;
1477 #else
1478  //Not implemented
1479  return ERROR_NOT_IMPLEMENTED;
1480 #endif
1481 }
1482 
1483 
1484 /**
1485  * @brief Send SNMP trap notification
1486  * @param[in] context Pointer to the SNMP agent context
1487  * @param[in] destIpAddr Destination IP address
1488  * @param[in] version SNMP version identifier
1489  * @param[in] userName User name or community name
1490  * @param[in] genericTrapType Generic trap type
1491  * @param[in] specificTrapCode Specific code
1492  * @param[in] objectList List of object names
1493  * @param[in] objectListSize Number of entries in the list
1494  * @return Error code
1495  **/
1496 
1498  SnmpVersion version, const char_t *userName, uint_t genericTrapType,
1499  uint_t specificTrapCode, const SnmpTrapObject *objectList, uint_t objectListSize)
1500 {
1501 #if (SNMP_AGENT_TRAP_SUPPORT == ENABLED)
1502  error_t error;
1503 
1504  //Check parameters
1505  if(context == NULL || destIpAddr == NULL || userName == NULL)
1506  return ERROR_INVALID_PARAMETER;
1507 
1508  //Make sure the list of objects is valid
1509  if(objectListSize > 0 && objectList == NULL)
1510  return ERROR_INVALID_PARAMETER;
1511 
1512  //Acquire exclusive access to the SNMP agent context
1513  osAcquireMutex(&context->mutex);
1514 
1515 #if (SNMP_V3_SUPPORT == ENABLED)
1516  //Refresh SNMP engine time
1517  snmpRefreshEngineTime(context);
1518 #endif
1519 
1520  //Format Trap message
1521  error = snmpFormatTrapMessage(context, version, userName,
1522  genericTrapType, specificTrapCode, objectList, objectListSize);
1523 
1524  //Check status code
1525  if(!error)
1526  {
1527  //Total number of messages which were passed from the SNMP protocol
1528  //entity to the transport service
1529  MIB2_INC_COUNTER32(snmpGroup.snmpOutPkts, 1);
1530 
1531  //Debug message
1532  TRACE_INFO("Sending SNMP message to %s port %" PRIu16
1533  " (%" PRIuSIZE " bytes)...\r\n",
1534  ipAddrToString(destIpAddr, NULL),
1535  context->settings.trapPort, context->response.length);
1536 
1537  //Display the contents of the SNMP message
1538  TRACE_DEBUG_ARRAY(" ", context->response.pos, context->response.length);
1539  //Display ASN.1 structure
1540  asn1DumpObject(context->response.pos, context->response.length, 0);
1541 
1542  //Send SNMP message
1543  error = socketSendTo(context->socket, destIpAddr, context->settings.trapPort,
1544  context->response.pos, context->response.length, NULL, 0);
1545  }
1546 
1547  //Release exclusive access to the SNMP agent context
1548  osReleaseMutex(&context->mutex);
1549 
1550  //Return status code
1551  return error;
1552 #else
1553  //Not implemented
1554  return ERROR_NOT_IMPLEMENTED;
1555 #endif
1556 }
1557 
1558 
1559 /**
1560  * @brief Send SNMP inform request
1561  * @param[in] context Pointer to the SNMP agent context
1562  * @param[in] destIpAddr Destination IP address
1563  * @param[in] version SNMP version identifier
1564  * @param[in] userName User name or community name
1565  * @param[in] genericTrapType Generic trap type
1566  * @param[in] specificTrapCode Specific code
1567  * @param[in] objectList List of object names
1568  * @param[in] objectListSize Number of entries in the list
1569  * @return Error code
1570  **/
1571 
1573  SnmpVersion version, const char_t *userName, uint_t genericTrapType,
1574  uint_t specificTrapCode, const SnmpTrapObject *objectList, uint_t objectListSize)
1575 {
1576 #if (SNMP_AGENT_INFORM_SUPPORT == ENABLED)
1577  error_t error;
1578  bool_t status;
1579 
1580  //Check parameters
1581  if(context == NULL || destIpAddr == NULL || userName == NULL)
1582  return ERROR_INVALID_PARAMETER;
1583 
1584  //Make sure the list of objects is valid
1585  if(objectListSize > 0 && objectList == NULL)
1586  return ERROR_INVALID_PARAMETER;
1587 
1588  //Initialize status code
1589  error = NO_ERROR;
1590 
1591  //Acquire exclusive access to the SNMP agent context
1592  osAcquireMutex(&context->mutex);
1593 
1594  //Send an inform request and wait for the acknowledgment to be received
1595  while(!error)
1596  {
1597  //Check current state
1598  if(context->informState == SNMP_AGENT_STATE_IDLE)
1599  {
1600  //Reset event object
1601  osResetEvent(&context->informEvent);
1602  //Initialize retransmission counter
1603  context->informRetransmitCount = 0;
1604 
1605 #if (SNMP_V3_SUPPORT == ENABLED)
1606  //SNMPv3 version?
1607  if(version == SNMP_VERSION_3)
1608  {
1609  //The User-based Security Model (USM) of SNMPv3 provides a mechanism
1610  //to discover the snmpEngineID of the remote SNMP engine
1611  context->informContextEngineLen = 0;
1612  context->informEngineBoots = 0;
1613  context->informEngineTime = 0;
1614 
1615  //Perform discovery process
1616  context->informState = SNMP_AGENT_STATE_SENDING_GET_REQ;
1617  }
1618  else
1619 #endif
1620  //SNMPv2c version?
1621  {
1622  //Send an inform request message
1623  context->informState = SNMP_AGENT_STATE_SENDING_INFORM_REQ;
1624  }
1625  }
1626 #if (SNMP_V3_SUPPORT == ENABLED)
1627  else if(context->informState == SNMP_AGENT_STATE_SENDING_GET_REQ)
1628  {
1629  //Format GetRequest message
1630  error = snmpFormatGetRequestMessage(context, version);
1631 
1632  //Check status
1633  if(!error)
1634  {
1635  //Total number of messages which were passed from the SNMP protocol
1636  //entity to the transport service
1637  MIB2_INC_COUNTER32(snmpGroup.snmpOutPkts, 1);
1638 
1639  //Debug message
1640  TRACE_INFO("Sending SNMP message to %s port %" PRIu16
1641  " (%" PRIuSIZE " bytes)...\r\n",
1642  ipAddrToString(destIpAddr, NULL),
1643  context->settings.trapPort, context->response.length);
1644 
1645  //Display the contents of the SNMP message
1646  TRACE_DEBUG_ARRAY(" ", context->response.pos, context->response.length);
1647  //Display ASN.1 structure
1648  asn1DumpObject(context->response.pos, context->response.length, 0);
1649 
1650  //Send SNMP message
1651  error = socketSendTo(context->socket, destIpAddr, context->settings.trapPort,
1652  context->response.pos, context->response.length, NULL, 0);
1653  }
1654 
1655  //Check status code
1656  if(!error)
1657  {
1658  //Save the time at which the GetResponse-PDU was sent
1659  context->informTimestamp = osGetSystemTime();
1660  //Increment retransmission counter
1661  context->informRetransmitCount++;
1662  //Wait for an Report-PDU to be received
1663  context->informState = SNMP_AGENT_STATE_WAITING_REPORT;
1664  }
1665  else
1666  {
1667  //Back to default state
1668  context->informState = SNMP_AGENT_STATE_IDLE;
1669  }
1670  }
1671  else if(context->informState == SNMP_AGENT_STATE_WAITING_REPORT)
1672  {
1673  //Release exclusive access to the SNMP agent context
1674  osReleaseMutex(&context->mutex);
1675 
1676  //Wait for a matching Report-PDU to be received
1677  status = osWaitForEvent(&context->informEvent,
1679 
1680  //Acquire exclusive access to the SNMP agent context
1681  osAcquireMutex(&context->mutex);
1682 
1683  //Any Report-PDU received?
1684  if(status && context->informContextEngineLen > 0)
1685  {
1686  //Reset event object
1687  osResetEvent(&context->informEvent);
1688  //Initialize retransmission counter
1689  context->informRetransmitCount = 0;
1690  //Send an inform request message
1691  context->informState = SNMP_AGENT_STATE_SENDING_INFORM_REQ;
1692  }
1693  else
1694  {
1695 #if (NET_RTOS_SUPPORT == DISABLED)
1696  //Get current time
1698 
1699  //Check current time
1700  if(timeCompare(time, context->informTimestamp + SNMP_AGENT_INFORM_TIMEOUT) < 0)
1701  {
1702  //Exit immediately
1703  error = ERROR_WOULD_BLOCK;
1704  }
1705  else
1706 #endif
1707  {
1708  //The request should be retransmitted if no corresponding response
1709  //is received in an appropriate time interval
1710  if(context->informRetransmitCount < SNMP_AGENT_INFORM_MAX_RETRIES)
1711  {
1712  //Retransmit the request
1713  context->informState = SNMP_AGENT_STATE_SENDING_GET_REQ;
1714  }
1715  else
1716  {
1717  //Back to default state
1718  context->informState = SNMP_AGENT_STATE_IDLE;
1719  //Report a timeout error
1720  error = ERROR_TIMEOUT;
1721  }
1722  }
1723  }
1724  }
1725 #endif
1726  else if(context->informState == SNMP_AGENT_STATE_SENDING_INFORM_REQ)
1727  {
1728  //Format InformRequest message
1729  error = snmpFormatInformRequestMessage(context, version, userName,
1730  genericTrapType, specificTrapCode, objectList, objectListSize);
1731 
1732  //Check status code
1733  if(!error)
1734  {
1735  //Total number of messages which were passed from the SNMP protocol
1736  //entity to the transport service
1737  MIB2_INC_COUNTER32(snmpGroup.snmpOutPkts, 1);
1738 
1739  //Debug message
1740  TRACE_INFO("Sending SNMP message to %s port %" PRIu16
1741  " (%" PRIuSIZE " bytes)...\r\n",
1742  ipAddrToString(destIpAddr, NULL),
1743  context->settings.trapPort, context->response.length);
1744 
1745  //Display the contents of the SNMP message
1746  TRACE_DEBUG_ARRAY(" ", context->response.pos, context->response.length);
1747  //Display ASN.1 structure
1748  asn1DumpObject(context->response.pos, context->response.length, 0);
1749 
1750  //Send SNMP message
1751  error = socketSendTo(context->socket, destIpAddr, context->settings.trapPort,
1752  context->response.pos, context->response.length, NULL, 0);
1753  }
1754 
1755  //Check status code
1756  if(!error)
1757  {
1758  //Save the time at which the InformRequest-PDU was sent
1759  context->informTimestamp = osGetSystemTime();
1760  //Increment retransmission counter
1761  context->informRetransmitCount++;
1762  //Wait for a GetResponse-PDU to be received
1763  context->informState = SNMP_AGENT_STATE_WAITING_GET_RESP;
1764  }
1765  else
1766  {
1767  //Back to default state
1768  context->informState = SNMP_AGENT_STATE_IDLE;
1769  }
1770  }
1771  else if(context->informState == SNMP_AGENT_STATE_WAITING_GET_RESP)
1772  {
1773  //Release exclusive access to the SNMP agent context
1774  osReleaseMutex(&context->mutex);
1775 
1776  //Wait for a matching GetResponse-PDU to be received
1777  status = osWaitForEvent(&context->informEvent,
1779 
1780  //Acquire exclusive access to the SNMP agent context
1781  osAcquireMutex(&context->mutex);
1782 
1783  //Any GetResponse-PDU received?
1784  if(status)
1785  {
1786  //Back to default state
1787  context->informState = SNMP_AGENT_STATE_IDLE;
1788  //The inform request has been acknowledged
1789  error = NO_ERROR;
1790  //We are done
1791  break;
1792  }
1793  else
1794  {
1795 #if (NET_RTOS_SUPPORT == DISABLED)
1796  //Get current time
1798 
1799  //Check current time
1800  if(timeCompare(time, context->informTimestamp + SNMP_AGENT_INFORM_TIMEOUT) < 0)
1801  {
1802  //Exit immediately
1803  error = ERROR_WOULD_BLOCK;
1804  }
1805  else
1806 #endif
1807  {
1808  //The request should be retransmitted if no corresponding response
1809  //is received in an appropriate time interval
1810  if(context->informRetransmitCount < SNMP_AGENT_INFORM_MAX_RETRIES)
1811  {
1812  //Retransmit the request
1813  context->informState = SNMP_AGENT_STATE_SENDING_INFORM_REQ;
1814  }
1815  else
1816  {
1817  //Back to default state
1818  context->informState = SNMP_AGENT_STATE_IDLE;
1819  //Report a timeout error
1820  error = ERROR_TIMEOUT;
1821  }
1822  }
1823  }
1824  }
1825  else
1826  {
1827  //Back to default state
1828  context->informState = SNMP_AGENT_STATE_IDLE;
1829  //Report an error
1830  error = ERROR_WRONG_STATE;
1831  }
1832  }
1833 
1834  //Release exclusive access to the SNMP agent context
1835  osReleaseMutex(&context->mutex);
1836 
1837  //Return status code
1838  return error;
1839 #else
1840  //Not implemented
1841  return ERROR_NOT_IMPLEMENTED;
1842 #endif
1843 }
1844 
1845 
1846 /**
1847  * @brief SNMP agent task
1848  * @param[in] context Pointer to the SNMP agent context
1849  **/
1850 
1852 {
1853  error_t error;
1854 
1855 #if (NET_RTOS_SUPPORT == ENABLED)
1856  //Task prologue
1857  osEnterTask();
1858 
1859  //Main loop
1860  while(1)
1861  {
1862 #endif
1863  //Wait for an incoming datagram
1864  error = socketReceiveFrom(context->socket, &context->remoteIpAddr,
1865  &context->remotePort, context->request.buffer,
1866  SNMP_MAX_MSG_SIZE, &context->request.bufferLen, 0);
1867 
1868  //Any datagram received?
1869  if(!error)
1870  {
1871  //Acquire exclusive access to the SNMP agent context
1872  osAcquireMutex(&context->mutex);
1873 
1874  //Debug message
1875  TRACE_INFO("\r\nSNMP message received from %s port %" PRIu16
1876  " (%" PRIuSIZE " bytes)...\r\n",
1877  ipAddrToString(&context->remoteIpAddr, NULL),
1878  context->remotePort, context->request.bufferLen);
1879 
1880  //Display the contents of the SNMP message
1881  TRACE_DEBUG_ARRAY(" ", context->request.buffer, context->request.bufferLen);
1882  //Dump ASN.1 structure
1883  asn1DumpObject(context->request.buffer, context->request.bufferLen, 0);
1884 
1885  //Process incoming SNMP message
1886  error = snmpProcessMessage(context);
1887 
1888  //Check status code
1889  if(!error)
1890  {
1891  //Any response?
1892  if(context->response.length > 0)
1893  {
1894  //Debug message
1895  TRACE_INFO("Sending SNMP message to %s port %" PRIu16
1896  " (%" PRIuSIZE " bytes)...\r\n",
1897  ipAddrToString(&context->remoteIpAddr, NULL),
1898  context->remotePort, context->response.length);
1899 
1900  //Display the contents of the SNMP message
1901  TRACE_DEBUG_ARRAY(" ", context->response.pos, context->response.length);
1902  //Display ASN.1 structure
1903  asn1DumpObject(context->response.pos, context->response.length, 0);
1904 
1905  //Send SNMP response message
1906  socketSendTo(context->socket, &context->remoteIpAddr,
1907  context->remotePort, context->response.pos,
1908  context->response.length, NULL, 0);
1909  }
1910  }
1911 
1912  //Release exclusive access to the SNMP agent context
1913  osReleaseMutex(&context->mutex);
1914  }
1915 #if (NET_RTOS_SUPPORT == ENABLED)
1916  }
1917 #endif
1918 }
1919 
1920 #endif
uint8_t subtree[SNMP_MAX_OID_SIZE]
char_t writeViewName[SNMP_MAX_VIEW_NAME_LEN+1]
@ SNMP_SECURITY_MODEL_ANY
Any.
MIB-II module.
@ SOCKET_IP_PROTO_UDP
Definition: socket.h:93
@ SNMP_SECURITY_MODEL_V1
SNMPv1.
SnmpVersion versionMax
Maximum version accepted by the SNMP agent.
Definition: snmp_agent.h:130
SnmpSecurityModel securityModel
error_t socketBind(Socket *socket, const IpAddr *localIpAddr, uint16_t localPort)
Associate a local address with a socket.
Definition: socket.c:355
@ SNMP_KEY_FORMAT_LOCALIZED
Localized key.
MibLoad load
Definition: mib_common.h:295
int bool_t
Definition: compiler_port.h:49
@ ERROR_NOT_FOUND
Definition: error.h:145
@ ERROR_OUT_OF_RANGE
Definition: error.h:135
bool_t osCreateMutex(OsMutex *mutex)
Create a mutex object.
error_t snmpAgentDeleteView(SnmpAgentContext *context, const char_t *viewName, const uint8_t *subtree, size_t subtreeLen)
Delete an existing MIB view.
Definition: snmp_agent.c:1438
SnmpViewEntry * snmpCreateViewEntry(SnmpAgentContext *context)
Create a new view entry.
#define SNMP_MAX_VIEW_NAME_LEN
Definition: snmp_common.h:102
@ ERROR_WOULD_BLOCK
Definition: error.h:95
SnmpUserEntry * snmpFindCommunityEntry(SnmpAgentContext *context, const char_t *community, size_t length)
Search the community table for a given community string.
SnmpKey localizedPrivKey
Localized privacy key.
IP network address.
Definition: ip.h:71
SnmpSecurityModel
Security models.
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
error_t snmpAgentInit(SnmpAgentContext *context, const SnmpAgentSettings *settings)
SNMP agent initialization.
Definition: snmp_agent.c:100
error_t snmpAgentSetVersion(SnmpAgentContext *context, SnmpVersion versionMin, SnmpVersion versionMax)
Set minimum and maximum versions permitted.
Definition: snmp_agent.c:391
SnmpAccess mode
Access mode.
error_t snmpAgentSetContextName(SnmpAgentContext *context, const char_t *contextName)
Set context name.
Definition: snmp_agent.c:562
OID (Object Identifier)
char_t contextPrefix[SNMP_MAX_CONTEXT_NAME_LEN+1]
@ SNMP_CONTEXT_MATCH_PREFIX
SnmpContextMatch
Context match.
char_t groupName[SNMP_MAX_GROUP_NAME_LEN+1]
error_t snmpAgentCreateCommunity(SnmpAgentContext *context, const char_t *community, SnmpAccess mode)
Create a new community string.
Definition: snmp_agent.c:603
void socketClose(Socket *socket)
Close an existing socket.
Definition: socket.c:822
size_t subtreeLen
SnmpKeyFormat
SNMP key format.
#define SNMP_AGENT_PRIORITY
Definition: snmp_agent.h:64
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
uint16_t version
Definition: dtls_misc.h:172
char_t * ipAddrToString(const IpAddr *ipAddr, char_t *str)
Convert a binary IP address to a string representation.
Definition: ip.c:726
@ SNMP_CONTEXT_MATCH_EXACT
@ SOCKET_TYPE_DGRAM
Definition: socket.h:78
Object descriptor for trap notifications.
@ SNMP_AGENT_STATE_WAITING_REPORT
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:690
SnmpGroupEntry * snmpFindGroupEntry(SnmpAgentContext *context, uint_t securityModel, const char_t *securityName, size_t securityNameLen)
Search the group table.
#define SNMP_AGENT_INFORM_MAX_RETRIES
SnmpGroupEntry * snmpCreateGroupEntry(SnmpAgentContext *context)
Create a new group entry.
@ SNMP_SECURITY_MODEL_USM
User-based security model.
char_t securityName[SNMP_MAX_GROUP_NAME_LEN+1]
#define SNMP_AGENT_MAX_MIBS
Definition: snmp_agent.h:69
#define SNMP_MAX_GROUP_NAME_LEN
Definition: snmp_common.h:95
SNMP trap notifications.
SnmpAccessEntry * snmpCreateAccessEntry(SnmpAgentContext *context)
Create a new access entry.
User table entry.
char_t groupName[SNMP_MAX_GROUP_NAME_LEN+1]
#define timeCompare(t1, t2)
Definition: os_port.h:42
SnmpViewType
View type.
size_t maskLen
#define SNMP_AGENT_INFORM_TIMEOUT
SnmpUserEntry * snmpCreateCommunityEntry(SnmpAgentContext *context)
Create a new community entry.
SNMP agent (Simple Network Management Protocol)
@ ERROR_WRONG_STATE
Definition: error.h:207
SnmpVersion
SNMP version identifiers.
Definition: snmp_common.h:136
error_t snmpAgentSetContextEngine(SnmpAgentContext *context, const void *contextEngine, size_t contextEngineLen)
Set context engine identifier.
Definition: snmp_agent.c:525
uint16_t trapPort
SNMP trap port number.
Definition: snmp_agent.h:132
@ ERROR_OPEN_FAILED
Definition: error.h:74
@ SNMP_AGENT_STATE_SENDING_INFORM_REQ
char_t readViewName[SNMP_MAX_VIEW_NAME_LEN+1]
SnmpUserEntry * snmpCreateUserEntry(SnmpAgentContext *context)
Create a new user entry.
error_t snmpAgentDeleteAccess(SnmpAgentContext *context, const char_t *groupName, SnmpSecurityModel securityModel, SnmpSecurityLevel securityLevel, const char_t *contextPrefix)
Delete an existing access policy.
Definition: snmp_agent.c:1276
const IpAddr IP_ADDR_ANY
Definition: ip.c:45
error_t snmpAgentStart(SnmpAgentContext *context)
Start SNMP agent.
Definition: snmp_agent.c:226
SnmpKey localizedAuthKey
Localized authentication key.
#define SNMP_MAX_CONTEXT_NAME_LEN
Definition: snmp_common.h:74
uint_t numObjects
Definition: mib_common.h:293
error_t snmpAgentLeaveGroup(SnmpAgentContext *context, const char_t *userName, SnmpSecurityModel securityModel)
Leave a group of users.
Definition: snmp_agent.c:1080
error_t snmpAgentLoadMib(SnmpAgentContext *context, const MibModule *module)
Load a MIB module.
Definition: snmp_agent.c:257
char_t notifyViewName[SNMP_MAX_VIEW_NAME_LEN+1]
error_t snmpAgentDeleteUser(SnmpAgentContext *context, const char_t *userName)
Remove existing user.
Definition: snmp_agent.c:933
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
OsTask * osCreateTask(const char_t *name, OsTaskCode taskCode, void *param, size_t stackSize, int_t priority)
Create a new task.
void osResetEvent(OsEvent *event)
Set the specified event object to the nonsignaled state.
SNMP inform notifications.
char_t type
@ SNMP_PRIV_PROTOCOL_NONE
No privacy.
error_t
Error codes.
Definition: error.h:42
#define MIB_MAX_OID_SIZE
Definition: mib_common.h:39
#define SNMP_MAX_USER_NAME_LEN
Definition: snmp_common.h:81
SnmpContextMatch contextMatch
error_t snmpFormatInformRequestMessage(SnmpAgentContext *context, SnmpVersion version, const char_t *userName, uint_t genericTrapType, uint_t specificTrapCode, const SnmpTrapObject *objectList, uint_t objectListSize)
Format SNMP InformRequest message.
@ SNMP_AGENT_STATE_WAITING_GET_RESP
SnmpViewType type
SnmpUserEntry * snmpFindUserEntry(SnmpAgentContext *context, const char_t *name, size_t length)
Search the user table for a given user name.
SnmpPrivProtocol
@ SNMP_KEY_FORMAT_TEXT
ASCII password.
#define SNMP_TRAP_PORT
Definition: snmp_common.h:124
error_t snmpProcessMessage(SnmpAgentContext *context)
Process incoming SNMP message.
@ SNMP_VIEW_TYPE_INCLUDED
@ SNMP_SECURITY_LEVEL_NO_AUTH_NO_PRIV
#define SNMP_MAX_BIT_MASK_SIZE
Definition: snmp_common.h:109
Task object.
MibRowStatus status
#define SNMP_MAX_OID_SIZE
Definition: snmp_common.h:116
@ ERROR_INVALID_LENGTH
Definition: error.h:109
@ MIB_ROW_STATUS_UNUSED
Definition: mib_common.h:102
error_t socketReceiveFrom(Socket *socket, IpAddr *srcIpAddr, uint16_t *srcPort, void *data, size_t size, size_t *received, uint_t flags)
Receive a datagram from a connectionless socket.
Definition: socket.c:629
General definitions for cryptographic algorithms.
SnmpViewEntry * snmpFindViewEntry(SnmpAgentContext *context, const char_t *viewName, const uint8_t *subtree, size_t subtreeLen)
Search the view table for a given entry.
uint8_t mask
Definition: web_socket.h:317
Helper functions for SNMP agent.
error_t snmpAgentJoinGroup(SnmpAgentContext *context, const char_t *userName, SnmpSecurityModel securityModel, const char_t *groupName)
Join a group of users.
Definition: snmp_agent.c:987
@ SNMP_AGENT_STATE_IDLE
error_t snmpAgentSendTrap(SnmpAgentContext *context, const IpAddr *destIpAddr, SnmpVersion version, const char_t *userName, uint_t genericTrapType, uint_t specificTrapCode, const SnmpTrapObject *objectList, uint_t objectListSize)
Send SNMP trap notification.
Definition: snmp_agent.c:1497
@ SNMP_SECURITY_LEVEL_AUTH_PRIV
#define TRACE_INFO(...)
Definition: debug.h:94
error_t snmpAgentGetEngineBoots(SnmpAgentContext *context, int32_t *engineBoots)
Get the value of the snmpEngineBoots variable.
Definition: snmp_agent.c:461
error_t snmpAgentSendInform(SnmpAgentContext *context, const IpAddr *destIpAddr, SnmpVersion version, const char_t *userName, uint_t genericTrapType, uint_t specificTrapCode, const SnmpTrapObject *objectList, uint_t objectListSize)
Send SNMP inform request.
Definition: snmp_agent.c:1572
Socket * socketOpen(uint_t type, uint_t protocol)
Create a socket (UDP or TCP)
Definition: socket.c:95
error_t snmpAgentSetEngineBoots(SnmpAgentContext *context, int32_t engineBoots)
Set the value of the snmpEngineBoots variable.
Definition: snmp_agent.c:422
MIB module.
Definition: mib_common.h:287
#define osEnterTask()
MibRowStatus status
Status of the user.
#define socketBindToInterface
Definition: net_legacy.h:270
#define SNMP_AGENT_STACK_SIZE
Definition: snmp_agent.h:57
int32_t netGetRandRange(int32_t min, int32_t max)
Get a random value in the specified range.
Definition: net.c:1841
@ SNMP_VERSION_3
Definition: snmp_common.h:140
char_t viewName[SNMP_MAX_VIEW_NAME_LEN+1]
error_t snmpAgentCreateUser(SnmpAgentContext *context, const char_t *userName, SnmpAccess mode, SnmpKeyFormat keyFormat, SnmpAuthProtocol authProtocol, const void *authKey, SnmpPrivProtocol privProtocol, const void *privKey)
Create a new user.
Definition: snmp_agent.c:735
SNMP secret key.
void snmpAgentGetDefaultSettings(SnmpAgentSettings *settings)
Initialize settings with default values.
Definition: snmp_agent.c:73
@ ERROR_TIMEOUT
Definition: error.h:94
char char_t
Definition: compiler_port.h:43
Ipv6Addr contextPrefix
Definition: ndp.h:518
@ MIB_ROW_STATUS_ACTIVE
Definition: mib_common.h:103
void snmpAgentTask(SnmpAgentContext *context)
SNMP agent task.
Definition: snmp_agent.c:1851
#define OS_INVALID_HANDLE
Definition: os_port.h:79
SnmpSecurityLevel securityLevel
uint16_t port
SNMP port number.
Definition: snmp_agent.h:131
uint32_t time
MibRowStatus status
error_t snmpAgentCreateView(SnmpAgentContext *context, const char_t *viewName, const uint8_t *subtree, size_t subtreeLen, const uint8_t *mask, size_t maskLen, SnmpViewType type)
Create a new MIB view.
Definition: snmp_agent.c:1336
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:107
void osDeleteMutex(OsMutex *mutex)
Delete a mutex object.
SnmpAuthProtocol authProtocol
Authentication protocol.
char_t name[SNMP_MAX_USER_NAME_LEN+1]
User name.
SnmpAgentRandCallback randCallback
Random data generation callback function.
Definition: snmp_agent.h:133
#define SNMP_MAX_MSG_SIZE
Definition: snmp_common.h:60
void(* OsTaskCode)(void *param)
Task routine.
uint8_t n
bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
Wait until the specified event is in the signaled state.
uint8_t mask[SNMP_MAX_BIT_MASK_SIZE]
NetInterface * interface
Network interface to configure.
Definition: snmp_agent.h:128
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
#define MIB2_INC_COUNTER32(name, value)
Definition: mib2_module.h:156
View table entry.
Access table entry.
@ SNMP_AGENT_STATE_SENDING_GET_REQ
bool_t osCreateEvent(OsEvent *event)
Create an event object.
SnmpVersion versionMin
Minimum version accepted by the SNMP agent.
Definition: snmp_agent.h:129
SnmpKey rawAuthKey
Raw authentication key.
error_t snmpLocalizeKey(SnmpAuthProtocol authProtocol, const uint8_t *engineId, size_t engineIdLen, SnmpKey *key, SnmpKey *localizedKey)
Key localization algorithm.
error_t snmpFormatTrapMessage(SnmpAgentContext *context, SnmpVersion version, const char_t *userName, uint_t genericTrapType, uint_t specificTrapCode, const SnmpTrapObject *objectList, uint_t objectListSize)
Format SNMP Trap message.
SnmpAuthProtocol
error_t snmpAgentCreateAccess(SnmpAgentContext *context, const char_t *groupName, SnmpSecurityModel securityModel, SnmpSecurityLevel securityLevel, const char_t *contextPrefix, SnmpContextMatch contextMatch, const char_t *readViewName, const char_t *writeViewName, const char_t *notifyViewName)
Create access policy for the specified group name.
Definition: snmp_agent.c:1141
error_t socketSendTo(Socket *socket, const IpAddr *destIpAddr, uint16_t destPort, const void *data, size_t length, size_t *written, uint_t flags)
Send a datagram to a specific destination.
Definition: socket.c:535
@ SNMP_VERSION_1
Definition: snmp_common.h:138
#define SNMP_PORT
Definition: snmp_common.h:122
SnmpPrivProtocol privProtocol
Privacy protocol.
SnmpSecurityModel securityModel
#define SNMP_MAX_CONTEXT_ENGINE_SIZE
Definition: snmp_common.h:67
#define SnmpAgentContext
Definition: snmp_agent.h:36
error_t snmpGenerateKey(SnmpAuthProtocol authProtocol, const char_t *password, SnmpKey *key)
Password to key algorithm.
error_t snmpAgentUnloadMib(SnmpAgentContext *context, const MibModule *module)
Unload a MIB module.
Definition: snmp_agent.c:333
uint8_t mode
Definition: ntp_common.h:149
SnmpSecurityLevel
Security levels.
SNMP agent (PDU processing)
@ SNMP_SECURITY_MODEL_V2C
SNMPv2c.
Group table entry.
void snmpRefreshEngineTime(SnmpAgentContext *context)
Refresh SNMP engine time.
#define PRIuSIZE
Definition: compiler_port.h:78
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
@ SNMP_AUTH_PROTOCOL_NONE
No authentication.
@ SNMP_KEY_FORMAT_RAW
Raw key.
@ SNMP_VIEW_TYPE_EXCLUDED
error_t snmpAgentDeleteCommunity(SnmpAgentContext *context, const char_t *community)
Remove a community string.
Definition: snmp_agent.c:677
SNMP agent settings.
Definition: snmp_agent.h:126
SnmpKey rawPrivKey
Raw privacy key.
uint32_t systime_t
Definition: compiler_port.h:46
SnmpAccess
Access modes.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
@ SNMP_SECURITY_LEVEL_AUTH_NO_PRIV
ASN.1 (Abstract Syntax Notation One)
SnmpAccessEntry * snmpFindAccessEntry(SnmpAgentContext *context, const char_t *groupName, const char_t *contextPrefix, uint_t securityModel, uint_t securityLevel)
Search the access table for a given entry.
error_t snmpFormatGetRequestMessage(SnmpAgentContext *context, SnmpVersion version)
Format SNMP GetRequest message.
MibRowStatus status
error_t snmpAgentSetEnterpriseOid(SnmpAgentContext *context, const uint8_t *enterpriseOid, size_t enterpriseOidLen)
Set enterprise OID.
Definition: snmp_agent.c:492
systime_t osGetSystemTime(void)
Retrieve system time.
SNMP message dispatching.
Ipv4Addr destIpAddr
Definition: ipcp.h:78