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