1 yi.zhou 1.1 //%2005////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // of this software and associated documentation files (the "Software"), to
14 // deal in the Software without restriction, including without limitation the
15 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16 // sell copies of the Software, and to permit persons to whom the Software is
17 // furnished to do so, subject to the following conditions:
18 //
19 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
20 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
21 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22 yi.zhou 1.1 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
23 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //==============================================================================
29 //
30 // Author: Yi Zhou, Hewlett-Packard Company (Yi.Zhou@hp.com)
31 //
32 // Modified By:
33 //
34 //%/////////////////////////////////////////////////////////////////////////////
35
36 #include <Pegasus/Common/Packer.h>
37 #include <Pegasus/Common/Tracer.h>
38 #include "snmpDeliverTrap_netsnmp.h"
39
40 PEGASUS_NAMESPACE_BEGIN
41
42 void snmpDeliverTrap_netsnmp::deliverTrap(
43 yi.zhou 1.1 const String& trapOid,
44 const String& securityName,
45 const String& targetHost,
46 const Uint16& targetHostFormat,
47 const String& otherTargetHostFormat,
48 const Uint32& portNumber,
49 const Uint16& snmpVersion,
50 const String& engineID,
51 const Array<String>& vbOids,
52 const Array<String>& vbTypes,
53 const Array<String>& vbValues)
54 {
55
56 PEG_METHOD_ENTER (TRC_IND_HANDLER,
57 "snmpDeliverTrap_netsnmp::deliverTrap");
58
59 void *sessionHandle;
60 struct snmp_session snmpSession, *sessionPtr;
61
62 struct snmp_pdu *snmpPdu;
63
64 yi.zhou 1.1 // Creates a SNMP session
65 _createSession(targetHost, portNumber, securityName, snmpSession,
66 sessionHandle, sessionPtr);
67
68 try
69 {
70 _createPdu(snmpVersion, trapOid, sessionPtr, snmpPdu);
71 }
72 catch (...)
73 {
74 _destroySession(sessionHandle);
75
76 PEG_METHOD_EXIT ();
77
78 throw;
79 }
80
81 // Pack OIDs into the PDU
82 try
83 {
84 _packOidsIntoPdu(vbOids, vbTypes, vbValues, snmpPdu);
85 yi.zhou 1.1 }
86 catch (Exception& e)
87 {
88 PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
89 e.getMessage ());
90
91 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
92 Logger::WARNING,
93 _MSG_PACK_CIM_PROPERTY_TO_PDU_FAILED_KEY,
94 _MSG_PACK_CIM_PROPERTY_TO_PDU_FAILED,
95 e.getMessage());
96 }
97 catch (...)
98 {
99 PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
100 "Snmp Indication Handler failed to pack a CIM "
101 "Property into the SNMP PDU: Unknown exception.");
102 }
103
104 // Send the trap to the destination
105 if (snmp_sess_send(sessionHandle, snmpPdu) == 0)
106 yi.zhou 1.1 {
107 Sint32 libErr, sysErr;
108 char *errStr;
109
110 // snmp_sess_send failed
111 // get library, system errno
112 snmp_sess_error(sessionHandle, &libErr, &sysErr, &errStr);
113
114 String exceptionStr = _MSG_SESSION_SEND_FAILED;
115 exceptionStr.append (errStr);
116
117 free(errStr);
118
119 _destroySession(sessionHandle);
120
121 PEG_METHOD_EXIT ();
122
123 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_FAILED,
124 MessageLoaderParms(_MSG_SESSION_SEND_FAILED_KEY,
125 exceptionStr));
126 }
127 yi.zhou 1.1
128 _destroySession(sessionHandle);
129
130 PEG_METHOD_EXIT ();
131
132 }
133
134 // Creates a SNMP session
135 void snmpDeliverTrap_netsnmp::_createSession(
136 const String & targetHost,
137 Uint32 portNumber,
138 const String & securityName,
139 snmp_session & snmpSession,
140 void *&sessionHandle,
141 snmp_session *&sessionPtr)
142 {
143 PEG_METHOD_ENTER (TRC_IND_HANDLER,
144 "snmpDeliverTrap_netsnmp::_createSession");
145
146 Sint32 libErr, sysErr;
147 char *errStr;
148 yi.zhou 1.1 String exceptionStr;
149
|
163 yi.zhou 1.1 // Initialize the mib reader
164 netsnmp_set_mib_directory("");
165 init_mib();
166
167 // Initializes the SNMP library
168 init_snmp("snmpIndicationHandler");
169
170 // Prepares a struct snmp_session that will be used for a set of
171 // SNMP transactions
172 snmp_sess_init(&snmpSession);
173
174 // windows32 specific initialization (is a NOOP on unix)
175 SOCK_STARTUP;
176
177 CString targetHostCStr = targetHost.getCString();
178
179 // peername has format: targetHost:portNumber
180 snmpSession.peername = (char *)malloc((size_t)(strlen(targetHostCStr)+
181 1+32));
182 sprintf(snmpSession.peername, "%s:%u", (const char*)targetHostCStr,
183 portNumber);
184 yi.zhou 1.1 sessionHandle = snmp_sess_open(&snmpSession);
185
186 if (sessionHandle == NULL)
187 {
188 exceptionStr = _MSG_SESSION_OPEN_FAILED;
189
190 // Get library, system errno
191 snmp_sess_error(&snmpSession, &libErr, &sysErr, &errStr);
192
193 exceptionStr.append(errStr);
194
195 free(errStr);
196
197 SOCK_CLEANUP;
198
199 PEG_METHOD_EXIT ();
200
201 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_FAILED,
202 MessageLoaderParms(_MSG_SESSION_OPEN_FAILED_KEY,
203 exceptionStr));
204
205 yi.zhou 1.1 }
206
207 try
208 {
209 // get the snmp_session pointer
210 sessionPtr = snmp_sess_session(sessionHandle);
211 if (sessionPtr == NULL)
212 {
213 exceptionStr = _MSG_GET_SESSION_POINT_FAILED;
214
215 // Get library, system errno
216 snmp_sess_error(&snmpSession, &libErr, &sysErr, &errStr);
217
218 exceptionStr.append(errStr);
219
220 free(errStr);
221
222 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_FAILED,
223 MessageLoaderParms(_MSG_GET_SESSION_POINTER_FAILED_KEY,
224 exceptionStr));
225 }
226 yi.zhou 1.1
227 // Community Name, default is public
228 String communityName;
229 if (securityName.size() == 0)
230 {
231 communityName.assign("public");
232 }
233 else
234 {
235 communityName = securityName;
236 }
237
238 if (snmpSession.peername)
239 {
240 free(snmpSession.peername);
241 }
242
243 if (sessionPtr->community)
244 {
245 free(sessionPtr->community);
246 }
247 yi.zhou 1.1
248 CString communityNameCStr = communityName.getCString();
249 size_t communityNameLen = strlen(communityNameCStr);
250
251 sessionPtr->community = (u_char*)malloc(communityNameLen);
252
253 memcpy(sessionPtr->community, (const char *)communityNameCStr,
254 communityNameLen);
255 sessionPtr->community_len = communityNameLen;
256 }
257 catch (...)
258 {
259 _destroySession(sessionHandle);
260
261 PEG_METHOD_EXIT ();
262 throw;
263 }
264
265 PEG_METHOD_EXIT ();
266 }
267
268 yi.zhou 1.1 // Creates a SNMP session
269 void snmpDeliverTrap_netsnmp::_destroySession(
270 void *sessionHandle)
271 {
272 PEG_METHOD_ENTER (TRC_IND_HANDLER,
273 "snmpDeliverTrap_netsnmp::_destroySession");
274
275 snmp_sess_close(sessionHandle);
276
277 SOCK_CLEANUP;
278
279 PEG_METHOD_EXIT ();
280 }
281
282 // Creates a SNMP TRAP PDU
283 void snmpDeliverTrap_netsnmp::_createPdu(
284 Uint16 snmpVersion,
285 const String& trapOid,
286 snmp_session *&sessionPtr,
287 snmp_pdu *& snmpPdu)
288 {
289 yi.zhou 1.1
290 PEG_METHOD_ENTER (TRC_IND_HANDLER,
291 "snmpDeliverTrap_netsnmp::_createPdu");
292
293 oid _SYSTEM_UP_TIME_OID [] = {1,3,6,1,2,1,1,3,0};
294 oid _SNMPTRAP_OID [] = {1,3,6,1,6,3,1,1,4,1,0};
295
296 in_addr_t *pduInAddr;
297
298 switch (snmpVersion)
299 {
300 case _SNMPv1_TRAP:
301 {
302
303 sessionPtr->version = SNMP_VERSION_1;
304
305 // Create the PDU
306 snmpPdu = snmp_pdu_create(SNMP_MSG_TRAP);
307
308 // Failed to create pdu
309 if (!snmpPdu)
310 yi.zhou 1.1 {
311 PEG_METHOD_EXIT ();
312
313 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_FAILED,
314 MessageLoaderParms(_MSG_PDU_CREATE_FAILED_KEY,
315 _MSG_PDU_CREATE_FAILED));
316 }
317
318 // Make sure that the v1 trap PDU includes the local IP address
319 pduInAddr = (in_addr_t*) snmpPdu->agent_addr;
320 *pduInAddr = get_myaddr();
321
322 // get system up time
323 snmpPdu->time = get_uptime();
324
325 // Pack trap information into the PDU
326 try
327 {
328 _packTrapInfoIntoPdu(trapOid, snmpPdu);
329 }
330 catch (CIMException& e)
331 yi.zhou 1.1 {
332 PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
333 e.getMessage ());
334 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
335 Logger::WARNING,
336 _MSG_PACK_TRAP_INFO_INTO_PDU_FAILED_KEY,
337 _MSG_PACK_TRAP_INFO_INTO_PDU_FAILED,
338 e.getMessage());
339 }
340
341 break;
342 }
343 case _SNMPv2C_TRAP:
344 {
345 sessionPtr->version = SNMP_VERSION_2c;
346
347 // Create the PDU
348 snmpPdu = snmp_pdu_create(SNMP_MSG_TRAP2);
349
350 // Failed to create pdu
351 if (!snmpPdu)
352 yi.zhou 1.1 {
353 PEG_METHOD_EXIT ();
354
355 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_FAILED,
356 MessageLoaderParms(_MSG_PDU_CREATE_FAILED_KEY,
357 _MSG_PDU_CREATE_FAILED));
358 }
359
360 // Add sysUpTime to the PDU
361 char sysUpTime[32];
362 sprintf(sysUpTime, "%ld", get_uptime());
363
364 Sint32 retCode;
365 retCode = snmp_add_var(snmpPdu, _SYSTEM_UP_TIME_OID,
366 OID_LENGTH(_SYSTEM_UP_TIME_OID), 't',
367 sysUpTime);
368
369
370 // Failed to add sysUpTime to the pdu
371 if (retCode != 0)
372 {
373 yi.zhou 1.1 String errMsg = snmp_api_errstring(retCode);
374
375 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
376 "Failed to add sysUpTime to pdu: " +
377 errMsg);
378 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
379 Logger::WARNING,
380 _MSG_ADD_SYSUPTIME_TO_PDU_FAILED_KEY,
381 _MSG_ADD_SYSUPTIME_TO_PDU_FAILED,
382 errMsg);
383 }
384
385 // Add snmp trap to the PDU
386 retCode = snmp_add_var(snmpPdu, _SNMPTRAP_OID, OID_LENGTH(
387 _SNMPTRAP_OID), 'o', trapOid.getCString());
388
389 // Failed to add snmp trap to the pdu
390 if (retCode != 0)
391 {
392 String errMsg = snmp_api_errstring(retCode);
393
394 yi.zhou 1.1 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
395 "Failed to add snmp trap to pdu: " +
396 errMsg);
397 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
398 Logger::WARNING,
399 _MSG_ADD_SNMP_TRAP_TO_PDU_FAILED_KEY,
400 _MSG_ADD_SNMP_TRAP_TO_PDU_FAILED,
401 errMsg);
402 }
403
404 break;
405 }
406 default:
407 {
408 PEG_METHOD_EXIT ();
409
410 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
411 MessageLoaderParms(_MSG_VERSION_NOT_SUPPORTED_KEY,
412 _MSG_VERSION_NOT_SUPPORTED));
413 break;
414 }
415 yi.zhou 1.1 }
416
417 PEG_METHOD_EXIT ();
418 }
419
420
421 // Pack trap information into the PDU
422 void snmpDeliverTrap_netsnmp::_packTrapInfoIntoPdu(
423 const String & trapOid,
424 snmp_pdu * snmpPdu)
425 {
426 PEG_METHOD_ENTER (TRC_IND_HANDLER,
427 "snmpDeliverTrap_netsnmp::_packTrapInfoIntoPdu");
428
429 oid enterpriseOid[MAX_OID_LEN];
430 size_t enterpriseOidLength;
431
432 Array<String> standard_traps;
433
434 standard_traps.append(String("1.3.6.1.6.3.1.1.5.1"));
435 standard_traps.append(String("1.3.6.1.6.3.1.1.5.2"));
436 yi.zhou 1.1 standard_traps.append(String("1.3.6.1.6.3.1.1.5.3"));
437 standard_traps.append(String("1.3.6.1.6.3.1.1.5.4"));
438 standard_traps.append(String("1.3.6.1.6.3.1.1.5.5"));
439 standard_traps.append(String("1.3.6.1.6.3.1.1.5.6"));
440
441 Array<const char *> oidSubIdentifiers;
442
443 CString trapOidCStr = trapOid.getCString();
444
445 char * trapOidCopy = strdup(trapOidCStr);
446
447 #if !defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC)
448 char *last;
449 for (const char* p = strtok_r(trapOidCopy, ".", &last); p;
450 p=strtok_r(NULL, ".", &last))
451 #else
452 for (const char* p = strtok(trapOidCopy, "."); p; p=strtok(NULL, "."))
453 #endif
454 {
455 oidSubIdentifiers.append(p);
456 }
457 yi.zhou 1.1
458 long genTrap = 0;
459 long specTrap = 0;
460
461 enterpriseOidLength = MAX_OID_LEN;
462
463 char * numericEntOid = (char *) malloc(strlen(trapOidCStr));
464 if (Contains(standard_traps, trapOid))
465 {
466 //
467 // if the trapOid is one of the standard traps,
468 // then the SNMPV1 enterprise parameter must be set
469 // to the value of the trapOid, the generic-trap
470 // parameter must be set to one of (0 - 5), and the
471 // specific-trap parameter must be set to 0
472 //
473
474 // Convert trapOid from numeric form to a list of subidentifiers
475 if (read_objid((const char*)trapOidCStr, enterpriseOid,
476 &enterpriseOidLength) == 0)
477 {
478 yi.zhou 1.1 // Failed to parse trapOid
479
480 PEG_METHOD_EXIT ();
481 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_FAILED,
482 MessageLoaderParms(_MSG_READ_OBJID_FAILED_KEY,
483 _MSG_READ_OBJID_FAILED,
484 trapOid));
485 }
486
487 // the generic trap is last sub-identifier of the
488 // trapOid minus 1
489 snmpPdu->trap_type =
490 atoi(oidSubIdentifiers[oidSubIdentifiers.size() - 1]) - 1;
491 snmpPdu->specific_type = 0;
492 }
493 else
494 {
495 //
496 // if the trapOid is not one of the standard traps:
497 // then 1) the generic-trap parameter must be set to 6,
498 // 2) if the next-to-last sub-identifier of the
499 yi.zhou 1.1 // trapOid is zero, then the SNMPV1 enterprise
500 // parameter is the trapOid with the last 2
501 // sub-identifiers removed, otherwise, the
502 // SNMPV1 enterprise parameter is the trapOid
503 // with the last sub-identifier removed;
504 // 3) the SNMPv1 specific-trap parameter is the last
505 // sub-identifier of the trapOid;
506 //
507
508 snmpPdu->trap_type = 6;
509
510 snmpPdu->specific_type =
511 atoi(oidSubIdentifiers[oidSubIdentifiers.size()-1]);
512
513 strcpy(numericEntOid, oidSubIdentifiers[0]);
514 for (Uint32 i = 1; i < oidSubIdentifiers.size()-2; i++)
515 {
516 strcat(numericEntOid, ".");
517 strcat(numericEntOid, oidSubIdentifiers[i]);
518 }
519
520 yi.zhou 1.1 if (oidSubIdentifiers[oidSubIdentifiers.size()-2] != "0")
521 {
522 strcat(numericEntOid, ".");
523 strcat(numericEntOid,
524 oidSubIdentifiers[oidSubIdentifiers.size()-2]);
525 }
526
527 // Convert ent from numeric form to a list of subidentifiers
528 if (read_objid(numericEntOid, enterpriseOid,
529 &enterpriseOidLength) == 0)
530 {
531 // Failed to parse numericEntOid
532
533 PEG_METHOD_EXIT ();
534
535 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_FAILED,
536 MessageLoaderParms(_MSG_READ_ENTOID_FAILED_KEY,
537 _MSG_READ_ENTOID_FAILED,
538 String(numericEntOid)));
539 }
540
541 yi.zhou 1.1 }
542
543 snmpPdu->enterprise = (oid*) malloc(enterpriseOidLength * sizeof(oid));
544 memcpy(snmpPdu->enterprise, enterpriseOid,
545 enterpriseOidLength * sizeof(oid));
546
547 snmpPdu->enterprise_length = enterpriseOidLength;
548
549 free(trapOidCopy);
550 free(numericEntOid);
551
552 PEG_METHOD_EXIT ();
553 }
554
555 // Pack oids into the PDU
556 void snmpDeliverTrap_netsnmp::_packOidsIntoPdu(
557 const Array<String>& vbOids,
558 const Array<String>& vbTypes,
559 const Array<String>& vbValues,
560 snmp_pdu * snmpPdu)
561 {
562 yi.zhou 1.1
563 PEG_METHOD_ENTER (TRC_IND_HANDLER,
564 "snmpDeliverTrap_netsnmp::_packOidsIntoPdu");
565
566 char dataType;
567 oid vbOid[MAX_OID_LEN];
568 size_t vbOidLength = MAX_OID_LEN;
569
570 for (Uint32 i=0; i < vbOids.size(); i++)
571 {
572 if (vbTypes[i] == "OctetString")
573 {
574 dataType = 's';
575 }
576 else if (vbTypes[i] == "Integer")
577 {
578 dataType = 'i';
579 }
580 else if (vbTypes[i] == "OID")
581 {
582 dataType = 'o';
583 yi.zhou 1.1 }
584 else
585 {
586 // Integer, OctetString, and OID are supported SNMP Data Types
587 // for the CIM Property
588
589 PEG_METHOD_EXIT ();
590
591 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_FAILED,
592 MessageLoaderParms(_MSG_UNSUPPORTED_SNMP_DATA_TYPE_KEY,
593 _MSG_UNSUPPORTED_SNMP_DATA_TYPE,
594 vbTypes[i]));
595
596 }
597
598 // Convert oid of a CIM property from numeric form to a list of
599 // subidentifiers
600 if (read_objid((const char*)vbOids[i].getCString(), vbOid,
601 &vbOidLength) == 0)
602 {
603 // Failed to parse vbOids
604 yi.zhou 1.1
605 PEG_METHOD_EXIT ();
606
607 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_FAILED,
608 MessageLoaderParms(_MSG_PARSE_CIM_PROPERTY_OID_FAILED_KEY,
609 _MSG_PARSE_CIM_PROPERTY_OID_FAILED,
610 vbOids[i]));
611 }
612
613 Sint32 retCode;
614 retCode = snmp_add_var(snmpPdu, vbOid, vbOidLength, dataType,
615 vbValues[i].getCString());
616
617 // Failed to add vbOid to the pdu
618 if (retCode != 0)
619 {
620 PEG_METHOD_EXIT ();
621
622 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_FAILED,
623 MessageLoaderParms(_MSG_ADD_VAR_TO_PDU_FAILED_KEY,
624 _MSG_ADD_VAR_TO_PDU_FAILED,
625 yi.zhou 1.1 vbOids[i],
626 String(snmp_api_errstring(retCode))));
627
628 }
629 }
630
631 PEG_METHOD_EXIT ();
632 }
633
634 PEGASUS_NAMESPACE_END
|