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