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