SNMP++  3.3.4
uxsnmp.h
Go to the documentation of this file.
1 /*_############################################################################
2  _##
3  _## uxsnmp.h
4  _##
5  _## SNMP++ v3.3
6  _## -----------------------------------------------
7  _## Copyright (c) 2001-2013 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  _##########################################################################*/
27 // $Id: uxsnmp.h 2359 2013-05-09 20:07:01Z fock $
28 
29 #ifndef _UXSNMP_H_
30 #define _UXSNMP_H_
31 
32 #include "snmp_pp/reentrant.h"
33 #include "snmp_pp/target.h"
34 #include "snmp_pp/oid.h"
35 #include "snmp_pp/address.h"
36 
37 #ifdef SNMP_PP_NAMESPACE
38 namespace Snmp_pp {
39 #endif
40 
41 #define SNMP_PP_WITH_UDPADDR // Snmp class has constructor with UdpAddress
42 
43 //-----[ internally used defines ]----------------------------------------
44 #define MAXNAME 80 // maximum name length
45 #define MAX_ADDR_LEN 10 // maximum address len, ipx is 4+6
46 #ifndef INVALID_SOCKET
47 #define INVALID_SOCKET ((SnmpSocket)(~0)) // value for invalid socket
48 #endif
49 
50 //-----[ async defines for engine ]---------------------------------------
51 #define sNMP_PDU_GET_ASYNC 21
52 #define sNMP_PDU_GETNEXT_ASYNC 22
53 #define sNMP_PDU_SET_ASYNC 23
54 #define sNMP_PDU_GETBULK_ASYNC 24
55 #define sNMP_PDU_INFORM_ASYNC 25
56 
57 //------[ forward declaration of Snmp class ]-----------------------------
58 class Snmp;
59 class EventListHolder;
60 class Pdu;
61 class v3MP;
62 
63 //-----------[ async methods callback ]-----------------------------------
64 /**
65  * Async methods of the class Snmp require the caller to provide a
66  * callback address of a function with this typedef.
67  *
68  * @note It is not allowed to call any synchronous Snmp methods within the
69  * callback. Async methods are allowed.
70  *
71  * @param reason - Reason for callback (see snmperrs.h)
72  * @param session - Pointer to Snmp object that was used to send the request
73  * @param pdu - The received Pdu if reason indicates a received message
74  * @param target - source target
75  * @param data - Pointer passed to the async method
76  */
77 typedef void (*snmp_callback)(int reason, Snmp *session,
78  Pdu &pdu, SnmpTarget &target, void *data);
79 
80 
81 //------------[ SNMP Class Def ]---------------------------------------------
82 //
83 /**
84  * SNMP class defintion. The Snmp class provides an object oriented
85  * approach to SNMP. The SNMP class is an encapsulation of SNMP
86  * sessions, gets, sets and get nexts. The class manages all SNMP
87  * resources and provides complete retry and timeout capability.
88  *
89  * This class is thread save.
90  *
91  * @note If you use the async methods to send requests you MUST call
92  * Snmp::eventListHolder->SNMPProcessPendingEvents() while waiting
93  * for the responses. This function triggers the resend of
94  * packets and calls your callback function if the response is
95  * received.
96  *
97  * @note Call srand() before creating the first Snmp object.
98  */
100 {
101  public:
102  //------------------[ constructors ]----------------------------------
103 
104  /** @name Constructors and Destructor */
105  //@{
106 
107  /**
108  * Construct a new SNMP session using the given UDP port.
109  *
110  * @param status
111  * after creation of the session this parameter will
112  * hold the creation status.
113  * @param port
114  * an UDP port to be used for the session
115  * @param bind_ipv6
116  * Set this to true if IPv6 should be used. The default is
117  * IPv4.
118  */
119  Snmp(int &status, const unsigned short port = 0,
120  const bool bind_ipv6 = false);
121 
122  /**
123  * Construct a new SNMP session using the given UDP address.
124  * Thus, binds the session on a specific IPv4 or IPv6 address.
125  *
126  * @param status
127  * after creation of the session this parameter will
128  * hold the creation status.
129  * @param addr
130  * an UDP address to be used for the session
131  */
132  Snmp(int &status, const UdpAddress &addr);
133 
134  /**
135  * Construct a new SNMP session using the given UDP addresses.
136  * Using this constructor will bind to both IPv4 and IPv6 ports.
137  *
138  * @param status
139  * after creation of the session this parameter will
140  * hold the creation status.
141  * @param addr_v4
142  * an IPv4 UDP address to be used for the session
143  * @param addr_v6
144  * an IPv6 UDP address to be used for the session
145  */
146  Snmp(int &status, const UdpAddress& addr_v4, const UdpAddress& addr_v6);
147 
148  //-------------------[ destructor ]------------------------------------
149  /**
150  * Destructor.
151  */
152  virtual ~Snmp();
153 
154  //@}
155 
156  //--------[ Get the version of the snmp++ library ]--------------------
157  /**
158  * Get the version of the snmp++ library.
159  *
160  * @return The version of the snmp++ lib at runtime.
161  */
162  static const char *get_version();
163 
164 
165  //-------------------[ returns error string ]--------------------------
166  /**
167  * Returns a human readable error string.
168  *
169  * @param c - Error code returned by any method of this class
170  * @return Null terminated error string.
171  */
172  static const char *error_msg(const int c);
173 #ifdef _SNMPv3
174  /**
175  * Returns the error code for a SNMPv3 report Oid.
176  * If a report message is returned, then the contained Oid can be
177  * used to get a error code.
178  *
179  * @param v3Oid - Oid of a SNMPv3 report Pdu
180  * @return Error code.
181  */
182  static int error_code(const Oid& v3Oid);
183 
184  /**
185  * Returns a human readable error string.
186  * If a report message is returned, then the contained Oid can be
187  * used to get a error string.
188  *
189  * @param v3Oid - Oid of a SNMPv3 report Pdu
190  * @return Null terminated error string.
191  */
192  static const char* error_msg(const Oid& v3Oid)
193  { return error_msg(error_code(v3Oid)); }
194 #endif
195 
196  //------------------------[ Windows Sockets ]----------------------------
197 
198  /**
199  * Initialize the Winsock library (WSAStartup).
200  *
201  * @note on Win32 this method *must* be called before creating Snmp or
202  * Address objects.
203  */
204  static void socket_startup();
205 
206 
207  /**
208  * Shut down the Winsock library (WSACleanup).
209  */
210  static void socket_cleanup();
211 
212  //------------------------[ send requests ]------------------------------
213 
214  /** @name Sending SNMP Pdus
215  */
216  //@{
217 
218  /**
219  * Send a blocking SNMP-GET request.
220  *
221  * @param pdu - Pdu to send
222  * @param target - Target for the get
223  *
224  * @return SNMP_CLASS_SUCCES or a negative error code
225  */
226  virtual int get(Pdu &pdu, const SnmpTarget &target);
227 
228  /**
229  * Send a async SNMP-GET request.
230  *
231  * @param pdu - Pdu to send
232  * @param target - Target for the get
233  * @param callback - User callback function to use
234  * @param callback_data - User definable data pointer
235  *
236  * @return SNMP_CLASS_SUCCES or a negative error code
237  */
238  virtual int get(Pdu &pdu, const SnmpTarget &target,
239  const snmp_callback callback,
240  const void *callback_data = 0);
241 
242  /**
243  * Send a blocking SNMP-GETNEXT request.
244  *
245  * @param pdu - Pdu to send
246  * @param target - Target for the getnext
247  *
248  * @return SNMP_CLASS_SUCCES or a negative error code
249  */
250  virtual int get_next(Pdu &pdu, const SnmpTarget &target);
251 
252  /**
253  * Send a async SNMP-GETNEXT request.
254  *
255  * @param pdu - Pdu to send
256  * @param target - Target for the getnext
257  * @param callback - User callback function to use
258  * @param callback_data - User definable data pointer
259  *
260  * @return SNMP_CLASS_SUCCES or a negative error code
261  */
262  virtual int get_next(Pdu &pdu, const SnmpTarget &target,
263  const snmp_callback callback,
264  const void *callback_data = 0);
265 
266  /**
267  * Send a blocking SNMP-SET request.
268  *
269  * @param pdu - Pdu to send
270  * @param target - Target for the set
271  *
272  * @return SNMP_CLASS_SUCCES or a negative error code
273  */
274  virtual int set(Pdu &pdu, const SnmpTarget &target);
275 
276  /**
277  * Send a async SNMP-SET request.
278  *
279  * @param pdu - Pdu to send
280  * @param target - Target for the set
281  * @param callback - User callback function to use
282  * @param callback_data - User definable data pointer
283  *
284  * @return SNMP_CLASS_SUCCES or a negative error code
285  */
286  virtual int set(Pdu &pdu, const SnmpTarget &target,
287  const snmp_callback callback,
288  const void * callback_data = 0);
289 
290  /**
291  * Send a blocking SNMP-GETBULK request.
292  *
293  * @param pdu - Pdu to send
294  * @param target - Target for the getbulk
295  * @param non_repeaters - number of non repeaters
296  * @param max_reps - maximum number of repetitions
297  *
298  * @return SNMP_CLASS_SUCCES or a negative error code
299  */
300  virtual int get_bulk(Pdu &pdu, const SnmpTarget &target,
301  const int non_repeaters, const int max_reps);
302 
303  /**
304  * Send a async SNMP-GETBULK request.
305  *
306  * @param pdu - Pdu to send
307  * @param target - Target for the getbulk
308  * @param non_repeaters - number of non repeaters
309  * @param max_reps - maximum number of repetitions
310  * @param callback - User callback function to use
311  * @param callback_data - User definable data pointer
312  *
313  * @return SNMP_CLASS_SUCCES or a negative error code
314  */
315  virtual int get_bulk(Pdu &pdu, const SnmpTarget &target,
316  const int non_repeaters, const int max_reps,
317  const snmp_callback callback,
318  const void *callback_data = 0);
319 
320  /**
321  * Send a SNMP-TRAP.
322  *
323  * @param pdu - Pdu to send
324  * @param target - Target for the trap
325  *
326  * @return SNMP_CLASS_SUCCES or a negative error code
327  */
328  virtual int trap(Pdu &pdu, const SnmpTarget &target);
329 
330 
331  /**
332  * Send a SNMPv3-REPORT.
333  *
334  * @param pdu - Pdu to send
335  * @param target - Target for the report (must be a UTarget)
336  *
337  * @return SNMP_CLASS_SUCCES or a negative error code
338  */
339  virtual int report(Pdu &pdu, const SnmpTarget &target);
340 
341  /**
342  * Send a blocking INFORM-REQ.
343  *
344  * @param pdu - Pdu to send
345  * @param target - Target for the inform
346  *
347  * @return SNMP_CLASS_SUCCES or a negative error code
348  */
349  virtual int inform(Pdu &pdu, const SnmpTarget &target);
350 
351  /**
352  * Send a async INFORM-REQ.
353  *
354  * @param pdu - Pdu to send
355  * @param target - Target for the inform
356  * @param callback - User callback function to use
357  * @param callback_data - User definable data pointer
358  *
359  * @return SNMP_CLASS_SUCCES or a negative error code
360  */
361  virtual int inform(Pdu &pdu, const SnmpTarget &target,
362  const snmp_callback callback,
363  const void * callback_data = 0);
364 
365  /**
366  * Send a RESPONSE.
367  *
368  * @param pdu - Pdu to send
369  * @param target - Target for the response
370  * @param fd - file descriptor to use, should be the one
371  * that was passed to the callback function
372  *
373  * @return SNMP_CLASS_SUCCES or a negative error code
374  */
375  virtual int response(Pdu &pdu, const SnmpTarget &target,
376  const SnmpSocket fd = INVALID_SOCKET);
377 
378 
379  /**
380  * Send a SNMP Broadcast message.
381  *
382  * This member function sends out a valid SNMP message to a
383  * broadcast address and waits for responses. The source addresses
384  * of the response messages are added to the collection.
385  *
386  * The message is sent only once.
387  *
388  * @note SNMP_BROADCAST has to be defined in config_snmp_pp.h.
389  *
390  * @note There is no SNMP standard that defines "SNMP Broadcast
391  * discovery". SNMP agents are not forced to answer requests
392  * that are sent to a broadcast address.
393  *
394  * @note Do not use this method while waiting for other responses,
395  * as these responses will be added to the collection and dropped
396  * by this method. Solution for this problem: Use a special
397  * Snmp object only for broadcasts.
398  *
399  * @param addresses - The addresses of the agents, that answered.
400  * @param timeout_sec - Timeout in seconds
401  * @param addr - Broadcast address
402  * @param version - SNMP version to use
403  * @param community - Only needed for SNMPv1/v2c, defaults to "public"
404  *
405  */
406  virtual int broadcast_discovery(UdpAddressCollection &addresses,
407  const int timeout_sec,
408  const UdpAddress &addr,
409  const snmp_version version,
410  const OctetStr *community = 0);
411 
412 #ifdef _SNMPv3
413  virtual int engine_id_discovery(OctetStr &engine_id,
414  const int timeout_sec,
415  const UdpAddress &addr);
416 #endif
417  //@}
418 
419  /**
420  * Cancel a pending request.
421  *
422  * @param rid - The request id to cancel
423  *
424  * @return SNMP_CLASS_SUCCES or SNMP_CLASS_INVALID_REQID on failure
425  */
426  virtual int cancel(const unsigned long rid);
427 
428 
429  /** @name Trap and Inform handling
430  */
431  //@{
432 
433  /**
434  * Set the port for listening to traps and informs.
435  *
436  * @note This function must be called before notify_register(),
437  * otherwise the default port is used.
438  */
439  virtual void notify_set_listen_port(const int port);
440 
441  /**
442  * Get the port that is used for listening to traps and informs.
443  */
444  virtual int notify_get_listen_port();
445 
446  /**
447  * Register to get traps and informs.
448  *
449  * @note Every call to one of the notify_register() methods overwrites
450  * the previous given values.
451  *
452  * @param trapids - ids to listen for
453  * @param targets - targets to listen for
454  * @param callback - User callback function to use
455  * @param callback_data - User definable data pointer
456  *
457  * @return SNMP_CLASS_SUCCESS, SNMP_CLASS_TL_FAILED or SNMP_CLASS_TL_IN_USE
458  */
459  virtual int notify_register(const OidCollection &trapids,
460  const TargetCollection &targets,
461  const snmp_callback callback,
462  const void *callback_data=0);
463 
464  /**
465  * Unregister to get traps and informs.
466  * Undo the call to notify_register().
467  *
468  * @return Always SNMP_CLASS_SUCCESS
469  */
470  virtual int notify_unregister();
471 
472  /**
473  * Get notify register info.
474  *
475  * @param trapids - ids listened for
476  * @param targets - targets listened for
477  *
478  * @return SNMP_CLASS_SUCCESS or SNMP_CLASS_INVALID if not registered
479  */
480  virtual int get_notify_filter(OidCollection &trapids,
481  TargetCollection &targets);
482 
483  //-----------------------[ access the trap reception info ]---------------
484  /**
485  * Get a pointer to the callback function used for trap reception.
486  *
487  * @return Pointer to the function set through notify_register()
488  */
489  snmp_callback get_notify_callback() { return notifycallback; };
490 
491  /**
492  * Get a pointer to the data that is passed to the callback function.
493  *
494  * @return Pointer to the data set through notify_register()
495  */
496  void *get_notify_callback_data() { return notifycallback_data; };
497 
498  //@}
499 
500  /**
501  * Send raw UDP data.
502  * This method may be used to send any data to the recepient.
503  *
504  * @param send_buf - Data buffer
505  * @param send_len - Length of the data
506  * @param address - Recepient
507  * @param fd - socket to use, if not specified, the socket of the
508  * object is used
509  *
510  * @return 0 on success, -1 on failure
511  */
512  virtual int send_raw_data(unsigned char *send_buf,
513  size_t send_len, UdpAddress &address,
515 
516  const IpAddress &get_listen_address() const {return listen_address; };
517 
518  /**
519  * Start one thread listening for responses and notifications.
520  * This method is used to start response and notification processing in a
521  * multi threadded setup.
522  *
523  * @note start_poll_thread() itself is not thread safe. The caller must make
524  * sure that only one thread is calling start_poll_thread() or
525  * stop_poll_thread() at any point in time.
526  *
527  * @param timeout - Timeout for each call of the select() or poll()
528  * system call.
529  *
530  * @return true if the thread is now running and false if it failed to start.
531  */
532  bool start_poll_thread(const int timeout);
533 
534  /**
535  * Stop the thread listening for responses and notifications.
536  * This method is used to stop the thread started with start_poll_thread().
537  *
538  * @note stop_poll_thread() itself is not thread safe. The caller must make
539  * sure that only one thread is calling start_poll_thread() or
540  * stop_poll_thread() at any point in time.
541  */
542  void stop_poll_thread();
543 
544  EventListHolder *get_eventListHolder() { return eventListHolder; };
545 
546 protected:
547 
548  /**
549  * Check for the status of the worker thread.
550  * @return BOOL - TRUE - if running, FALSE - otherwise
551  */
552  bool is_running(void) const
553  { return m_bThreadRunning; };
554 
555  /**
556  * This is a working thread for the recovery of the pending events.
557  *
558  * @param pSnmp [in] pointer to the whole object
559  *
560  * @return int
561  * 0 - if succesful,
562  * 1 - in the case of error
563  */
564 #ifdef WIN32
565  static int process_thread(Snmp *pSnmp);
566 #else
567  static void* process_thread(void *arg);
568 #endif
569 
570  protected:
571 
572  /**
573  * Generate a unique (for this Snmp obect) request id.
574  *
575  * @return Unique id between PDU_MIN_RID and PDU_MAX_RID
576  */
577  long MyMakeReqId();
578 
579  /**
580  * Common init function used by constructors.
581  */
582  void init(int& status, IpAddress*[2],
583  const unsigned short port_v4, const unsigned short port_v6);
584 
585  /**
586  * Set the notify timestamp of a trap pdu if the user did not set it.
587  */
588  void check_notify_timestamp(Pdu &pdu);
589 
590  //-----------[ Snmp Engine ]----------------------------------------
591  /**
592  * gets, sets and get nexts go through here....
593  * This mf does all snmp sending and reception
594  * except for traps which are sent using trap().
595  *
596  * @note that for a UTarget with an empty engine id the
597  * Utarget::set_engine_id() may be called.
598  */
599  int snmp_engine( Pdu &pdu, // pdu to use
600  long int non_reps, // get bulk only
601  long int max_reps, // get bulk only
602  const SnmpTarget &target, // destination target
603  const snmp_callback cb, // async callback function
604  const void *cbd, // callback data
606  int reports_received = 0);
607 
608  //--------[ map action ]------------------------------------------------
609  // map the snmp++ action to a SMI pdu type
610  void map_action(unsigned short action, unsigned short &pdu_action);
611 
612 #ifdef _SNMPv3
613  /**
614  * Internal used callback data structure for async v3 requests.
615  */
617  {
618  Pdu *pdu; ///< The Pdu that was sent
619  long int non_reps; ///< For GET-BULK requests
620  long int max_reps; ///< For GET-BULK requests
621  SnmpTarget *target; ///< Pointer to the Target object to use
622  snmp_callback oldCallback; ///< User callback function
623  const void *cbd; ///< User callback data
624  int reports_received; ///< How many reports are already received
625  };
626 
627  friend void v3CallBack(int reason, Snmp *snmp, Pdu &pdu,
628  SnmpTarget &target, void *v3cd);
629  friend void deleteV3Callback(struct Snmp::V3CallBackData *&cbData);
630 #endif
631 
632  //---[ instance variables ]
634 #ifdef SNMP_PP_IPv6
635  SnmpSocket iv_snmp_session_ipv6;
636 #endif
637 
639  long current_rid; // current rid to use
640 
641  // inform receive member variables
644 
645  // this member var will simulate a global var
647 
648 private:
649 
652 
653  // Keep track of the thread.
654 #ifdef _THREADS
655 #ifdef WIN32
656  HANDLE m_hThread;
657  HANDLE m_hThreadEndEvent;
658 #elif defined (CPU) && CPU == PPC603
659  int m_hThread;
660 #else
661  pthread_t m_hThread;
662 #endif
663 #endif
664 };
665 
666 #ifdef SNMP_PP_NAMESPACE
667 } // end of namespace Snmp_pp
668 #endif
669 
670 #endif
Pdu * pdu
The Pdu that was sent.
Definition: uxsnmp.h:618
const void * cbd
User callback data.
Definition: uxsnmp.h:623
bool m_bThreadRunning
Definition: uxsnmp.h:650
EventListHolder * eventListHolder
Definition: uxsnmp.h:646
SnmpTarget * target
Pointer to the Target object to use.
Definition: uxsnmp.h:621
void * get_notify_callback_data()
Get a pointer to the data that is passed to the callback function.
Definition: uxsnmp.h:496
bool is_running(void) const
Check for the status of the worker thread.
Definition: uxsnmp.h:552
long current_rid
Definition: uxsnmp.h:639
SNMP class defintion.
Definition: uxsnmp.h:99
SnmpSocket iv_snmp_session
Definition: uxsnmp.h:633
int m_iPollTimeOut
Definition: uxsnmp.h:651
pthread_t m_hThread
Definition: uxsnmp.h:661
void * notifycallback_data
Definition: uxsnmp.h:643
#define DLLOPT
The Object Identifier Class.
Definition: oid.h:94
The SNMPv3 Message Processing Model (v3MP).
Definition: mp_v3.h:103
long int non_reps
For GET-BULK requests.
Definition: uxsnmp.h:619
snmp_version
The SNMP version to use is passed with this enum.
Definition: target.h:75
#define INVALID_SOCKET
Definition: uxsnmp.h:47
Definition: octet.h:67
snmp_callback notifycallback
Definition: uxsnmp.h:642
Internal used callback data structure for async v3 requests.
Definition: uxsnmp.h:616
IpAddress listen_address
Definition: uxsnmp.h:638
const IpAddress & get_listen_address() const
Definition: uxsnmp.h:516
long int max_reps
For GET-BULK requests.
Definition: uxsnmp.h:620
snmp_callback get_notify_callback()
Get a pointer to the callback function used for trap reception.
Definition: uxsnmp.h:489
int SnmpSocket
snmp_callback oldCallback
User callback function.
Definition: uxsnmp.h:622
int reports_received
How many reports are already received.
Definition: uxsnmp.h:624
static const char * error_msg(const Oid &v3Oid)
Returns a human readable error string.
Definition: uxsnmp.h:192
Pdu class...
Definition: pdu.h:81
void(* snmp_callback)(int reason, Snmp *session, Pdu &pdu, SnmpTarget &target, void *data)
Async methods of the class Snmp require the caller to provide a callback address of a function with t...
Definition: uxsnmp.h:77
Abstract class used to provide a virtual interface into Targets.
Definition: target.h:92
EventListHolder * get_eventListHolder()
Definition: uxsnmp.h:544