snmpNextAsync.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*_############################################################################
  2. _##
  3. _## snmpNextAsync.cpp
  4. _##
  5. _## SNMP++v3.2.23
  6. _## -----------------------------------------------
  7. _## Copyright (c) 2001-2007 Jochen Katz, Frank Fock
  8. _##
  9. _## This software is based on SNMP++2.6 from Hewlett Packard:
  10. _##
  11. _## Copyright (c) 1996
  12. _## Hewlett-Packard Company
  13. _##
  14. _## ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  15. _## Permission to use, copy, modify, distribute and/or sell this software
  16. _## and/or its documentation is hereby granted without fee. User agrees
  17. _## to display the above copyright notice and this license notice in all
  18. _## copies of the software and any documentation of the software. User
  19. _## agrees to assume all liability for the use of the software;
  20. _## Hewlett-Packard and Jochen Katz make no representations about the
  21. _## suitability of this software for any purpose. It is provided
  22. _## "AS-IS" without warranty of any kind, either express or implied. User
  23. _## hereby grants a royalty-free license to any and all derivatives based
  24. _## upon this software code base.
  25. _##
  26. _## Stuttgart, Germany, Sun Nov 11 15:10:59 CET 2007
  27. _##
  28. _##########################################################################*/
  29. /*
  30. snmpNextAsync.cpp
  31. Copyright (c) 1996
  32. Hewlett-Packard Company
  33. ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  34. Permission to use, copy, modify, distribute and/or sell this software
  35. and/or its documentation is hereby granted without fee. User agrees
  36. to display the above copyright notice and this license notice in all
  37. copies of the software and any documentation of the software. User
  38. agrees to assume all liability for the use of the software; Hewlett-Packard
  39. makes no representations about the suitability of this software for any
  40. purpose. It is provided "AS-IS" without warranty of any kind,either express
  41. or implied. User hereby grants a royalty-free license to any and all
  42. derivatives based upon this software code base.
  43. Peter E. Mellquist
  44. */
  45. char snmpnextasync_cpp_version[]="@(#) SNMP++ $Id: snmpNextAsync.cpp 264 2006-06-16 20:53:15Z fock $";
  46. #include "snmp_pp/snmp_pp.h"
  47. #include <stdlib.h>
  48. #include <stdio.h>
  49. #ifdef WIN32
  50. #define strcasecmp stricmp
  51. #endif
  52. #ifdef SNMP_PP_NAMESPACE
  53. using namespace Snmp_pp;
  54. #endif
  55. #if (__GNUC__ > 2)
  56. #include <iostream>
  57. using std::cerr;
  58. using std::cout;
  59. using std::endl;
  60. using std::flush;
  61. #else
  62. #include <iostream.h>
  63. #endif
  64. void callback( int reason, Snmp *snmp, Pdu &pdu, SnmpTarget &target, void *cd)
  65. {
  66. Vb nextVb;
  67. int pdu_error;
  68. cout << "reason: " << reason << endl
  69. << "msg: " << snmp->error_msg(reason) << endl;
  70. pdu_error = pdu.get_error_status();
  71. if (pdu_error){
  72. cout << "Response contains error: "
  73. << snmp->error_msg(pdu_error)<< endl;
  74. }
  75. for (int i=0; i<pdu.get_vb_count(); i++)
  76. {
  77. pdu.get_vb(nextVb, i);
  78. cout << "Oid: " << nextVb.get_printable_oid() << endl
  79. << "Val: " << nextVb.get_printable_value() << endl;
  80. }
  81. if (pdu.get_type() == sNMP_PDU_INFORM) {
  82. cout << "pdu type: " << pdu.get_type() << endl;
  83. cout << "sending response to inform: " << endl;
  84. nextVb.set_value("This is the response.");
  85. pdu.set_vb(nextVb, 0);
  86. snmp->response(pdu, target);
  87. }
  88. cout << endl;
  89. }
  90. int main(int argc, char **argv)
  91. {
  92. //---------[ check the arg count ]----------------------------------------
  93. if ( argc < 2) {
  94. cout << "Usage:\n";
  95. cout << argv[0] << " IpAddress | DNSName [Oid] [options]\n";
  96. cout << "Oid: sysDescr object is default\n";
  97. cout << "options: -vN , use SNMP version 1, 2 or 3, default is 1\n";
  98. cout << " -PPort , remote port to use\n";
  99. cout << " -CCommunity_name, specify community default is 'public' \n";
  100. cout << " -rN , retries default is N = 1 retry\n";
  101. cout << " -tN , timeout in hundredths of seconds; default is N = 100\n";
  102. #ifdef _SNMPv3
  103. cout << " -snSecurityName, " << endl;
  104. cout << " -slN , securityLevel to use, default N = 3 = authPriv" << endl;
  105. cout << " -smN , securityModel to use, only default N = 3 = USM possible\n";
  106. cout << " -cnContextName, default empty string" << endl;
  107. cout << " -ceContextEngineID, as hex e.g. 800007E580, default empty string" << endl;
  108. cout << " -authPROT, use authentication protocol NONE, SHA or MD5\n";
  109. cout << " -privPROT, use privacy protocol NONE, DES, 3DESEDE, IDEA, AES128, AES192 or AES256\n";
  110. cout << " -uaAuthPassword\n";
  111. cout << " -upPrivPassword\n";
  112. #endif
  113. return 1;
  114. }
  115. Snmp::socket_startup(); // Initialize socket subsystem
  116. //---------[ make a GenAddress and Oid object to retrieve ]---------------
  117. UdpAddress address( argv[1]); // make a SNMP++ Generic address
  118. if ( !address.valid()) { // check validity of address
  119. cout << "Invalid Address or DNS Name, " << argv[1] << "\n";
  120. return 1;
  121. }
  122. Oid oid("1.3.6.1.2.1.1.1"); // default is sysDescr
  123. if ( argc >= 3) { // if 3 args, then use the callers Oid
  124. if ( strstr( argv[2],"-")==0) {
  125. oid = argv[2];
  126. if ( !oid.valid()) { // check validity of user oid
  127. cout << "Invalid Oid, " << argv[2] << "\n";
  128. return 1;
  129. }
  130. }
  131. }
  132. //---------[ determine options to use ]-----------------------------------
  133. snmp_version version=version1; // default is v1
  134. int retries=1; // default retries is 1
  135. int timeout=100; // default is 1 second
  136. u_short port=161; // default snmp port is 161
  137. OctetStr community("public"); // community name
  138. #ifdef _SNMPv3
  139. OctetStr privPassword("");
  140. OctetStr authPassword("");
  141. OctetStr securityName("");
  142. int securityModel = SecurityModel_USM;
  143. int securityLevel = SecurityLevel_authPriv;
  144. OctetStr contextName("");
  145. OctetStr contextEngineID("");
  146. long authProtocol = SNMPv3_usmNoAuthProtocol;
  147. long privProtocol = SNMPv3_usmNoPrivProtocol;
  148. v3MP *v3_MP;
  149. #endif
  150. char *ptr;
  151. for(int x=1;x<argc;x++) { // parse for version
  152. if ( strstr( argv[x],"-v2")!= 0) {
  153. version = version2c;
  154. continue;
  155. }
  156. if ( strstr( argv[x],"-r")!= 0) { // parse for retries
  157. ptr = argv[x]; ptr++; ptr++;
  158. retries = atoi(ptr);
  159. if (( retries<0)|| (retries>5)) retries=1;
  160. continue;
  161. }
  162. if ( strstr( argv[x], "-t")!=0) { // parse for timeout
  163. ptr = argv[x]; ptr++; ptr++;
  164. timeout = atoi( ptr);
  165. if (( timeout < 100)||( timeout>500)) timeout=100;
  166. continue;
  167. }
  168. if ( strstr( argv[x],"-C")!=0) {
  169. ptr = argv[x]; ptr++; ptr++;
  170. community = ptr;
  171. continue;
  172. }
  173. if ( strstr( argv[x],"-P")!=0) {
  174. ptr = argv[x]; ptr++; ptr++;
  175. sscanf(ptr, "%hu", &port);
  176. continue;
  177. }
  178. #ifdef _SNMPv3
  179. if ( strstr( argv[x],"-v3")!= 0) {
  180. version = version3;
  181. continue;
  182. }
  183. if ( strstr( argv[x],"-auth") != 0) {
  184. ptr = argv[x]; ptr+=5;
  185. if (strcasecmp(ptr, "SHA") == 0)
  186. authProtocol = SNMP_AUTHPROTOCOL_HMACSHA;
  187. else if (strcasecmp(ptr, "MD5") == 0)
  188. authProtocol = SNMP_AUTHPROTOCOL_HMACMD5;
  189. else
  190. authProtocol = SNMP_AUTHPROTOCOL_NONE;
  191. continue;
  192. }
  193. if ( strstr( argv[x],"-priv") != 0) {
  194. ptr = argv[x]; ptr+=5;
  195. if (strcasecmp(ptr, "DES") == 0)
  196. privProtocol = SNMP_PRIVPROTOCOL_DES;
  197. else if (strcasecmp(ptr, "3DESEDE") == 0)
  198. privProtocol = SNMP_PRIVPROTOCOL_3DESEDE;
  199. else if (strcasecmp(ptr, "IDEA") == 0)
  200. privProtocol = SNMP_PRIVPROTOCOL_IDEA;
  201. else if (strcasecmp(ptr, "AES128") == 0)
  202. privProtocol = SNMP_PRIVPROTOCOL_AES128;
  203. else if (strcasecmp(ptr, "AES192") == 0)
  204. privProtocol = SNMP_PRIVPROTOCOL_AES192;
  205. else if (strcasecmp(ptr, "AES256") == 0)
  206. privProtocol = SNMP_PRIVPROTOCOL_AES256;
  207. else
  208. privProtocol = SNMP_PRIVPROTOCOL_NONE;
  209. printf("\n\nPrivProt : %ld\n", privProtocol);
  210. continue;
  211. }
  212. if ( strstr( argv[x],"-sn")!=0) {
  213. ptr = argv[x]; ptr+=3;
  214. securityName = ptr;
  215. continue;
  216. }
  217. if ( strstr( argv[x], "-sl")!=0) {
  218. ptr = argv[x]; ptr+=3;
  219. securityLevel = atoi( ptr);
  220. if (( securityLevel < SecurityLevel_noAuthNoPriv) ||
  221. ( securityLevel > SecurityLevel_authPriv))
  222. securityLevel = SecurityLevel_authPriv;
  223. continue;
  224. }
  225. if ( strstr( argv[x], "-sm")!=0) {
  226. ptr = argv[x]; ptr+=3;
  227. securityModel = atoi( ptr);
  228. if (( securityModel < SecurityModel_v1) ||
  229. ( securityModel > SecurityModel_USM))
  230. securityModel = SecurityModel_USM;
  231. continue;
  232. }
  233. if ( strstr( argv[x],"-cn")!=0) {
  234. ptr = argv[x]; ptr+=3;
  235. contextName = ptr;
  236. continue;
  237. }
  238. if ( strstr( argv[x],"-ce")!=0) {
  239. ptr = argv[x]; ptr+=3;
  240. contextEngineID = OctetStr::from_hex_string(ptr);
  241. continue;
  242. }
  243. if ( strstr( argv[x],"-ua")!=0) {
  244. ptr = argv[x]; ptr+=3;
  245. authPassword = ptr;
  246. continue;
  247. }
  248. if ( strstr( argv[x],"-up")!=0) {
  249. ptr = argv[x]; ptr+=3;
  250. privPassword = ptr;
  251. continue;
  252. }
  253. #endif
  254. }
  255. //----------[ create a SNMP++ session ]-----------------------------------
  256. int status;
  257. // bind to any port and use IPv6 if needed
  258. Snmp snmp(status, 0, (address.get_ip_version() == Address::version_ipv6));
  259. if ( status != SNMP_CLASS_SUCCESS) {
  260. cout << "SNMP++ Session Create Fail, " << snmp.error_msg(status) << "\n";
  261. return 1;
  262. }
  263. //---------[ init SnmpV3 ]--------------------------------------------
  264. #ifdef _SNMPv3
  265. if (version == version3) {
  266. char *engineId = "snmpNextAsync";
  267. char *filename = "snmpv3_boot_counter";
  268. unsigned int snmpEngineBoots = 0;
  269. int status;
  270. status = getBootCounter(filename, engineId, snmpEngineBoots);
  271. if ((status != SNMPv3_OK) && (status < SNMPv3_FILEOPEN_ERROR))
  272. {
  273. cout << "Error loading snmpEngineBoots counter: " << status << endl;
  274. return 1;
  275. }
  276. snmpEngineBoots++;
  277. status = saveBootCounter(filename, engineId, snmpEngineBoots);
  278. if (status != SNMPv3_OK)
  279. {
  280. cout << "Error saving snmpEngineBoots counter: " << status << endl;
  281. return 1;
  282. }
  283. int construct_status;
  284. v3_MP = new v3MP(engineId, snmpEngineBoots, construct_status);
  285. USM *usm = v3_MP->get_usm();
  286. usm->add_usm_user(securityName,
  287. authProtocol, privProtocol,
  288. authPassword, privPassword);
  289. }
  290. else
  291. {
  292. // MUST create a dummy v3MP object if _SNMPv3 is enabled!
  293. int construct_status;
  294. v3_MP = new v3MP("dummy", 0, construct_status);
  295. }
  296. #endif
  297. //--------[ build up SNMP++ object needed ]-------------------------------
  298. Pdu pdu; // construct a Pdu object
  299. Vb vb; // construct a Vb object
  300. vb.set_oid( oid); // set the Oid portion of the Vb
  301. pdu += vb; // add the vb to the Pdu
  302. address.set_port(port);
  303. CTarget ctarget( address); // make a target using the address
  304. #ifdef _SNMPv3
  305. UTarget utarget( address);
  306. if (version == version3) {
  307. utarget.set_version( version); // set the SNMP version SNMPV1 or V2 or V3
  308. utarget.set_retry( retries); // set the number of auto retries
  309. utarget.set_timeout( timeout); // set timeout
  310. utarget.set_security_model( securityModel);
  311. utarget.set_security_name( securityName);
  312. pdu.set_security_level( securityLevel);
  313. pdu.set_context_name (contextName);
  314. pdu.set_context_engine_id(contextEngineID);
  315. }
  316. else {
  317. #endif
  318. ctarget.set_version( version); // set the SNMP version SNMPV1 or V2
  319. ctarget.set_retry( retries); // set the number of auto retries
  320. ctarget.set_timeout( timeout); // set timeout
  321. ctarget.set_readcommunity( community); // set the read community name
  322. #ifdef _SNMPv3
  323. }
  324. #endif
  325. //-------[ issue the request, blocked mode ]-----------------------------
  326. cout << "SNMP++ GetNext to " << argv[1] << " SNMPV"
  327. #ifdef _SNMPv3
  328. << ((version==version3) ? (version) : (version+1))
  329. #else
  330. << (version+1)
  331. #endif
  332. << " Retries=" << retries
  333. << " Timeout=" << timeout * 10 <<"ms";
  334. #ifdef _SNMPv3
  335. if (version == version3)
  336. cout << endl
  337. << "securityName= " << securityName.get_printable()
  338. << ", securityLevel= " << securityLevel
  339. << ", securityModel= " << securityModel << endl
  340. << "contextName= " << contextName.get_printable()
  341. << ", contextEngineID= " << contextEngineID.get_printable()
  342. << endl;
  343. else
  344. #endif
  345. cout << " Community=" << community.get_printable() << endl << flush;
  346. SnmpTarget *target;
  347. #ifdef _SNMPv3
  348. if (version == version3)
  349. target = &utarget;
  350. else
  351. #endif
  352. target = &ctarget;
  353. status = snmp.get_next( pdu, *target, callback,NULL);
  354. if (status == SNMP_CLASS_SUCCESS)
  355. {
  356. cout << "Async GetNext Request sent." << endl;
  357. }
  358. else
  359. cout << "SNMP++ GetNext Error, " << snmp.error_msg( status)
  360. << " (" << status <<")" << endl ;
  361. for (int t=1; t<=10;t++)
  362. {
  363. snmp.eventListHolder->SNMPProcessPendingEvents();
  364. #ifdef WIN32
  365. Sleep(1000);
  366. #else
  367. sleep(1);
  368. #endif
  369. }
  370. Snmp::socket_cleanup(); // Shut down socket subsystem
  371. }