SNMP++  3.3.11
oid.h
Go to the documentation of this file.
1 /*_############################################################################
2  _##
3  _## oid.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 /*===================================================================
28 
29  Copyright (c) 1999
30  Hewlett-Packard Company
31 
32  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
33  Permission to use, copy, modify, distribute and/or sell this software
34  and/or its documentation is hereby granted without fee. User agrees
35  to display the above copyright notice and this license notice in all
36  copies of the software and any documentation of the software. User
37  agrees to assume all liability for the use of the software; Hewlett-Packard
38  makes no representations about the suitability of this software for any
39  purpose. It is provided "AS-IS without warranty of any kind,either express
40  or implied. User hereby grants a royalty-free license to any and all
41  derivatives based upon this software code base.
42 
43 
44  SNMP++ O I D. H
45 
46  OID CLASS DEFINITION
47 
48  DESIGN + AUTHOR: Peter E Mellquist
49 
50  DESCRIPTION:
51  This class is fully contained and does not rely on or any other
52  SNMP libraries. This class is portable across any platform
53  which supports C++.
54 
55 =====================================================================*/
56 // $Id$
57 
58 #ifndef _SNMP_OID_H_
59 #define _SNMP_OID_H_
60 
61 #include <libsnmp.h>
62 #include "snmp_pp/smival.h"
63 #include "snmp_pp/collect.h"
64 
65 #ifdef SNMP_PP_NAMESPACE
66 namespace Snmp_pp {
67 #endif
68 
69 /**
70  * The Object Identifier Class.
71  *
72  * The Object Identification (Oid) class is the encapsulation of an
73  * SMI object identifier. The SMI object is a data identifier for a
74  * data element found in a Management Information Base (MIB), as
75  * defined by a MIB definition. The SMI Oid, its related structures
76  * and functions, are a natural fit for object orientation. In fact,
77  * the Oid class shares many common features to the C++ String
78  * class. For those of you familiar with the C++ String class or
79  * Microsoft's Foundation Classes (MFC) CString class, the Oid class
80  * will be familiar and easy to use. The Oid class is designed to be
81  * efficient and fast. The Oid class allows definition and
82  * manipulation of object identifiers.
83  *
84  * @note Oid holds two internal buffers for get_printable() functions.
85  * The buffer returned by get_printable() is valid until the
86  * Oid object is modified. The functions get_printable(len) and
87  * get_printable(start, len) share the same buffer which is
88  * freed and newly allocated for each call.
89  */
90 class DLLOPT Oid : public SnmpSyntax
91 {
92  public:
93 
94  /**
95  * Construct an invalid Oid.
96  */
97  Oid()
98  : iv_str(0), iv_part_str(0), m_changed(true)
99  {
100  smival.syntax = sNMP_SYNTAX_OID;
101  smival.value.oid.len = 0;
102  smival.value.oid.ptr = 0;
103  }
104 
105  /**
106  * Construct an Oid from a string.
107  *
108  * Depending on the second param, the oid_string can either be
109  * - a dotted oid string (like "1.3.6.1.6"). An arbitrary part
110  * of the oid can be given as a string value enclosed in
111  * '$' characters. For example the oid string
112  * "1.3.6.1.6.1.12.1.3.$public_0$" will result to the oid
113  * 1.3.6.1.6.1.12.1.3.112.117.98.108.105.99.95.48
114  * - a normal string (like "public"). The Oid will have the
115  * ASCII values of the string characters. So "public" will
116  * result to the oid 112.117.98.108.105.99
117  *
118  * @param oid_string - for example "1.3.1.6.1.10"
119  * @param is_dotted_oid_string - Select format within oid_string
120  */
121  Oid(const char *oid_string, const bool is_dotted_oid_string = true);
122 
123  /**
124  * Constructor using another oid object (copy constructor).
125  *
126  * @param oid - Source Oid
127  */
128  Oid(const Oid &oid)
129  : iv_str(0), iv_part_str(0), m_changed(true)
130  {
131  smival.syntax = sNMP_SYNTAX_OID;
132  smival.value.oid.len = 0;
133  smival.value.oid.ptr = 0;
134 
135  // allocate some memory for the oid
136  // in this case the size to allocate is the same size as the source oid
137  if (oid.smival.value.oid.len)
138  {
139  smival.value.oid.ptr = (SmiLPUINT32) new unsigned long[oid.smival.value.oid.len];
140  if (smival.value.oid.ptr)
141  OidCopy((SmiLPOID)&(oid.smival.value.oid), (SmiLPOID)&smival.value.oid);
142  }
143  }
144 
145  /**
146  * Constructor from array.
147  *
148  * @param raw_oid - array of oid values
149  * @param oid_len - length of array
150  */
151  Oid(const unsigned long *raw_oid, int oid_len)
152  : iv_str(0), iv_part_str(0), m_changed(true)
153  {
154  smival.syntax = sNMP_SYNTAX_OID;
155  smival.value.oid.len = 0;
156  smival.value.oid.ptr = 0;
157 
158  if (raw_oid && (oid_len > 0))
159  {
160  smival.value.oid.ptr = (SmiLPUINT32) new unsigned long[oid_len];
161  if (smival.value.oid.ptr)
162  {
163  smival.value.oid.len = oid_len;
164  for (int i=0; i < oid_len; i++)
165  smival.value.oid.ptr[i] = raw_oid[i];
166  }
167  }
168  }
169 
170  /**
171  * Destructor.
172  */
173  virtual ~Oid()
174  {
175  delete_oid_ptr();
176  if (iv_str) delete [] iv_str; // free up the output string
177  if (iv_part_str) delete [] iv_part_str; // free up the output string
178  }
179 
180  /**
181  * Return the current syntax.
182  *
183  * @return always sNMP_SYNTAX_OID
184  */
186 
187  /**
188  * Assignment from a string.
189  *
190  * @param dotted_oid_string - New value (for example "1.3.6.1.6.0");
191  */
192  virtual Oid& operator=(const char *dotted_oid_string);
193 
194  /**
195  * Assign one Oid to another.
196  */
197  virtual Oid& operator=(const Oid &oid)
198  {
199  if (this == &oid) return *this; // protect against assignment from self
200 
201  delete_oid_ptr();
202 
203  // check for zero len on source
204  if (oid.smival.value.oid.len == 0)
205  return *this;
206 
207  // allocate some memory for the oid
208  smival.value.oid.ptr = (SmiLPUINT32) new unsigned long[oid.smival.value.oid.len];
209  if (smival.value.oid.ptr)
210  OidCopy((SmiLPOID)&(oid.smival.value.oid), (SmiLPOID)&smival.value.oid);
211  return *this;
212  }
213 
214  /**
215  * Return the space needed for serialization.
216  */
217  int get_asn1_length() const;
218 
219  /**
220  * Overloaded equal operator.
221  */
222  bool operator == (const Oid &rhs) const
223  {
224  // ensure same len, then use nCompare
225  if (len() != rhs.len())
226  return 0;
227  return (nCompare(rhs) == 0);
228  }
229 
230  /**
231  * Overloaded not equal operator.
232  */
233  bool operator != (const Oid &rhs) const
234  { return (!(*this == rhs)); } // just invert ==
235 
236  /**
237  * Overloaded less than < operator.
238  */
239  bool operator < (const Oid &rhs) const
240  {
241  int result;
242  // call nCompare with the current
243  // Oidx, Oidy and len of Oidx
244  if((result = nCompare(rhs))<0) return 1;
245  if (result > 0) return 0;
246 
247  // if here, equivalent substrings, call the shorter one <
248  return (len() < rhs.len());
249  }
250 
251  /**
252  * Overloaded less than <= operator.
253  */
254  bool operator <= (const Oid &rhs) const
255  { return ((*this < rhs) || (*this == rhs)); }
256 
257  /**
258  * Overloaded greater than > operator.
259  */
260  bool operator > (const Oid &rhs) const
261  { return (!(*this <= rhs)); } // just invert existing <=
262 
263  /**
264  * Overloaded greater than >= operator.
265  */
266  bool operator >= (const Oid &rhs) const
267  { return (!(*this < rhs)); } // just invert existing <
268 
269  /**
270  * Overloaded operator +, Concatenate two Oids.
271  */
272  DLLOPT friend Oid operator +(const Oid &lhs, const Oid &rhs)
273  { Oid tmp(lhs); tmp += rhs; return tmp;}
274 
275  /**
276  * Append operator, appends the dotted oid string.
277  *
278  * @param a - dotted oid string, for example "5.192.14.6"
279  */
280  Oid& operator+=(const char *a);
281 
282  /**
283  * Appends an int.
284  *
285  * @param i - Value to add at the end of the Oid
286  */
287  Oid& operator+=(const unsigned long i)
288  {
289  Oid other(&i, 1);
290  (*this) += other;
291  return *this;
292  }
293 
294  /**
295  * Appends an Oid.
296  *
297  * @param o - Oid to add at the end
298  */
299  Oid& operator+=(const Oid &o)
300  {
301  SmiLPUINT32 new_oid;
302 
303  if (o.smival.value.oid.len == 0)
304  return *this;
305 
306  new_oid = (SmiLPUINT32) new unsigned long[smival.value.oid.len + o.smival.value.oid.len];
307  if (new_oid == 0)
308  {
309  delete_oid_ptr();
310  return *this;
311  }
312 
313  if (smival.value.oid.ptr)
314  {
315  MEMCPY((SmiLPBYTE) new_oid,
316  (SmiLPBYTE) smival.value.oid.ptr,
317  (size_t) (smival.value.oid.len*sizeof(SmiUINT32)));
318 
319  delete [] smival.value.oid.ptr;
320  }
321 
322  // out with the old, in with the new...
323  smival.value.oid.ptr = new_oid;
324 
325  MEMCPY((SmiLPBYTE) &new_oid[smival.value.oid.len],
327  (size_t) (o.smival.value.oid.len*sizeof(SmiUINT32)));
328 
329  smival.value.oid.len += o.smival.value.oid.len;
330 
331  m_changed = true;
332  return *this;
333  }
334 
335  /**
336  * Allows element access as an array.
337  * This method behaves like real array: if your index
338  * is out of bounds, you're lost!
339  *
340  * @param index - valid index -- 0 to (len() - 1)
341  *
342  * @return Value on the given index
343  */
344  unsigned long &operator[](const unsigned int index)
345  { m_changed = true; return smival.value.oid.ptr[index]; }
346 
347  /**
348  * Allows element access as an array for const objects.
349  * This method behaves like real array: if your index
350  * is out of bounds, you're lost!
351  *
352  * @param index - valid index -- 0 to (len() - 1)
353  *
354  * @return Value on the given position
355  */
356  unsigned long operator[](const unsigned int index) const
357  { return (index >= len()) ? 0 : smival.value.oid.ptr[index]; }
358 
359  /**
360  * Get the WinSnmp oid part.
361  * @note This method returns a pointer to internal data.
362  * If it is modified, the Oid changes too.
363  *
364  * @return pointer to the internal oid structure.
365  */
366  SmiLPOID oidval() { return (SmiLPOID) &smival.value.oid; }
367 
368  /**
369  * Set the data from raw form.
370  *
371  * @param raw_oid - Array of new values
372  * @param oid_len - Length of the array raw_oid
373  */
374  void set_data(const unsigned long *raw_oid, const unsigned int oid_len);
375 
376  /**
377  * Set the data from raw form.
378  *
379  * @param str - Array of new values (a string)
380  * @param str_len - Length of the array raw_oid
381  */
382  void set_data(const char *str, const unsigned int str_len);
383 
384  /**
385  * Get the length of the oid.
386  */
387  unsigned long len() const { return smival.value.oid.len; }
388 
389  /**
390  * Trim off the rightmost values of an oid.
391  *
392  * @param n - Trim off n values from the right (default is one)
393  */
394  void trim(const unsigned long n = 1)
395  {
396  // verify that n is legal
397  if ((n <= smival.value.oid.len) && (n > 0))
398  {
399  smival.value.oid.len -= n;
400  if (smival.value.oid.len == 0)
401  delete_oid_ptr();
402  m_changed = true;
403  }
404  }
405 
406  /**
407  * Compare two Oids from the left in direction left-to-right.
408  *
409  * @param n - Subvalues to compare
410  * @param o - The Oid to compare with
411  *
412  * @return 0 if equal / -1 if less / 1 if greater
413  */
414  int nCompare(const unsigned long n, const Oid &o) const
415  {
416  unsigned long length = n;
417  bool reduced_len = false;
418 
419  // If both oids are too short, decrease len
420  if ((smival.value.oid.len < length) && (o.smival.value.oid.len < length))
421  length = smival.value.oid.len < o.smival.value.oid.len ? o.smival.value.oid.len : smival.value.oid.len;
422 
423  if (length == 0) return 0; // equal
424 
425  // only compare for the minimal length
426  if (length > smival.value.oid.len)
427  {
428  length = smival.value.oid.len;
429  reduced_len = true;
430  }
431  if (length > o.smival.value.oid.len)
432  {
433  length = o.smival.value.oid.len;
434  reduced_len = true;
435  }
436 
437  unsigned long z = 0;
438  while (z < length)
439  {
440  if (smival.value.oid.ptr[z] < o.smival.value.oid.ptr[z])
441  return -1; // less than
442  if (smival.value.oid.ptr[z] > o.smival.value.oid.ptr[z])
443  return 1; // greater than
444  ++z;
445  }
446 
447  // if we truncated the len then these may not be equal
448  if (reduced_len)
449  {
450  if (smival.value.oid.len < o.smival.value.oid.len) return -1;
451  if (smival.value.oid.len > o.smival.value.oid.len) return 1;
452  }
453  return 0; // equal
454  }
455 
456  /**
457  * Compare two Oids from the left in direction left-to-right.
458  *
459  * @param o - The Oid to compare with
460  *
461  * @return 0 if equal / -1 if less / 1 if greater
462  */
463  int nCompare(const Oid &o) const
464  {
465  unsigned long length;
466  bool reduced_len = false;
467 
468  length = smival.value.oid.len < o.smival.value.oid.len ? o.smival.value.oid.len : smival.value.oid.len;
469 
470  if (length == 0) return 0; // equal
471 
472  // only compare for the minimal length
473  if (length > smival.value.oid.len)
474  {
475  length = smival.value.oid.len;
476  reduced_len = true;
477  }
478  if (length > o.smival.value.oid.len)
479  {
480  length = o.smival.value.oid.len;
481  reduced_len = true;
482  }
483 
484  unsigned long z = 0;
485  while (z < length)
486  {
487  if (smival.value.oid.ptr[z] < o.smival.value.oid.ptr[z])
488  return -1; // less than
489  if (smival.value.oid.ptr[z] > o.smival.value.oid.ptr[z])
490  return 1; // greater than
491  ++z;
492  }
493 
494  // if we truncated the len then these may not be equal
495  if (reduced_len)
496  {
497  if (smival.value.oid.len < o.smival.value.oid.len) return -1;
498  if (smival.value.oid.len > o.smival.value.oid.len) return 1;
499  }
500  return 0; // equal
501  }
502 
503  /**
504  * Return validity of the object.
505  */
506  bool valid() const { return (smival.value.oid.ptr ? true : false); }
507 
508  /**
509  * Get a printable ASCII string of the whole value.
510  *
511  * @return Dotted oid string (for example "1.3.6.1.6.0")
512  */
513  const char *get_printable() const
514  { return get_printable(1, smival.value.oid.len, (char*&)iv_str); };
515 
516  /**
517  * Get a printable ASCII string of the right part of the value.
518  *
519  * @param n - positions to print, counted from right.
520  *
521  * @return Dotted oid string (for example "6.0")
522  */
523  const char *get_printable(const unsigned long n) const
524  { return get_printable(smival.value.oid.len - n + 1, n, (char*&)iv_part_str); };
525 
526  /**
527  * Get a printable ASCII string of a part of the value.
528  *
529  * @param start - First position to print, starting with 1 (not zero!)
530  * @param n - positions to print.
531  * @param buffer - pointer to the returned buffer
532  *
533  * @note If buffer is not NULL, this function calls "delete [] buffer",
534  * a new buffer is allocated using "new" and the caller has
535  * to delete it.
536  *
537  * @return Dotted oid string (for example "3.6.1.6")
538  */
539  const char *get_printable(const unsigned long start,
540  const unsigned long n,
541  char *&buffer) const;
542 
543  /**
544  * Get a printable ASCII string of a part of the value.
545  *
546  * @param start - First position to print, starting with 1 (not zero!)
547  * @param n - positions to print.
548  *
549  * @return Dotted oid string (for example "3.6.1.6")
550  */
551  const char *get_printable(const unsigned long start,
552  const unsigned long n) const
553  { return get_printable(start, n, (char*&)iv_part_str); };
554 
555  /**
556  * Clone this object.
557  *
558  * @return Pointer to the newly created object (allocated through new).
559  */
560  SnmpSyntax *clone() const { return (SnmpSyntax *) new Oid(*this); }
561 
562  /**
563  * Map other SnmpSyntax objects to Oid.
564  */
565  SnmpSyntax& operator=(const SnmpSyntax &val);
566 
567  /**
568  * Clear the Oid.
569  */
570  void clear() { delete_oid_ptr(); }
571 
572  protected:
573  /**
574  * Convert a string to an smi oid.
575  *
576  * @param string - input string
577  * @param dstOid - destination oid
578  */
579  virtual int StrToOid(const char *string, SmiLPOID dstOid) const;
580 
581  /**
582  * Clone an smi oid.
583  *
584  * @param srcOid - source oid
585  * @param dstOid - destination oid
586  */
587  virtual int OidCopy(SmiLPOID srcOid, SmiLPOID dstOid) const
588  {
589  // check source len ! zero
590  if (srcOid->len == 0) return -1;
591 
592  // copy source to destination
593  MEMCPY((SmiLPBYTE) dstOid->ptr,
594  (SmiLPBYTE) srcOid->ptr,
595  (size_t) (srcOid->len*sizeof(SmiUINT32)));
596 
597  //set the new len
598  dstOid->len = srcOid->len;
599  return (int) srcOid->len;
600  }
601 
602  /**
603  * Convert an smi oid to its string representation.
604  *
605  * @param srcOid - source oid
606  * @param size - size of string
607  * @param string - pointer to string
608  */
609  virtual int OidToStr(const SmiOID *srcOid,
610  SmiUINT32 size,
611  char *string) const;
612 
613  /**
614  * Free the internal oid pointer and set the pointer and the length to zero.
615  */
616  inline void delete_oid_ptr();
617 
618  //----[ instance variables ]
619 
620  SNMP_PP_MUTABLE char *iv_str; // used for returning complete oid string
621  SNMP_PP_MUTABLE char *iv_part_str; // used for returning part oid string
623 };
624 
625 //-----------[ End Oid Class ]-------------------------------------
626 
627 // create OidCollection type
629 
630 inline void Oid::delete_oid_ptr()
631 {
632  // delete the old value
633  if (smival.value.oid.ptr)
634  {
635  delete [] smival.value.oid.ptr;
636  smival.value.oid.ptr = 0;
637  }
638  smival.value.oid.len = 0;
639  m_changed = true;
640 }
641 
642 #ifdef SNMP_PP_NAMESPACE
643 } // end of namespace Snmp_pp
644 #endif
645 
646 #endif // _SNMP_OID_H_
void delete_oid_ptr()
Free the internal oid pointer and set the pointer and the length to zero.
Definition: oid.h:630
int nCompare(const unsigned long n, const Oid &o) const
Compare two Oids from the left in direction left-to-right.
Definition: oid.h:414
unsigned long SmiUINT32
Definition: smi.h:157
SmiVALUE smival
Definition: smival.h:175
SmiUINT32 len
Definition: smi.h:169
Oid(const unsigned long *raw_oid, int oid_len)
Constructor from array.
Definition: oid.h:151
#define SNMP_PP_MUTABLE
void clear()
Clear the Oid.
Definition: oid.h:570
#define sNMP_SYNTAX_OID
Definition: smi.h:104
SmiOID oid
Definition: smival.h:100
SmiLPUINT32 ptr
Definition: smi.h:170
virtual int OidCopy(SmiLPOID srcOid, SmiLPOID dstOid) const
Clone an smi oid.
Definition: oid.h:587
bool valid() const
Return validity of the object.
Definition: oid.h:506
void trim(const unsigned long n=1)
Trim off the rightmost values of an oid.
Definition: oid.h:394
SNMP_PP_MUTABLE char * iv_part_str
Definition: oid.h:621
unsigned long operator[](const unsigned int index) const
Allows element access as an array for const objects.
Definition: oid.h:356
#define DLLOPT
The Object Identifier Class.
Definition: oid.h:90
SnmpCollection< Oid > OidCollection
Definition: oid.h:628
SNMP_PP_MUTABLE char * iv_str
Definition: oid.h:620
Oid(const Oid &oid)
Constructor using another oid object (copy constructor).
Definition: oid.h:128
unsigned long WINFAR * SmiLPUINT32
Definition: smi.h:157
SnmpSyntax * clone() const
Clone this object.
Definition: oid.h:560
Oid & operator+=(const Oid &o)
Appends an Oid.
Definition: oid.h:299
const char * get_printable(const unsigned long n) const
Get a printable ASCII string of the right part of the value.
Definition: oid.h:523
union SmiVALUE::@1 value
unsigned long len() const
Get the length of the oid.
Definition: oid.h:387
SmiUINT32 get_syntax() const
Return the current syntax.
Definition: oid.h:185
const char * get_printable() const
Get a printable ASCII string of the whole value.
Definition: oid.h:513
Oid()
Construct an invalid Oid.
Definition: oid.h:97
SNMP_PP_MUTABLE bool m_changed
Definition: oid.h:622
int nCompare(const Oid &o) const
Compare two Oids from the left in direction left-to-right.
Definition: oid.h:463
unsigned char WINFAR * SmiLPBYTE
Definition: smi.h:148
SmiLPOID oidval()
Get the WinSnmp oid part.
Definition: oid.h:366
virtual ~Oid()
Destructor.
Definition: oid.h:173
unsigned long & operator[](const unsigned int index)
Allows element access as an array.
Definition: oid.h:344
virtual Oid & operator=(const Oid &oid)
Assign one Oid to another.
Definition: oid.h:197
#define MEMCPY
Definition: smi.h:65
An "abstract" (pure virtual) class that serves as the base class for all specific SNMP syntax types...
Definition: smival.h:117
const char * get_printable(const unsigned long start, const unsigned long n) const
Get a printable ASCII string of a part of the value.
Definition: oid.h:551
Oid & operator+=(const unsigned long i)
Appends an int.
Definition: oid.h:287
Definition: smi.h:168
unsigned long oid
Definition: asn1.h:41