Last modified by Frank Fock on 2024/05/25 10:09

Show last authors
1
2
3 In AGENT++ prior to 4.3.0, there were many MibEntry relations and the usage of the central Mib instance organised by static class members called "instance". Although this reduces code size and makes initialisation routines easier it makes it impossible to run more than one Mib instance in a process.
4
5 In AGENT++ 4.3.0 this has been refactored by lot of internal changes, which had two main goals:
6
7 1. Remove any Mib::instance usages that are not optional to the API user (i.e. backward compatibility can/should be provided)
8 1. Remove any v3MP::I usages that are not optional to the API user.
9
10 If you do not want to use the multi-agent support, you do not have to change anything in your code. In case, you want to clean-up the API usage and/or want to use the new features, please follow the steps below in your agent application:
11
12 {{info}}
13 **AGENT++ agent intialisation (+new/-old)**
14
15 {{code language="none" title=" "}}
16 Snmpx snmp(status, inaddr);
17 - mib = new Mib(persistentObjectsPath);
18 + mib = new Mib(persistentObjectsPath, path(bootCounterFile));
19 - reqList = new RequestList();
20 + reqList = new RequestList(mib);
21 reqList->set_snmp(&snmp);
22 mib->set_request_list(reqList);
23
24 v3MP *v3mp = new v3MP(engineId, snmpEngineBoots, stat);
25 + snmp.set_mpv3(v3mp);
26
27 - mib.add(new snmp_community_mib());
28 + mib.add(new snmp_community_mib(&mib));
29
30 - mib.add(new agentpp_config_mib());
31 + mib.add(new agentpp_config_mib(&mib));
32
33 - mib.add(new notification_log_mib());
34 + mib.add(new notification_log_mib(&mib));
35
36 + snmpCommunityEntry* communityEntry = snmpCommunityEntry::get_instance(mib);
37 + if (communityEntry) {
38 OctetStr co("public");
39 - MibTableRow* row = snmpCommunityEntry::instance->add_row(Oidx::from_string(co, FALSE));
40 + MibTableRow* row = communityEntry->add_row(Oidx::from_string(co, FALSE));
41 OctetStr tag("v1v2cPermittedManagers");
42 - snmpCommunityEntry::instance->set_row(row, co, co,
43 + communityEntry->set_row(row, co, co, reqList->get_v3mp()->get_local_engine_id(),"", tag, 3, 1);
44 + }
45
46 - UsmUserTable *uut = new UsmUserTable();
47 + v3MP* v3mp = mib.get_request_list()->get_v3mp();
48 + UsmUserTable *uut = new UsmUserTable(v3mp);
49 // add non persistent USM statistics
50 - mib.add(new UsmStats());
51 + mib.add(new UsmStats(v3mp));
52 // add the USM MIB - usm_mib MibGroup is used to
53 // make user added entries persistent
54 mib.add(new usm_mib(uut));
55 // add non persistent SNMPv3 engine object
56 - mib.add(new V3SnmpEngine());
57 - mib.add(new MPDGroup());
58 + mib.add(new V3SnmpEngine(v3mp));
59 + mib.add(new MPDGroup(v3mp));
60 {{/code}}
61 {{/info}}
62
63 A complete sample agent C++ code with multiple full featured agents in one process is show below.
64
65 It provides per **SNMP agent port** the following features:
66
67 * USM
68 * MPv3
69 * Request queue and processing
70 * MIB counters
71 * Independent MIB modules including persistency
72 * SNMPv3 context support
73 * An agent may contain the same or different MIB modules/objects
74
75 {{info}}
76 Multi-Agent Sample Code
77
78 {{code}}
79 /*_############################################################################
80 _##
81 _## AGENT++ 4.0 - agent.cpp
82 _##
83 _## Copyright (C) 2000-2020 Frank Fock and Jochen Katz (agentpp.com)
84 _##
85 _## Licensed under the Apache License, Version 2.0 (the "License");
86 _## you may not use this file except in compliance with the License.
87 _## You may obtain a copy of the License at
88 _##
89 _## http://www.apache.org/licenses/LICENSE-2.0
90 _##
91 _## Unless required by applicable law or agreed to in writing, software
92 _## distributed under the License is distributed on an "AS IS" BASIS,
93 _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
94 _## See the License for the specific language governing permissions and
95 _## limitations under the License.
96 _##
97 _##########################################################################*/
98
99 #include <stdlib.h>
100 #include <signal.h>
101
102 #include <agent_pp/agent++.h>
103 #include <agent_pp/snmp_group.h>
104 #include <agent_pp/system_group.h>
105 #include <agent_pp/snmp_target_mib.h>
106 #include <agent_pp/snmp_notification_mib.h>
107 #include <agent_pp/snmp_community_mib.h>
108 #include <agent_pp/notification_originator.h>
109 #include <agent_pp/notification_log_mib.h>
110 #include <agent_pp/agentpp_simulation_mib.h>
111 #include <agent_pp/agentpp_config_mib.h>
112 #include <agent_pp/v3_mib.h>
113 #include <agent_pp/mib_policy.h>
114 #include <agent_pp/vacm.h>
115 #include <agent_pp/threads.h>
116 #include <agent_pp/tools.h>
117
118 #include <snmp_pp/oid_def.h>
119 #include <snmp_pp/mp_v3.h>
120 #include <snmp_pp/log.h>
121
122 #include "atm_mib.h"
123 #include "agentpp_notifytest_mib.h"
124 #include "agentpp_test_mib.h"
125
126
127 #ifdef SNMP_PP_NAMESPACE
128 using namespace Snmp_pp;
129 #endif
130
131 #ifdef AGENTPP_NAMESPACE
132 using namespace Agentpp;
133 #endif
134
135 static const char* loggerModuleName = "agent++.multi.agent";
136
137 // table size policies
138
139
140 // globals:
141 const unsigned int MAX_NUMBER_OF_AGENTS = 10;
142
143 bool go = TRUE;
144
145 unsigned short port[MAX_NUMBER_OF_AGENTS];
146 #ifdef _SNMPv3
147 const table_size_def table_sizes[4] =
148 { table_size_def(oidUsmUserEntry, 30),
149 table_size_def(oidVacmSecurityToGroupEntry, 30),
150 table_size_def(oidVacmAccessEntry, 30),
151 table_size_def(oidVacmViewTreeFamilyEntry, 30)
152 };
153 MibTableSizePolicy policy(table_sizes, 4, 5000);
154 #endif
155
156
157 static void sig(int signo)
158 {
159 if ((signo == SIGTERM) || (signo == SIGINT) ||
160 (signo == SIGSEGV)) {
161
162 printf ("\n");
163
164 switch (signo) {
165 case SIGSEGV: {
166 printf ("Segmentation fault, aborting.\n");
167 exit(1);
168 }
169 case SIGTERM:
170 case SIGINT: {
171 if (go) {
172 go = FALSE;
173 printf ("User abort\n");
174 }
175 }
176 }
177 }
178 }
179
180
181 void init_signals()
182 {
183 signal (SIGTERM, sig);
184 signal (SIGINT, sig);
185 signal (SIGSEGV, sig);
186 }
187
188
189
190 void init(Mib& mib, const NS_SNMP OctetStr& engineID, const UdpAddress& inaddr)
191 {
192 OctetStr sysDescr("AGENT++v");
193 sysDescr += AGENTPP_VERSION_STRING;
194 sysDescr += " ATM Simulation Agent (";
195 sysDescr += inaddr.get_printable();
196 sysDescr += ")";
197 mib.add(new sysGroup(sysDescr.get_printable(),
198 "1.3.6.1.4.1.4976", 10));
199 mib.add(new snmpGroup());
200 mib.add(new TestAndIncr(oidSnmpSetSerialNo));
201 mib.add(new atm_mib());
202 mib.add(new agentpp_simulation_mib());
203 mib.add(new agentpp_notifytest_mib(&mib));
204 mib.add(new agentpp_test_mib());
205 mib.add(new snmp_target_mib());
206 #ifdef _SNMPv3
207 mib.add(new snmp_community_mib(&mib));
208 #endif
209 mib.add(new snmp_notification_mib());
210 #ifdef _SNMPv3
211 #ifdef _NO_THREADS
212 mib.add(new agentpp_config_mib(&mib));
213 #else
214 mib.add(new agentpp_config_mib(&mib));
215 #endif
216 mib.add(new notification_log_mib(&mib));
217
218 OctetStr nonDefaultContext("other");
219 mib.add(nonDefaultContext, new atm_mib());
220
221 v3MP* v3mp = mib.get_request_list()->get_v3mp();
222 UsmUserTable *uut = new UsmUserTable(v3mp);
223
224 uut->addNewRow("unsecureUser",
225 SNMP_AUTHPROTOCOL_NONE,
226 SNMP_PRIVPROTOCOL_NONE, "", "", engineID, false);
227
228 uut->addNewRow("MD5",
229 SNMP_AUTHPROTOCOL_HMACMD5,
230 SNMP_PRIVPROTOCOL_NONE,
231 "MD5UserAuthPassword", "", engineID, false);
232
233 uut->addNewRow("SHA",
234 SNMP_AUTHPROTOCOL_HMACSHA,
235 SNMP_PRIVPROTOCOL_NONE,
236 "SHAUserAuthPassword", "", engineID, false);
237
238 uut->addNewRow("MD5DES",
239 SNMP_AUTHPROTOCOL_HMACMD5,
240 SNMP_PRIVPROTOCOL_DES,
241 "MD5DESUserAuthPassword",
242 "MD5DESUserPrivPassword", engineID, false);
243
244 uut->addNewRow("SHADES",
245 SNMP_AUTHPROTOCOL_HMACSHA,
246 SNMP_PRIVPROTOCOL_DES,
247 "SHADESUserAuthPassword",
248 "SHADESUserPrivPassword", engineID, false);
249
250 uut->addNewRow("MD53DES",
251 SNMP_AUTHPROTOCOL_HMACMD5,
252 SNMP_PRIVPROTOCOL_3DESEDE,
253 "MD53DESUserAuthPassword",
254 "MD53DESUserPrivPassword", engineID, false);
255
256 uut->addNewRow("SHA3DES",
257 SNMP_AUTHPROTOCOL_HMACSHA,
258 SNMP_PRIVPROTOCOL_3DESEDE,
259 "SHA3DESUserAuthPassword",
260 "SHA3DESUserPrivPassword", engineID, false);
261
262 uut->addNewRow("MD5IDEA",
263 SNMP_AUTHPROTOCOL_HMACMD5,
264 SNMP_PRIVPROTOCOL_IDEA,
265 "MD5IDEAUserAuthPassword",
266 "MD5IDEAUserPrivPassword", engineID, false);
267
268 uut->addNewRow("SHAIDEA",
269 SNMP_AUTHPROTOCOL_HMACSHA,
270 SNMP_PRIVPROTOCOL_IDEA,
271 "SHAIDEAUserAuthPassword",
272 "SHAIDEAUserPrivPassword", engineID, false);
273
274 uut->addNewRow("MD5AES128",
275 SNMP_AUTHPROTOCOL_HMACMD5,
276 SNMP_PRIVPROTOCOL_AES128,
277 "MD5AES128UserAuthPassword",
278 "MD5AES128UserPrivPassword", engineID, false);
279
280 MibTableRow* r = uut->addNewRow("SHAAES128",
281 SNMP_AUTHPROTOCOL_HMACSHA,
282 SNMP_PRIVPROTOCOL_AES128,
283 "SHAAES128UserAuthPassword",
284 "SHAAES128UserPrivPassword", engineID, false);
285 if (r) { uut->set_storage_type(r, storageType_permanent); }
286
287 uut->addNewRow("MD5AES192",
288 SNMP_AUTHPROTOCOL_HMACMD5,
289 SNMP_PRIVPROTOCOL_AES192,
290 "MD5AES192UserAuthPassword",
291 "MD5AES192UserPrivPassword", engineID, false);
292
293 uut->addNewRow("SHAAES192",
294 SNMP_AUTHPROTOCOL_HMACSHA,
295 SNMP_PRIVPROTOCOL_AES192,
296 "SHAAES192UserAuthPassword",
297 "SHAAES192UserPrivPassword", engineID, false);
298
299 r = uut->addNewRow("MD5AES256",
300 SNMP_AUTHPROTOCOL_HMACMD5,
301 SNMP_PRIVPROTOCOL_AES256,
302 "MD5AES256UserAuthPassword",
303 "MD5AES256UserPrivPassword", engineID, false);
304 if (r) { uut->set_storage_type(r, storageType_readOnly); }
305
306 uut->addNewRow("SHAAES256",
307 SNMP_AUTHPROTOCOL_HMACSHA,
308 SNMP_PRIVPROTOCOL_AES256,
309 "SHAAES256UserAuthPassword",
310 "SHAAES256UserPrivPassword", engineID, false);
311
312 uut->addNewRow("SHA512AES256",
313 SNMP_AUTHPROTOCOL_HMAC384SHA512,
314 SNMP_PRIVPROTOCOL_AES256,
315 "SHA512AES256UserAuthPassword",
316 "SHA512AES256UserPrivPassword", engineID, false);
317
318 uut->addNewRow("SHA384AES128",
319 SNMP_AUTHPROTOCOL_HMAC256SHA384,
320 SNMP_PRIVPROTOCOL_AES256,
321 "SHA384AES128UserAuthPassword",
322 "SHA384AES128UserPrivPassword", engineID, false);
323
324 uut->addNewRow("SHA256AES128",
325 SNMP_AUTHPROTOCOL_HMAC192SHA256,
326 SNMP_PRIVPROTOCOL_AES128,
327 "SHA256AES128UserAuthPassword",
328 "SHA256AES128UserPrivPassword", engineID, false);
329
330 uut->addNewRow("SHA224AES128",
331 SNMP_AUTHPROTOCOL_HMAC128SHA224,
332 SNMP_PRIVPROTOCOL_AES128,
333 "SHA224AES128UserAuthPassword",
334 "SHA224AES128UserPrivPassword", engineID, false);
335
336 // add non persistent USM statistics
337 mib.add(new UsmStats(v3mp));
338 // add the USM MIB - usm_mib MibGroup is used to
339 // make user added entries persistent
340 mib.add(new usm_mib(uut));
341 // add non persistent SNMPv3 engine object
342 mib.add(new V3SnmpEngine(v3mp));
343 mib.add(new MPDGroup(v3mp));
344 #endif
345 }
346
347 class SnmpAgent: public Runnable {
348
349 public:
350 SnmpAgent(const UdpAddress& address): Runnable() {
351 inaddr = address;
352 }
353 virtual ~SnmpAgent() { }
354 virtual void run();
355
356 protected:
357 UdpAddress inaddr;
358 };
359
360 OctetStr& path(OctetStr& path)
361 {
362 for (int i=0; i<path.len(); i++) {
363 if (path[i] == '/') {
364 path[i] = '_';
365 }
366 }
367 return path;
368 }
369
370 void SnmpAgent::run() {
371 Mib* mib;
372 RequestList* reqList;
373 int status;
374 // bind localhost only -> agent will not be reachable from
375 // outside
376 // UdpAddress inaddr("127.0.0.1");
377 Snmpx snmp(status, inaddr);
378
379 if (status == SNMP_CLASS_SUCCESS) {
380
381 LOG_BEGIN(loggerModuleName, EVENT_LOG | 1);
382 LOG("main: SNMP listen address");
383 LOG(inaddr.get_printable());
384 LOG_END;
385 }
386 else {
387 LOG_BEGIN(loggerModuleName, ERROR_LOG | 0);
388 LOG("main: SNMP port init failed");
389 LOG(status);
390 LOG(Snmp::error_msg(status));
391 LOG_END;
392 exit(1);
393 }
394
395 OctetStr persistentObjectsPath(".config/");
396 OctetStr bootCounterFile(".config_bc_");
397 persistentObjectsPath += inaddr.get_printable();
398 bootCounterFile += inaddr.get_printable();
399 persistentObjectsPath += "/";
400 // Make sure persistent objects path exists:
401 if (!AgentTools::make_path(persistentObjectsPath.get_printable())) {
402 LOG_BEGIN(loggerModuleName, WARNING_LOG | 1);
403 LOG("Directory for storing persistent data could not be created (dir)");
404 LOG(persistentObjectsPath.get_printable());
405 LOG_END;
406 }
407 mib = new Mib(persistentObjectsPath, path(bootCounterFile));
408
409 #ifdef _SNMPv3
410 unsigned int snmpEngineBoots = 0;
411 OctetStr engineId(SnmpEngineID::create_engine_id(inaddr.get_port()));
412
413 // you may use your own methods to load/store this counter
414 status = mib->get_boot_counter(engineId, snmpEngineBoots);
415 if ((status != SNMPv3_OK) && (status < SNMPv3_FILEOPEN_ERROR)) {
416 LOG_BEGIN(loggerModuleName, ERROR_LOG | 0);
417 LOG("main: Error loading snmpEngineBoots counter (status)");
418 LOG(status);
419 LOG_END;
420 exit(1);
421 }
422
423 snmpEngineBoots++;
424 status = mib->set_boot_counter(engineId, snmpEngineBoots);
425 if (status != SNMPv3_OK) {
426 LOG_BEGIN(loggerModuleName, ERROR_LOG | 0);
427 LOG("main: Error saving snmpEngineBoots counter (status)");
428 LOG(status);
429 LOG_END;
430 exit(1);
431 }
432
433 int stat;
434 v3MP *v3mp = new v3MP(engineId, snmpEngineBoots, stat);
435 snmp.set_mpv3(v3mp);
436 #endif
437 reqList = new RequestList(mib);
438 #ifdef _SNMPv3
439 // register v3MP
440 reqList->set_v3mp(v3mp);
441 #endif
442 // register requestList for outgoing requests
443 mib->set_request_list(reqList);
444
445 // add supported objects
446 init(*mib, engineId, inaddr);
447
448 reqList->set_snmp(&snmp);
449
450 #ifdef _SNMPv3
451 // register VACM
452 Vacm* vacm = new Vacm(*mib);
453 reqList->set_vacm(vacm);
454
455 // initialize security information
456 vacm->addNewContext("");
457 vacm->addNewContext("other");
458
459 // Add new entries to the SecurityToGroupTable.
460 // Used to determine the group a given SecurityName belongs to.
461 // User "new" of the USM belongs to newGroup
462
463 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "new",
464 "newGroup", storageType_nonVolatile);
465
466 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "test",
467 "testGroup", storageType_nonVolatile);
468 vacm->addNewGroup(SNMP_SECURITY_MODEL_V2, "public",
469 "v1v2group", storageType_nonVolatile);
470 vacm->addNewGroup(SNMP_SECURITY_MODEL_V1, "public",
471 "v1v2group", storageType_nonVolatile);
472 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "initial",
473 "initial", storageType_nonVolatile);
474 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "unsecureUser",
475 "newGroup", storageType_nonVolatile);
476 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "MD5",
477 "testNoPrivGroup", storageType_nonVolatile);
478 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHA",
479 "testNoPrivGroup", storageType_nonVolatile);
480 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "MD5DES",
481 "testGroup", storageType_nonVolatile);
482 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHADES",
483 "testGroup", storageType_nonVolatile);
484 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "MD53DES",
485 "testGroup", storageType_nonVolatile);
486 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHA3DES",
487 "testGroup", storageType_nonVolatile);
488 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "MD5IDEA",
489 "testGroup", storageType_nonVolatile);
490 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHAIDEA",
491 "testGroup", storageType_nonVolatile);
492 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "MD5AES128",
493 "testGroup", storageType_nonVolatile);
494 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHAAES128",
495 "testGroup", storageType_nonVolatile);
496 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "MD5AES192",
497 "testGroup", storageType_nonVolatile);
498 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHAAES192",
499 "testGroup", storageType_nonVolatile);
500 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "MD5AES256",
501 "testGroup", storageType_nonVolatile);
502 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHAAES256",
503 "testGroup", storageType_nonVolatile);
504 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHA512AES256",
505 "testGroup", storageType_nonVolatile);
506 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHA384AES128",
507 "testGroup", storageType_nonVolatile);
508 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHA256AES128",
509 "testGroup", storageType_nonVolatile);
510 vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHA224AES128",
511 "testGroup", storageType_nonVolatile);
512
513 // remove a group with:
514 //vacm->deleteGroup(SNMP_SECURITY_MODEL_USM, "neu");
515
516 // Set access rights of groups.
517 // The group "newGroup" (when using the USM with a security
518 // level >= noAuthNoPriv within context "") would have full access
519 // (read, write, notify) to all objects in view "newView".
520 vacm->addNewAccessEntry("newGroup",
521 "other", // context
522 SNMP_SECURITY_MODEL_USM,
523 SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV,
524 match_exact, // context must mach exactly
525 // alternatively: match_prefix
526 "newView", // readView
527 "newView", // writeView
528 "newView", // notifyView
529 storageType_nonVolatile);
530 vacm->addNewAccessEntry("testGroup", "",
531 SNMP_SECURITY_MODEL_USM,
532 SNMP_SECURITY_LEVEL_AUTH_PRIV,
533 match_prefix,
534 "testView", "testView",
535 "testView", storageType_nonVolatile);
536 vacm->addNewAccessEntry("testNoPrivGroup", "",
537 SNMP_SECURITY_MODEL_USM,
538 SNMP_SECURITY_LEVEL_AUTH_NOPRIV,
539 match_prefix,
540 "testView", "testView",
541 "testView", storageType_nonVolatile);
542 vacm->addNewAccessEntry("testNoPrivGroup", "",
543 SNMP_SECURITY_MODEL_USM,
544 SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV,
545 match_prefix,
546 "testView", "testView",
547 "testView", storageType_nonVolatile);
548 vacm->addNewAccessEntry("testGroup", "",
549 SNMP_SECURITY_MODEL_USM,
550 SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV,
551 match_prefix,
552 "testView", "testView",
553 "testView", storageType_nonVolatile);
554 vacm->addNewAccessEntry("v1v2group", "",
555 SNMP_SECURITY_MODEL_V2,
556 SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV,
557 match_exact,
558 "v1ReadView", "v1WriteView",
559 "v1NotifyView", storageType_nonVolatile);
560 vacm->addNewAccessEntry("v1v2group", "",
561 SNMP_SECURITY_MODEL_V1,
562 SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV,
563 match_exact,
564 "v1ReadView", "v1WriteView",
565 "v1NotifyView", storageType_nonVolatile);
566 vacm->addNewAccessEntry("initial", "",
567 SNMP_SECURITY_MODEL_USM,
568 SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV,
569 match_exact,
570 "restricted", "",
571 "restricted", storageType_nonVolatile);
572 vacm->addNewAccessEntry("initial", "",
573 SNMP_SECURITY_MODEL_USM,
574 SNMP_SECURITY_LEVEL_AUTH_NOPRIV,
575 match_exact,
576 "internet", "internet",
577 "internet", storageType_nonVolatile);
578 vacm->addNewAccessEntry("initial", "",
579 SNMP_SECURITY_MODEL_USM,
580 SNMP_SECURITY_LEVEL_AUTH_PRIV,
581 match_exact,
582 "internet", "internet",
583 "internet", storageType_nonVolatile);
584
585 // remove an AccessEntry with:
586 // vacm->deleteAccessEntry("newGroup",
587 // "",
588 // SNMP_SECURITY_MODEL_USM,
589 // SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV);
590
591
592 // Defining Views
593 // View "v1ReadView" includes all objects starting with "1.3".
594 // If the ith bit of the mask is not set (0), then also all objects
595 // which have a different subid at position i are included in the
596 // view.
597 // For example: Oid "6.5.4.3.2.1", Mask(binary) 110111
598 // Then all objects with Oid with "6.5.<?>.3.2.1"
599 // are included in the view, whereas <?> may be any
600 // natural number.
601
602 vacm->addNewView("v1ReadView",
603 "1.3",
604 "", // Mask "" is same as 0xFFFFFFFFFF...
605 view_included, // alternatively: view_excluded
606 storageType_nonVolatile);
607
608 vacm->addNewView("v1WriteView",
609 "1.3",
610 "", // Mask "" is same as 0xFFFFFFFFFF...
611 view_included, // alternatively: view_excluded
612 storageType_nonVolatile);
613
614 vacm->addNewView("v1NotifyView",
615 "1.3",
616 "", // Mask "" is same as 0xFFFFFFFFFF...
617 view_included, // alternatively: view_excluded
618 storageType_nonVolatile);
619
620 vacm->addNewView("newView", "1.3", "",
621 view_included, storageType_nonVolatile);
622 vacm->addNewView("testView", "1.3.6", "",
623 view_included, storageType_nonVolatile);
624 vacm->addNewView("internet", "1.3.6.1","",
625 view_included, storageType_nonVolatile);
626 vacm->addNewView("restricted", "1.3.6.1.2.1.1","",
627 view_included, storageType_nonVolatile);
628 vacm->addNewView("restricted", "1.3.6.1.2.1.11","",
629 view_included, storageType_nonVolatile);
630 vacm->addNewView("restricted", "1.3.6.1.6.3.10.2.1","",
631 view_included, storageType_nonVolatile);
632 vacm->addNewView("restricted", "1.3.6.1.6.3.11.2.1","",
633 view_included, storageType_nonVolatile);
634 vacm->addNewView("restricted", "1.3.6.1.6.3.15.1.1","",
635 view_included, storageType_nonVolatile);
636
637 // add SNMPv1/v2c community to v3 security name mapping
638 snmpCommunityEntry* communityEntry =
639 snmpCommunityEntry::get_instance(mib);
640 if (communityEntry) {
641 OctetStr co("public");
642 MibTableRow* row = communityEntry->add_row(Oidx::from_string(co, FALSE));
643 OctetStr tag("v1v2cPermittedManagers");
644 communityEntry->set_row(row, co, co,
645 reqList->get_v3mp()->get_local_engine_id(),
646 "", tag, 3, 1);
647 }
648
649 #endif
650
651 #ifdef _SNMPv3
652 // register table size policies
653 MibTableSizePolicy::register_policy(mib->get_default_context(),
654 &policy);
655 #endif
656 // load persistent objects from disk
657 mib->init();
658
659
660 Vbx* vbs = 0;
661 coldStartOid coldOid;
662 NotificationOriginator no(mib);
663 // add an example destination
664 UdpAddress dest("127.0.0.1/162");
665 no.add_v1_trap_destination(dest, "defaultV1Trap", "v1trap", "public");
666 // send the notification
667 mib->notify("", coldOid, vbs, 0);
668
669 Request* req;
670 while (go) {
671 req = reqList->receive(2);
672 if (req) {
673 mib->process_request(req);
674 }
675 else {
676 mib->cleanup();
677 }
678 }
679 delete reqList;
680 delete mib;
681 #ifdef _SNMPv3
682 delete vacm;
683 delete v3mp;
684 #endif
685 }
686
687 int main (int argc, char* argv[])
688 {
689 int num_agents = 0;
690 while (num_agents < MAX_NUMBER_OF_AGENTS && num_agents < argc - 1) {
691 port[num_agents] = atoi(argv[1+num_agents]);
692 num_agents++;
693 }
694 if (num_agents == 0) {
695 // minimum of two agents if not specified explicitly:
696 port[0] = 4700;
697 port[1] = 4701;
698 num_agents = 2;
699 }
700
701 #ifndef _NO_LOGGING
702 DefaultLog::log()->set_filter(ERROR_LOG, 5);
703 DefaultLog::log()->set_filter(WARNING_LOG, 5);
704 DefaultLog::log()->set_filter(EVENT_LOG, 5);
705 DefaultLog::log()->set_filter(INFO_LOG, 5);
706 DefaultLog::log()->set_filter(DEBUG_LOG, 1);
707 #endif
708 Snmp::socket_startup(); // Initialize socket subsystem
709
710 init_signals();
711
712 ThreadPool agentPool(num_agents);
713 agentPool.set_one_time_execution(TRUE);
714 SnmpAgent* agents[num_agents];
715 for (int i=0; i<num_agents; i++) {
716 UdpAddress inaddr("0.0.0.0");
717 inaddr.set_port(port[i]);
718 agents[i] = new SnmpAgent(inaddr);
719 agentPool.execute(agents[i]);
720 }
721 agentPool.join();
722 Snmp::socket_cleanup(); // Shut down socket subsystem
723 return 0;
724 }
725 {{/code}}
726 {{/info}}