summaryrefslogtreecommitdiff
path: root/ACE/ASNMP/asnmp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ASNMP/asnmp')
-rw-r--r--ACE/ASNMP/asnmp/ASNMP_Export.h58
-rw-r--r--ACE/ASNMP/asnmp/ChangeLog227
-rw-r--r--ACE/ASNMP/asnmp/Makefile.am66
-rw-r--r--ACE/ASNMP/asnmp/TODO25
-rw-r--r--ACE/ASNMP/asnmp/address.cpp2705
-rw-r--r--ACE/ASNMP/asnmp/address.h845
-rw-r--r--ACE/ASNMP/asnmp/asn1.cpp1729
-rw-r--r--ACE/ASNMP/asnmp/asn1.h345
-rw-r--r--ACE/ASNMP/asnmp/asnmp.mpc26
-rw-r--r--ACE/ASNMP/asnmp/counter.cpp107
-rw-r--r--ACE/ASNMP/asnmp/counter.h79
-rw-r--r--ACE/ASNMP/asnmp/ctr64.cpp213
-rw-r--r--ACE/ASNMP/asnmp/ctr64.h111
-rw-r--r--ACE/ASNMP/asnmp/enttraps.h147
-rw-r--r--ACE/ASNMP/asnmp/gauge.cpp114
-rw-r--r--ACE/ASNMP/asnmp/gauge.h79
-rw-r--r--ACE/ASNMP/asnmp/integer.cpp230
-rw-r--r--ACE/ASNMP/asnmp/integer.h142
-rw-r--r--ACE/ASNMP/asnmp/octet.cpp594
-rw-r--r--ACE/ASNMP/asnmp/octet.h152
-rw-r--r--ACE/ASNMP/asnmp/oid.cpp803
-rw-r--r--ACE/ASNMP/asnmp/oid.h175
-rw-r--r--ACE/ASNMP/asnmp/oid_def.h84
-rw-r--r--ACE/ASNMP/asnmp/pdu.cpp499
-rw-r--r--ACE/ASNMP/asnmp/pdu.h219
-rw-r--r--ACE/ASNMP/asnmp/sagent.cpp97
-rw-r--r--ACE/ASNMP/asnmp/sagent.h82
-rw-r--r--ACE/ASNMP/asnmp/smi.h147
-rw-r--r--ACE/ASNMP/asnmp/smival.h102
-rw-r--r--ACE/ASNMP/asnmp/snmp.cpp286
-rw-r--r--ACE/ASNMP/asnmp/snmp.h137
-rw-r--r--ACE/ASNMP/asnmp/snmperrs.h210
-rw-r--r--ACE/ASNMP/asnmp/target.cpp321
-rw-r--r--ACE/ASNMP/asnmp/target.h260
-rw-r--r--ACE/ASNMP/asnmp/timetick.cpp144
-rw-r--r--ACE/ASNMP/asnmp/timetick.h85
-rw-r--r--ACE/ASNMP/asnmp/transaction.cpp207
-rw-r--r--ACE/ASNMP/asnmp/transaction.h83
-rw-r--r--ACE/ASNMP/asnmp/transaction_result.h26
-rw-r--r--ACE/ASNMP/asnmp/vb.cpp399
-rw-r--r--ACE/ASNMP/asnmp/vb.h207
-rw-r--r--ACE/ASNMP/asnmp/wpdu.cpp521
-rw-r--r--ACE/ASNMP/asnmp/wpdu.h84
43 files changed, 13172 insertions, 0 deletions
diff --git a/ACE/ASNMP/asnmp/ASNMP_Export.h b/ACE/ASNMP/asnmp/ASNMP_Export.h
new file mode 100644
index 00000000000..e4c9898f3f5
--- /dev/null
+++ b/ACE/ASNMP/asnmp/ASNMP_Export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl ASNMP
+// ------------------------------
+#ifndef ASNMP_EXPORT_H
+#define ASNMP_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (ASNMP_HAS_DLL)
+# define ASNMP_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && ! ASNMP_HAS_DLL */
+
+#if !defined (ASNMP_HAS_DLL)
+# define ASNMP_HAS_DLL 1
+#endif /* ! ASNMP_HAS_DLL */
+
+#if defined (ASNMP_HAS_DLL) && (ASNMP_HAS_DLL == 1)
+# if defined (ASNMP_BUILD_DLL)
+# define ASNMP_Export ACE_Proper_Export_Flag
+# define ASNMP_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define ASNMP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* ASNMP_BUILD_DLL */
+# define ASNMP_Export ACE_Proper_Import_Flag
+# define ASNMP_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define ASNMP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* ASNMP_BUILD_DLL */
+#else /* ASNMP_HAS_DLL == 1 */
+# define ASNMP_Export
+# define ASNMP_SINGLETON_DECLARATION(T)
+# define ASNMP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* ASNMP_HAS_DLL == 1 */
+
+// Set ASNMP_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (ASNMP_NTRACE)
+# if (ACE_NTRACE == 1)
+# define ASNMP_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define ASNMP_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !ASNMP_NTRACE */
+
+#if (ASNMP_NTRACE == 1)
+# define ASNMP_TRACE(X)
+#else /* (ASNMP_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define ASNMP_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (ASNMP_NTRACE == 1) */
+
+#endif /* ASNMP_EXPORT_H */
+
+// End of auto generated file.
diff --git a/ACE/ASNMP/asnmp/ChangeLog b/ACE/ASNMP/asnmp/ChangeLog
new file mode 100644
index 00000000000..8d82c1aa36c
--- /dev/null
+++ b/ACE/ASNMP/asnmp/ChangeLog
@@ -0,0 +1,227 @@
+Wed Jan 4 22:50:09 UTC 2006 J.T. Conklin <jtc@acorntoolworks.com>
+
+ * ChangeLog:
+
+ Untabify.
+ Delete-trailing-whitespace.
+
+ Added "Local Variables" section defining "add-log-time-format"
+ to a really ugly lambda expression that formats changelog
+ timestamps in UTC and works with both GNU Emacs and XEmacs.
+
+Fri May 7 11:40:25 2004 Ossama Othman <ossama@dre.vanderbilt.edu>
+
+ * pdu.cpp (agent_error_reason):
+
+ Really fixed mismatched sprintf() format specifiers this time
+ around.
+
+Thu May 6 11:13:25 2004 Ossama Othman <ossama@dre.vanderbilt.edu>
+
+ * oid.cpp (operator+=, OidToStr):
+ * pdu.cpp (agent_error_reason):
+
+ Fixed warnings regarding mismatch format specifiers and
+ arguments to sprintf().
+
+Thu May 6 11:05:01 2004 Ossama Othman <ossama@dre.vanderbilt.edu>
+
+ * gauge.h:
+
+ Nuked trailing white space.
+
+Fri Apr 23 11:23:21 2004 Ossama Othman <ossama@dre.vanderbilt.edu>
+
+ * oid.cpp:
+
+ Missed some bool return types for equality operators.
+
+Thu Apr 22 23:03:48 2004 Ossama Othman <ossama@dre.vanderbilt.edu>
+
+ * address.cpp:
+ * address.h:
+ * octet.cpp:
+ * octet.h:
+ * oid.cpp:
+ * oid.h:
+ * target.cpp:
+ * target.h:
+ * vb.cpp:
+ * vb.h:
+
+ Changed all return types for equality, relational and logical
+ operators to "bool", as is the norm for modern C++.
+
+Fri Aug 29 07:57:05 2003 Ossama Othman <ossama@dre.vanderbilt.edu>
+
+ * octet.cpp (to_string_hex):
+
+ Fixed "string literal converted to char *" warning. String
+ literals are now considered "const" by standard C++.
+
+Tue Mar 16 16:28:14 1999 David L. Levine <levine@cs.wustl.edu>
+
+ * address.cpp, address.h, asn1.cpp, asn1.h, counter.cpp, ctr64.cpp,
+ gauge.cpp, integer.cpp, octet.cpp, oid.cpp, pdu.cpp, sagent.cpp,
+ snmp.cpp, target.cpp, timetick.cpp, transaction.cpp, vb.cpp,
+ wpdu.cpp:
+ replaced TRUE with 1, and FALSE and NULL with 0. Thanks to
+ Achint Sandhu <sandhu@nortelnetworks.com> for reporting that
+ TRUE and FALSE weren't define on his Linux platform.
+
+ * wpdu.cpp (set_trap_info): wrapped condition with () to
+ avoid g++ warning about using result of an assignment as
+ the condition.
+
+ * ctr64.cpp: made MAX64 unsigned, to avoid warning about it
+ being to big to be signed.
+
+Wed Jul 15 20:27:23 1998 Mike MacFaden <mrm@tango.cs.wustl.edu>
+ * asn1.cpp - Hien Nguyen <hnguyen@apexgrp.com> fixed these bugs:
+
+ Problem: The V1 trap agent-addr field tag value is OCTET STRING
+ instead of IPADDRESS, and the time stamp field tag value is INTEGER
+ instead of TIME TICKS.
+
+ Fix: Change cmu_snmp::build() to pass in the correct type for agent-addr
+ and time stamp.
+
+ 2. Problem: The V1 trap enterprise OID is corrupted after is was set in
+ wpdu constructor.
+
+ Fix: In wpdu::set_trap_info(), the raw_pdu enterprise OID pointer was
+ assigned to the raw data of an enterprise Oid object on the stack.
+ Changed to perform an ACE_NEW_RETURN on the raw_pdu->enterprise and
+ perform a memcpy to copy the OID. The allocated memory is freed in
+ cmu_snmp::free_pdu() as currently implemented.
+
+ 3. The V1 trap agent-addr field is currently initialized to "0.0.0.0".
+ I changed wpdu::set_trap_info to initialize it to the local host IP
+ Address.
+
+ 4. I noticed that the memory allocation for OID in asn1.cpp using
+ ACE_NEW consistently use (OID length * size(oid)) as the size.
+ Shouldn't it be simply OID length ? Since there are numerous instances
+ of this usage in asn1.cpp, I have not fixed those. If you can double
+ check and fix these, I appreciate it.
+
+
+Wed Aug 20 15:11:23 1997 Mike MacFaden <mrm@tango.cs.wustl.edu>
+
+ * rebuilt Makefile using g++dep
+
+ * pdu.h pdu.cpp initialization errors fixed
+
+ * address.h address.cpp IpAddress::to_octet() added
+
+Fri Aug 1 19:23:52 1997 Mike MacFaden (mrm@mrm-ss20)
+
+ * NOTES: This first version only tested on Solaris 2.5
+
+ * review classes for thread safety. Current thread design only
+ allows for one thread to safely access any ASNMP object created.
+
+ * run purify test of get routine no -memory leaks.
+
+ * verify both shared archive/static archive types work with
+ example programs
+
+ * << Globals Changes >>
+
+ * tested only archiver library version
+
+ * reformat code to use one brace style.
+
+ * changed all manifest constants defined as _XX to XX_ to stay out
+ of compiler namespace
+
+ * change all OS calls to use ACE_OS:: portability layer, #include
+ <ace/OS.h>
+
+ * reformat code to use one consistent brace layout and redo
+ header using ACE
+
+ * remove semicolons on member functions foo{}; - not necessary
+
+ * make get() methods const member functions
+
+ * removed unnecessary casts that looked like this: and revamped
+ all memory allocations via ACE_NEW macro
+
+ new_oid = (SmiLPUINT32) new unsigned long [ smival.value.oid.len
+
+ To
+
+ ACE_NEW(new_oid, SmiUINT32[ smival.value.oid.len])
+
+ * Collapsed default constructors with constructors to constructors
+ with default arguments.
+
+ * removed unused #include <iostream.h>
+
+ * Added ACE_TRACE() to classes
+
+ * change get_printable() to to_string() - there will be more java
+ programmers in the future so this should be the first step...
+
+ * removed ASYNC interface till it can be rebuilt using ACE patterns
+
+ * Attempt to make interface more type strict but leaving generic
+ interfaces as escape hatch. Example: CTarget becomes UdpTarget
+ for UDP/IP based agents.
+
+ * << Class Specific Changes >>
+
+ * Oid class:
+ - remove char * routines, simplify class
+ - added suboid method and removed get_printable() overloads
+
+ * CTarget class:
+ - renamed to UdpTarget. Stay out of Microsoft Namespace per MSJ
+ Article by Allen Hollub.
+
+ * Varbind class:
+ - remove generic set_value for char,int, etc. Too easy to get
+ this wrong. Allow just types defined.
+ - added overload for equality operator (==)
+ - added new constructor to allow setting full vb state oid,value, exception
+ - add to_string()
+
+ * Address class:
+ - change manifest constants to enums for address lengths, add IP V6 lens
+
+ - add a netbios name class, still pretty worthless since I don't have spec
+ in front of me yet...
+
+ - rewrite resolver calls to be thread safe and cleaner by moving to two
+ class (static) member functions:
+
+ // thread safe routine to lookup ip address given hostname
+ // return <> 0 on error
+ static int resolve_to_addr(const char *hostname, in_addr& quad_addr);
+
+ // thread safe routine to lookup name given ip address
+ // return <> 0 on error
+ static int resolve_to_hostname(const in_addr& quad_addr, char *hostname)
+
+ * added some interrogation routines to class IpAddress:
+ is_loopback() const;
+
+ * Ctr64 class:
+ - added constructor using long long datatype (needs to be made
+ portable to NT
+
+ * Pdu class: add to_string()
+
+ * Classes added wpdu class:
+ - a new adpater class between CMU and HP pdu, varbind data structures
+
+ * transaction class:
+ - implement get/getnext timeout and retry logic using ACE
+ Reactor class, ACE_Time_Value
+
+Local Variables:
+mode: change-log
+add-log-time-format: (lambda () (progn (setq tz (getenv "TZ")) (set-time-zone-rule "UTC") (setq time (format-time-string "%a %b %e %H:%M:%S %Z %Y" (current-time))) (set-time-zone-rule tz) time))
+indent-tabs-mode: nil
+End:
diff --git a/ACE/ASNMP/asnmp/Makefile.am b/ACE/ASNMP/asnmp/Makefile.am
new file mode 100644
index 00000000000..71347a6d858
--- /dev/null
+++ b/ACE/ASNMP/asnmp/Makefile.am
@@ -0,0 +1,66 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu
+
+ACE_BUILDDIR = $(top_builddir)
+ACE_ROOT = $(top_srcdir)
+
+## Makefile.asnmp_lib.am
+
+noinst_LTLIBRARIES = libasnmp.la
+
+libasnmp_la_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(ACE_ROOT)/ASNMP \
+ -DASNMP_BUILD_DLL
+
+libasnmp_la_SOURCES = \
+ address.cpp \
+ asn1.cpp \
+ counter.cpp \
+ ctr64.cpp \
+ gauge.cpp \
+ integer.cpp \
+ octet.cpp \
+ oid.cpp \
+ pdu.cpp \
+ sagent.cpp \
+ snmp.cpp \
+ target.cpp \
+ timetick.cpp \
+ transaction.cpp \
+ vb.cpp \
+ wpdu.cpp
+
+noinst_HEADERS = \
+ address.h \
+ asn1.h \
+ counter.h \
+ ctr64.h \
+ gauge.h \
+ integer.h \
+ octet.h \
+ oid.h \
+ pdu.h \
+ sagent.h \
+ snmp.h \
+ target.h \
+ timetick.h \
+ transaction.h \
+ vb.h \
+ wpdu.h
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/ACE/ASNMP/asnmp/TODO b/ACE/ASNMP/asnmp/TODO
new file mode 100644
index 00000000000..12beb91406b
--- /dev/null
+++ b/ACE/ASNMP/asnmp/TODO
@@ -0,0 +1,25 @@
+This is the todo list aka wish list: feel free to add/implmement
+Fri Aug 1 19:40:55 PDT 1997
+
+0) collapse CMU and HP code - make this thing faster since it is really
+ slow and bulky...
+
+1) implement response time statistics collection so that timeout can vary based
+ on empirical response times
+
+2) Implement pdu fragmentation based on tooBig errors or app directed
+ Snmp::set_pdu_max_size() command
+
+3) implement async interface
+
+4) make templatized version to implement sync/nonsync (thread safe version)
+
+5) add V2c when a real agent is in the field that supports it
+
+6) Add DISMAN support when IETF approves the Expression Mib
+
+7) way too many procedural case stmts in the code...
+
+8) add compare_right() method to be orthogonal to oid class.
+
+
diff --git a/ACE/ASNMP/asnmp/address.cpp b/ACE/ASNMP/asnmp/address.cpp
new file mode 100644
index 00000000000..8231868bd89
--- /dev/null
+++ b/ACE/ASNMP/asnmp/address.cpp
@@ -0,0 +1,2705 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// address.cpp
+//
+// = DESCRIPTION
+// The Vb class is an encapsulation of the snmp variable binding.
+// This module contains the class definition for the variable binding (VB)
+// class. The VB class is an encapsulation of a SNMP VB. A VB object is
+// composed of one SNMP++ Oid and one SMI value. The Vb class utilizes Oid
+// objects and thus requires the Oid class. To use this class,
+// set oid, value then call valid() to be sure object was constructed correctly.
+//
+// = AUTHOR
+// Peter E Mellquist
+// Michael R MacFaden mrm@cisco.com - rework & ACE port
+// ============================================================================
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+ =====================================================================*/
+
+#include "asnmp/address.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_arpa_inet.h"
+#include "ace/OS_NS_netdb.h"
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/os_include/os_ctype.h"
+#include "ace/OS_Memory.h"
+
+ACE_RCSID(asnmp, address, "$Id$")
+
+//=================================================================
+//======== Abstract Address Class Implementation ==================
+//=================================================================
+
+// allow destruction of derived classes
+Address::~Address()
+{
+}
+
+
+//-----------------------------------------------------------------
+// is the address object valid?
+int Address::valid() const
+{
+ return valid_flag;
+}
+
+//------------[ Address::trim_white_space( char * ptr) ]------------
+// destructive trim white space
+void Address::trim_white_space( char * ptr)
+{
+ char *tmp;
+
+ tmp = ptr;
+ // skip leading white space
+ while (*tmp==' ')tmp++;
+ ACE_OS::strcpy(ptr,tmp);
+
+ // find end of string
+ while ((*tmp!=' ') && (*tmp !=0)) tmp++;
+ if (*tmp!=0) *tmp=0;
+}
+
+//TM: this is not used nor needed, remove?
+//-----[ element access ]----------------------------------------------
+unsigned char& Address::operator[]( const int position)
+{
+ if ( position < MAX_ADDR_SZ)
+ return address_buffer[ position];
+ else
+ return address_buffer[0];
+}
+
+
+//-----------------------------------------------------------------------
+// overloaded equivlence operator, are two addresses equal?
+bool operator==( const Address &lhs, const Address &rhs)
+{
+ if ( ACE_OS::strcmp( (const char*) lhs, (const char*)rhs)==0)
+ return true;
+ else
+ return false;
+}
+
+//-----------------------------------------------------------------------
+// overloaded equivlence operator, are two addresses equal?
+bool operator!=( const Address &lhs, const Address &rhs)
+{
+ return (!( lhs == rhs));
+}
+
+
+//------------------------------------------------------------------
+// overloaded > operator, is a1 > a2
+bool operator>( const Address &lhs, const Address &rhs)
+{
+ if (ACE_OS::strcmp( (const char*) lhs, (const char*)rhs)>0)
+ return true;
+ else
+ return false;
+}
+
+// overloaded >= operator, is a1 > a2
+bool operator>=( const Address &lhs,const Address &rhs)
+{
+ if (( lhs > rhs) || ( lhs == rhs))
+ return true;
+ else
+ return false;
+}
+
+// overloaded < operator, is a1 <= a2
+bool operator<=( const Address &lhs,const Address &rhs)
+{
+ if (( lhs < rhs) || ( lhs == rhs))
+ return true;
+ else
+ return false;
+
+}
+
+
+//-----------------------------------------------------------------
+// overloaded < operator, is a1 < a2
+bool operator<( const Address &lhs, const Address &rhs)
+{
+ if (ACE_OS::strcmp( (const char*) lhs, (const char*)rhs)<0)
+ return true;
+ else
+ return false;
+}
+
+//------------------------------------------------------------------
+// equivlence operator overloaded, are an address and a string equal?
+bool operator==( const Address &lhs,const char *rhs)
+{
+ if (!rhs && !lhs.valid())
+ return true;
+ if (ACE_OS::strcmp( (const char *) lhs, rhs)== 0)
+ return true;
+ else
+ return false;
+}
+
+//------------------------------------------------------------------
+// not equal operator overloaded, are an address and a string not equal?
+bool operator!=( const Address &lhs,const char *rhs)
+{
+ return (!( lhs == rhs));
+}
+
+//------------------------------------------------------------------
+// overloaded > , is a > inaddr
+bool operator>( const Address &lhs,const char *rhs)
+{
+ if (!rhs)
+ return lhs.valid(); // if lhs valid then > 0, else invalid !> 0
+ if (ACE_OS::strcmp( (const char *) lhs, rhs)> 0)
+ return true;
+ else
+ return false;
+}
+
+//------------------------------------------------------------------
+// overloaded >= , is a >= inaddr
+bool operator>=( const Address &lhs,const char *rhs)
+{
+ if (!rhs)
+ return true; // always >= 0
+ if (ACE_OS::strcmp( (const char *) lhs, rhs)>= 0)
+ return true;
+ else
+ return false;
+}
+
+//-----------------------------------------------------------------
+// overloaded < , are an address and a string equal?
+bool operator<( const Address &lhs,const char *rhs)
+{
+ if (!rhs)
+ return false; // always >= 0
+ if (ACE_OS::strcmp( (const char *) lhs, rhs)< 0)
+ return true;
+ else
+ return false;
+}
+
+//-----------------------------------------------------------------
+// overloaded <= , is a <= inaddr
+bool operator<=( const Address &lhs,const char *rhs)
+{
+ if (!rhs)
+ return !lhs.valid(); // invalid == 0, else valid > 0
+ if (ACE_OS::strcmp( (const char *) lhs, rhs) <= 0)
+ return true;
+ else
+ return false;
+}
+
+
+//=====================================================================
+//============ IPAddress Implementation ===============================
+//=====================================================================
+
+//-----------[ syntax type ]----------------------------------------------
+SmiUINT32 IpAddress::get_syntax()
+{
+ return sNMP_SYNTAX_IPADDR;
+}
+
+//-----[ IP Address copy constructor ]---------------------------------
+IpAddress::IpAddress(const IpAddress &ipaddr)
+ : Address (ipaddr)
+{
+ // always initialize what type this object is
+ smival.syntax = sNMP_SYNTAX_IPADDR;
+ smival.value.string.len =IPV4LEN;
+ smival.value.string.ptr = address_buffer;
+
+ iv_friendly_name_[0] = 0;
+ iv_friendly_name_status_ = 0;
+ valid_flag = ipaddr.valid_flag;
+ if (valid_flag) {
+ ACE_OS::memcpy(address_buffer, ipaddr.address_buffer,IPV4LEN);
+ ACE_OS::strcpy( iv_friendly_name_, ipaddr.iv_friendly_name_);
+ }
+
+ IpAddress::format_output();
+}
+
+
+//-------[ default construct, an IP address with a string ]---------------------
+IpAddress::IpAddress( const char *inaddr): Address()
+{
+ // always initialize what type this object is
+ smival.syntax = sNMP_SYNTAX_IPADDR;
+ smival.value.string.len = IPV4LEN;
+ smival.value.string.ptr = address_buffer;
+
+ if (ACE_OS::strlen(inaddr) == 0) {
+
+ valid_flag = 0;
+ iv_friendly_name_[0] = 0;
+ iv_friendly_name_status_ = 0;
+ IpAddress::format_output();
+ return;
+ }
+
+ // parse_address initializes valid, address_buffer & iv_friendly_name_
+ valid_flag = parse_address(inaddr);
+ IpAddress::format_output();
+}
+
+
+//-----[ construct an IP address with a GenAddress ]---------------------
+IpAddress::IpAddress( const GenAddress &genaddr)
+{
+ // always initialize what type this object is
+ smival.syntax = sNMP_SYNTAX_IPADDR;
+ smival.value.string.len = IPV4LEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = 0;
+ iv_friendly_name_[0] = 0;
+ iv_friendly_name_status_ = 0;
+ // allow use of an ip or udp genaddress
+ if (genaddr.get_type() == type_ip) {
+ valid_flag = genaddr.valid();
+ if ( valid_flag) {
+ // copy in the IP address data
+ IpAddress temp_ip( (const char *) genaddr);
+ *this = temp_ip;
+ }
+ }
+ else
+ if (genaddr.get_type() == type_udp) {
+ valid_flag = genaddr.valid();
+ if ( valid_flag) {
+ // copy in the IP address data
+ UdpAddress temp_udp( (const char *) genaddr);
+ *this = temp_udp;
+ }
+ }
+ IpAddress::format_output();
+}
+
+//-----[ destructor ]--------------------------------------------------
+IpAddress::~IpAddress()
+{
+}
+
+// assumes member data is word aligned to avoid sigbus
+int IpAddress::is_loopback() const
+{
+ if (valid()) {
+ return (*(u_long *)&address_buffer == INADDR_LOOPBACK);
+ }
+ return 0;
+}
+
+int IpAddress::is_multicast() const
+{
+ if (valid()) {
+ return (IN_MULTICAST(*(u_long *)&address_buffer));
+ }
+ return 0;
+}
+
+// Private addressess not are not assignable in the Internet, they are
+// defined in RFC 1597 as: 10, 172.16, and 192.168.0
+// Some companies use them internally and apply NAT to allow translation
+// instead of paying for ip networks.
+// Cisco IOS devices can provide NAT aka Network Address Translation
+// but don't expect SNMP based networks to handle cross-NAT address spaces.
+// assumes storage in network byte order mrm@cisco.com 7/28/97
+
+int IpAddress::is_private() const
+{
+ if (valid()) {
+ if (address_buffer[0] == 10)
+ return 1;
+ if (address_buffer[0] == 172 && address_buffer[1] == 16)
+ return 1;
+ if (address_buffer[0] == 192 && address_buffer[1] == 168 &&
+ address_buffer[2] == 0)
+ return 1;
+ }
+ return 0;
+}
+
+
+// convert address into octet string format in network byte order
+void IpAddress::to_octet(OctetStr& octet) const
+{
+ octet.set_data( smival.value.string.ptr, smival.value.string.len);
+}
+
+
+int IpAddress::is_broadcast() const
+{
+ if (valid()) {
+ return ( (*(u_long *)&address_buffer) & INADDR_BROADCAST);
+ }
+ return 0;
+}
+
+//-----[ IP Address general = operator ]-------------------------------
+SnmpSyntax& IpAddress::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from itself
+ if ( this == &val )
+ return *this;
+
+ valid_flag = 0; // will get set 1 if really valid
+ iv_friendly_name_[0]=0;
+
+ if (val.valid()) {
+ switch (val.get_syntax()) {
+ case sNMP_SYNTAX_IPADDR:
+ case sNMP_SYNTAX_OCTETS:
+ if (((IpAddress &)val).smival.value.string.len ==IPV4LEN) {
+ ACE_OS::memcpy(address_buffer,
+ ((IpAddress &)val).smival.value.string.ptr,IPV4LEN);
+ valid_flag = 1;
+ }
+ break;
+
+ // NOTE: as a value add, other types could have "logical"
+ // mappings, i.e. integer32 and unsigned32
+ }
+ }
+ IpAddress::format_output();
+ return *this;
+}
+
+//------[ assignment to another ipaddress object overloaded ]-----------------
+IpAddress& IpAddress::operator=( const IpAddress &ipaddress)
+{
+ // protect against assignment from itself
+ if ( this == &ipaddress )
+ return *this;
+
+ valid_flag = ipaddress.valid_flag;
+ iv_friendly_name_[0]=0;
+
+ if (valid_flag) {
+ ACE_OS::memcpy(address_buffer, ipaddress.address_buffer, IPV4LEN);
+ ACE_OS::strcpy(iv_friendly_name_, ipaddress.iv_friendly_name_);
+ }
+ IpAddress::format_output();
+ return *this;
+}
+
+
+//--------[ create a new instance of this Value ]-----------------------
+SnmpSyntax *IpAddress::clone() const
+{
+ return (SnmpSyntax *) new IpAddress(*this);
+}
+
+//-------[ return the Fully Qualified Domain Name ]----------------------
+const char *IpAddress::resolve_hostname(int &status)
+{
+ if ((iv_friendly_name_[0] == 0) && valid_flag)
+ addr_to_friendly();
+ status = iv_friendly_name_status_;
+ return iv_friendly_name_;
+}
+
+// parse a dotted string
+int IpAddress::parse_dotted_ipstring( const char *inaddr)
+{
+ char *ip_token;
+ int token_count=0;
+ unsigned int value;
+ int error_status = 0;
+ char temp[MAXHOSTNAMELEN +1]; // temp buffer for destruction
+ int z,w;
+
+ // check len, an ip can never be bigger than 15
+ // 123456789012345
+ // XXX.XXX.XXX.XXX
+ if ( !inaddr || (ACE_OS::strlen( inaddr) > 30))
+ return 0;
+ ACE_OS::strcpy( temp, inaddr);
+ trim_white_space( temp);
+ if ( ACE_OS::strlen( temp) > 15)
+ return 0;
+
+ // must only have three dots
+ // strtok will not catch this !
+ char *ptr = temp;
+ int dot_count = 0;
+ while ( *ptr != 0) {
+ if ( *ptr == '.') dot_count++;
+ ptr++;
+ }
+ if ( dot_count != 3)
+ return 0;
+
+ // look for dot token separator
+ ip_token = ACE_OS::strtok( (char *) temp,".");
+
+ // while more tokens..
+ while ( ip_token != 0) {
+ // verify that the token is all numerics
+ w = ACE_OS::strlen( ip_token);
+ if (w>3)
+ return 0;
+ for (z=0;z<w;z++)
+ if (( ip_token[z] < '0') || ( ip_token[z] > '9'))
+ return 0;
+
+ value = ( unsigned int) strtod(ip_token,0);
+ if (( value > 0)&& ( value <=255))
+ address_buffer[token_count] = (unsigned char) value;
+ else
+ if (ACE_OS::strcmp(ip_token,"0")==0)
+ address_buffer[token_count]= (unsigned char) 0;
+ else
+ error_status = 1;
+ token_count++;
+ ip_token = ACE_OS::strtok( 0, ".");
+ }
+
+ // gota be four in len
+ if ( token_count != 4)
+ return 0;
+
+ // any parsing errors?
+ if ( error_status)
+ return 0;
+
+ return 1;
+}
+
+//-----[ IP Address parse Address ]---------------------------------
+int IpAddress::parse_address( const char *inaddr)
+{
+ // parse the input char array
+ // fill up internal buffer with four ip bytes
+ // set and return validity flag
+
+ in_addr ipAddr;
+ char ds[MAXHOSTNAMELEN +1];
+
+ // intialize the friendly_name member variable
+ iv_friendly_name_[0] = 0;
+ iv_friendly_name_status_ = 0;
+
+ // is this a dotted IP notation string or
+ // a friendly name
+ if ( parse_dotted_ipstring( inaddr)) {
+
+ // since this is a valid dotted string
+ // don't do any DNS (Performance!)
+ return 1;
+ }
+ else {
+ int rc;
+ if ((rc = resolve_to_address(inaddr, ipAddr)) == 0) {
+
+ // now lets check out the dotted string
+ ACE_OS::strncpy( ds, ACE_OS::inet_ntoa(ipAddr), MAXHOSTNAMELEN);
+
+ if ( !parse_dotted_ipstring( ds))
+ return 0;
+
+ // save the friendly name
+ ACE_OS::strcpy( iv_friendly_name_, inaddr);
+
+ } // end if lookup result
+ else {
+ iv_friendly_name_status_ = rc;
+ return 0;
+ }
+ } // end else not a dotted string
+ return 1;
+}
+
+// using the currently defined address, do a DNS
+// and try to fill up the name
+int IpAddress::addr_to_friendly()
+{
+ in_addr ipAddr;
+ long result = ACE_OS::inet_addr(to_string());
+ if (result == -1)
+ return -1; // expected a dotted quad!
+
+ ipAddr.s_addr = result;
+
+ // set iv_friendly_name_ from ipAddr
+ if (resolve_to_hostname(ipAddr, iv_friendly_name_) == 0) {
+ return 0;
+ }
+ else {
+#if defined (VXWORKS)
+ // VxWorks doesn't have h_errno
+ iv_friendly_name_status_ = errno;
+#else
+ iv_friendly_name_status_ = h_errno;
+#endif /* VXWORKS */
+ return iv_friendly_name_status_;
+ }
+}
+
+// static aka class member function (1.2.3.4 -> foo.com)
+int IpAddress::resolve_to_hostname(const in_addr& quad_addr, char *hostname)
+{
+ struct hostent lookupResult;
+ int loc_errno = 0;
+ ACE_HOSTENT_DATA buffer;
+ ACE_OS::memset(&lookupResult, 0, sizeof(struct hostent));
+ ACE_OS::memset(&buffer, 0, sizeof(ACE_HOSTENT_DATA));
+
+ // reverse lookup (requires in-addr.arpa to be setup in DNS
+ if (ACE_OS::gethostbyaddr_r((const char *)&quad_addr.s_addr, IPV4LEN,
+ AF_INET, &lookupResult, buffer, &loc_errno)) {
+
+ // verify right type of record
+ if (lookupResult.h_addrtype == AF_INET &&
+ lookupResult.h_length == IPV4LEN) {
+ ACE_OS::strcpy( hostname, lookupResult.h_name);
+ // setup multiple entries
+ return 0;
+ }
+ else {
+ ACE_ASSERT(0); // todo add trace and debug and dump
+ return -1; // wrong resource record type
+ }
+ }
+
+ return loc_errno;
+}
+
+// static aka class member function (foo.com -> 1.2.3.4)
+int IpAddress::resolve_to_address(const char *hostname, in_addr& quad_addr)
+{
+ struct hostent lookupResult;
+ ACE_HOSTENT_DATA buffer;
+ ACE_OS::memset(&buffer, 0, sizeof(ACE_HOSTENT_DATA));
+ ACE_OS::memset(&lookupResult, 0, sizeof(struct hostent));
+ int loc_errno = 0;
+ if (ACE_OS::gethostbyname_r( hostname, &lookupResult, buffer, &loc_errno)) {
+ if (lookupResult.h_length == sizeof(in_addr) &&
+ lookupResult.h_addrtype == AF_INET) {
+ ACE_OS::memcpy((void *) &quad_addr,
+ (void *) lookupResult.h_addr_list[0], sizeof(in_addr));
+ return 0;
+ }
+ else
+ return -1; // wrong address size
+ }
+ return loc_errno;
+}
+
+//----[ IP address char * cast ]--------------------------------------
+IpAddress::operator const char *() const
+{
+ return (char *)output_buffer;
+}
+
+//----[ IP address get char representation ]--------------------------
+const char * IpAddress::to_string()
+{
+ return (char *)output_buffer;
+}
+
+//----[ IP address format output ]------------------------------------
+void IpAddress::format_output()
+{
+ // if valid format else null it
+ if ( valid_flag)
+ ACE_OS::sprintf( (char *) output_buffer,"%d.%d.%d.%d",address_buffer[0],
+ address_buffer[1], address_buffer[2], address_buffer[3]);
+ else
+ output_buffer[0] = 0;
+}
+
+//------[ return the type ]----------------------------------
+addr_type IpAddress::get_type() const
+{
+ return type_ip;
+}
+
+//-----------------------------------------------------------------
+// logically and two IPaddresses and
+// return the new one
+void IpAddress::mask( const IpAddress& ipaddr)
+{
+ if ( this->valid() && ipaddr.valid()) {
+ this->address_buffer[0] = this->address_buffer[0] & ipaddr.address_buffer[0];
+ this->address_buffer[1] = this->address_buffer[1] & ipaddr.address_buffer[1];
+ this->address_buffer[2] = this->address_buffer[2] & ipaddr.address_buffer[2];
+ this->address_buffer[3] = this->address_buffer[3] & ipaddr.address_buffer[3];
+ format_output();
+ }
+
+}
+
+//=======================================================================
+//========== DNS Iterator Implementation ================================
+//=======================================================================
+
+
+Address_Iter::Address_Iter(const char *hostname): valid_(0), count_(0),
+ entry_(0)
+{
+ ACE_OS::memset(&buffer_, 0, sizeof(ACE_HOSTENT_DATA));
+ ACE_OS::memset(&lookupResult_, 0, sizeof(struct hostent));
+ if (ACE_OS::inet_addr(hostname) == (unsigned long) -1)
+ valid_ = query_dns(hostname);
+ else {
+ ACE_ASSERT(0); // don't support dot-quad lookup yet
+ }
+
+ // count number of hostnames
+ int n;
+ char **pc;
+ for (n = 0, pc = lookupResult_.h_addr_list; *pc != 0; ++n, ++pc);
+ count_ = n; // plus first one
+ entry_ = lookupResult_.h_addr_list;
+}
+
+int Address_Iter::valid() const
+{
+ return (valid_ == 1);
+}
+
+int Address_Iter::how_many_addresses()
+{
+ return count_;
+}
+
+// return next entry, rc = 0, if entry is null return 0
+int Address_Iter::next(IpAddress& addr)
+{
+ if (!entry_ || *entry_ == 0)
+ return 1;
+
+ IpAddress tmp(*entry_++); // return data
+ addr = tmp;
+ if (*entry_ == 0)
+ return 1;
+ return 0;
+}
+
+// query DNS here
+int Address_Iter::query_dns(const char *hostname)
+{
+ int loc_errno = 0;
+ if (ACE_OS::gethostbyname_r( hostname, &lookupResult_, buffer_,
+ &loc_errno)) {
+ if (lookupResult_.h_length == sizeof(IPV4LEN) &&
+ lookupResult_.h_addrtype == AF_INET) {
+ return 0;
+ }
+ else
+ return -1; // wrong address size
+ }
+ return loc_errno;
+}
+
+//=======================================================================
+//========== Udp Address Implementation =================================
+//=======================================================================
+
+//-----------[ syntax type ]----------------------------------------------
+SmiUINT32 UdpAddress::get_syntax()
+{
+ return sNMP_SYNTAX_OCTETS;
+}
+
+//-----------------[ construct an Udp address with another Udp address ]---
+UdpAddress::UdpAddress( const UdpAddress &udpaddr):IpAddress(udpaddr)
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = UDPIPV4LEN;
+ smival.value.string.ptr = address_buffer;
+
+ // Copy the port value
+ set_port(udpaddr.get_port());
+ format_output();
+}
+
+// default constructor with a dotted string
+UdpAddress::UdpAddress( const char *inaddr):IpAddress()
+{
+ if (ACE_OS::strlen(inaddr) == 0) {
+ // Inherits IP Address attributes
+ // Always initialize (override) what type this object is
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = UDPIPV4LEN;
+ smival.value.string.ptr = address_buffer;
+ set_port(0);
+ format_output();
+ return;
+ }
+
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = UDPIPV4LEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = parse_address( (char *)inaddr);
+ format_output();
+}
+
+//-----------------[ construct a UdpAddress from a GenAddress ]--------------
+UdpAddress::UdpAddress( const GenAddress &genaddr):IpAddress()
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = UDPIPV4LEN;
+ smival.value.string.ptr = address_buffer;
+
+ unsigned int port = 0;
+ valid_flag = 0;
+
+ // allow use of an ip or udp genaddress
+ if (genaddr.get_type() == type_udp)
+ {
+ valid_flag = genaddr.valid();
+ if ( valid_flag)
+ {
+ // copy in the IP address data
+ UdpAddress temp_udp( (const char *) genaddr);
+ *this = temp_udp;
+
+ // port info since are making an UpAddress
+ port = temp_udp.get_port();
+ }
+ }
+ else
+ if (genaddr.get_type() == type_ip)
+ {
+ valid_flag = genaddr.valid();
+ if ( valid_flag)
+ {
+ // copy in the IP address data
+ IpAddress temp_ip( (const char *) genaddr);
+ *this = temp_ip;
+ }
+ }
+ set_port(port);
+ format_output();
+}
+
+
+//--------[ construct a udp from an IpAddress ]--------------------------
+UdpAddress::UdpAddress( const IpAddress &ipaddr):IpAddress(ipaddr)
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = UDPIPV4LEN;
+ smival.value.string.ptr = address_buffer;
+
+ set_port(0);
+ format_output();
+}
+
+
+//-----[ destructor ]--------------------------------------------------
+UdpAddress::~UdpAddress()
+{
+}
+
+
+ // copy an instance of this Value
+SnmpSyntax& UdpAddress::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from itself
+ if ( this == &val )
+ return *this;
+
+ valid_flag=0; // will get set 1 if really valid
+ if (val.valid()){
+ switch (val.get_syntax()){
+ case sNMP_SYNTAX_IPADDR:
+ {
+ UdpAddress temp_udp(val.to_string());
+ *this = temp_udp; // valid_flag is set by the udp assignment
+ }
+ break;
+
+ case sNMP_SYNTAX_OCTETS:
+ if (((UdpAddress &)val).smival.value.string.len == UDPIPV4LEN){
+ ACE_OS::memcpy(address_buffer,
+ ((UdpAddress &)val).smival.value.string.ptr, UDPIPV4LEN);
+ iv_friendly_name_[0] = 0;
+ valid_flag = 1;
+ }
+ break;
+
+ // NOTE: as a value add, other types could have "logical"
+ // mappings, i.e. integer32 and unsigned32
+ }
+ }
+ format_output();
+ return *this;
+}
+
+ // assignment to another UdpAddress object overloaded
+UdpAddress& UdpAddress::operator=( const UdpAddress &udpaddr)
+{
+ // protect against assignment from itself
+ if ( this == &udpaddr )
+ return *this;
+
+ (IpAddress &)*this = udpaddr; // use ancestor assignment for ipaddr value
+ set_port(udpaddr.get_port()); // copy to port value
+ format_output();
+ return *this;
+}
+
+
+//-----[ IP Address parse Address ]---------------------------------
+int UdpAddress::parse_address( const char *inaddr)
+{
+ char buffer[MAXHOSTNAMELEN +1];
+
+ unsigned short port = 0;
+ if (inaddr && (ACE_OS::strlen( inaddr)< MAXHOSTNAMELEN +1))
+ ACE_OS::strcpy( buffer, inaddr);
+ else {
+ valid_flag = 0;
+ return 0;
+ }
+ // look for port info @ the end of the string
+ // port can be delineated by a ':' or a '/'
+ // if neither are present then just treat it
+ // like a normal IpAddress
+ char *tmp;
+ tmp = ACE_OS::strstr( buffer,":");
+ if (tmp==0)
+ tmp = ACE_OS::strstr(buffer,"/");
+
+ if ( tmp != 0) {
+ *tmp=0; // null terminator
+ tmp++;
+ port = ACE_OS::atoi( tmp);
+ }
+
+ set_port(port);
+ return IpAddress::parse_address( buffer);
+}
+
+
+//----------[ create a new instance of this Value ]------------------------
+SnmpSyntax *UdpAddress::clone() const
+{
+ return (SnmpSyntax *) new UdpAddress(*this);
+}
+
+//--------[ set the port number ]---------------------------------------
+void UdpAddress::set_port( const unsigned short p)
+{
+ unsigned short port_nbo = htons(p);
+ ACE_OS::memcpy(&address_buffer[IPV4LEN], &port_nbo, 2);
+ format_output();
+}
+
+//---------[ get the port number ]--------------------------------------
+unsigned short UdpAddress::get_port() const
+{
+ if (valid_flag) {
+ unsigned short port_nbo;
+ ACE_OS::memcpy(&port_nbo, &address_buffer[IPV4LEN], 2);
+ return ntohs(port_nbo);
+ }
+ else
+ return 0; // don't use uninitialized memory
+}
+
+//------[ return the type ]--------------------------------------------
+addr_type UdpAddress::get_type() const
+{
+ return type_udp;
+}
+
+//----[ UDP address char * cast ]--------------------------------------
+UdpAddress::operator const char *() const
+{
+ return (char *)output_buffer;
+}
+
+//----[ UDP address get char representation ]--------------------------
+const char * UdpAddress::to_string()
+{
+ return (char *)output_buffer;
+}
+
+// make format same as ACE_INET_Addr class (addr:port)
+void UdpAddress::format_output()
+{
+ IpAddress::format_output(); // allow ancestors to format their buffers
+
+ // if valid format else null it
+ if ( valid_flag)
+ ACE_OS::sprintf( (char *) output_buffer,"%s:%d",
+ IpAddress::to_string(),
+ get_port() );
+ else
+ output_buffer[0] = 0;
+}
+
+
+//=======================================================================
+//=========== Netbios Address Implementation ============================
+//=======================================================================
+
+void NetbiosAddress::format_output()
+{
+ if ( valid_flag)
+ ACE_OS::memcpy(output_buffer, address_buffer, NETBIOSLEN);
+ else
+ output_buffer[0] = 0;
+}
+
+void NetbiosAddress::InitNBAddr(const char *inaddr)
+{
+ if (ACE_OS::strlen(inaddr) == 0) {
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = NETBIOSLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag=0;
+ NetbiosAddress::format_output();
+ return;
+ }
+
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = IPXLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = parse_address( (char *) inaddr);
+ NetbiosAddress::format_output();
+}
+
+// TODO: how to handle addresses < 15 chars (zero out or pad with ' ')
+NetbiosAddress::NetbiosAddress( const char *inaddr)
+{
+ InitNBAddr(inaddr);
+
+}
+
+NetbiosAddress::NetbiosAddress( const char *inaddr, nb_service svc)
+{
+ InitNBAddr(inaddr);
+ address_buffer[15] = svc;
+}
+
+// TODO: go back over ms/ibm specs and verify this
+// 16 chars, 15 can be any character, 16th is service number between 0 and 20
+// names beginning with IBM are reserved, and hence invalid
+// and doubt IBM would use this class anyway
+int NetbiosAddress::parse_address(const char *address)
+{
+ if (ACE_OS::strlen(address) > NETBIOSLEN)
+ return 0; // invalid
+
+ if (ACE_OS::strncmp(address, "IBM", 3) == 0)
+ return 0; // invalid
+
+ // addresses are free form but this check may need to be expose to user
+ //
+ //if (address[15] < nb_workstation || address[15] > nb_server)
+ // return 0; //invalid service type
+
+ ACE_OS::memset(address_buffer, 0, NETBIOSLEN);
+ ACE_OS::memcpy(address_buffer, address, NETBIOSLEN);
+
+ return 1; // valid
+}
+
+NetbiosAddress::NetbiosAddress( const NetbiosAddress& nbaddr)
+ : Address (nbaddr)
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = NETBIOSLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = nbaddr.valid_flag;
+ if (valid_flag)
+ ACE_OS::memcpy(address_buffer, nbaddr.address_buffer, NETBIOSLEN);
+ NetbiosAddress::format_output();
+}
+
+NetbiosAddress::NetbiosAddress( const GenAddress& genaddr)
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = NETBIOSLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = 0;
+ // allow use of an ipx or ipxsock address
+ if ( (genaddr.get_type() == type_nb) ) {
+ valid_flag = genaddr.valid();
+ if ( valid_flag) {
+ // copy in the Ipx address data
+ NetbiosAddress temp_nb( (const char *) genaddr);
+ *this = temp_nb;
+ }
+ }
+ NetbiosAddress::format_output();
+}
+
+NetbiosAddress::~NetbiosAddress()
+{
+}
+
+const char *NetbiosAddress::to_string()
+{
+ return (char *)output_buffer;
+}
+
+void NetbiosAddress::to_octet(OctetStr& octet) const
+{
+ octet.set_data( smival.value.string.ptr, smival.value.string.len);
+}
+
+NetbiosAddress& NetbiosAddress::operator=( const NetbiosAddress &val)
+{
+ // protect against assignment from itself
+ if ( this == &val )
+ return *this;
+
+ valid_flag = 0; // will set to 1 if really valid
+ if (val.valid()) {
+ switch (((NetbiosAddress *) &val)->get_syntax()) {
+ case sNMP_SYNTAX_OCTETS:
+ ACE_OS::memcpy(address_buffer,
+ ((NetbiosAddress &)val).smival.value.string.ptr, NETBIOSLEN);
+ valid_flag = 1;
+ break;
+ }
+ }
+ NetbiosAddress::format_output();
+ return *this;
+}
+
+nb_service NetbiosAddress::get_service_type() const
+{
+ return (nb_service) address_buffer[15];
+}
+
+void NetbiosAddress::set_service_type(nb_service nbservice)
+{
+ address_buffer[15] = nbservice;
+ NetbiosAddress::format_output();
+}
+
+NetbiosAddress::operator const char *() const
+{
+ return (char *)output_buffer;
+}
+
+SnmpSyntax& NetbiosAddress::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from itself
+ if ( this == &val )
+ return *this;
+
+ valid_flag = 0; // will set to 1 if really valid
+ if (val.valid()) {
+ switch (val.get_syntax()) {
+ case sNMP_SYNTAX_OCTETS:
+ if (((NetbiosAddress &)val).smival.value.string.len == NETBIOSLEN) {
+ ACE_OS::memcpy(address_buffer,
+ ((NetbiosAddress &)val).smival.value.string.ptr, NETBIOSLEN);
+ valid_flag=1;
+ }
+ break;
+ }
+ }
+ NetbiosAddress::format_output();
+ return *this;
+}
+
+SnmpSyntax *NetbiosAddress::clone() const
+{
+ return (SnmpSyntax *) new NetbiosAddress(*this);
+}
+
+SmiUINT32 NetbiosAddress::get_syntax()
+{
+ return sNMP_SYNTAX_OCTETS;
+}
+
+addr_type NetbiosAddress::get_type() const
+{
+ return type_nb;
+}
+
+//=======================================================================
+//=========== IPX Address Implementation ================================
+//=======================================================================
+
+//-----------[ syntax type ]----------------------------------------------
+SmiUINT32 IpxAddress::get_syntax()
+{
+ return sNMP_SYNTAX_OCTETS;
+}
+
+
+//----------[ default constructor with a string arg ]---------------------------
+IpxAddress::IpxAddress( const char *inaddr):Address( )
+{
+ if (ACE_OS::strlen(inaddr) == 0) {
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = IPXLEN;
+ smival.value.string.ptr = address_buffer;
+
+ separator = '\0';
+ valid_flag=0;
+ IpxAddress::format_output();
+ return;
+ }
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = IPXLEN;
+ smival.value.string.ptr = address_buffer;
+
+ separator = '\0';
+ valid_flag = parse_address( (char *) inaddr);
+ IpxAddress::format_output();
+}
+
+
+//-----[ IPX Address copy constructor ]----------------------------------
+IpxAddress::IpxAddress(const IpxAddress &ipxaddr)
+ : Address (ipxaddr)
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = IPXLEN;
+ smival.value.string.ptr = address_buffer;
+
+ separator = '\0';
+ valid_flag = ipxaddr.valid_flag;
+ if (valid_flag)
+ ACE_OS::memcpy(address_buffer, ipxaddr.address_buffer, IPXLEN);
+ IpxAddress::format_output();
+}
+
+
+//----[ construct an IpxAddress from a GenAddress ]---------------------------
+IpxAddress::IpxAddress( const GenAddress &genaddr)
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = IPXLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = 0;
+ // allow use of an ipx or ipxsock address
+ if ( (genaddr.get_type() == type_ipx) ) {
+ valid_flag = genaddr.valid();
+ if ( valid_flag) {
+ // copy in the Ipx address data
+ IpxAddress temp_ipx( (const char *) genaddr);
+ *this = temp_ipx;
+ }
+ }
+ else
+ if ( (genaddr.get_type() == type_ipxsock) ) {
+ valid_flag = genaddr.valid();
+ if ( valid_flag) {
+ // copy in the Ipx address data
+ IpxSockAddress temp_ipxsock( (const char *) genaddr);
+ *this = temp_ipxsock;
+ }
+ }
+ IpxAddress::format_output();
+}
+
+
+//-----[ destructor ]--------------------------------------------------
+IpxAddress::~IpxAddress()
+{
+}
+
+
+//-----[ IPX Address general = operator ]-------------------------------
+SnmpSyntax& IpxAddress::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from itself
+ if ( this == &val )
+ return *this;
+
+ valid_flag=0; // will set to 1 if really valid
+ if (val.valid()){
+ switch (val.get_syntax()){
+ case sNMP_SYNTAX_OCTETS:
+ if (((IpxAddress &)val).smival.value.string.len == IPXLEN){
+ ACE_OS::memcpy(address_buffer, ((IpxAddress &)val).smival.value.string.ptr, IPXLEN);
+ valid_flag=1;
+ }
+ break;
+ }
+ }
+ IpxAddress::format_output();
+ return *this;
+}
+
+//--------[ assignment to another IpAddress object overloaded ]----------
+IpxAddress& IpxAddress::operator=( const IpxAddress &ipxaddress)
+{
+ // protect against assignment from itself
+ if ( this == &ipxaddress )
+ return *this;
+
+ valid_flag = ipxaddress.valid_flag;
+ if (valid_flag)
+ ACE_OS::memcpy(address_buffer, ipxaddress.address_buffer, IPXLEN);
+ IpxAddress::format_output();
+ return *this;
+}
+
+
+// create a new instance of this Value
+SnmpSyntax *IpxAddress::clone() const
+{
+ return (SnmpSyntax *) new IpxAddress(*this);
+}
+
+//-----[ IPX Address parse Address ]-----------------------------------
+// Convert a string to a ten byte ipx address
+// On success sets validity 1 or 0
+//
+// IPX address format
+//
+// NETWORK ID| MAC ADDRESS
+// 01 02 03 04|05 06 07 08 09 10
+// XX XX XX XX|XX XX XX XX XX XX
+//
+// Valid input format
+//
+// XXXXXXXX.XXXXXXXXXXXX
+// Total length must be 21
+// Must have a separator in it
+// First string length must be 8
+// Second string length must be 12
+// Each char must take on value 0-F
+//
+//
+// Input formats recognized
+//
+// XXXXXXXX.XXXXXXXXXXXX
+// XXXXXXXX:XXXXXXXXXXXX
+// XXXXXXXX-XXXXXXXXXXXX
+// XXXXXXXX.XXXXXX-XXXXXX
+// XXXXXXXX:XXXXXX-XXXXXX
+// XXXXXXXX-XXXXXX-XXXXXX
+int IpxAddress::parse_address( const char *inaddr)
+{
+ char unsigned *str1,*str2;
+ char temp[30]; // don't destroy original
+ char unsigned *tmp;
+ size_t z, tmplen;
+
+
+ // save the orginal source
+ if (!inaddr || (ACE_OS::strlen( inaddr) >(sizeof(temp)-1))) return 0;
+ ACE_OS::strcpy( temp, inaddr);
+ trim_white_space( temp);
+ tmplen = ACE_OS::strlen(temp);
+
+ // bad total length check
+ // 123456789012345678901
+ // XXXXXXXX-XXXXXXXXXXXX 21 len
+ //
+ // XXXXXXXX-XXXXXX-XXXXXX 22 len
+ // need at least 21 chars and no more than 22
+ if ( (tmplen <21) || (tmplen >22))
+ return 0;
+
+ // convert the string to all lower case
+ // this allows hex values to be in upper or lower
+ for (z=0;z< tmplen;z++)
+ temp[z] = tolower(temp[z]);
+
+ // check for separated nodeid
+ // if found remove it
+ if (temp[15] == '-')
+ {
+ for(z=16;z<tmplen;z++)
+ temp[z-1] = temp[z];
+ temp[tmplen-1] = 0;
+ }
+
+ // no dot or colon separator check
+ separator = temp[8];
+ if (( separator != ':') &&
+ ( separator != '.') &&
+ ( separator != '-') &&
+ ( separator != ' '))
+ return 0;
+
+ // separate the strings
+ str1 = ( unsigned char *) temp;
+ while( *str1 != separator) str1++;
+ str2 = str1 + 1;
+ *str1 = 0;
+ str1= ( unsigned char *) temp;
+
+ // check len of the network portion
+ if ( ACE_OS::strlen((char *) str1) != 8)
+ return 0;
+
+ // check len of mac portion
+ if ( ACE_OS::strlen( (char *) str2) != 12)
+ return 0;
+
+ // ok we like then lens, make sure that all chars are 0-f
+ // check out the net id
+ tmp = str1;
+ while( *tmp != 0)
+ if (((*tmp >= '0') && (*tmp <= '9'))|| // good 0-9
+ ((*tmp >= 'a') && (*tmp <= 'f'))) // or a-f
+ tmp++;
+ else
+ return 0;
+
+ // check out the MAC address
+ tmp = str2;
+ while( *tmp != 0)
+ if (((*tmp >= '0') && (*tmp <= '9'))|| // good 0-9
+ ((*tmp >= 'a') && (*tmp <= 'f'))) // or a-f
+ tmp++;
+ else
+ return 0;
+
+ // convert to target string
+ tmp = str1;
+ while ( *tmp != 0)
+ {
+ if (( *tmp >= '0') && ( *tmp <= '9'))
+ *tmp = *tmp - (char unsigned )'0';
+ else
+ *tmp = *tmp - (char unsigned) 'a' + (char unsigned) 10;
+ tmp++;
+ }
+
+ // network id portion
+ address_buffer[0] = (str1[0]*16) + str1[1];
+ address_buffer[1] = (str1[2]*16) + str1[3];
+ address_buffer[2] = (str1[4]*16) + str1[5];
+ address_buffer[3] = (str1[6]*16) + str1[7];
+
+ tmp = str2;
+ while ( *tmp != 0)
+ {
+ if (( *tmp >= '0') && ( *tmp <= '9'))
+ *tmp = *tmp - (char unsigned) '0';
+ else
+ *tmp = *tmp - (char unsigned) 'a'+ (char unsigned) 10;
+ tmp++;
+ }
+
+ address_buffer[4] = (str2[0]*16) + str2[1];
+ address_buffer[5] = (str2[2]*16) + str2[3];
+ address_buffer[6] = (str2[4]*16) + str2[5];
+ address_buffer[7] = (str2[6]*16) + str2[7];
+ address_buffer[8] = (str2[8]*16) + str2[9];
+ address_buffer[9] = (str2[10]*16) + str2[11];
+
+ return 1;
+}
+
+//----[ IPX address char * cast ]--------------------------------------
+IpxAddress::operator const char *() const
+{
+ return (char *)output_buffer;
+}
+
+//----[ IPX address get char representation ]--------------------------
+const char * IpxAddress::to_string()
+{
+ return (char *)output_buffer;
+}
+
+
+//----[ IPX address format output ]-------------------------------------
+void IpxAddress::format_output()
+{
+ if ( valid_flag)
+ ACE_OS::sprintf((char *) output_buffer,
+ "%02x%02x%02x%02x%c%02x%02x%02x%02x%02x%02x",
+ address_buffer[0],address_buffer[1],
+ address_buffer[2],address_buffer[3],'-',
+ address_buffer[4],address_buffer[5],
+ address_buffer[6],address_buffer[7],
+ address_buffer[8],address_buffer[9]);
+ else
+ output_buffer[0] = 0;
+}
+
+
+// get the host id portion of an ipx address
+int IpxAddress::get_hostid( MacAddress& mac)
+{
+ if ( valid_flag)
+ {
+ char buffer[18];
+ ACE_OS::sprintf( buffer,"%02x:%02x:%02x:%02x:%02x:%02x",
+ address_buffer[4],
+ address_buffer[5], address_buffer[6], address_buffer[7],
+ address_buffer[8], address_buffer[9]);
+ MacAddress temp( buffer);
+ // mac = (SnmpSyntax&) temp;
+ mac = temp;
+ if ( mac.valid())
+ return 1;
+ else
+ return 0;
+ }
+ else
+ return 0;
+}
+
+
+//------[ return the type ]----------------------------------
+addr_type IpxAddress::get_type() const
+{
+ return type_ipx;
+}
+
+void IpxAddress::to_octet(OctetStr& octet) const
+{
+ octet.set_data( smival.value.string.ptr, smival.value.string.len);
+}
+
+
+//========================================================================
+//======== IpxSockAddress Implementation =================================
+//========================================================================
+
+//-----------[ syntax type ]----------------------------------------------
+SmiUINT32 IpxSockAddress::get_syntax()
+{
+ return sNMP_SYNTAX_OCTETS;
+}
+
+//-----------[ construct an IpxSockAddress with another IpxSockAddress]----
+IpxSockAddress::IpxSockAddress( const IpxSockAddress &ipxaddr):IpxAddress(ipxaddr)
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = IPXSOCKLEN;
+ smival.value.string.ptr = address_buffer;
+
+ // copy the socket value
+ set_socket(ipxaddr.get_socket());
+ format_output();
+}
+
+
+//---------------[ default construct a IpxSockAddress ]--------------
+IpxSockAddress::IpxSockAddress( const char *inaddr):IpxAddress()
+{
+ if (ACE_OS::strlen(inaddr) == 0) {
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = IPXSOCKLEN;
+ smival.value.string.ptr = address_buffer;
+
+ set_socket(0);
+ format_output();
+ return;
+ }
+
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = IPXSOCKLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = parse_address( (char *) inaddr);
+ format_output();
+}
+
+
+//---------------[ construct a IpxSockAddress from a GenAddress ]----------
+IpxSockAddress::IpxSockAddress( const GenAddress &genaddr):IpxAddress()
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = IPXSOCKLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = 0;
+ unsigned short socketid = 0;
+ // allow use of an ipx or ipxsock address
+ if ( (genaddr.get_type() == type_ipx) )
+ {
+ valid_flag = genaddr.valid();
+ if ( valid_flag)
+ {
+ // copy in the Ipx address data
+ IpxAddress temp_ipx( (const char *) genaddr);
+ *this = temp_ipx;
+ }
+ }
+ else
+ if ( (genaddr.get_type() == type_ipxsock) )
+ {
+ valid_flag = genaddr.valid();
+ if ( valid_flag)
+ {
+ // copy in the Ipx address data
+ IpxSockAddress temp_ipxsock( (const char *) genaddr);
+ *this = temp_ipxsock;
+ // socketid info since are making an IpxSockAddress
+ socketid = temp_ipxsock.get_socket();
+ }
+ }
+ set_socket(socketid);
+ format_output();
+}
+
+
+//------------[ construct an IpxSockAddress from a IpxAddress ]--------------
+IpxSockAddress::IpxSockAddress( const IpxAddress &ipxaddr):IpxAddress(ipxaddr)
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = IPXSOCKLEN;
+ smival.value.string.ptr = address_buffer;
+
+ set_socket(0);
+ format_output();
+}
+
+//-----[ destructor ]--------------------------------------------------
+IpxSockAddress::~IpxSockAddress()
+{
+}
+
+// copy an instance of this Value
+SnmpSyntax& IpxSockAddress::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from itself
+ if ( this == &val )
+ return *this;
+
+ valid_flag=0; // will set to 1 if really valid
+ if (val.valid()){
+ switch (val.get_syntax()){
+ case sNMP_SYNTAX_OCTETS:
+ {
+ // See if it is of the Ipx address family
+ // This handles IpxSockAddress == IpxAddress
+ IpxSockAddress temp_ipx(val.to_string());
+ if (temp_ipx.valid()){
+ *this = temp_ipx; // ipxsock = ipxsock
+ }
+ // See if it is an OctetStr of appropriate length
+ else if (((IpxSockAddress &)val).smival.value.string.len == IPXSOCKLEN){
+ ACE_OS::memcpy(address_buffer,
+ ((IpxSockAddress &)val).smival.value.string.ptr,
+ IPXSOCKLEN);
+ valid_flag=1;
+ }
+ }
+ break;
+ }
+ }
+ format_output();
+ return *this;
+}
+
+// assignment to another IpAddress object overloaded
+IpxSockAddress& IpxSockAddress::operator=( const IpxSockAddress &ipxaddr)
+{
+ // protect against assignment from itself
+ if ( this == &ipxaddr )
+ return *this;
+
+ (IpxAddress&)*this = ipxaddr; // use ancestor assignment for ipx addr
+ set_socket(ipxaddr.get_socket()); // copy socket value
+ format_output();
+ return *this;
+}
+
+
+//----------[ create a new instance of this Value ]------------------------
+SnmpSyntax *IpxSockAddress::clone() const
+{
+ return (SnmpSyntax *) new IpxSockAddress(*this);
+}
+
+//----[ IPXSock address char * cast ]--------------------------------------
+IpxSockAddress::operator const char *() const
+{
+ return (char *)output_buffer;
+}
+
+//----[ IPXSock address get char representation ]--------------------------
+const char * IpxSockAddress::to_string()
+{
+ return (char *)output_buffer;
+}
+
+//----[ IPX address format output ]-------------------------------------
+void IpxSockAddress::format_output()
+{
+ IpxAddress::format_output(); // allow ancestors to format their buffers
+
+ if ( valid_flag)
+ ACE_OS::sprintf((char *) output_buffer,"%s/%d",
+ IpxAddress::to_string(), get_socket());
+ else
+ output_buffer[0] = 0;
+}
+
+//-----[ IP Address parse Address ]---------------------------------
+int IpxSockAddress::parse_address( const char *inaddr)
+{
+ char buffer[MAXHOSTNAMELEN +1];
+ unsigned short socketid=0;
+
+ if (inaddr && (ACE_OS::strlen( inaddr)< MAXHOSTNAMELEN))
+ ACE_OS::strcpy( buffer, inaddr);
+ else
+ {
+ valid_flag = 0;
+ return 0;
+ }
+ // look for port info @ the end of the string
+ // port can be delineated by a ':' or a '/'
+ // if neither are present then just treat it
+ // like a normal IpAddress
+ char *tmp;
+ tmp = ACE_OS::strstr( buffer,"/");
+
+ if (tmp != 0)
+ {
+ *tmp=0; // null terminator
+ tmp++;
+ socketid = ACE_OS::atoi( tmp);
+ }
+ set_socket(socketid);
+ return IpxAddress::parse_address( buffer);
+}
+
+
+
+//-------------[ set the socket number ]----------------------------------
+void IpxSockAddress::set_socket( const unsigned short s)
+{
+ unsigned short sock_nbo = htons(s);
+ ACE_OS::memcpy(&address_buffer[IPXLEN], &sock_nbo, 2);
+}
+
+//--------------[ get the socket number ]---------------------------------
+unsigned short IpxSockAddress::get_socket() const
+{
+ if (valid_flag)
+ {
+ unsigned short sock_nbo;
+ ACE_OS::memcpy(&sock_nbo, &address_buffer[IPXLEN], 2);
+ return ntohs(sock_nbo);
+ }
+ else
+ return 0; // don't use uninitialized memory
+}
+
+//------[ return the type ]----------------------------------------------
+addr_type IpxSockAddress::get_type() const
+{
+ return type_ipxsock;
+}
+
+
+//========================================================================
+//======== MACAddress Implementation =====================================
+//========================================================================
+
+//-----------[ syntax type ]----------------------------------------------
+SmiUINT32 MacAddress::get_syntax()
+{
+ return sNMP_SYNTAX_OCTETS;
+}
+
+//-----[ MAC Address copy constructor ]---------------------------------
+MacAddress::MacAddress(const MacAddress &macaddr)
+ : Address (macaddr)
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = MACLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = macaddr.valid_flag;
+ if (valid_flag)
+ ACE_OS::memcpy(address_buffer, macaddr.address_buffer, MACLEN);
+ format_output();
+}
+
+//---------[ constructor with a string argument ]-------------------------
+MacAddress::MacAddress( const char *inaddr):Address( )
+{
+ if (ACE_OS::strlen(inaddr) == 0) {
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = MACLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag=0;
+ format_output();
+ return;
+ }
+
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = MACLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = parse_address( (char *) inaddr);
+ format_output();
+}
+
+//-----[ construct a MacAddress from a GenAddress ]------------------------
+MacAddress::MacAddress( const GenAddress &genaddr)
+{
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = MACLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = 0;
+ // allow use of mac address
+ if (genaddr.get_type() == type_mac)
+ {
+ valid_flag = genaddr.valid();
+ if ( valid_flag)
+ {
+ // copy in the Mac address data
+ MacAddress temp_mac( (const char *) genaddr);
+ *this = temp_mac;
+ }
+ }
+ format_output();
+}
+
+//-----[ destructor ]--------------------------------------------------
+MacAddress::~MacAddress()
+{
+}
+
+//---------[ MacAddress clone ]-------------------------------------------
+SnmpSyntax *MacAddress::clone() const
+{
+ return (SnmpSyntax *) new MacAddress(*this);
+}
+
+//------[ assignment to another ipaddress object overloaded ]--------------
+MacAddress& MacAddress::operator=( const MacAddress &macaddress)
+{
+ // protect against assignment from itself
+ if ( this == &macaddress )
+ return *this;
+
+ valid_flag = macaddress.valid_flag;
+ if (valid_flag)
+ ACE_OS::memcpy(address_buffer, macaddress.address_buffer, MACLEN);
+ format_output();
+ return *this;
+}
+
+
+
+//-----[ MAC Address general = operator ]---------------------------------
+SnmpSyntax& MacAddress::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from itself
+ if ( this == &val )
+ return *this;
+
+ valid_flag=0; // will set to 1 if really valid
+ if (val.valid()){
+ switch (val.get_syntax()){
+ case sNMP_SYNTAX_OCTETS:
+ if (((MacAddress &)val).smival.value.string.len == MACLEN){
+ ACE_OS::memcpy(address_buffer,
+ ((MacAddress &)val).smival.value.string.ptr, MACLEN);
+ valid_flag=1;
+ }
+ break;
+ }
+ }
+ format_output();
+ return *this;
+}
+
+//-----[ MAC Address parse Address ]--------------------------------------
+// Convert a string to a six byte MAC address
+// On success sets validity 1 or 0
+//
+// MAC address format
+//
+// MAC ADDRESS
+// 01 02 03 04 05 06
+// XX:XX:XX:XX:XX:XX
+// Valid input format
+//
+// XXXXXXXXXXXX
+// Total length must be 17
+// Each char must take on value 0-F
+//
+//
+int MacAddress::parse_address( const char *inaddr)
+{
+ char temp[MAXHOSTNAMELEN +1]; // don't destroy original
+ char unsigned *tmp;
+ size_t z;
+
+
+ // save the orginal source
+ if ( !inaddr || (ACE_OS::strlen( inaddr) > 30)) return 0;
+ ACE_OS::strcpy( temp, inaddr);
+ trim_white_space( temp);
+
+ // bad total length check
+ if ( ACE_OS::strlen(temp) != 17)
+ return 0;
+
+ // check for colons
+ if ((temp[2] != ':')||(temp[5] != ':')||(temp[8]!=':')||(temp[11]!=':')
+ ||(temp[14] !=':'))
+ return 0;
+
+ // strip off the colons
+ tmp = ( unsigned char *) temp;
+ int i = 0;
+ while ( *tmp != 0)
+ {
+ if (*tmp != ':')
+ {
+ temp[i] = *tmp;
+ i++;
+ }
+ tmp++;
+ }
+ temp[i] = 0;
+
+ // convert to lower
+ for(z=0;z<ACE_OS::strlen(temp);z++)
+ temp[z] = tolower( temp[z]);
+
+
+ // check out the MAC address
+ tmp = ( unsigned char *) temp;
+ while( *tmp != 0)
+ if (((*tmp >= '0') && (*tmp <= '9'))|| // good 0-9
+ ((*tmp >= 'a') && (*tmp <= 'f'))) // or a-f
+ tmp++;
+ else
+ return 0;
+
+ // convert to target string
+ tmp = (unsigned char *) temp;
+ while ( *tmp != 0)
+ {
+ if (( *tmp >= '0') && ( *tmp <= '9'))
+ *tmp = *tmp - (char unsigned )'0';
+ else
+ *tmp = *tmp - (char unsigned) 'a' + (char unsigned) 10;
+ tmp++;
+ }
+
+ address_buffer[0] = (temp[0]*16) + temp[1];
+ address_buffer[1] = (temp[2]*16) + temp[3];
+ address_buffer[2] = (temp[4]*16) + temp[5];
+ address_buffer[3] = (temp[6]*16) + temp[7];
+ address_buffer[4] = (temp[8]*16) + temp[9];
+ address_buffer[5] = (temp[10]*16) + temp[11];
+
+ return 1;
+}
+
+//----[ MAC address char * cast ]--------------------------------------
+MacAddress::operator const char *() const
+{
+ return (char *)output_buffer;
+}
+//----[ MAC address get char representation ]--------------------------
+const char * MacAddress::to_string()
+{
+ return (char *)output_buffer;
+}
+
+//----[ MAC address format output ]---------------------------------
+void MacAddress::format_output()
+{
+ if ( valid_flag)
+ sprintf(output_buffer,"%02x:%02x:%02x:%02x:%02x:%02x",address_buffer[0],
+ address_buffer[1],address_buffer[2],address_buffer[3],
+ address_buffer[4],address_buffer[5]);
+ else
+ output_buffer[0] = 0;
+}
+
+//------[ return the type ]----------------------------------
+addr_type MacAddress::get_type() const
+{
+ return type_mac;
+}
+
+
+unsigned int MacAddress::hashFunction() const
+{
+ return ((((address_buffer[0] << 8) + address_buffer[1]) * HASH0LEN)
+ + (((address_buffer[2] << 8) + address_buffer[3]) * HASH1LEN)
+ + (((address_buffer[4] << 8) + address_buffer[5]) * HASH2LEN));
+}
+
+void MacAddress::to_octet(OctetStr& octet) const
+{
+ octet.set_data( smival.value.string.ptr, smival.value.string.len);
+}
+
+//========================================================================
+//========== Generic Address Implementation ==============================
+//========================================================================
+
+//-----------[ get the syntax]----------------------------------------------
+SmiUINT32 GenAddress::get_syntax()
+{
+ if (address != 0)
+ return address->get_syntax();
+
+ return sNMP_SYNTAX_NULL;
+}
+
+void GenAddress::init_smi()
+{
+ smival.syntax = sNMP_SYNTAX_NULL; // to be overridden
+ smival.value.string.len = 0; // to be overridden
+ smival.value.string.ptr = address_buffer; // constant
+}
+
+//-----------[ constructor with a string argument ]----------------------
+GenAddress::GenAddress( const char *addr): address(0)
+{
+ valid_flag = 0;
+ // initialize SMI info
+ // BOK: smival is generally not used for GenAddress, but
+ // we need this to be a replica of the real address'
+ // smival info so that <class>::operator=SnmpSyntax
+ // will work.
+ init_smi();
+
+ if (addr && ACE_OS::strlen(addr) == 0) {
+ format_output();
+ return;
+ }
+
+ parse_address(addr);
+
+ // Copy real address smival info into GenAddr smival
+ // BOK: smival is generally not used for GenAddress, but
+ // we need this to be a replica of the real address'
+ // smival info so that <class>::operator=SnmpSyntax
+ // will work.
+ if ( valid_flag ) {
+ smival.syntax = ((GenAddress *)address)->smival.syntax;
+ smival.value.string.len =
+ ((GenAddress *)address)->smival.value.string.len;
+ ACE_OS::memcpy(smival.value.string.ptr,
+ ((GenAddress *)address)->smival.value.string.ptr,
+ (size_t)smival.value.string.len);
+ }
+}
+
+//-----------[ constructor with an Address argument ]--------------------
+GenAddress::GenAddress( const Address &addr): address(0)
+{
+ valid_flag = 0;
+
+ // initialize SMI info
+ // BOK: this is generally not used for GenAddress,
+ // but we need this to be a replica of the real address'
+ // smival info so that operator=SnmpSyntax will work.
+ init_smi();
+ // make sure that the object is valid
+ if (!addr.valid()) {
+ format_output();
+ return;
+ }
+
+ address = (Address*)addr.clone();
+ if (address)
+ valid_flag = address->valid();
+
+ // Copy real address smival info into GenAddr smival
+ // BOK: smival is generally not used for GenAddress, but
+ // we need this to be a replica of the real address'
+ // smival info so that <class>::operator=SnmpSyntax
+ // will work.
+ if ( valid_flag ) {
+ smival.syntax = address->get_syntax();
+ smival.value.string.len =
+ ((GenAddress *)address)->smival.value.string.len;
+ ACE_OS::memcpy(smival.value.string.ptr,
+ ((GenAddress *)address)->smival.value.string.ptr,
+ (size_t)smival.value.string.len);
+ }
+
+ format_output();
+}
+
+//-----------------[ constructor with another GenAddress object ]-------------
+GenAddress::GenAddress( const GenAddress &addr)
+ : Address (addr),
+ address(0)
+{
+ valid_flag = 0;
+
+ // initialize SMI info
+ // BOK: this is generally not used for GenAddress,
+ // but we need this to be a replica of the real address'
+ // smival info so that operator=SnmpSyntax will work.
+ init_smi();
+
+ // make sure that the object is valid
+ if (!addr.valid_flag) {
+ format_output();
+ return;
+ }
+
+ address = (Address *)addr.address->clone();
+ if (address)
+ valid_flag = address->valid();
+
+ // Copy real address smival info into GenAddr smival
+ // BOK: smival is generally not used for GenAddress, but
+ // we need this to be a replica of the real address'
+ // smival info so that <class>::operator=SnmpSyntax
+ // will work.
+ if ( valid_flag ) {
+ smival.syntax = ((GenAddress *)address)->smival.syntax;
+ smival.value.string.len =
+ ((GenAddress *)address)->smival.value.string.len;
+ ACE_OS::memcpy(smival.value.string.ptr,
+ ((GenAddress *)address)->smival.value.string.ptr,
+ (size_t)smival.value.string.len);
+ }
+
+ format_output();
+}
+
+//----------[ destructor ] ------------------------------------------------
+GenAddress::~GenAddress()
+{
+ if ( address != 0)
+ delete address;
+}
+
+//----------[ create a new instance of this Value ]------------------------
+SnmpSyntax *GenAddress::clone() const
+{
+ return (SnmpSyntax *) new GenAddress(*this);
+}
+
+//------[ assignment GenAddress = GenAddress ]-----------------------------
+GenAddress& GenAddress::operator=( const GenAddress &addr)
+{
+ // protect against assignment from itself
+ if ( this == &addr )
+ return *this;
+
+ valid_flag = 0;
+ if (address) {
+ delete address;
+ address = 0;
+ }
+
+ if (addr.address)
+ address = (Address *)(addr.address)->clone();
+
+ if (address)
+ valid_flag = address->valid();
+
+ // Copy real address smival info into GenAddr smival
+ // BOK: smival is generally not used for GenAddress, but
+ // we need this to be a replica of the real address'
+ // smival info so that <class>::operator=SnmpSyntax
+ // will work.
+ if ( valid_flag ) {
+ smival.syntax = ((GenAddress *)address)->smival.syntax;
+ smival.value.string.len =
+ ((GenAddress *)address)->smival.value.string.len;
+ ACE_OS::memcpy(smival.value.string.ptr,
+ ((GenAddress *)address)->smival.value.string.ptr,
+ (size_t)smival.value.string.len);
+ }
+
+ format_output();
+ return *this;
+}
+
+
+//------[ assignment GenAddress = any SnmpSyntax ]-----------------------
+SnmpSyntax& GenAddress::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from itself
+ if ( this == &val )
+ return *this;
+
+ valid_flag = 0; // will get set to 1 if really valid
+ if ( address != 0) {
+ delete address;
+ address = 0;
+ }
+
+ if (val.valid()) {
+ switch ( val.get_syntax() ) {
+ //-----[ ip address case ]-------------
+ // BOK: this case shouldn't be needed since there is an explicit
+ // GenAddr=Address assignment that will override this assignment.
+ // Left here for posterity.
+ case sNMP_SYNTAX_IPADDR:
+ {
+ address = (Address *)val.clone();
+ if (address)
+ valid_flag = address->valid();
+ }
+ break;
+
+ //-----[ udp address case ]------------
+ //-----[ ipx address case ]------------
+ //-----[ mac address case ]------------
+ // BOK: This is here only to support GenAddr = primitive OctetStr.
+ // The explicit GenAddr=Address assignment will handle the cases
+ // GenAddr = [UdpAdd|IpxAddr|IpxSock|MacAddr|DecNetAddr|NetbiosAddr|AppleTlk].
+ // Note, using the heuristic of octet str len to determine type of
+ // address to create is not accurate when address lengths are equal
+ // (e.g., UDPIPV4LEN == MACLEN). It gets worse if we add AppleTalk or
+ // OSI which use variable length addresses! assume AppleTalk as used in IOS Mibs
+ // is defined in CISCO-TC.my as fixed length of 3 octets
+
+ case sNMP_SYNTAX_OCTETS:
+ {
+ unsigned long val_len;
+ val_len = ((GenAddress &)val).smival.value.string.len;
+
+ if (val_len == UDPIPV4LEN) {
+ ACE_NEW_RETURN(address, UdpAddress, *this);
+ }
+ else if (val_len ==IPV4LEN) {
+ ACE_NEW_RETURN(address, IpAddress, *this);
+ }
+ else if (val_len == IPXLEN) {
+ ACE_NEW_RETURN(address, IpxAddress, *this);
+ }
+ else if (val_len == IPXSOCKLEN) {
+ ACE_NEW_RETURN(address, IpxSockAddress, *this);
+ }
+ else if (val_len == MACLEN) {
+ ACE_NEW_RETURN(address, MacAddress, *this);
+ }
+ else if (val_len == APPLETKLEN) {
+ ACE_NEW_RETURN(address, AppleTalkAddress, *this);
+ }
+ else if (val_len == DECNETLEN) {
+ ACE_NEW_RETURN(address, DecNetAddress, *this);
+ }
+ else if (val_len == NETBIOSLEN) {
+ ACE_NEW_RETURN(address, DecNetAddress, *this);
+ }
+
+ if (address) {
+ *address = val;
+ valid_flag = address->valid();
+ }
+ }
+ break;
+ } // end switch
+ }
+
+ // Copy real address smival info into GenAddr smival
+ // BOK: smival is generally not used for GenAddress, but
+ // we need this to be a replica of the real address'
+ // smival info so that <class>::operator=SnmpSyntax
+ // will work.
+ if ( valid_flag ) {
+ smival.syntax = ((GenAddress *)address)->smival.syntax;
+ smival.value.string.len =
+ ((GenAddress *)address)->smival.value.string.len;
+ ACE_OS::memcpy(smival.value.string.ptr,
+ ((GenAddress *)address)->smival.value.string.ptr,
+ (size_t)smival.value.string.len);
+ }
+
+ format_output();
+ return *this;
+}
+
+
+// redefined parse address for macs
+// TODO: Add netbios, appletalk, and decnet addresses here
+int GenAddress::parse_address( const char *addr)
+{
+ if ( address != 0)
+ delete address;
+
+ // try to create each of the addresses until the correct one
+ // is found
+
+//BOK: Need to try IPX Sock and IPX before UDP since on Win32,
+// gethostbyname() seems to think the ipx network number
+// portion is a valid ipaddress string... stupid WinSOCK!
+
+ // ipxsock address
+ ACE_NEW_RETURN(address, IpxSockAddress( addr), -1);
+ valid_flag = address->valid();
+ if ( valid_flag && ((IpxSockAddress*)address)->get_socket()) {
+ format_output();
+ return 1; // ok its an ipxsock address
+ }
+ // otherwise delete it and try another
+ delete address;
+
+ // ipx address
+ ACE_NEW_RETURN(address, IpxAddress( addr), -1);
+ valid_flag = address->valid();
+ if ( valid_flag) {
+ format_output();
+ return 1; // ok its an ipx address
+ }
+ // otherwise delete it and try another
+ delete address;
+
+//TM: Must try the derived classes first...one pitfall of the
+//following solution is if someone creates with a port/socket of 0 the
+//class will get demoted to ip/ipx. The only proper way to do this is
+//to parse the strings ourselves.
+
+ // udp address
+ ACE_NEW_RETURN(address, UdpAddress( addr), -1);
+ valid_flag = address->valid();
+ if ( valid_flag && ((UdpAddress*)address)->get_port()) {
+ format_output();
+ return 1; // ok its a udp address
+ }
+
+ // otherwise delete it and try another
+ delete address;
+
+ // ip address
+ ACE_NEW_RETURN(address, IpAddress( addr), -1);
+ valid_flag = address->valid();
+ if ( valid_flag)
+ {
+ format_output();
+ return 1; // ok its an ip address
+ }
+ // otherwise delete it and try another
+ delete address;
+
+ // mac address
+ ACE_NEW_RETURN(address, MacAddress( addr), -1);
+ valid_flag = address->valid();
+ if ( valid_flag) {
+ format_output();
+ return 1; // ok, its a mac
+ }
+
+ // guess by length of argument the type of address
+ switch (ACE_OS::strlen(addr)) {
+ case NETBIOSLEN:
+ ACE_NEW_RETURN(address, NetbiosAddress( addr), -1);
+ valid_flag = address->valid();
+ if ( valid_flag) {
+ format_output();
+ return 1; // ok, its a mac
+ }
+ break;
+
+ case APPLETKLEN:
+ ACE_NEW_RETURN(address, AppleTalkAddress( addr), -1);
+ valid_flag = address->valid();
+ if ( valid_flag) {
+ format_output();
+ return 1; // ok, its a mac
+ }
+ break;
+
+ case DECNETLEN:
+ ACE_NEW_RETURN(address, DecNetAddress( addr), -1);
+ valid_flag = address->valid();
+ if ( valid_flag) {
+ format_output();
+ return 1; // ok, its a mac
+ }
+ break;
+
+ }
+ // otherwise its invalid
+ delete address;
+ address = 0;
+ format_output();
+ return 0;
+}
+
+GenAddress::operator const char *() const
+{
+ if ( address != 0)
+ return (const char *)*address; // pass thru
+ else
+ return (char *)output_buffer;
+}
+
+// to_string form of the contained address
+const char * GenAddress::to_string()
+{
+ if ( address != 0)
+ return address->to_string(); // pass thru
+ else
+ return (char *)output_buffer;
+}
+
+// format output
+void GenAddress::format_output()
+{
+ output_buffer[0] = '\0';
+}
+
+//------[ return the type ]----------------------------------
+addr_type GenAddress::get_type() const
+{
+ if (!valid())
+ return type_invalid;
+ else
+ return address->get_type();
+}
+
+// call the particular type class here
+void GenAddress::to_octet(OctetStr& octet) const
+{
+ if (!valid())
+ return;
+
+ address->to_octet(octet);
+}
+
+//------------------------------------------------------------------------
+//---------[ DecNet Address Class ]---------------------------------------
+//------------------------------------------------------------------------
+
+DecNetAddress::DecNetAddress( const char *inaddr): Address()
+{
+ if (ACE_OS::strlen(inaddr) == 0) {
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = DECNETLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag=0;
+ DecNetAddress::format_output();
+ return;
+ }
+
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = DECNETLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = parse_address( (char *) inaddr);
+ DecNetAddress::format_output();
+}
+
+DecNetAddress::DecNetAddress( const DecNetAddress& addr)
+ : Address (addr)
+{
+}
+
+DecNetAddress::DecNetAddress( const GenAddress& genaddr)
+{
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = DECNETLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = 0;
+ // allow use of an ipx or ipxsock address
+ if ( (genaddr.get_type() == type_decnet) ) {
+ valid_flag = genaddr.valid();
+ if ( valid_flag) {
+ // copy in the Ipx address data
+ DecNetAddress temp_ipx( (const char *) genaddr);
+ *this = temp_ipx;
+ }
+ }
+ DecNetAddress::format_output();
+}
+
+DecNetAddress::~DecNetAddress()
+{
+}
+
+const char *DecNetAddress::to_string()
+{
+ return (char *)output_buffer;
+}
+
+DecNetAddress& DecNetAddress::operator=( const DecNetAddress &decaddr)
+{
+ // protect against assignment from itself
+ if ( this == &decaddr )
+ return *this;
+ valid_flag = decaddr.valid_flag;
+ if (valid_flag)
+ ACE_OS::memcpy(address_buffer, decaddr.address_buffer, DECNETLEN);
+ format_output();
+ return *this;
+}
+
+void DecNetAddress::to_octet(OctetStr& octet) const
+{
+ octet.set_data( smival.value.string.ptr, smival.value.string.len);
+}
+
+DecNetAddress::operator const char *() const
+{
+ return (char *)output_buffer;
+}
+
+SmiUINT32 DecNetAddress::get_syntax()
+{
+ return sNMP_SYNTAX_OCTETS;
+}
+
+SnmpSyntax& DecNetAddress::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from itself
+ if ( this == &val )
+ return *this;
+
+ valid_flag = 0; // will get set 1 if really valid
+
+ if (val.valid()) {
+ if (((DecNetAddress &)val).smival.value.string.len ==DECNETLEN) {
+ ACE_OS::memcpy(address_buffer,
+ ((DecNetAddress &)val).smival.value.string.ptr, DECNETLEN);
+ valid_flag = 1;
+ }
+ }
+ DecNetAddress::format_output();
+ return *this;
+}
+
+SnmpSyntax *DecNetAddress::clone() const
+{
+ return (SnmpSyntax *) new DecNetAddress(*this);
+}
+
+addr_type DecNetAddress::get_type() const
+{
+ return type_decnet;
+}
+
+void DecNetAddress::format_output()
+{
+ // if valid format else null it
+ if ( valid_flag)
+ ACE_OS::sprintf( (char *) output_buffer,"%d.%d",address_buffer[0],
+ address_buffer[1]);
+ else
+ output_buffer[0] = 0;
+}
+
+int DecNetAddress::parse_address( const char *address)
+{
+ if (ACE_OS::strlen(address) > DECNETLEN)
+ return 0; // invalid
+
+ ACE_OS::memset(address_buffer, 0, DECNETLEN);
+ ACE_OS::memcpy(address_buffer, address, DECNETLEN);
+
+ return 1; // valid
+}
+
+
+//------------------------------------------------------------------------
+//---------[ AppleTalk Address Class ]------------------------------------
+//------------------------------------------------------------------------
+
+AppleTalkAddress::AppleTalkAddress( const char *inaddr): Address()
+{
+ if (ACE_OS::strlen(inaddr) == 0) {
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = APPLETKLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag=0;
+ AppleTalkAddress::format_output();
+ return;
+ }
+
+ // always initialize SMI info
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = APPLETKLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = parse_address( (char *) inaddr);
+ AppleTalkAddress::format_output();
+}
+AppleTalkAddress::AppleTalkAddress( const AppleTalkAddress& addr)
+ : Address (addr)
+{
+}
+
+AppleTalkAddress::AppleTalkAddress( const GenAddress& genaddr)
+{
+ smival.syntax = sNMP_SYNTAX_OCTETS;
+ smival.value.string.len = APPLETKLEN;
+ smival.value.string.ptr = address_buffer;
+
+ valid_flag = 0;
+ // allow use of an ipx or ipxsock address
+ if ( (genaddr.get_type() == type_atk) ) {
+ valid_flag = genaddr.valid();
+ if ( valid_flag) {
+ // copy in the Ipx address data
+ AppleTalkAddress temp_ipx( (const char *) genaddr);
+ *this = temp_ipx;
+ }
+ }
+ AppleTalkAddress::format_output();
+}
+
+AppleTalkAddress::~AppleTalkAddress()
+{
+}
+
+const char *AppleTalkAddress::to_string()
+{
+ return (char *)output_buffer;
+}
+
+AppleTalkAddress& AppleTalkAddress::operator=( const AppleTalkAddress &ataddr)
+{
+ // protect against assignment from itself
+ if ( this == &ataddr )
+ return *this;
+ valid_flag = ataddr.valid_flag;
+ if (valid_flag)
+ ACE_OS::memcpy(address_buffer, ataddr.address_buffer, APPLETKLEN);
+ format_output();
+ return *this;
+}
+
+void AppleTalkAddress::to_octet(OctetStr& octet) const
+{
+ octet.set_data( smival.value.string.ptr, smival.value.string.len);
+}
+
+AppleTalkAddress::operator const char *() const
+{
+ return (char *)output_buffer;
+}
+
+SmiUINT32 AppleTalkAddress::get_syntax()
+{
+ return sNMP_SYNTAX_OCTETS;
+}
+
+SnmpSyntax& AppleTalkAddress::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from itself
+ if ( this == &val )
+ return *this;
+
+ valid_flag = 0; // will get set 1 if really valid
+
+ if (val.valid()) {
+ if (((AppleTalkAddress &)val).smival.value.string.len ==APPLETKLEN) {
+ ACE_OS::memcpy(address_buffer,
+ ((AppleTalkAddress &)val).smival.value.string.ptr,APPLETKLEN);
+ valid_flag = 1;
+ }
+ }
+ AppleTalkAddress::format_output();
+ return *this;
+}
+
+SnmpSyntax *AppleTalkAddress::clone() const
+{
+ return (SnmpSyntax *) new AppleTalkAddress(*this);
+}
+
+addr_type AppleTalkAddress::get_type() const
+{
+ return type_atk;
+}
+
+void AppleTalkAddress::format_output()
+{
+ // if valid format else null it
+ if ( valid_flag)
+ ACE_OS::sprintf( (char *) output_buffer,"%d.%d.%d", address_buffer[0],
+ address_buffer[1], address_buffer[3]);
+ else
+ output_buffer[0] = 0;
+}
+
+int AppleTalkAddress::parse_address( const char *address)
+{
+ if (ACE_OS::strlen(address) > APPLETKLEN)
+ return 0; // invalid
+
+ ACE_OS::memset(address_buffer, 0, APPLETKLEN);
+ ACE_OS::memcpy(address_buffer, address, APPLETKLEN);
+
+ return 1; // valid
+}
+
+char AppleTalkAddress::get_host_address() const
+{
+ return address_buffer[2];
+}
+
+void AppleTalkAddress::set_host_address(const char host)
+{
+ address_buffer[2] = host;
+}
+
+short AppleTalkAddress::get_net_address() const
+{
+ short net;
+ ACE_OS::memcpy(&net, address_buffer, APPLETKLEN - 1);
+ return net;
+}
+
+void AppleTalkAddress::set_net_address(const short atknet)
+{
+ ACE_OS::memcpy(address_buffer, &atknet, APPLETKLEN -1);
+}
diff --git a/ACE/ASNMP/asnmp/address.h b/ACE/ASNMP/asnmp/address.h
new file mode 100644
index 00000000000..f8131c19485
--- /dev/null
+++ b/ACE/ASNMP/asnmp/address.h
@@ -0,0 +1,845 @@
+
+
+#ifndef ADDRESS_
+#define ADDRESS_
+//=============================================================================
+/**
+ * @file address.h
+ *
+ * $Id$
+ *
+ * Address class definition. Encapsulates various network
+ * addresses into easy to use, safe and portable classes.
+ *
+ *
+ * @author Peter E Mellquist
+ */
+//=============================================================================
+
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+//----[ includes ]-----------------------------------------------------
+// ACE OS Adaption layer
+#include "ace/os_include/netinet/os_in.h"
+#include "ace/os_include/os_netdb.h"
+#include "ace/Log_Msg.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "asnmp/smival.h"
+#include "asnmp/octet.h"
+
+//----[ enumerated types ] --------------------------------
+enum address_lengths {
+ IPV4LEN=4,
+ UDPIPV4LEN=6,
+ IPV6LEN=16,
+ UDPIPV6LEN=18,
+ IPXLEN=10,
+ IPXSOCKLEN=12,
+ NETBIOSLEN=16,
+ APPLETKLEN=3,
+ DECNETLEN=2,
+ MACLEN=6,
+ HASH0LEN=19,
+ HASH1LEN=13,
+ HASH2LEN=7,
+ MAX_ADDR_SZ=20,
+ MAX_DISPLAY_SZ=MAXHOSTNAMELEN+1
+};
+
+enum addr_type {
+ type_ip,
+ type_ipx,
+ type_udp,
+ type_ipxsock,
+ type_mac,
+ type_nb,
+ type_atk,
+ type_decnet,
+ type_e164,
+ type_sip, // IPv6
+ type_invalid
+};
+
+// TODO: get rest of nb service types added here
+enum nb_service {
+ nb_workstation = 0x0, nb_server = 0x20
+};
+
+//---[ forward declarations ]-----------------------------------------
+class GenAddress;
+class UdpAddress;
+class IpxSockAddress;
+class NetbiosAddress;
+class SIPAddress; // aka ipv6
+
+// TODO:
+// class AtmE164Address;
+
+
+//--------------------------------------------------------------------
+//----[ Address class ]-----------------------------------------------
+//--------------------------------------------------------------------
+/**
+ * @class
+ *
+ * @brief Defines the member functions for the abstract base class
+ * Address. An Address is a unique network endpoint.
+ */
+class ASNMP_Export Address: public SnmpSyntax
+{
+
+public:
+ /// allow destruction of derived classes
+ virtual ~Address();
+
+ /// overloaded equivlence operator, are two addresses equal?
+ friend ASNMP_Export bool operator==( const Address &lhs,const Address &rhs);
+
+ /// overloaded not equivlence operator, are two addresses not equal?
+ friend ASNMP_Export bool operator!=( const Address &lhs,const Address &rhs);
+
+ /// overloaded > operator, is a1 > a2
+ friend ASNMP_Export bool operator>( const Address &lhs,const Address &rhs);
+
+ /// overloaded >= operator, is a1 >= a2
+ friend ASNMP_Export bool operator>=( const Address &lhs,const Address &rhs);
+
+ /// overloaded < operator, is a1 < a2
+ friend ASNMP_Export bool operator<( const Address &lhs,const Address &rhs);
+
+ /// overloaded <= operator, is a1 <= a2
+ friend ASNMP_Export bool operator<=( const Address &lhs,const Address &rhs);
+
+ /// equivlence operator overloaded, are an address and a string equal?
+ friend ASNMP_Export bool operator==( const Address &lhs,const char *rhs);
+
+ /// overloaded not equivlence operator, are an address and string not equal?
+ friend ASNMP_Export bool operator!=( const Address &lhs,const char *rhs);
+
+ /// overloaded < , is an address greater than a string?
+ friend ASNMP_Export bool operator>( const Address &lhs,const char *rhs);
+
+ /// overloaded >=, is an address greater than or equal to a string?
+ friend ASNMP_Export bool operator>=( const Address &lhs,const char *rhs);
+
+ /// overloaded < , is an address less than a string?
+ friend ASNMP_Export bool operator<( const Address &lhs,const char *rhs);
+
+ /// overloaded <=, is an address less than or equal to a string?
+ friend ASNMP_Export bool operator<=( const Address &lhs,const char *rhs);
+
+ /// overloaded const char * cast
+ virtual operator const char *() const = 0;
+
+ /// verify the is the address object constructed ok
+ virtual int valid() const;
+
+ /// return a suitable buffer to contain the address
+ virtual void to_octet(OctetStr& octet) const = 0;
+
+ /// (pure virtual) syntax type
+ virtual SmiUINT32 get_syntax() = 0;
+
+ /// for non const [], allows reading and writing
+ unsigned char& operator[]( const int position);
+
+ /// get a printable ASCII value
+ virtual const char *to_string() = 0;
+
+ /// create a new instance of this Value
+ virtual SnmpSyntax *clone() const = 0;
+
+ /// return the type of address
+ virtual addr_type get_type() const = 0;
+
+ /// overloaded assignment operator
+ virtual SnmpSyntax& operator=( SnmpSyntax &val) = 0;
+
+ /// return a hash key
+ virtual unsigned int hashFunction() const { return 0;};
+
+
+protected:
+ /// state of constructed object (1/0)
+ /// addr internal representation
+ int valid_flag;
+ unsigned char address_buffer[MAX_ADDR_SZ];
+
+ /// parse the address string
+ /// redefined for each specific address subclass
+ virtual int parse_address( const char * inaddr) =0;
+
+ /// format the output
+ /// redefined for each specific address subclass
+ virtual void format_output() =0;
+
+ /// a reused trimm white space method
+ void trim_white_space( char * ptr);
+};
+
+
+//-----------------------------------------------------------------------
+//---------[ IPv4 Address Class ]----------------------------------------
+//-----------------------------------------------------------------------
+/**
+ * @class IpAddress
+ *
+ * @brief Defines the member functions for the concrete class IpAddress
+ * An IP Version 4 Address is 4 bytes long and consists of a
+ * Network, Sub Network, and host component.
+ */
+class ASNMP_Export IpAddress : public Address
+{
+public:
+ /// default construct an IP address with a string
+ IpAddress( const char *inaddr = "");
+
+ /// construct an IP address with another IP address
+ IpAddress( const IpAddress &ipaddr);
+
+ /// construct an IP address with a GenAddress
+ IpAddress( const GenAddress &genaddr);
+
+ /// destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden)
+ ~IpAddress();
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// assignment to another IpAddress object overloaded
+ IpAddress& operator=( const IpAddress &ipaddress);
+
+ // TODO: add ability to set addr given long
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// return the DNS Fully Qualified Domain Name (host.domain)
+ /// on failure returns dotted_quad string
+ const char *resolve_hostname(int& was_found);
+
+ /// return string representation of object (dotted quad returned)
+ virtual const char *to_string() ;
+
+ /// const char * operator overloaded for streaming output
+ virtual operator const char *() const;
+
+ /// logically AND two IPaddresses and
+ /// return the new one
+ void mask( const IpAddress& ipaddr);
+
+ /// return the type
+ virtual addr_type get_type() const;
+
+ /// syntax type
+ virtual SmiUINT32 get_syntax();
+
+ /// is this the loopback address? 127.0.0.1/loopback/1.0.0.127.in-addr.arpa
+ int is_loopback() const;
+
+ /// determine if this is a multicast address
+ int is_multicast() const;
+
+ /// determine if this a broadcast address
+ int is_broadcast() const;
+
+ /// per RFC 1597, private addresses are:: 10, 172.16, and 192.168.0
+ int is_private() const;
+
+ /// convert address into octet string format in network byte order
+ virtual void to_octet(OctetStr& octet) const;
+
+protected:
+ char output_buffer[MAX_DISPLAY_SZ]; // output buffer
+
+ /// friendly name storage
+ char iv_friendly_name_[MAX_DISPLAY_SZ];
+
+ /// did resolver call work? some addrs won't resolve
+ int iv_friendly_name_status_;
+
+ /// redefined parse address
+ /// specific to IP addresses
+ virtual int parse_address( const char *inaddr);
+
+ /// redefined format output
+ /// specific to IP addresses
+ virtual void format_output();
+
+ /// parse a dotted string
+ int parse_dotted_ipstring( const char *inaddr);
+
+ /// using the currently defined address, do a gethostbyname()
+ /// and try to fill up the name
+ int addr_to_friendly();
+
+ /// thread safe routine to lookup ip address given hostname
+ /// return <> 0 on error
+ static int resolve_to_address(const char *hostname, in_addr& quad_addr);
+
+ /// thread safe routine to lookup name given ip address
+ /// return <> 0 on error
+ static int resolve_to_hostname(const in_addr& quad_addr, char *hostname);
+
+};
+
+//------------------------------------------------------------------------
+//--------------[ DNS Iterator Class ]------------------------------------
+//------------------------------------------------------------------------
+
+/**
+ * @class Address_Iter
+ *
+ * @brief Defines routines to obtain information on a hostname/FQDN
+ * such as multiple addresses
+ */
+class ASNMP_Export Address_Iter
+{
+public:
+ Address_Iter(const char *hostname); // fully qualified domain name, hostname
+
+ /// did hostname resolve via DNS?
+ int valid() const;
+
+ /// how many addresses associated with this hostname
+ int how_many_addresses();
+
+ /// return next address
+ int next(IpAddress& addr);
+
+private:
+ Address_Iter(const Address_Iter&);
+ int valid_; // ctor status
+ int count_; // number of addresses
+ char **entry_; // ptr to current address
+ struct hostent lookupResult_;
+ ACE_HOSTENT_DATA buffer_;
+ int query_dns(const char *hostname);
+};
+
+//------------------------------------------------------------------------
+//---------[ UDP/IPv4 Address Class ]-------------------------------------
+//------------------------------------------------------------------------
+/**
+ * @class
+ *
+ * @brief Defines the member functions for the concrete class UdpAddress
+ * A Udp Address consists of an IP Version 4 Address (IpAddress)
+ * and a 2 byte unsigned port number. (see /etc/services file)
+ * User Datagram Protocol (UDP) is a best effort transport
+ */
+class ASNMP_Export UdpAddress : public IpAddress
+{
+public:
+ /// default constructor with a dotted string in the form of addr:port
+ UdpAddress( const char *inaddr = "");
+
+ /// construct an Udp address with another Udp address
+ UdpAddress( const UdpAddress &udpaddr);
+
+ /// construct a Udp address with a GenAddress
+ UdpAddress( const GenAddress &genaddr);
+
+ /// construct a Udp address with an IpAddress
+ /// default port # to zero
+ UdpAddress( const IpAddress &ipaddr);
+
+ /// destructor
+ ~UdpAddress();
+
+ /// syntax type
+ SmiUINT32 get_syntax();
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// assignment to another IpAddress object overloaded
+ UdpAddress& operator=( const UdpAddress &udpaddr);
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// output in the form of address:port
+ virtual const char *to_string() ;
+
+ /// const char * operator overloaded for streaming output
+ virtual operator const char *() const;
+
+ /// set the port number
+ void set_port( const unsigned short p);
+
+ /// get the port number
+ unsigned short get_port() const;
+
+ /// return the type
+ virtual addr_type get_type() const;
+
+protected:
+ /// output buffer
+ char output_buffer[MAX_DISPLAY_SZ];
+
+ /// redefined parse address
+ /// specific to IP addresses
+ virtual int parse_address( const char *inaddr);
+
+ /// redefined format output
+ /// specific to IP addresses
+ virtual void format_output();
+};
+
+
+//-------------------------------------------------------------------------
+//---------[ 802.3 MAC Address Class ]-------------------------------------
+//-------------------------------------------------------------------------
+/**
+ * @class
+ *
+ * @brief Defines the member functions for the concrete class MacAddress.
+ * A Media Access Control Address consists of 48 bits as defined
+ * in IEEE 802.3 specifications.
+ */
+class ASNMP_Export MacAddress : public Address
+{
+public:
+ /// constructor with a string argument
+ MacAddress( const char *inaddr = "");
+
+ /// constructor with another MAC object
+ MacAddress( const MacAddress &macaddr);
+
+ /// construct a MacAddress with a GenAddress
+ MacAddress( const GenAddress &genaddr);
+
+ /// destructor
+ ~MacAddress();
+
+ /// syntax type
+ SmiUINT32 get_syntax();
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// assignment to another IpAddress object overloaded
+ MacAddress& operator=( const MacAddress &macaddress);
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// create a string to internal class storage representing object
+ virtual const char *to_string();
+
+ /// const char * operator overloaded for streaming output
+ virtual operator const char *() const;
+
+ /// return the type
+ virtual addr_type get_type() const;
+
+ /// return a hash key
+ unsigned int hashFunction() const;
+
+ /// return byte array of the mac address
+ virtual void to_octet(OctetStr& octet) const;
+
+protected:
+ /// output buffer containing string representation of object
+ char output_buffer[MAX_DISPLAY_SZ];
+
+ /// redefined parse address for macs
+ virtual int parse_address( const char *inaddr);
+
+ /// redefined format output for MACs
+ virtual void format_output();
+};
+
+//------------------------------------------------------------------------
+//---------[ Netbios Address Class ]--------------------------------------
+//------------------------------------------------------------------------
+/**
+ * @class
+ *
+ * @brief Defines the member functions for the concrete class NetbiosAddress.
+ * The IBM/Microsoft address for NETBIOS, NETBEUI protocol transport.
+ */
+class ASNMP_Export NetbiosAddress : public Address
+{
+public:
+
+ /// default constructor with string arg
+ NetbiosAddress( const char *inaddr = "");
+
+ /// set name and service type
+ NetbiosAddress( const char *inaddr, nb_service svc);
+
+ /// copy constructor
+ NetbiosAddress( const NetbiosAddress& nbaddr);
+
+ /// construct with a GenAddress
+ NetbiosAddress( const GenAddress& genaddr);
+
+ ~NetbiosAddress();
+
+ virtual const char *to_string();
+
+ NetbiosAddress& operator=( const NetbiosAddress &nbaddr);
+
+ /// retrieve the network service type
+ nb_service get_service_type() const;
+
+ /// set the service type (workstation, server, etc)
+ void set_service_type(nb_service nbservice);
+
+ /// const char * operator overloaded for streaming output
+ virtual operator const char *() const;
+
+ /// syntax type
+ virtual SmiUINT32 get_syntax();
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// output byte buffer containing netbios name
+ virtual void to_octet(OctetStr& octet) const;
+
+protected:
+ void InitNBAddr(const char *inaddr);
+ char output_buffer[MAX_DISPLAY_SZ];
+
+ /// output buffer to hold string representation
+ virtual void format_output();
+ virtual int parse_address( const char *inaddr);
+ virtual addr_type get_type() const;
+};
+
+//------------------------------------------------------------------------
+//---------[ DecNet Address Class ]---------------------------------------
+//------------------------------------------------------------------------
+/**
+ * @class
+ *
+ * @brief Defines the member functions for the concrete class DecNetAddress.
+ * DecNet Phase ? address consists of two octets (CISCO-TC.my)
+ */
+class ASNMP_Export DecNetAddress : public Address
+{
+ public:
+ /// default constructor with string arg
+ DecNetAddress( const char *inaddr = "");
+
+ /// copy constructor
+ DecNetAddress( const DecNetAddress& decaddr);
+
+ /// construct with a GenAddress
+ DecNetAddress( const GenAddress& genaddr);
+
+ ~DecNetAddress();
+
+ virtual const char *to_string();
+
+ DecNetAddress& operator=( const DecNetAddress &decaddr);
+
+ /// convert address into octet string format 2 bytes of decnet address
+ virtual void to_octet(OctetStr& octet) const;
+
+ /// const char * operator overloaded for streaming output
+ virtual operator const char *() const;
+
+ /// syntax type
+ virtual SmiUINT32 get_syntax();
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ protected:
+ virtual int parse_address( const char *inaddr);
+ virtual addr_type get_type() const;
+ virtual void format_output();
+ char output_buffer[MAX_DISPLAY_SZ];
+};
+
+//------------------------------------------------------------------------
+//---------[ AppleTalk Address Class ]------------------------------------
+//------------------------------------------------------------------------
+/**
+ * @class
+ *
+ * @brief Defines the member functions for the concrete class DecNetAddress.
+ * DecNet Phase ? address consists of two octets (CISCO-TC.my)
+ */
+class ASNMP_Export AppleTalkAddress : public Address
+{
+ public:
+ /// default constructor with string arg
+ AppleTalkAddress( const char *inaddr = "");
+
+ /// copy constructor
+ AppleTalkAddress( const AppleTalkAddress& atkaddr);
+
+ /// construct with a GenAddress
+ AppleTalkAddress( const GenAddress& genaddr);
+
+ ~AppleTalkAddress();
+
+ virtual const char *to_string();
+
+ AppleTalkAddress& operator=( const AppleTalkAddress &atkaddr);
+
+ /// convert address into octet string format 3 bytes of atk address
+ virtual void to_octet(OctetStr& octet) const;
+
+ /// get the host part of the address
+ char get_host_address() const;
+
+ /// set the host part of the address
+ void set_host_address(const char);
+
+ /// get the 2 byte atk network address
+ short get_net_address() const;
+
+ /// set the host 2 byte atk network address
+ void set_net_address(const short atknet);
+
+ /// const char * operator overloaded for streaming output
+ virtual operator const char *() const;
+
+ /// syntax type
+ virtual SmiUINT32 get_syntax();
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ private:
+ virtual int parse_address( const char *inaddr);
+ virtual addr_type get_type() const;
+ virtual void format_output();
+ char output_buffer[MAX_DISPLAY_SZ];
+};
+
+//------------------------------------------------------------------------
+//---------[ IPX Address Class ]------------------------------------------
+//------------------------------------------------------------------------
+/**
+ * @class IpxAddress
+ *
+ * @brief Defines the member functions for the concrete class IpxAddress.
+ * Novell's IPX (version ?) network protocol endpoint
+ */
+class ASNMP_Export IpxAddress : public Address
+{
+public:
+ /// default constructor with a string arg
+ IpxAddress( const char *inaddr = "");
+
+ /// constructor with another ipx object
+ IpxAddress( const IpxAddress &ipxaddr);
+
+ /// construct with a GenAddress
+ IpxAddress( const GenAddress &genaddr);
+
+ /// destructor
+ ~IpxAddress();
+
+ /// syntax type
+ virtual SmiUINT32 get_syntax();
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// assignment to another IpxAddress object overloaded
+ IpxAddress& operator=( const IpxAddress &ipxaddress);
+
+ /// get the host id portion of an ipx address
+ int get_hostid( MacAddress& mac);
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// create string represtation of object value
+ virtual const char *to_string();
+
+ /// const char * operator overloaded for streaming output
+ virtual operator const char *() const;
+
+ /// return the type
+ virtual addr_type get_type() const;
+
+ /// return byte sequence containing ipx address
+ virtual void to_octet(OctetStr& octet) const;
+
+protected:
+ /// ipx format separator {:,/}
+ char separator;
+
+ /// output buffer to hold string representation
+ char output_buffer[MAX_DISPLAY_SZ];
+
+ /// redefined parse address for ipx strings
+ virtual int parse_address( const char *inaddr);
+
+ /// redefined format output for ipx strings
+ /// uses same separator as when constructed
+ virtual void format_output();
+};
+
+
+
+//------------------------------------------------------------------------
+//---------[ IpxSock Address Class ]--------------------------------------
+//------------------------------------------------------------------------
+/**
+ * @class IpxSockAddress
+ *
+ * @brief Defines the member functions for the concrete class IpxAddress.
+ * Novell's IPX (version ?) network protocol endpoint
+ */
+class ASNMP_Export IpxSockAddress : public IpxAddress
+{
+public:
+ /// constructor with a dotted string
+ IpxSockAddress( const char *inaddr = "");
+
+ /// construct an Udp address with another Udp address
+ IpxSockAddress( const IpxSockAddress &ipxaddr);
+
+ ///constructor with a GenAddress
+ IpxSockAddress( const GenAddress &genaddr);
+
+ ///constructor with a IpxAddress
+ /// default socket # is 0
+ IpxSockAddress( const IpxAddress &ipxaddr);
+
+ /// destructor
+ ~IpxSockAddress();
+
+ /// syntax type
+ virtual SmiUINT32 get_syntax();
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// assignment to another IpxAddress object overloaded
+ IpxSockAddress& operator=( const IpxSockAddress &ipxaddr);
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// set the socket number
+ void set_socket( const unsigned short s);
+
+ /// get the socket number
+ unsigned short get_socket() const;
+
+ /// create string representation of object value
+ virtual const char *to_string();
+
+ /// const char * operator overloaded for streaming output
+ virtual operator const char *() const;
+
+ /// return the type
+ virtual addr_type get_type() const;
+
+protected:
+ /// output buffer to hold string representation of object
+ char output_buffer[MAX_DISPLAY_SZ];
+
+ /// redefined parse address for ipx strings
+ virtual int parse_address( const char *inaddr);
+
+ /// redefined format output
+ /// specific to IP addresses
+ virtual void format_output();
+};
+
+//-------------------------------------------------------------------------
+//--------[ Generic Address ]----------------------------------------------
+//-------------------------------------------------------------------------
+/**
+ * @class GenAddress
+ *
+ * @brief Defines the member functions for the concrete class GenAddress.
+ * This class attempts to determine an address type given a char string.
+ */
+class ASNMP_Export GenAddress : public Address
+{
+public:
+ /// constructor with a string argument
+ GenAddress( const char *addr = "");
+
+ /// constructor with an Address
+ GenAddress( const Address &addr);
+
+ /// constructor with another GenAddress
+ GenAddress( const GenAddress &addr);
+
+ /// destructor
+ ~GenAddress();
+
+ /// get the snmp syntax of the contained address
+ SmiUINT32 get_syntax();
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// assignment of a GenAddress
+ GenAddress& operator=( const GenAddress &addr);
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// string representation of object value
+ virtual const char *to_string();
+
+ /// const char * operator overloaded for streaming output
+ virtual operator const char *() const;
+
+ /// return the type
+ virtual addr_type get_type() const;
+
+ /// return the address as a octet sequence
+ virtual void to_octet(OctetStr& octet) const;
+
+protected:
+ /// pointer to a a concrete address
+ Address *address;
+
+ /// output buffer of objects value
+ char output_buffer[MAX_DISPLAY_SZ];
+
+ /// redefined parse address for macs
+ virtual int parse_address( const char *addr);
+
+ /// format output for a generic address
+ virtual void format_output();
+
+ /// initialize smi data structure
+ void init_smi();
+};
+
+#endif //_ADDRESS
diff --git a/ACE/ASNMP/asnmp/asn1.cpp b/ACE/ASNMP/asnmp/asn1.cpp
new file mode 100644
index 00000000000..8a3b6f9c088
--- /dev/null
+++ b/ACE/ASNMP/asnmp/asn1.cpp
@@ -0,0 +1,1729 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// asn1.cpp
+//
+// = DESCRIPTION
+// The Vb class is an encapsulation of the snmp variable binding.
+// This module contains the class definition for the variable binding (VB)
+// class. The VB class is an encapsulation of a SNMP VB. A VB object is
+// composed of one SNMP++ Oid and one SMI value. The Vb class utilizes Oid
+// objects and thus requires the Oid class. To use this class,
+// set oid, value then call valid() to be sure object was constructed correctly.
+//
+// = AUTHOR
+// S. Waldbusser (assumed)
+// Michael R MacFaden mrm@cisco.com - rework & ACE port
+// ============================================================================
+/**********************************************************************
+// *
+ * Abstract Syntax Notation One, ASN.1
+ * As defined in ISO/IS 8824 and ISO/IS 8825
+ * This implements a subset of the above International Standards that
+ * is sufficient to implement SNMP.
+ *
+ * Encodes abstract data types into a machine independent stream of bytes.
+ *
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appear in all copies and that
+ both that copyright notice and this permission notice appear in
+ supporting documentation, and that the name of CMU not be
+ used in advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ SOFTWARE.
+ ******************************************************************/
+
+#include "asnmp/asn1.h"
+#include "asnmp/snmp.h"
+#include "ace/OS_NS_string.h"
+
+ACE_RCSID(asnmp, asn1, "$Id$")
+
+/*
+ * parse_int - pulls a long out of an ASN int type.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the end of this object.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char * asn1::parse_int( u_char *data,
+ int *datalength,
+ u_char *type,
+ long int *intp,
+ int intsize)
+{
+ ACE_TRACE("asn1::parse_int");
+ /*
+ * ASN.1 integer ::= 0x02 asnlength byte {byte}*
+ */
+ u_char *bufp = data;
+ u_long asn_length;
+ long value = 0;
+
+ if (intsize != sizeof (long)){
+ ASNERROR("not long");
+ return 0;
+ }
+ *type = *bufp++;
+ bufp =asn1::parse_length(bufp, &asn_length);
+ if (bufp == 0){
+ ASNERROR("bad length");
+ return 0;
+ }
+ if ((int)(asn_length + (bufp - data)) > *datalength){
+ ASNERROR("overflow of message");
+ return 0;
+ }
+ if ((int)asn_length > intsize){
+ ASNERROR("I don't support such large integers");
+ return 0;
+ }
+ *datalength -= (int)asn_length + (bufp - data);
+ if (*bufp & 0x80)
+ value = -1; /* integer is negative */
+ while(asn_length--)
+ value = (value << 8) | *bufp++;
+ *intp = value;
+ return bufp;
+}
+
+
+/*
+ * parse_unsigned_int - pulls an u_long out of an ASN int type.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the end of this object.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char * asn1::parse_unsigned_int( u_char *data,
+ int *datalength,
+ u_char *type,
+ u_long *intp,
+ int intsize)
+{
+ ACE_TRACE("asn1::parse_unsigned_int");
+ /*
+ * ASN.1 integer ::= 0x02 asnlength byte {byte}*
+ */
+ u_char *bufp = data;
+ u_long asn_length;
+ u_long value = 0;
+
+ if (intsize != sizeof (long)){
+ ASNERROR("not long");
+ return 0;
+ }
+ *type = *bufp++;
+ bufp = asn1::parse_length(bufp, &asn_length);
+ if (bufp == 0){
+ ASNERROR("bad length");
+ return 0;
+ }
+ if ((int)(asn_length + (bufp - data)) > *datalength){
+ ASNERROR("overflow of message");
+ return 0;
+ }
+ if (((int)asn_length > (intsize + 1)) ||
+ (((int)asn_length == intsize + 1) && *bufp != 0x00)){
+ ASNERROR("I don't support such large integers");
+ return 0;
+ }
+ *datalength -= (int)asn_length + (bufp - data);
+ if (*bufp & 0x80)
+ value = (u_long) -1;
+ while(asn_length--)
+ value = (value << 8) | *bufp++;
+ *intp = value;
+ return bufp;
+}
+
+
+/*
+ * build_int - builds an ASN object containing an integer.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the end of this object.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char * asn1::build_int( u_char *data,
+ int *datalength,
+ u_char type,
+ long *intp,
+ int intsize)
+{
+ ACE_TRACE("asn1::build_int");
+ /*
+ * ASN.1 integer ::= 0x02 asnlength byte {byte}*
+ */
+
+ long integer;
+ u_long mask;
+
+ if (intsize != sizeof (long))
+ return 0;
+ integer = *intp;
+ /*
+ * Truncate "unnecessary" bytes off of the most significant end of this
+ * 2's complement integer. There should be no sequence of 9
+ * consecutive 1's or 0's at the most significant end of the
+ * integer.
+ */
+ mask = u_long (0x1FF) << ((8 * (sizeof(u_long) - 1)) - 1);
+ /* mask is 0xFF800000 on a big-endian machine */
+ while((((integer & mask) == 0) || ((integer & mask) == mask))
+ && intsize > 1){
+ intsize--;
+ integer <<= 8;
+ }
+ data = asn1::build_header(data, datalength, type, intsize);
+ if (data == 0)
+ return 0;
+ if (*datalength < intsize)
+ return 0;
+ *datalength -= intsize;
+ mask = u_long (0xFF) << (8 * (sizeof(u_long) - 1));
+ /* mask is 0xFF000000 on a big-endian machine */
+ while(intsize--){
+ *data++ = (u_char)((integer & mask) >> (8 * (sizeof(long) - 1)));
+ integer <<= 8;
+ }
+ return data;
+}
+
+
+/*
+ * build_unsigned_int - builds an ASN object containing an integer.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the end of this object.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char * asn1::build_unsigned_int( u_char *data,
+ int *datalength,
+ u_char type,
+ u_long *intp,
+ int intsize)
+{
+ ACE_TRACE("asn1::build_unsigned_int");
+ /*
+ * ASN.1 integer ::= 0x02 asnlength byte {byte}*
+ */
+
+ u_long integer;
+ u_long mask;
+ int add_null_byte = 0;
+
+ if (intsize != sizeof (long))
+ return 0;
+ integer = *intp;
+ mask = u_long (0xFF) << (8 * (sizeof(u_long) - 1));
+ /* mask is 0xFF000000 on a big-endian machine */
+ if ((u_char)((integer & mask) >> (8 * (sizeof(long) - 1))) & 0x80){
+ /* if MSB is set */
+ add_null_byte = 1;
+ intsize++;
+ }
+ /*
+ * Truncate "unnecessary" bytes off of the most significant end of this 2's complement integer.
+ * There should be no sequence of 9 consecutive 1's or 0's at the most significant end of the
+ * integer.
+ */
+ mask = u_long (0x1FF) << ((8 * (sizeof(u_long) - 1)) - 1);
+ /* mask is 0xFF800000 on a big-endian machine */
+ while((((integer & mask) == 0) || ((integer & mask) == mask)) && intsize > 1){
+ intsize--;
+ integer <<= 8;
+ }
+ data = asn1::build_header(data, datalength, type, intsize);
+ if (data == 0)
+ return 0;
+ if (*datalength < intsize)
+ return 0;
+ *datalength -= intsize;
+ if (add_null_byte == 1){
+ *data++ = '\0';
+ intsize--;
+ }
+ mask = u_long (0xFF) << (8 * (sizeof(u_long) - 1));
+ /* mask is 0xFF000000 on a big-endian machine */
+ while(intsize--){
+ *data++ = (u_char)((integer & mask) >> (8 * (sizeof(long) - 1)));
+ integer <<= 8;
+ }
+ return data;
+}
+
+
+/*
+ * parse_string - pulls an octet string out of an ASN octet string type.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the beginning of the next object.
+ *
+ * "string" is filled with the octet string.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char * asn1::parse_string( u_char *data,
+ int *datalength,
+ u_char *type,
+ u_char *string,
+ int *strlength)
+{
+ ACE_TRACE("asn1::parse_string");
+ /*
+ * ASN.1 octet string ::= primstring | cmpdstring
+ * primstring ::= 0x04 asnlength byte {byte}*
+ * cmpdstring ::= 0x24 asnlength string {string}*
+ */
+ u_char *bufp = data;
+ u_long asn_length;
+
+ *type = *bufp++;
+ bufp = asn1::parse_length(bufp, &asn_length);
+ if (bufp == 0)
+ return 0;
+ if ((int)(asn_length + (bufp - data)) > *datalength){
+ ASNERROR("overflow of message");
+ return 0;
+ }
+ if ((int)asn_length > *strlength){
+ ASNERROR("I don't support such long strings");
+ return 0;
+ }
+ // fixed
+ ACE_OS::memcpy((char *)string, (char *)bufp, (int)asn_length);
+ *strlength = (int)asn_length;
+ *datalength -= (int)asn_length + (bufp - data);
+ return bufp + asn_length;
+}
+
+
+/*
+ * build_string - Builds an ASN octet string object containing the input string.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the beginning of the next object.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char * asn1::build_string( u_char *data,
+ int *datalength,
+ u_char type,
+ u_char *string,
+ int strlength)
+{
+ ACE_TRACE("asn1::build_string");
+ /*
+ * ASN.1 octet string ::= primstring | cmpdstring
+ * primstring ::= 0x04 asnlength byte {byte}*
+ * cmpdstring ::= 0x24 asnlength string {string}*
+ * This code will never send a compound string.
+ */
+ data = asn1::build_header(data, datalength, type, strlength);
+ if (data == 0)
+ return 0;
+ if (*datalength < strlength)
+ return 0;
+ // fixed
+ ACE_OS::memcpy((u_char *)data,(u_char *)string, strlength);
+ *datalength -= strlength;
+ return data + strlength;
+}
+
+
+/*
+ * parse_header - interprets the ID and length of the current object.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * in this object following the id and length.
+ *
+ * Returns a pointer to the first byte of the contents of this object.
+ * Returns 0 on any error.
+ */
+u_char *asn1::parse_header( u_char *data,
+ int *datalength,
+ u_char *type)
+{
+ ACE_TRACE("asn1::parse_header");
+ u_char *bufp = data;
+ register int header_len;
+ u_long asn_length;
+
+ /* this only works on data types < 30, i.e. no extension octets */
+ if (IS_EXTENSION_ID(*bufp)){
+ ASNERROR("can't process ID >= 30");
+ return 0;
+ }
+ *type = *bufp;
+ bufp = asn1::parse_length(bufp + 1, &asn_length);
+ if (bufp == 0)
+ return 0;
+ header_len = bufp - data;
+ if ((int)(header_len + asn_length) > *datalength){
+ ASNERROR("asn length too long");
+ return 0;
+ }
+ *datalength = (int)asn_length;
+ return bufp;
+}
+
+/*
+ * asn1::build_header - builds an ASN header for an object with the ID and
+ * length specified.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * in this object following the id and length.
+ *
+ * This only works on data types < 30, i.e. no extension octets.
+ * The maximum length is 0xFFFF;
+ *
+ * Returns a pointer to the first byte of the contents of this object.
+ * Returns 0 on any error.
+ */
+u_char * asn1::build_header( u_char *data,
+ int *datalength,
+ u_char type,
+ int length)
+{
+ ACE_TRACE("asn1::build_header");
+ if (*datalength < 1)
+ return 0;
+ *data++ = type;
+ (*datalength)--;
+ return asn1::build_length(data, datalength, length);
+
+}
+
+/*
+ * asn_build_sequence - builds an ASN header for a sequence with the ID and
+ * length specified.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * in this object following the id and length.
+ *
+ * This only works on data types < 30, i.e. no extension octets.
+ * The maximum length is 0xFFFF;
+ *
+ * Returns a pointer to the first byte of the contents of this object.
+ * Returns 0 on any error.
+ */
+u_char * asn1::build_sequence( u_char *data,
+ int *datalength,
+ u_char type,
+ int length)
+{
+ ACE_TRACE("asn1::build_sequence");
+ *datalength -= 4;
+ if (*datalength < 0){
+ *datalength += 4; /* fix up before punting */
+ return 0;
+ }
+ *data++ = type;
+ *data++ = (u_char)(0x02 | ASN_LONG_LEN);
+ *data++ = (u_char)((length >> 8) & 0xFF);
+ *data++ = (u_char)(length & 0xFF);
+ return data;
+}
+
+/*
+ * parse_length - interprets the length of the current object.
+ * On exit, length contains the value of this length field.
+ *
+ * Returns a pointer to the first byte after this length
+ * field (aka: the start of the data field).
+ * Returns 0 on any error.
+ */
+u_char * asn1::parse_length( u_char *data,
+ u_long *length)
+{
+ ACE_TRACE("asn1::parse_length");
+ u_char lengthbyte = *data;
+
+ if (lengthbyte & ASN_LONG_LEN){
+ lengthbyte &= ~ASN_LONG_LEN; /* turn MSb off */
+ if (lengthbyte == 0){
+ ASNERROR("We don't support indefinite lengths");
+ return 0;
+ }
+ if (lengthbyte > sizeof(long)){
+ ASNERROR("we can't support data lengths that long");
+ return 0;
+ }
+ // fixed
+ ACE_OS::memcpy((char *)length, (char *)data + 1, (int)lengthbyte);
+ *length = ntohl(*length);
+ *length >>= (8 * ((sizeof *length) - lengthbyte));
+ return data + lengthbyte + 1;
+ } else { /* short asnlength */
+ *length = (long)lengthbyte;
+ return data + 1;
+ }
+}
+
+u_char *asn1::build_length( u_char *data,
+ int *datalength,
+ int length)
+{
+ ACE_TRACE("asn1::build_length");
+ u_char *start_data = data;
+
+ /* no indefinite lengths sent */
+ if (length < 0x80){
+ if (*datalength < 1){
+ ASNERROR("build_length");
+ return 0;
+ }
+ *data++ = (u_char)length;
+ } else if (length <= 0xFF){
+ if (*datalength < 2){
+ ASNERROR("build_length");
+ return 0;
+ }
+ *data++ = (u_char)(0x01 | ASN_LONG_LEN);
+ *data++ = (u_char)length;
+ } else { /* 0xFF < length <= 0xFFFF */
+ if (*datalength < 3){
+ ASNERROR("build_length");
+ return 0;
+ }
+ *data++ = (u_char)(0x02 | ASN_LONG_LEN);
+ *data++ = (u_char)((length >> 8) & 0xFF);
+ *data++ = (u_char)(length & 0xFF);
+ }
+ *datalength -= (data - start_data);
+ return data;
+
+}
+
+/*
+ * parse_objid - pulls an object indentifier out of an ASN object identifier type.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the beginning of the next object.
+ *
+ * "objid" is filled with the object identifier.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char *asn1::parse_objid( u_char *data,
+ int *datalength,
+ u_char *type,
+ oid *objid,
+ int *objidlength)
+{
+ ACE_TRACE("asn1::parse_objid");
+ /*
+ * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*
+ * subidentifier ::= {leadingbyte}* lastbyte
+ * leadingbyte ::= 1 7bitvalue
+ * lastbyte ::= 0 7bitvalue
+ */
+ u_char *bufp = data;
+ oid *oidp = objid + 1;
+ u_long subidentifier;
+ long length;
+ u_long asn_length;
+
+ *type = *bufp++;
+ bufp = asn1::parse_length(bufp, &asn_length);
+ if (bufp == 0)
+ return 0;
+ if ((int)asn_length + (bufp - data) > *datalength){
+ ASNERROR("overflow of message");
+ return 0;
+ }
+ *datalength -= (int)asn_length + (bufp - data);
+
+ /* Handle invalid object identifier encodings of the form 06 00 robustly */
+ if (asn_length == 0)
+ objid[0] = objid[1] = 0;
+
+ length = asn_length;
+ (*objidlength)--; /* account for expansion of first byte */
+ while (length > 0 && (*objidlength)-- > 0){
+ subidentifier = 0;
+ do { /* shift and add in low order 7 bits */
+ subidentifier = (subidentifier << 7) + (*(u_char *)bufp & ~ASN_BIT8);
+ length--;
+ } while (*(u_char *)bufp++ & ASN_BIT8); /* last byte has high bit clear */
+ if (subidentifier > (u_long)MAX_SUBID){
+ ASNERROR("subidentifier too long");
+ return 0;
+ }
+ *oidp++ = (oid)subidentifier;
+ }
+
+ /*
+ * The first two subidentifiers are encoded into the first component
+ * with the value (X * 40) + Y, where:
+ * X is the value of the first subidentifier.
+ * Y is the value of the second subidentifier.
+ */
+ subidentifier = (u_long)objid[1];
+ if (subidentifier == 0x2B){
+ objid[0] = 1;
+ objid[1] = 3;
+ } else {
+ objid[1] = (u_char)(subidentifier % 40);
+ objid[0] = (u_char)((subidentifier - objid[1]) / 40);
+ }
+
+ *objidlength = (int)(oidp - objid);
+ return bufp;
+}
+
+/*
+ * build_objid - Builds an ASN object identifier object containing the
+ * input string.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the beginning of the next object.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char *asn1::build_objid( u_char *data,
+ int *datalength,
+ u_char type,
+ oid *objid,
+ int objidlength)
+{
+ ACE_TRACE("asn1::build_objid");
+ /*
+ * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*
+ * subidentifier ::= {leadingbyte}* lastbyte
+ * leadingbyte ::= 1 7bitvalue
+ * lastbyte ::= 0 7bitvalue
+ */
+ u_char buf[MAX_OID_LEN];
+ u_char *bp = buf;
+ oid *op = objid;
+ int asnlength;
+ u_long subid, mask, testmask;
+ int bits, testbits;
+
+ if (objidlength < 2){
+ *bp++ = 0;
+ objidlength = 0;
+ } else {
+ *bp++ = (u_char) (op[1] + (op[0] * 40));
+ objidlength -= 2;
+ op += 2;
+ }
+
+ while(objidlength-- > 0){
+ subid = *op++;
+ if (subid < 127){ /* off by one? */
+ *bp++ = (u_char )subid;
+ } else {
+ mask = 0x7F; /* handle subid == 0 case */
+ bits = 0;
+ /* testmask *MUST* !!!! be of an u_type */
+ for(testmask = 0x7F, testbits = 0; testmask != 0;
+ testmask <<= 7, testbits += 7){
+ if (subid & testmask){ /* if any bits set */
+ mask = testmask;
+ bits = testbits;
+ }
+ }
+ /* mask can't be zero here */
+ for(;mask != 0x7F; mask >>= 7, bits -= 7){
+ /* fix a mask that got truncated above */
+ if (mask == 0x1E00000)
+ mask = 0xFE00000;
+ *bp++ = (u_char)(((subid & mask) >> bits) | ASN_BIT8);
+ }
+ *bp++ = (u_char)(subid & mask);
+ }
+ }
+ asnlength = bp - buf;
+ data = asn1::build_header(data, datalength, type, asnlength);
+ if (data == 0)
+ return 0;
+ if (*datalength < asnlength)
+ return 0;
+ // fixed
+ ACE_OS::memcpy((char *)data, (char *)buf, asnlength);
+ *datalength -= asnlength;
+ return data + asnlength;
+}
+
+/*
+ * parse_null - Interprets an ASN null type.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the beginning of the next object.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char *asn1::parse_null(u_char *data,
+ int *datalength,
+ u_char *type)
+{
+ ACE_TRACE("asn1::parse_null");
+ /*
+ * ASN.1 null ::= 0x05 0x00
+ */
+ u_char *bufp = data;
+ u_long asn_length;
+
+ *type = *bufp++;
+ bufp = asn1::parse_length(bufp, &asn_length);
+ if (bufp == 0)
+ return 0;
+ if (asn_length != 0){
+ ASNERROR("Malformed 0");
+ return 0;
+ }
+ *datalength -= (bufp - data);
+ return bufp + asn_length;
+}
+
+
+/*
+ * build_null - Builds an ASN null object.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the beginning of the next object.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char *asn1::build_null( u_char *data,
+ int *datalength,
+ u_char type)
+{
+ ACE_TRACE("asn1::build_null");
+ /*
+ * ASN.1 null ::= 0x05 0x00
+ */
+ return asn1::build_header(data, datalength, type, 0);
+}
+
+/*
+ * parse_bitstring - pulls a bitstring out of an ASN bitstring type.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the beginning of the next object.
+ *
+ * "string" is filled with the bit string.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char *asn1::parse_bitstring( u_char *data,
+ int *datalength,
+ u_char *type,
+ u_char *string,
+ int *strlength)
+{
+ ACE_TRACE("asn1::parse_bitstring");
+ /*
+ * bitstring ::= 0x03 asnlength unused {byte}*
+ */
+ u_char *bufp = data;
+ u_long asn_length;
+
+ *type = *bufp++;
+ bufp = asn1::parse_length(bufp, &asn_length);
+ if (bufp == 0)
+ return 0;
+ if ((int)(asn_length + (bufp - data)) > *datalength){
+ ASNERROR("overflow of message");
+ return 0;
+ }
+ if ((int) asn_length > *strlength){
+ ASNERROR("I don't support such long bitstrings");
+ return 0;
+ }
+ if (asn_length < 1){
+ ASNERROR("Invalid bitstring");
+ return 0;
+ }
+ if (*bufp > 7){
+ ASNERROR("Invalid bitstring");
+ return 0;
+ }
+ // fixed
+ ACE_OS::memcpy((char *)string,(char *)bufp, (int)asn_length);
+ *strlength = (int)asn_length;
+ *datalength -= (int)asn_length + (bufp - data);
+ return bufp + asn_length;
+}
+
+
+/*
+ * build_bitstring - Builds an ASN bit string object containing the
+ * input string.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the beginning of the next object.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char *asn1::build_bitstring( u_char *data,
+ int *datalength,
+ u_char type,
+ u_char *string,
+ int strlength)
+{
+ ACE_TRACE("asn1::build_bitstring");
+ /*
+ * ASN.1 bit string ::= 0x03 asnlength unused {byte}*
+ */
+ if (strlength < 1 || *string || *string > 7){
+ ASNERROR("Building invalid bitstring");
+ return 0;
+ }
+ data = asn1::build_header(data, datalength, type, strlength);
+ if (data == 0)
+ return 0;
+ if (*datalength < strlength)
+ return 0;
+ // fixed
+ ACE_OS::memcpy((char *)data,(char *)string, strlength);
+ *datalength -= strlength;
+ return data + strlength;
+}
+
+
+/*
+ * parse_unsigned_int64 - pulls a 64 bit u_long out of an ASN int
+ * type.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the end of this object.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char * asn1::parse_unsigned_int64(u_char *data,
+ int *datalength,
+ u_char *type,
+ struct counter64 *cp,
+ int countersize)
+{
+ ACE_TRACE("asn1::parse_unsigned_int64");
+ /*
+ * ASN.1 integer ::= 0x02 asnlength byte {byte}*
+ */
+ u_char *bufp = data;
+ u_long asn_length;
+ u_long low = 0, high = 0;
+ int intsize = 4;
+
+ if (countersize != sizeof(struct counter64)){
+ ASNERROR("not right size");
+ return 0;
+ }
+ *type = *bufp++;
+ bufp = asn1::parse_length(bufp, &asn_length);
+ if (bufp == 0){
+ ASNERROR("bad length");
+ return 0;
+ }
+ if ((int)(asn_length + (bufp - data)) > *datalength){
+ ASNERROR("overflow of message");
+ return 0;
+ }
+ if (((int)asn_length > (intsize * 2 + 1)) ||
+ (((int)asn_length == (intsize * 2) + 1) && *bufp != 0x00)){
+ ASNERROR("I don't support such large integers");
+ return 0;
+ }
+ *datalength -= (int)asn_length + (bufp - data);
+ if (*bufp & 0x80){
+ low = (u_long) -1; // integer is negative
+ high = (u_long) -1;
+ }
+ while(asn_length--){
+ high = (high << 8) | ((low & 0xFF000000) >> 24);
+ low = (low << 8) | *bufp++;
+ }
+ cp->low = low;
+ cp->high = high;
+ return bufp;
+}
+
+
+/*
+ * build_unsigned_int64 - builds an ASN object containing a 64 bit integer.
+ * On entry, datalength is input as the number of valid bytes following
+ * "data". On exit, it is returned as the number of valid bytes
+ * following the end of this object.
+ *
+ * Returns a pointer to the first byte past the end
+ * of this object (i.e. the start of the next object).
+ * Returns 0 on any error.
+ */
+u_char * asn1::build_unsigned_int64( u_char *data,
+ int *datalength,
+ u_char type,
+ struct counter64 *cp,
+ int countersize)
+{
+ ACE_TRACE("asn1::build_unsigned_int64");
+ /*
+ * ASN.1 integer ::= 0x02 asnlength byte {byte}*
+ */
+
+ u_long low, high;
+ u_long mask, mask2;
+ int add_null_byte = 0;
+ int intsize;
+
+ if (countersize != sizeof (struct counter64))
+ return 0;
+ intsize = 8;
+ low = cp->low;
+ high = cp->high;
+ mask = u_long (0xFF) << (8 * (sizeof(u_long) - 1));
+ /* mask is 0xFF000000 on a big-endian machine */
+ if ((u_char)((high & mask) >> (8 * (sizeof(long) - 1))) & 0x80){
+ /* if MSB is set */
+ add_null_byte = 1;
+ intsize++;
+ }
+ /*
+ * Truncate "unnecessary" bytes off of the most significant end of this 2's
+ * complement integer.
+ * There should be no sequence of 9 consecutive 1's or 0's at the most
+ * significant end of the integer.
+ */
+ mask2 = u_long (0x1FF) << ((8 * (sizeof(u_long) - 1)) - 1);
+ /* mask2 is 0xFF800000 on a big-endian machine */
+ while((((high & mask2) == 0) || ((high & mask2) == mask2))
+ && intsize > 1){
+ intsize--;
+ high = (high << 8)
+ | ((low & mask) >> (8 * (sizeof(long) - 1)));
+ low <<= 8;
+ }
+ data = asn1::build_header(data, datalength, type, intsize);
+ if (data == 0)
+ return 0;
+ if (*datalength < intsize)
+ return 0;
+ *datalength -= intsize;
+ if (add_null_byte == 1){
+ *data++ = '\0';
+ intsize--;
+ }
+ while(intsize--){
+ *data++ = (u_char)((high & mask) >> (8 * (sizeof(long) - 1)));
+ high = (high << 8)
+ | ((low & mask) >> (8 * (sizeof(long) - 1)));
+ low <<= 8;
+
+ }
+ return data;
+}
+
+
+// create a pdu
+struct snmp_pdu * cmu_snmp::pdu_create( int command)
+{
+ ACE_TRACE("cmu_snmp::snmp_pdu_create");
+ struct snmp_pdu *pdu;
+
+ ACE_NEW_RETURN(pdu, snmp_pdu, 0);
+ ACE_OS::memset((char *)pdu, 0,sizeof(struct snmp_pdu));
+ pdu->command = command;
+ pdu->errstat = 0;
+ pdu->errindex = 0;
+ pdu->enterprise = 0;
+ pdu->enterprise_length = 0;
+ pdu->variables = 0;
+ return pdu;
+}
+
+// release a pdu from memory
+void cmu_snmp::free_pdu( struct snmp_pdu *pdu)
+{
+ ACE_TRACE("cmu_snmp::free_pdu");
+ struct variable_list *vp, *ovp;
+
+ vp = pdu->variables;
+ while(vp){
+ // release the oid part
+ if (vp->name)
+ delete [] vp->name;
+ // if deep data, then release as well
+ if (vp->val.string)
+ delete [] vp->val.string;
+ ovp = vp;
+ // go to the next one
+ vp = vp->next_variable;
+ // release up vb itself
+ delete ovp;
+ }
+ // if enterprise release it up
+ if (pdu->enterprise)
+ delete [] pdu->enterprise;
+ // release up pdu itself
+ delete pdu;
+}
+
+
+// add a null var to a pdu
+void cmu_snmp::add_var(struct snmp_pdu *pdu,
+ oid *name,
+ int name_length,
+ SmiVALUE *smival)
+{
+ ACE_TRACE("cmu_snmp::add_var");
+
+ struct variable_list *vars = 0;
+
+ // if we don't have a vb list ,create one
+ if (pdu->variables == 0) {
+ ACE_NEW(pdu->variables, variable_list);
+ vars = pdu->variables;
+ }
+ else
+ { // we have one, find the end
+ for(vars = pdu->variables; vars->next_variable; vars = vars->next_variable);
+ // create one
+ ACE_NEW(vars->next_variable, variable_list);
+ // bump ptr
+ vars = vars->next_variable;
+ }
+
+ // add the oid with no data
+ vars->next_variable = 0;
+
+ // hook in the Oid portion
+ ACE_NEW(vars->name, oid[(name_length)]);
+
+ // fixed
+ ACE_OS::memcpy((char *)vars->name,(char *)name, name_length * sizeof(oid));
+ vars->name_length = name_length;
+
+ // hook in the SMI value
+ switch( smival->syntax)
+ {
+ // null , do nothing
+ case sNMP_SYNTAX_NULL:
+ case sNMP_SYNTAX_NOSUCHOBJECT:
+ case sNMP_SYNTAX_NOSUCHINSTANCE:
+ case sNMP_SYNTAX_ENDOFMIBVIEW:
+ {
+ vars->type = (u_char) smival->syntax;
+ vars->val.string = 0;
+ vars->val_len = 0;
+ }
+ break;
+
+ // octects
+ case sNMP_SYNTAX_OCTETS:
+ case sNMP_SYNTAX_OPAQUE:
+ case sNMP_SYNTAX_IPADDR:
+ {
+ vars->type = (u_char) smival->syntax;
+ ACE_NEW(vars->val.string,
+ u_char[(unsigned)smival->value.string.len]);
+ vars->val_len = (int) smival->value.string.len;
+ ACE_OS::memcpy( (u_char *) vars->val.string,
+ (u_char *) smival->value.string.ptr,
+ (unsigned) smival->value.string.len);
+ }
+ break;
+
+ // oid
+ case sNMP_SYNTAX_OID:
+ {
+ vars->type = (u_char) smival->syntax;
+ vars->val_len = (int) smival->value.oid.len * sizeof(oid);
+ ACE_NEW(vars->val.objid, oid[(unsigned)vars->val_len]);
+ ACE_OS::memcpy((u_long *)vars->val.objid,
+ (u_long *)smival->value.oid.ptr,
+ (unsigned) vars->val_len);
+ }
+ break;
+
+
+
+ case sNMP_SYNTAX_TIMETICKS:
+ case sNMP_SYNTAX_CNTR32:
+ case sNMP_SYNTAX_GAUGE32:
+ case sNMP_SYNTAX_UINT32:
+ {
+ long templong;
+ vars->type = (u_char) smival->syntax;
+ ACE_NEW(vars->val.integer, long);
+ vars->val_len = sizeof(long);
+ templong = (long) smival->value.uNumber;
+ ACE_OS::memcpy( (long*) vars->val.integer,
+ (long*) &templong,
+ sizeof(long));
+ }
+ break;
+
+ case sNMP_SYNTAX_INT32:
+ {
+ long templong;
+ vars->type = (u_char) smival->syntax;
+ ACE_NEW(vars->val.integer, long);
+ vars->val_len = sizeof(long);
+ templong = (long) smival->value.sNumber;
+ ACE_OS::memcpy( (long*) vars->val.integer,
+ (long*) &templong,
+ sizeof(long));
+ }
+ break;
+
+ // 64 bit counter
+ case sNMP_SYNTAX_CNTR64:
+ {
+ vars->type = ( u_char) smival->syntax;
+ ACE_NEW(vars->val.counter64, counter64);
+ vars->val_len = sizeof(struct counter64);
+ ACE_OS::memcpy( (struct counter64*) vars->val.counter64,
+ (SmiLPCNTR64) &(smival->value.hNumber),
+ sizeof( SmiCNTR64));
+ }
+ break;
+
+ } // end switch
+
+}
+
+// build the authentication
+// works for v1 or v2c
+u_char *cmu_snmp::auth_build( u_char *data,
+ int *length,
+ long int version,
+ u_char *community,
+ int community_len,
+ int messagelen)
+{
+ ACE_TRACE("cmu_snmp::auth_build");
+ u_char *params;
+ int plen;
+
+ params = community;
+ plen = community_len;
+
+ data = asn1::build_sequence(data,
+ length,
+ (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
+ messagelen + plen + 5);
+ if (data == 0){
+ ASNERROR("buildheader");
+ return 0;
+ }
+ data = asn1::build_int(data,
+ length,
+ (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+ (long *)&version,
+ sizeof(version));
+ if (data == 0){
+ ASNERROR("buildint");
+ return 0;
+ }
+
+ data = asn1::build_string(data,
+ length,
+ (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR),
+ params,
+ plen );
+ if (data == 0){
+ ASNERROR("buildstring");
+ return 0;
+ }
+
+ return (u_char *)data;
+}
+
+
+// build a variable binding
+u_char * cmu_snmp::build_var_op(u_char *data, oid * var_name,
+ int *var_name_len,
+ u_char var_val_type,
+ int var_val_len, u_char *var_val,
+ int *listlength)
+
+{
+ ACE_TRACE("cmu_snmp::build_var_op");
+ int dummyLen, headerLen;
+ u_char *dataPtr;
+
+ dummyLen = *listlength;
+ dataPtr = data;
+
+ data += 4;
+ dummyLen -=4;
+ if (dummyLen < 0)
+ return 0;
+
+ headerLen = data - dataPtr;
+ *listlength -= headerLen;
+ data = asn1::build_objid( data, listlength,
+ (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+ var_name, *var_name_len);
+ if (data == 0) {
+ ASNERROR("");
+ return 0;
+ }
+
+ // based on the type...
+ switch(var_val_type) {
+ case ASN_INTEGER:
+ data = asn1::build_int( data, listlength, var_val_type, (long *)var_val,
+ var_val_len);
+ break;
+
+ case SMI_GAUGE:
+ case SMI_COUNTER:
+ case SMI_TIMETICKS:
+ case SMI_UINTEGER:
+ data = asn1::build_unsigned_int( data,
+ listlength,
+ var_val_type,
+ (u_long *)var_val,
+ var_val_len);
+ break;
+
+ case SMI_COUNTER64:
+ data = asn1::build_unsigned_int64(data,
+ listlength,
+ var_val_type,
+ (struct counter64 *)var_val,
+ var_val_len);
+ break;
+
+ case ASN_OCTET_STR:
+ case SMI_IPADDRESS:
+ case SMI_OPAQUE:
+ case SMI_NSAP:
+ data = asn1::build_string(data, listlength, var_val_type,
+ var_val, var_val_len);
+ break;
+
+ case ASN_OBJECT_ID:
+ data = asn1::build_objid(data, listlength, var_val_type,
+ (oid *)var_val, var_val_len / sizeof(oid));
+ break;
+
+ case ASN_NULL:
+ data = asn1::build_null(data, listlength, var_val_type);
+ break;
+
+ case ASN_BIT_STR:
+ data = asn1::build_bitstring(data, listlength, var_val_type,
+ var_val, var_val_len);
+ break;
+
+ case SNMP_NOSUCHOBJECT:
+ case SNMP_NOSUCHINSTANCE:
+ case SNMP_ENDOFMIBVIEW:
+ data = asn1::build_null(data, listlength, var_val_type);
+ break;
+
+ default:
+ ASNERROR("wrong type");
+ return 0;
+ }
+ if (data == 0) {
+ ASNERROR("");
+ return 0;
+ }
+ dummyLen = (data - dataPtr) - headerLen;
+
+ asn1::build_sequence(dataPtr, &dummyLen,
+ (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
+ dummyLen);
+ return data;
+}
+
+
+// serialize the pdu
+int cmu_snmp::build( struct snmp_pdu *pdu, u_char *packet,
+ int *out_length, long version,
+ u_char* community, int community_len)
+{
+ ACE_TRACE("cmu_snmp::build");
+ u_char buf[SNMP_MSG_LENGTH];
+ u_char *cp;
+ struct variable_list *vp;
+ int length;
+ int totallength;
+
+ length = *out_length;
+ cp = packet;
+ for(vp = pdu->variables; vp; vp = vp->next_variable) {
+ cp = cmu_snmp::build_var_op( cp, vp->name,
+ &vp->name_length, vp->type,
+ vp->val_len, (u_char *)vp->val.string,
+ &length);
+ if (cp == 0)
+ return -1;
+ }
+ totallength = cp - packet;
+
+ length = SNMP_MSG_LENGTH;
+
+ // encode the total len
+ cp = asn1::build_header( buf, &length,
+ (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
+ totallength);
+ if (cp == 0)
+ return -1;
+ ACE_OS::memcpy( (char *)cp, (char *)packet,totallength);
+ totallength += cp - buf;
+
+ length = *out_length;
+ if (pdu->command != TRP_REQ_MSG) {
+
+ // request id
+ cp = asn1::build_int( packet,
+ &length,
+ (u_char )(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+ (long *)&pdu->reqid,
+ sizeof(pdu->reqid));
+ if (cp == 0)
+ return -1;
+
+ // error status
+ cp = asn1::build_int(cp,
+ &length,
+ (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+ (long *)&pdu->errstat, sizeof(pdu->errstat));
+ if (cp == 0)
+ return -1;
+
+ // error index
+ cp = asn1::build_int(cp,
+ &length,
+ (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+ (long *)&pdu->errindex, sizeof(pdu->errindex));
+ if (cp == 0)
+ return -1;
+ }
+ else { // this is a trap message
+
+ // enterprise
+ cp = asn1::build_objid( packet,
+ &length,
+ (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
+ (oid *)pdu->enterprise,
+ pdu->enterprise_length);
+ if (cp == 0)
+ return -1;
+
+ // agent-addr
+ cp = asn1::build_string(cp,
+ &length,
+ // HDN Fixed to use correct tag
+ (u_char)SMI_IPADDRESS,
+ //(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR),
+ (u_char *)&pdu->agent_addr.sin_addr.s_addr,
+ sizeof(pdu->agent_addr.sin_addr.s_addr));
+ if (cp == 0)
+ return -1;
+
+ // generic trap
+ cp = asn1::build_int(cp,
+ &length,
+ (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+ (long *)&pdu->trap_type,
+ sizeof(pdu->trap_type));
+ if (cp == 0)
+ return -1;
+
+ // specific trap
+ cp = asn1::build_int( cp,
+ &length,
+ (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+ (long *)&pdu->specific_type,
+ sizeof(pdu->specific_type));
+ if (cp == 0)
+ return -1;
+
+ // timestamp
+ cp = asn1::build_int(cp,
+ &length,
+ // HDN Fixed to use correct tag
+ (u_char)SMI_TIMETICKS,
+ //(u_char )(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
+ (long *)&pdu->time,
+ sizeof(pdu->time));
+ if (cp == 0)
+ return -1;
+ }
+
+ if (length < totallength)
+ return -1;
+ // fixed
+ ACE_OS::memcpy((char *)cp, (char *)buf, totallength);
+ totallength += cp - packet;
+
+ length = SNMP_MSG_LENGTH;
+ cp = asn1::build_header(buf,
+ &length,
+ (u_char)pdu->command,
+ totallength);
+ if (cp == 0)
+ return -1;
+ if (length < totallength)
+ return -1;
+ // fixed
+ ACE_OS::memcpy((char *)cp, (char *)packet, totallength);
+ totallength += cp - buf;
+
+ length = *out_length;
+
+ cp = cmu_snmp::auth_build( packet,
+ &length,
+ version,
+ community,
+ community_len,
+ totallength );
+ if (cp == 0)
+ return -1;
+ if ((*out_length - (cp - packet)) < totallength)
+ return -1;
+ // fixed
+ ACE_OS::memcpy((char *)cp, (char *)buf, totallength);
+ totallength += cp - packet;
+ *out_length = totallength;
+
+ return 0;
+}
+
+// parse the authentication header
+u_char *cmu_snmp::auth_parse(u_char *data,
+ int *length, u_char *sid,
+ int *slen, long *version)
+{
+ ACE_TRACE("cmu_snmp::auth_parse");
+ u_char type;
+
+ // get the type
+ data = asn1::parse_header( data, length, &type);
+ if (data == 0){
+ ASNERROR("bad header");
+ return 0;
+ }
+
+ if (type != (ASN_SEQUENCE | ASN_CONSTRUCTOR)) {
+ ASNERROR("wrong auth header type");
+ return 0;
+ }
+
+ // get the version
+ data = asn1::parse_int(data, length, &type, version, sizeof(*version));
+ if (data == 0) {
+ ASNERROR("bad parse of version");
+ return 0;
+ }
+
+ // get the community name
+ data = asn1::parse_string(data, length, &type, sid, slen);
+ if (data == 0) {
+ ASNERROR("bad parse of community");
+ return 0;
+ }
+
+ return (u_char *)data;
+}
+
+/* u_char *data, // IN - pointer to the start of object
+ oid *var_name, // OUT - object id of variable
+ int *var_name_len, // IN/OUT - length of variable name
+ u_char *var_val_type, // OUT - type of variable
+ (int or octet string) (one byte)
+ int *var_val_len, // OUT - length of variable
+ u_char **var_val, // OUT - pointer to ASN1 encoded value of variable
+*/
+
+u_char *
+cmu_snmp::parse_var_op( u_char *data, oid *var_name,
+ int *var_name_len, u_char *var_val_type,
+ int *var_val_len, u_char **var_val,
+ int *listlength)
+{
+ ACE_TRACE("cmu_snmp::parse_var_op");
+ u_char var_op_type;
+ int var_op_len = *listlength;
+ u_char *var_op_start = data;
+
+ data = asn1::parse_header(data, &var_op_len, &var_op_type);
+ if (data == 0){
+ ASNERROR("");
+ return 0;
+ }
+ if (var_op_type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+ return 0;
+ data = asn1::parse_objid(data, &var_op_len, &var_op_type, var_name, var_name_len);
+ if (data == 0) {
+ ASNERROR("");
+ return 0;
+ }
+ if (var_op_type != (u_char)
+ (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID))
+ return 0;
+ *var_val = data; /* save pointer to this object */
+ /* find out what type of object this is */
+ data = asn1::parse_header(data, &var_op_len, var_val_type);
+ if (data == 0) {
+ ASNERROR("");
+ return 0;
+ }
+ *var_val_len = var_op_len;
+ data += var_op_len;
+ *listlength -= (int)(data - var_op_start);
+ return data;
+}
+
+
+
+// build a pdu from a data and length
+int cmu_snmp::parse( struct snmp_pdu *pdu,
+ u_char *data,
+ u_char *community_name,
+ u_long &community_len,
+ snmp_version &spp_version,
+ int length)
+{
+ ACE_TRACE("cmu_snmp::parse");
+ u_char msg_type;
+ u_char type;
+ u_char *var_val;
+ long version;
+ int len, four;
+ u_char community[256];
+ int community_length = 256;
+ struct variable_list *vp = 0;
+ oid objid[MAX_NAME_LEN], *op;
+
+ // authenticates message and returns length if valid
+ data = cmu_snmp::auth_parse(data,
+ &length,
+ community,
+ &community_length,
+ &version);
+ if (data == 0)
+ return -1;
+
+ // copy the returned community name
+ ACE_OS::memcpy( (u_char *) community_name,
+ (u_char *) community,
+ community_length);
+ community_len = (long) community_length;
+
+ if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C ) {
+ ASNERROR("Wrong version");
+ return -1;
+ }
+
+ spp_version = (snmp_version) version;
+
+ data = asn1::parse_header(data,
+ &length,
+ &msg_type);
+ if (data == 0)
+ return -1;
+ pdu->command = msg_type;
+
+ if (pdu->command != TRP_REQ_MSG){
+ // get the rid
+ data = asn1::parse_int(data,
+ &length, &type,
+ (long *)&pdu->reqid,
+ sizeof(pdu->reqid));
+ if (data == 0)
+ return -1;
+ // get the error status
+ data = asn1::parse_int(data,
+ &length,
+ &type,
+ (long *)&pdu->errstat,
+ sizeof(pdu->errstat));
+ if (data == 0)
+ return -1;
+ // get the error index
+ data = asn1::parse_int(data,
+ &length,
+ &type,
+ (long *)&pdu->errindex,
+ sizeof(pdu->errindex));
+ if (data == 0)
+ return -1;
+ }
+ else { // is a trap
+
+ // get the enterprise
+ pdu->enterprise_length = MAX_NAME_LEN;
+ data = asn1::parse_objid(data,
+ &length,
+ &type,
+ objid,
+ &pdu->enterprise_length);
+ if (data == 0)
+ return -1;
+
+ ACE_NEW_RETURN(pdu->enterprise,
+ oid[pdu->enterprise_length*sizeof(oid)],-1);
+
+ // fixed
+ ACE_OS::memcpy((char *)pdu->enterprise,(char *)objid,
+ pdu->enterprise_length * sizeof(oid));
+
+ // get source address
+ four = 4;
+ data = asn1::parse_string(data, &length, &type,
+ (u_char *)&pdu->agent_addr.sin_addr.s_addr,
+ &four);
+ if (data == 0)
+ return -1;
+
+ // get trap type
+ data = asn1::parse_int(data, &length, &type, (long *)&pdu->trap_type,
+ sizeof(pdu->trap_type));
+ if (data == 0)
+ return -1;
+
+ // trap type
+ data = asn1::parse_int(data, &length, &type, (long *)&pdu->specific_type,
+ sizeof(pdu->specific_type));
+ if (data == 0)
+ return -1;
+
+ // timestamp
+ data = asn1::parse_int(data, &length, &type, (long *)&pdu->time,
+ sizeof(pdu->time));
+ if (data == 0)
+ return -1;
+ }
+
+ // get the vb list
+ data = asn1::parse_header(data, &length, &type);
+ if (data == 0)
+ return -1;
+
+ if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
+ return -1;
+
+ while((int)length > 0) {
+ if (pdu->variables == 0) {
+ ACE_NEW_RETURN(pdu->variables, variable_list, -1);
+ vp = pdu->variables;
+ } else {
+ ACE_NEW_RETURN(vp->next_variable, variable_list, -1);
+ vp = vp->next_variable;
+ }
+ vp->next_variable = 0;
+ vp->val.string = 0;
+ vp->name = 0;
+ vp->name_length = MAX_NAME_LEN;
+ data = cmu_snmp::parse_var_op( data, objid,
+ &vp->name_length, &vp->type,
+ &vp->val_len, &var_val,
+ (int *)&length);
+ if (data == 0)
+ return -1;
+
+ ACE_NEW_RETURN(op, oid[(unsigned)vp->name_length * sizeof(oid)], -1);
+
+ // fixed
+ ACE_OS::memcpy((char *)op, (char *)objid, vp->name_length * sizeof(oid));
+ vp->name = op;
+
+ len = SNMP_MSG_LENGTH;
+ switch((short)vp->type) {
+ case ASN_INTEGER:
+ case SMI_COUNTER:
+ case SMI_GAUGE:
+ case SMI_TIMETICKS:
+ case SMI_UINTEGER:
+ ACE_NEW_RETURN(vp->val.integer,long, -1);
+ vp->val_len = sizeof(long);
+ asn1::parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
+ break;
+ case SMI_COUNTER64:
+ ACE_NEW_RETURN(vp->val.counter64, counter64, -1);
+ vp->val_len = sizeof(struct counter64);
+ asn1::parse_unsigned_int64(var_val, &len, &vp->type,
+ (struct counter64 *)vp->val.counter64,
+ sizeof(*vp->val.counter64));
+ break;
+
+ case ASN_OCTET_STR:
+ case SMI_IPADDRESS:
+ case SMI_OPAQUE:
+ case SMI_NSAP:
+ ACE_NEW_RETURN(vp->val.string, u_char[(unsigned)vp->val_len + 1], -1);
+ asn1::parse_string(var_val, &len, &vp->type, vp->val.string,
+ &vp->val_len);
+ break;
+
+ case ASN_OBJECT_ID:
+ vp->val_len = MAX_NAME_LEN;
+ asn1::parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
+ //vp->val_len *= sizeof(oid);
+
+ ACE_NEW_RETURN(vp->val.objid, oid[(unsigned)vp->val_len*sizeof(oid)], -1);
+
+ // fixed
+ ACE_OS::memcpy((char *)vp->val.objid,
+ (char *)objid,
+ vp->val_len * sizeof(oid));
+ break;
+
+ case SNMP_NOSUCHOBJECT:
+ case SNMP_NOSUCHINSTANCE:
+ case SNMP_ENDOFMIBVIEW:
+ case ASN_NULL:
+ break;
+ default:
+ ASNERROR("bad type returned ");
+ break;
+ }
+ }
+ return 0;
+}
diff --git a/ACE/ASNMP/asnmp/asn1.h b/ACE/ASNMP/asnmp/asn1.h
new file mode 100644
index 00000000000..3be7e3925ef
--- /dev/null
+++ b/ACE/ASNMP/asnmp/asn1.h
@@ -0,0 +1,345 @@
+/* -*-C++-*- */
+#ifndef ASN1
+#define ASN1
+//=============================================================================
+/**
+ * @file asn1.h
+ *
+ * $Id$
+ *
+ * Abstract Syntax Notation One, ASN.1
+ * As defined in ISO/IS 8824 and ISO/IS 8825
+ * This implements a subset of the above International Standards that
+ * is sufficient to implement SNMP.
+ *
+ *
+ * @author Steve Waldbusser/CMU ?
+ */
+//=============================================================================
+
+
+/**********************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "asnmp/snmp.h"
+
+// CMU code to define "oid" typedef (old C style)
+#ifndef EIGHTBIT_SUBIDS
+typedef unsigned long oid;
+#define MAX_SUBID 0xFFFFFFFF
+#else
+typedef unsigned char oid;
+#define MAX_SUBID 0xFF
+#endif
+
+#define MAX_OID_LEN 64 /* max subid's in an oid */
+
+
+// asn.1 values
+#define ASN_BOOLEAN (0x01)
+#define ASN_INTEGER (0x02)
+#define ASN_BIT_STR (0x03)
+#define ASN_OCTET_STR (0x04)
+#define ASN_NULL (0x05)
+#define ASN_OBJECT_ID (0x06)
+#define ASN_SEQUENCE (0x10)
+#define ASN_SET (0x11)
+#define ASN_UNIVERSAL (0x00)
+#define ASN_APPLICATION (0x40)
+#define ASN_CONTEXT (0x80)
+#define ASN_PRIVATE (0xC0)
+#define ASN_PRIMITIVE (0x00)
+#define ASN_CONSTRUCTOR (0x20)
+#define ASN_LONG_LEN (0x80)
+#define ASN_EXTENSION_ID (0x1F)
+#define ASN_BIT8 (0x80)
+
+#define IS_CONSTRUCTOR(byte) ((byte) & ASN_CONSTRUCTOR)
+#define IS_EXTENSION_ID(byte) (((byte) & ASN_EXTENSION_ID) == ASN_EXTENSION_ID)
+
+#define ASNERROR( string)
+#define MAX_NAME_LEN 64
+#define SNMP_VERSION_1 0
+#define SNMP_VERSION_2C 1
+
+
+// defined types (from the SMI, RFC 1065)
+#define SMI_IPADDRESS (ASN_APPLICATION | 0)
+#define SMI_COUNTER (ASN_APPLICATION | 1)
+#define SMI_GAUGE (ASN_APPLICATION | 2)
+#define SMI_TIMETICKS (ASN_APPLICATION | 3)
+#define SMI_OPAQUE (ASN_APPLICATION | 4)
+#define SMI_NSAP (ASN_APPLICATION | 5)
+#define SMI_COUNTER64 (ASN_APPLICATION | 6)
+#define SMI_UINTEGER (ASN_APPLICATION | 7)
+
+#define GET_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x0)
+#define GETNEXT_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x1)
+#define GET_RSP_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x2)
+#define SET_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x3)
+#define TRP_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x4)
+
+#define GETBULK_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x5)
+#define INFORM_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x6)
+#define TRP2_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x7)
+#define REPORT_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x8)
+
+#define SNMP_NOSUCHOBJECT (ASN_CONTEXT | ASN_PRIMITIVE | 0x0)
+#define SNMP_NOSUCHINSTANCE (ASN_CONTEXT | ASN_PRIMITIVE | 0x1)
+#define SNMP_ENDOFMIBVIEW (ASN_CONTEXT | ASN_PRIMITIVE | 0x2)
+
+#define SNMP_MSG_LENGTH 1500
+
+typedef struct sockaddr_in ipaddr;
+
+// pdu
+struct snmp_pdu {
+ int command; // pdu type
+ unsigned long reqid; // Request id
+ unsigned long errstat; // Error status
+ unsigned long errindex; // Error index
+
+ // Trap information
+ oid *enterprise; // System OID
+ int enterprise_length;
+ ipaddr agent_addr; // address of object generating trap
+ int trap_type; // trap type
+ int specific_type; // specific type
+ unsigned long time; // Uptime
+
+ // vb list
+ struct variable_list *variables;
+};
+
+// vb list
+struct variable_list {
+ struct variable_list *next_variable; // 0 for last variable
+ oid *name; // Object identifier of variable
+ int name_length; // number of subid's in name
+ unsigned char type; // ASN type of variable
+ union { // value of variable
+ long *integer;
+ unsigned char *string;
+ oid *objid;
+ unsigned char *bitstring;
+ struct counter64 *counter64;
+ } val;
+ int val_len;
+};
+
+struct counter64 {
+ unsigned long high;
+ unsigned long low;
+};
+
+// CMU Interface class for ASN.1 routines
+/**
+ * @class asn1
+ *
+ * @brief Defines the member functions for the asn1 concrete interface class
+ * CMU routines for performing ASN.1 data marshalling / representation
+ */
+class ASNMP_Export asn1
+
+{
+public:
+static unsigned char *parse_int( unsigned char *data,
+ int *datalength,
+ unsigned char *type,
+ long int *intp,
+ int intsize);
+static unsigned char *parse_unsigned_int( unsigned char *data,
+ int *datalength,
+ unsigned char *type,
+ unsigned long *intp,
+ int intsize);
+static unsigned char *build_int( unsigned char *data,
+ int *datalength,
+ unsigned char type,
+ long *intp,
+ int intsize);
+
+static unsigned char *build_unsigned_int( unsigned char *data,
+ int *datalength,
+ unsigned char type,
+ unsigned long *intp,
+ int intsize);
+
+static unsigned char *parse_string( unsigned char *data,
+ int *datalength,
+ unsigned char *type,
+ unsigned char *string,
+ int *strlength);
+
+static unsigned char *build_string( unsigned char *data,
+ int *datalength,
+ unsigned char type,
+ unsigned char *string,
+ int strlength);
+
+static unsigned char *parse_header( unsigned char *data,
+ int *datalength,
+ unsigned char *type);
+
+static unsigned char * build_header( unsigned char *data,
+ int *datalength,
+ unsigned char type,
+ int length);
+
+static unsigned char * build_sequence( unsigned char *data,
+ int *datalength,
+ unsigned char type,
+ int length);
+
+static unsigned char * parse_length( unsigned char *data,
+ unsigned long *length);
+
+static unsigned char *build_length( unsigned char *data,
+ int *datalength,
+ int length);
+
+static unsigned char *build_objid( unsigned char *data,
+ int *datalength,
+ unsigned char type,
+ oid *objid,
+ int objidlength);
+
+static unsigned char *parse_objid( unsigned char *data,
+ int *datalength,
+ unsigned char *type,
+ oid *objid,
+ int *objidlength);
+
+static unsigned char *parse_null(unsigned char *data,
+ int *datalength, unsigned
+ char *type);
+
+static unsigned char *build_null( unsigned char *data,
+ int *datalength,
+ unsigned char type);
+
+static unsigned char *parse_bitstring( unsigned char *data,
+ int *datalength,
+ unsigned char *type,
+ unsigned char *string,
+ int *strlength);
+
+static unsigned char *build_bitstring( unsigned char *data,
+ int *datalength,
+ unsigned char type,
+ unsigned char *string,
+ int strlength);
+
+static unsigned char * parse_unsigned_int64(unsigned char *data,
+ int *datalength,
+ unsigned char *type,
+ struct counter64 *cp,
+ int countersize);
+
+static unsigned char * build_unsigned_int64( unsigned char *data,
+ int *datalength,
+ unsigned char type,
+ struct counter64 *cp,
+ int countersize);
+
+};
+
+
+// CMU Interface class for SNMPv1, SNMPv2c routines
+/**
+ * @class cmu_snmp
+ *
+ * @brief Defines the static functions for the cmu_snmp concrete class.
+ * These routine create cmu pdu's that can be sent/received on/from agents
+ */
+class ASNMP_Export cmu_snmp
+{
+ public:
+ static struct snmp_pdu *pdu_create( int command);
+ static void free_pdu( struct snmp_pdu *pdu);
+ static int build( struct snmp_pdu *pdu,
+ unsigned char *packet,
+ int *out_length,
+ long version,
+ unsigned char* community,
+ int community_len);
+
+ static void add_var(struct snmp_pdu *pdu,
+ oid *name,
+ int name_length,
+ SmiVALUE *smival);
+
+ static int parse( struct snmp_pdu *pdu,
+ unsigned char *data,
+ unsigned char *community_name,
+ unsigned long &community_len,
+ snmp_version &version,
+ int length);
+ static unsigned char *auth_build( unsigned char *data,
+ int *length,
+ long int version,
+ unsigned char *community,
+ int community_len,
+ int messagelen);
+
+ static unsigned char *build_var_op(unsigned char *data,
+ oid * var_name,
+ int *var_name_len,
+ unsigned char var_val_type,
+ int var_val_len,
+ unsigned char *var_val,
+ int *listlength);
+
+
+static unsigned char *auth_parse(unsigned char *data,
+ int *length,
+ unsigned char *sid,
+ int *slen,
+ long *version);
+
+/*
+ @params data, IN - pointer to the start of object
+ var_name OUT - object id of variable
+ var_name_len IN/OUT - length of variable name
+ var_val_type OUT - type of variable (int or octet string) (one byte)
+ var_val_len OUT - length of variable
+ var_val, OUT - pointer to ASN1 encoded value of variable
+ listlength IN/OUT - number of valid bytes left in var_op_list
+*/
+static unsigned char *parse_var_op( unsigned char *data,
+ oid *var_name,
+ int *var_name_len,
+ unsigned char *var_val_type,
+ int *var_val_len,
+ unsigned char **var_val,
+ int *listlength);
+
+};
+
+#endif // ASN1
+
diff --git a/ACE/ASNMP/asnmp/asnmp.mpc b/ACE/ASNMP/asnmp/asnmp.mpc
new file mode 100644
index 00000000000..40063285e2b
--- /dev/null
+++ b/ACE/ASNMP/asnmp/asnmp.mpc
@@ -0,0 +1,26 @@
+// $Id$
+
+project (asnmp_lib) : acelib {
+ sharedname = asnmp
+ dynamicflags = ASNMP_BUILD_DLL
+ includes += $(ACE_ROOT)/ASNMP
+
+ source_files {
+ address.cpp
+ asn1.cpp
+ counter.cpp
+ ctr64.cpp
+ gauge.cpp
+ integer.cpp
+ octet.cpp
+ oid.cpp
+ pdu.cpp
+ snmp.cpp
+ target.cpp
+ timetick.cpp
+ transaction.cpp
+ vb.cpp
+ wpdu.cpp
+ sagent.cpp
+ }
+}
diff --git a/ACE/ASNMP/asnmp/counter.cpp b/ACE/ASNMP/asnmp/counter.cpp
new file mode 100644
index 00000000000..c62b1d0a20a
--- /dev/null
+++ b/ACE/ASNMP/asnmp/counter.cpp
@@ -0,0 +1,107 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// counter.cpp
+//
+// = DESCRIPTION
+// Class implementation for SMI Counter32 class.
+//
+// = AUTHOR
+// Peter E Mellquist
+// Michael R MacFaden mrm@cisco.com - rework & ACE port
+// ============================================================================
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/counter.h"
+
+ACE_RCSID(asnmp, counter, "$Id$")
+
+// constructor with a value
+Counter32::Counter32( const unsigned long i):SnmpUInt32(i)
+{
+ smival.syntax = sNMP_SYNTAX_CNTR32;
+}
+
+// copy constructor
+Counter32::Counter32( const Counter32 &c)
+ : SnmpUInt32 (c)
+{
+ this->smival.value.uNumber = c.smival.value.uNumber;
+ smival.syntax = sNMP_SYNTAX_CNTR32;
+ valid_flag = 1;
+}
+
+// syntax type
+SmiUINT32 Counter32::get_syntax()
+{
+ return sNMP_SYNTAX_CNTR32;
+}
+
+// general assignment from any Value
+SnmpSyntax& Counter32::operator=( SnmpSyntax &in_val){
+ if ( this == &in_val ) // handle assignement from itself
+ return *this;
+
+ valid_flag = 0; // will get set true if really valid
+ if (in_val.valid())
+ {
+ switch (in_val.get_syntax())
+ {
+ case sNMP_SYNTAX_UINT32:
+ // case sNMP_SYNTAX_GAUGE32: .. indistinquishable from UINT32
+ case sNMP_SYNTAX_CNTR32:
+ case sNMP_SYNTAX_TIMETICKS:
+ case sNMP_SYNTAX_INT32: // implied cast int -> uint
+ this->smival.value.uNumber =
+ ((Counter32 &)in_val).smival.value.uNumber;
+ valid_flag = 1;
+ break;
+ }
+ }
+ return *this;
+}
+
+// overloaded assignment
+Counter32& Counter32::operator=( const unsigned long int i)
+{
+ this->smival.value.uNumber=i;
+ return *this;
+}
+
+// overloaded assignment
+Counter32& Counter32::operator=( const Counter32 &uli)
+{
+ this->smival.value.uNumber = uli.smival.value.uNumber;
+ return *this;
+}
+
+// otherwise, behave like an unsigned long int
+Counter32::operator unsigned long()
+{
+ return this->smival.value.uNumber;
+}
+
+// clone
+SnmpSyntax * Counter32::clone() const
+{
+ return ( SnmpSyntax *) new Counter32(*this);
+}
diff --git a/ACE/ASNMP/asnmp/counter.h b/ACE/ASNMP/asnmp/counter.h
new file mode 100644
index 00000000000..36fda2f84ce
--- /dev/null
+++ b/ACE/ASNMP/asnmp/counter.h
@@ -0,0 +1,79 @@
+/* -*-C++-*- */
+#ifndef COUNTER_
+#define COUNTER_
+//=============================================================================
+/**
+ * @file counter.h
+ *
+ * $Id$
+ *
+ * Class definition for SMI Counter32 class.
+ *
+ *
+ * @author Peter E Mellquist
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/smival.h"
+#include "asnmp/integer.h"
+
+//------------[ Counter32 Class ]------------------------------------------
+// The counter class allows all the functionality of unsigned
+// 32 bit integers but is recognized as a distinct SMI type. Counter32
+// class objects may be set or get into Vb objects.
+//
+// This class does not behave as defined by the abstract model
+// in RFC 1155 section 3.2.3.3
+
+/**
+ * @class Counter32
+ *
+ * @brief Defines the member functions for the Counter32 concrete class
+ * This class implements RFC 1155 Counter Object and is named
+ * Counter32 after the RFC1902 redefinition of V1 SMI datatypes
+ */
+class ASNMP_Export Counter32 : public SnmpUInt32
+{
+ public:
+ /// constructor with a value
+ Counter32( const unsigned long i = 0);
+
+ /// copy constructor
+ Counter32( const Counter32 &c);
+
+ /// syntax type
+ SmiUINT32 get_syntax();
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// overloaded assignment
+ Counter32& operator=( const Counter32 &uli);
+
+ /// overloaded assignment
+ Counter32& operator=( const unsigned long i);
+
+ /// otherwise, behave like an unsigned long int
+ operator unsigned long();
+};
+
+#endif // COUNTER_
diff --git a/ACE/ASNMP/asnmp/ctr64.cpp b/ACE/ASNMP/asnmp/ctr64.cpp
new file mode 100644
index 00000000000..df3468a1475
--- /dev/null
+++ b/ACE/ASNMP/asnmp/ctr64.cpp
@@ -0,0 +1,213 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// ctr64.cpp
+//
+// = DESCRIPTION
+// Implementation for Counter64 ( 64 bit counter class).
+//
+// = AUTHOR
+// Peter E Mellquist
+// Michael R MacFaden mrm@cisco.com - rework & ACE port
+// ============================================================================
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/ctr64.h"
+#include "ace/OS_NS_stdio.h"
+
+ACE_RCSID(asnmp, ctr64, "$Id$")
+
+#define MAX32 4294967295u
+
+//-----------[ syntax type ]----------------------------------------------
+SmiUINT32 Counter64::get_syntax()
+{
+ return sNMP_SYNTAX_CNTR64;
+}
+
+//------------------[ constructor with values ]--------------------------
+Counter64::Counter64( unsigned long hiparm, unsigned long loparm)
+{
+ smival.syntax = sNMP_SYNTAX_CNTR64;
+ smival.value.hNumber.hipart = hiparm;
+ smival.value.hNumber.lopart = loparm;
+}
+
+//------------------[ constructor with low value only ]------------------
+Counter64::Counter64( ACE_UINT64 llw )
+{
+ smival.syntax = sNMP_SYNTAX_CNTR64;
+ smival.value.hNumber.hipart = (unsigned long) (llw >> 32);
+ smival.value.hNumber.lopart = (unsigned long) llw & 0xffffffff;
+}
+
+//------------------[ copy constructor ]---------------------------------
+Counter64::Counter64( const Counter64 &ctr64 )
+ : SnmpSyntax (ctr64)
+{
+ smival.syntax = sNMP_SYNTAX_CNTR64;
+ smival.value.hNumber.hipart = ctr64.high();
+ smival.value.hNumber.lopart = ctr64.low();
+}
+
+//------------------[ destructor ]---------------------------------
+Counter64::~Counter64()
+{
+}
+
+
+//------------------[ Counter64::high() ]------------------------------
+// return the high part
+unsigned long Counter64::high() const
+{
+ return smival.value.hNumber.hipart;
+}
+
+
+//------------------[ Counter64::low() ]-------------------------------
+// return the low part
+unsigned long Counter64::low() const
+{
+ return smival.value.hNumber.lopart;
+}
+
+//------------------[ set_high( const unsigned long h) ]-----------
+// set the high part
+void Counter64::set_high( const unsigned long h)
+{
+ smival.value.hNumber.hipart = h;
+}
+
+//------------------[ set_low( const unsigned long l) ]------------
+// set the low part
+void Counter64::set_low( const unsigned long l)
+{
+ smival.value.hNumber.lopart = l;
+}
+
+
+//-----------[ to_long_double( Counter64 c64) ]-----------------------------
+// convert a Counter 64 to a long double
+long double Counter64::to_long_double() const
+{
+ long double ld = this->high();
+ ld *= MAX32;
+ ld += this->low();
+ return ld;
+}
+
+
+//-----------[ ld_to_c64( long double ld) ]----------------------------
+// convert a long double to a Counter64
+// semantics changed from prior version
+Counter64& Counter64::assign( long double ld)
+{
+ smival.syntax = sNMP_SYNTAX_CNTR64;
+ unsigned long h = smival.value.hNumber.hipart = (unsigned long)(ld / MAX32);
+ smival.value.hNumber.lopart = (unsigned long)(ld - h);
+ return *this;
+}
+
+//----------------[ general Value = operator ]---------------------
+SnmpSyntax& Counter64::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from itself
+ if ( this == &val )
+ return *this;
+
+ smival.value.hNumber.lopart = 0; // pessimsitic - assume no mapping
+ smival.value.hNumber.hipart = 0;
+
+ // try to make assignment valid
+ if (val.valid()){
+ switch (val.get_syntax()){
+ case sNMP_SYNTAX_CNTR64:
+ smival.value.hNumber.hipart =
+ ((Counter64 &)val).smival.value.hNumber.hipart;
+ smival.value.hNumber.lopart =
+ ((Counter64 &)val).smival.value.hNumber.lopart;
+ break;
+
+ case sNMP_SYNTAX_CNTR32:
+ case sNMP_SYNTAX_TIMETICKS:
+ case sNMP_SYNTAX_GAUGE32:
+ // case sNMP_SYNTAX_UINT32: .. indistinguishable from GAUGE32
+ case sNMP_SYNTAX_INT32:
+ // take advantage of union...
+ smival.value.hNumber.lopart = ((Counter64 &)val).smival.value.uNumber;
+ smival.value.hNumber.hipart = 0;
+ break;
+ }
+ }
+ return *this;
+}
+
+// overloaded assignment
+Counter64& Counter64::operator=( const ACE_UINT64 rhs)
+{
+ smival.value.hNumber.hipart = (unsigned long) (rhs >> 32);
+ smival.value.hNumber.lopart = (unsigned long) rhs;
+ return *this;
+}
+
+// overloaded assignment
+Counter64& Counter64::operator=( const Counter64 &rhs)
+{
+ smival.value.hNumber.hipart = rhs.high();
+ smival.value.hNumber.lopart = rhs.low();
+ return *this;
+}
+
+// otherwise, behave like an unsigned long int
+Counter64::operator ACE_UINT64()
+{
+ ACE_UINT64 val = smival.value.hNumber.hipart;
+ val = val << 32; // shift right 4 bytes
+ val |= smival.value.hNumber.lopart;
+ return val;
+}
+
+//----------------[ Counter64::clone() ]-----------------------------------
+// create a new instance of this Value
+SnmpSyntax* Counter64::clone() const
+{
+ return ( SnmpSyntax *) new Counter64(*this);
+}
+
+//----------------[ Counter64::valid() ]-------------------------------------
+int Counter64::valid() const
+{
+ return 1;
+}
+
+//----------[ return ASCII format ]-------------------------
+// TODO: Fix up to do real 64bit decimal value printing...
+// For now, print > 32-bit values in hex
+const char * Counter64::to_string()
+{
+ if ( high() != 0 )
+ sprintf(output_buffer, "0x%X%08X",
+ (unsigned int)high(), (unsigned int)low());
+ else
+ sprintf(output_buffer, "%d", (int) low());
+ return output_buffer;
+}
diff --git a/ACE/ASNMP/asnmp/ctr64.h b/ACE/ASNMP/asnmp/ctr64.h
new file mode 100644
index 00000000000..6b97b9966f2
--- /dev/null
+++ b/ACE/ASNMP/asnmp/ctr64.h
@@ -0,0 +1,111 @@
+/* -*-C++-*- */
+#ifndef CTR64_
+#define CTR64_
+//=============================================================================
+/**
+ * @file ctr64.h
+ *
+ * $Id$
+ *
+ * SNMP Counter64 class definition.
+ *
+ *
+ * @author Peter E Mellquist
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/smival.h"
+#include "ace/Basic_Types.h"
+
+#define CTR64OUTBUF 30 // maximum ascii string for a 64-bit ctr
+
+
+//---------[ 64 bit Counter Class ]--------------------------------
+// Counter64 Class encapsulates two unsigned integers into a
+// a single entity. This type has is available in SNMPv2 but
+// may be used anywhere where needed.
+//
+/**
+ * @class Counter64
+ *
+ * @brief Defines the member functions for the Counter64 concrete class
+ * This class implements RFC 1902 64 bit Counter Object.
+ */
+class ASNMP_Export Counter64 : public SnmpSyntax
+{
+public:
+ /// default constructor
+ Counter64( ACE_UINT64 llw = 0);
+
+ /// constructor with values
+ Counter64( unsigned long hiparm, unsigned long loparm);
+
+ /// copy constructor
+ Counter64( const Counter64 &ctr64);
+
+ /// destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden)
+ ~Counter64();
+
+ /// syntax type
+ SmiUINT32 get_syntax();
+
+ /// return a long double representation
+ long double to_long_double() const;
+
+ /// assign a long double to a counter64
+ Counter64& assign( long double ld);
+
+ /// return the high part
+ unsigned long high() const;
+
+ /// return the low part
+ unsigned long low() const;
+
+ /// set the high part
+ void set_high( const unsigned long h);
+
+ /// set the low part
+ void set_low( const unsigned long l);
+
+ /// overloaded assignment
+ Counter64& operator=( const ACE_UINT64 rhs);
+
+ /// overloaded assignment
+ Counter64& operator=( const Counter64 &rhs);
+
+ /// get a printable ASCII representation
+ const char *to_string();
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// general validity test, always true
+ int valid() const;
+
+ /// otherwise, behave like an ACE_UINT64
+ operator ACE_UINT64();
+
+protected:
+ char output_buffer[CTR64OUTBUF];
+};
+
+#endif // CTR64_
diff --git a/ACE/ASNMP/asnmp/enttraps.h b/ACE/ASNMP/asnmp/enttraps.h
new file mode 100644
index 00000000000..433538eb258
--- /dev/null
+++ b/ACE/ASNMP/asnmp/enttraps.h
@@ -0,0 +1,147 @@
+/* -*-C++-*- */
+#ifndef ENTTRAPS_
+#define ENTTRAPS_
+//=============================================================================
+/**
+ * @file enttraps.h
+ *
+ * $Id$
+ *
+ * constants for Enterprise Traps
+ *
+ *
+ * @author Peter E MellquistMichael R MacFaden mrm@cisco.com - rework & ACE port
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/asn1.h" // ASN.1 header file
+
+//--------------[ well known trap ids ]-----------------------------------
+/**
+ * @class snmpTrapsOid
+ *
+ * @brief Defines the member functions for the snmpTrapsOid base class
+ * to implement the traps defined in RFC 1215
+ */
+class ASNMP_Export snmpTrapsOid : public Oid
+{
+ public:
+ snmpTrapsOid (void):Oid("1.3.6.1.6.3.1.1.5"){}
+ SnmpSyntax& operator=( SnmpSyntax &val){ return Oid::operator=(val); }
+};
+
+/**
+ * @class snmpTrapEnterpriseOid
+ *
+ * @brief Defines the default Enterprise Oid for this software package
+ */
+class ASNMP_Export snmpTrapEnterpriseOid : public Oid
+{
+ public:
+ snmpTrapEnterpriseOid(void): Oid("1.3.6.1.6.3.1.1.4.3.0") { }
+ SnmpSyntax& operator=( SnmpSyntax &val){ return Oid::operator=(val); }
+};
+
+/**
+ * @class coldStartOid
+ *
+ * @brief Defines the RFC 1215 agent cold start generic trap (system reboot)
+ */
+class ASNMP_Export coldStartOid : public snmpTrapsOid
+{
+ public:
+ coldStartOid( void){*this+=".1";}
+ SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); }
+};
+
+/**
+ * @class warmStartOid
+ *
+ * @brief Defines the RFC 1215 agent warm start generic trap (agent reboot)
+ */
+class ASNMP_Export warmStartOid : public snmpTrapsOid
+{
+ public:
+ warmStartOid( void){*this+=".2";}
+ SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); }
+};
+
+/**
+ * @class linkDownOid
+ *
+ * @brief Defines the RFC 1215 interface (link) down trap
+ */
+class ASNMP_Export linkDownOid : public snmpTrapsOid
+{
+ public:
+ linkDownOid( void){*this+=".3";}
+ SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); }
+};
+
+
+// SMI LinkUp Oid
+/**
+ * @class linkUpOid
+ *
+ * @brief Defines the RFC 1215 interface (link) up trap
+ */
+class ASNMP_Export linkUpOid : public snmpTrapsOid
+{
+ public:
+ linkUpOid( void){*this+=".4";}
+ SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); }
+};
+
+/**
+ * @class authenticationFailureOid
+ *
+ * @brief Defines the RFC 1215 device/agent invalid access trap
+ */
+class ASNMP_Export authenticationFailureOid : public snmpTrapsOid
+{
+ public:
+ authenticationFailureOid( void){*this+=".5";}
+ SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); }
+};
+
+/**
+ * @class egpNeighborLossOid
+ *
+ * @brief Defines the RFC 1215 Exterior Gateway Protocol neighbor loss trap
+ */
+class ASNMP_Export egpNeighborLossOid : public snmpTrapsOid
+{
+ public:
+ egpNeighborLossOid( void){*this+=".6";}
+ SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); }
+};
+
+#ifdef DEFINE_TRAP_CONSTANTS_
+
+const coldStartOid coldStart;
+const warmStartOid warmStart;
+const linkDownOid linkDown;
+const linkUpOid linkUp;
+const authenticationFailureOid authenticationFailure;
+const egpNeighborLossOid egpNeighborLoss;
+const snmpTrapEnterpriseOid snmpTrapEnterprise;
+
+#endif
+
+#endif // ENTTRAPS_
diff --git a/ACE/ASNMP/asnmp/gauge.cpp b/ACE/ASNMP/asnmp/gauge.cpp
new file mode 100644
index 00000000000..9051e2f83fb
--- /dev/null
+++ b/ACE/ASNMP/asnmp/gauge.cpp
@@ -0,0 +1,114 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// gauge.cpp
+//
+// = DESCRIPTION
+// Class implemtation for SMI Gauge32 class.
+// NOTES: This does not behave exactly as a Gauge described in RFC 1155
+//
+// = AUTHOR
+// Peter E Mellquist
+// Michael R MacFaden mrm@cisco.com - rework & ACE port
+// ============================================================================
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/gauge.h" // header file for gauge class
+
+ACE_RCSID(asnmp, gauge, "$Id$")
+
+// constructor with a value
+Gauge32::Gauge32( const unsigned long i):SnmpUInt32(i)
+{
+ smival.syntax = sNMP_SYNTAX_GAUGE32;
+}
+
+// copy constructor
+Gauge32::Gauge32 ( const Gauge32 &g)
+ : SnmpUInt32 (g)
+{ this->smival.value.uNumber = g.smival.value.uNumber;
+ smival.syntax = sNMP_SYNTAX_GAUGE32;
+ valid_flag = 1;
+}
+
+// destructor
+Gauge32::~Gauge32()
+{
+}
+
+// syntax type
+SmiUINT32 Gauge32::get_syntax()
+{
+ return sNMP_SYNTAX_GAUGE32;
+}
+
+// overloaded assignment
+Gauge32& Gauge32::operator=( const Gauge32 &uli)
+{
+ this->smival.value.uNumber = uli.smival.value.uNumber;
+ return *this;
+}
+
+// overloaded assignment
+Gauge32& Gauge32::operator=( const unsigned long int i)
+{
+ smival.value.uNumber=i; return *this;
+}
+
+// general assignment from any Value
+// TODO: this is broken if not inherited from UInt32 (see UInt32 code).
+SnmpSyntax& Gauge32::operator=( SnmpSyntax &in_val)
+{
+
+ if ( this == &in_val ) // handle assignement from itself
+ return *this;
+
+ valid_flag = 0; // will get set true if really valid
+ if (in_val.valid())
+ {
+ switch (in_val.get_syntax())
+ {
+ case sNMP_SYNTAX_UINT32:
+ case sNMP_SYNTAX_GAUGE32:
+ case sNMP_SYNTAX_CNTR32:
+ case sNMP_SYNTAX_TIMETICKS:
+ case sNMP_SYNTAX_INT32: // implied cast int -> uint
+ this->smival.value.uNumber =
+ ((Gauge32 &)in_val).smival.value.uNumber;
+ valid_flag = 1;
+ break;
+ }
+ }
+ return *this;
+}
+
+// otherwise, act as unsigned long
+Gauge32::operator unsigned long()
+{
+ return smival.value.uNumber;
+}
+
+// clone - create a new instance of this Value
+SnmpSyntax* Gauge32::clone() const
+{
+ return ( SnmpSyntax *) new Gauge32(*this);
+}
diff --git a/ACE/ASNMP/asnmp/gauge.h b/ACE/ASNMP/asnmp/gauge.h
new file mode 100644
index 00000000000..202edaf98bf
--- /dev/null
+++ b/ACE/ASNMP/asnmp/gauge.h
@@ -0,0 +1,79 @@
+/* -*-C++-*- */
+#ifndef GAUGE_
+#define GAUGE_
+//=============================================================================
+/**
+ * @file gauge.h
+ *
+ * $Id$
+ *
+ * Class definition for SMI Gauge32 class.
+ * This class currently does not behave as defined by the abstract model
+ * in RFC 1155 section 3.2.3.4 (ie the value doesn't latch on the max value)
+ *
+ *
+ * @author Peter E Mellquist
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/integer.h"
+
+//------------[ Gauge32 Class ]------------------------------------------
+// The gauge class allows all the functionality of unsigned
+// integers but is recognized as a distinct SMI type. Gauge32
+// objects may be set or get into Vb objects.
+//
+
+/**
+ * @class Gauge32:
+ *
+ * @brief Define RFC1902 Gauge datatype from RFC 1155 section 3.2.3.4
+ * Note that this datatype does not behave exactly (acts like a long)
+ */
+class ASNMP_Export Gauge32: public SnmpUInt32
+{
+ public:
+ /// constructor with a value
+ Gauge32( const unsigned long i = 0);
+
+ /// copy constructor
+ Gauge32 ( const Gauge32 &g);
+
+ /// destructor for a Gauge32 (ensure that Value::~Value() is overridden)
+ ~Gauge32();
+
+ /// syntax type
+ SmiUINT32 get_syntax();
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// overloaded assignment
+ Gauge32& operator=( const Gauge32 &uli);
+
+ /// overloaded assignment
+ Gauge32& operator=( const unsigned long i);
+
+ /// otherwise, behave like an unsigned int
+ operator unsigned long();
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+};
+#endif //GAUGE_
diff --git a/ACE/ASNMP/asnmp/integer.cpp b/ACE/ASNMP/asnmp/integer.cpp
new file mode 100644
index 00000000000..d732e0f3ff9
--- /dev/null
+++ b/ACE/ASNMP/asnmp/integer.cpp
@@ -0,0 +1,230 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// integer.cpp
+//
+// = DESCRIPTION
+// Class implemtation for SMI Integer classes.
+//
+// = AUTHOR
+// Jeff Meyer
+// Michael R MacFaden mrm@cisco.com - rework & ACE port
+// ============================================================================
+/*===================================================================
+
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/integer.h" // header file for gauge class
+#include "ace/OS_NS_stdio.h"
+
+ACE_RCSID(asnmp, integer, "$Id$")
+
+// constructor with value
+SnmpUInt32::SnmpUInt32 (const unsigned long i)
+{
+ smival.value.uNumber=i;
+ smival.syntax = sNMP_SYNTAX_UINT32;
+ valid_flag = 1;
+}
+
+// copy constructor
+SnmpUInt32::SnmpUInt32( const SnmpUInt32 &c)
+ : SnmpSyntax (c)
+{
+ smival.value.uNumber=c.smival.value.uNumber;
+ smival.syntax = sNMP_SYNTAX_UINT32;
+ valid_flag = 1;
+}
+
+// destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden)
+SnmpUInt32::~SnmpUInt32()
+{
+}
+
+// syntax type
+SmiUINT32 SnmpUInt32::get_syntax()
+{
+ return sNMP_SYNTAX_UINT32;
+}
+
+// object validity
+int SnmpUInt32::valid( void) const
+{
+ return valid_flag;
+}
+
+// overloaded assignment
+SnmpUInt32& SnmpUInt32::operator=( const unsigned long int i)
+{
+ smival.value.uNumber=i;
+ valid_flag = 1;
+ return *this;
+}
+
+// general assignment from any Value
+SnmpSyntax& SnmpUInt32::operator=( SnmpSyntax &in_val)
+{
+ if ( this == &in_val ) // handle assignement from itself
+ return *this;
+
+ valid_flag = 0; // will get set true if really valid
+ if (in_val.valid())
+ {
+ switch (in_val.get_syntax())
+ {
+ case sNMP_SYNTAX_UINT32:
+ // case sNMP_SYNTAX_GAUGE32: .. indistinquishable from UINT32
+ case sNMP_SYNTAX_CNTR32:
+ case sNMP_SYNTAX_TIMETICKS:
+ case sNMP_SYNTAX_INT32: // implied cast int -> uint
+ this->smival.value.uNumber =
+ ((SnmpUInt32 &)in_val).smival.value.uNumber;
+ valid_flag = 1;
+ break;
+ }
+ }
+ return *this;
+}
+
+// overloaded assignment
+SnmpUInt32& SnmpUInt32::operator=( const SnmpUInt32 &uli)
+{
+ this->smival.value.uNumber = uli.smival.value.uNumber; return *this;
+}
+
+// otherwise, behave like an unsigned long int
+SnmpUInt32::operator unsigned long()
+{
+ return smival.value.uNumber;
+}
+
+// create a new instance of this Value
+SnmpSyntax* SnmpUInt32::clone() const
+{
+ return (SnmpSyntax *) new SnmpUInt32(*this);
+}
+
+// ASCII format return
+const char * SnmpUInt32::to_string()
+{
+ sprintf(output_buffer, "%d", (int) (this->smival.value.uNumber));
+ return output_buffer;
+}
+
+
+//====================================================================
+// INT 32 Implementation
+//====================================================================
+
+// default constructor
+SnmpInt32::SnmpInt32 (const long i)
+{
+ smival.value.sNumber=i;
+ smival.syntax = sNMP_SYNTAX_INT32;
+ valid_flag = 1;
+}
+
+// constructor with value
+SnmpInt32::SnmpInt32 (const SnmpInt32 &c)
+ : SnmpSyntax (c)
+{
+ smival.value.sNumber=c.smival.value.sNumber;
+ smival.syntax = sNMP_SYNTAX_INT32;
+ valid_flag = 1;
+}
+
+// destructor
+SnmpInt32::~SnmpInt32()
+{
+}
+
+// syntax type
+SmiUINT32 SnmpInt32::get_syntax()
+{
+ return sNMP_SYNTAX_INT32;
+}
+
+// object validity
+int SnmpInt32::valid( void) const
+{
+ return valid_flag;
+}
+
+// overloaded assignment
+SnmpInt32& SnmpInt32::operator=( const long i)
+{
+ this->smival.value.sNumber = (unsigned long) i;
+ valid_flag = 1;
+ return *this;
+}
+
+// overloaded assignment
+SnmpInt32& SnmpInt32::operator=( const SnmpInt32 &uli)
+{
+ this->smival.value.sNumber = uli.smival.value.sNumber;
+ valid_flag = 1;
+ return *this;
+}
+
+// general assignment from any Value
+SnmpSyntax& SnmpInt32::operator=( SnmpSyntax &in_val)
+{
+ if ( this == &in_val ) // handle assignement from itself
+ return *this;
+
+ valid_flag = 0; // will get set true if really valid
+ if (in_val.valid())
+ {
+ switch (in_val.get_syntax())
+ {
+ case sNMP_SYNTAX_INT32:
+ case sNMP_SYNTAX_UINT32: // implied cast uint -> int
+ // case sNMP_SYNTAX_GAUGE32: .. indistinquishable from UINT32
+ case sNMP_SYNTAX_CNTR32: // implied cast uint -> int
+ case sNMP_SYNTAX_TIMETICKS: // implied cast uint -> int
+ this->smival.value.sNumber =
+ ((SnmpInt32 &)in_val).smival.value.sNumber;
+ valid_flag = 1;
+ break;
+ }
+ }
+ return *this;
+}
+
+// otherwise, behave like a long int
+SnmpInt32::operator long()
+{
+ return (long) smival.value.sNumber;
+}
+
+// clone - create a new instance of this Value
+SnmpSyntax* SnmpInt32::clone() const
+{
+ return ( SnmpSyntax *) new SnmpInt32(*this);
+}
+
+// ASCII format return
+
+const char *SnmpInt32::to_string()
+{
+ sprintf(output_buffer, "%d", (int) (long) this->smival.value.sNumber);
+ return output_buffer;
+}
diff --git a/ACE/ASNMP/asnmp/integer.h b/ACE/ASNMP/asnmp/integer.h
new file mode 100644
index 00000000000..d120684c095
--- /dev/null
+++ b/ACE/ASNMP/asnmp/integer.h
@@ -0,0 +1,142 @@
+/* -*-C++-*- */
+#ifndef SNMPINTEGER_
+#define SNMPINTEGER_
+//=============================================================================
+/**
+ * @file integer.h
+ *
+ * $Id$
+ *
+ * Class definition for Integer classes convertable to SMI.
+ *
+ *
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/smival.h"
+
+// TODO get rid of this constant
+#define INTOUTBUF 15 // largest ASCII formatted integer
+
+//------------[ Integer Classes ]------------------------------------------
+// The integer class allows all the functionality of the various
+// integers but is contained in a Value object for consistency
+// among the various types.
+// class objects may be set or get into Vb objects.
+//
+
+// 32 bit unsigned integer class
+/**
+ * @class SnmpUInt32
+ *
+ * @brief Implement RFC 1920 Unsigned Integer SMI datatype
+ */
+class ASNMP_Export SnmpUInt32 : public SnmpSyntax
+{
+
+ public:
+ /// default constructor
+ SnmpUInt32 (const unsigned long i = 0);
+
+ /// copy constructor
+ SnmpUInt32( const SnmpUInt32 &c);
+
+ /// destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden)
+ virtual ~SnmpUInt32();
+
+ /// syntax type
+ virtual SmiUINT32 get_syntax();
+
+ /// overloaded assignment
+ SnmpUInt32& operator=( const unsigned long i);
+
+ /// overloaded assignment
+ SnmpUInt32& operator=( const SnmpUInt32 &uli);
+
+ /// otherwise, behave like an unsigned long int
+ operator unsigned long();
+
+ /// get a printable ASCII value
+ virtual const char *to_string();
+
+ /// create a new instance of this Value
+ virtual SnmpSyntax *clone() const;
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// did object construct properly
+ int valid() const;
+
+ protected:
+ /// contain string representation of object
+ int valid_flag;
+ char output_buffer[INTOUTBUF];
+};
+
+
+// 32 bit signed integer class
+ /**
+ * @class SnmpInt32
+ *
+ * @brief Implement RFC 1902 32 bit Integer SMI data object
+ */
+class ASNMP_Export SnmpInt32 : public SnmpSyntax
+{
+ public:
+ /// constructor with value
+ SnmpInt32 (const long i = 0);
+
+ /// constructor with value
+ SnmpInt32 (const SnmpInt32 &c);
+
+ /// destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden)
+ virtual ~SnmpInt32();
+
+ /// syntax type
+ virtual SmiUINT32 get_syntax();
+
+ /// overloaded assignment
+ SnmpInt32& operator=( const long i);
+
+ /// overloaded assignment
+ SnmpInt32& operator=( const SnmpInt32 &li);
+
+ /// otherwise, behave like a long int
+ operator long();
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+ /// get a printable ASCII value
+ const char *to_string();
+
+ /// logical state of object
+ int valid() const;
+
+ protected:
+ /// contain string representation of object
+ int valid_flag;
+ char output_buffer[INTOUTBUF];
+};
+
+#endif
diff --git a/ACE/ASNMP/asnmp/octet.cpp b/ACE/ASNMP/asnmp/octet.cpp
new file mode 100644
index 00000000000..885197919c4
--- /dev/null
+++ b/ACE/ASNMP/asnmp/octet.cpp
@@ -0,0 +1,594 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// octet.cpp
+//
+// = DESCRIPTION
+// Implements the SMI Octet datatype (RFC 1155)
+// This class is fully contained and does not rely on or any other
+// SNMP libraries. Ported to ACE by Michael MacFaden mrm@cisco.com
+//
+// = AUTHOR
+// Peter E Mellquist
+//
+// ============================================================================
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/octet.h" // include definition for octet class
+#include "ace/OS_Memory.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_ctype.h"
+#include "ace/os_include/os_ctype.h"
+
+ACE_RCSID(asnmp, octet, "$Id$")
+
+//============[ syntax type ]=========================================
+SmiUINT32 OctetStr::get_syntax()
+{
+ return sNMP_SYNTAX_OCTETS;
+}
+
+inline
+void init_octet_smi(SmiVALUE& smi)
+{
+ smi.syntax = sNMP_SYNTAX_OCTETS;
+ smi.value.string.ptr = 0;
+ smi.value.string.len = 0;
+}
+
+inline
+void reset_octet_smi(SmiVALUE& smi)
+{
+ delete [] smi.value.string.ptr;
+ smi.value.string.ptr = 0;
+ smi.value.string.len = 0;
+}
+
+inline
+int copy_octet_smi(SmiVALUE& smi, int size, const char *src, int& valid_flag)
+{
+ valid_flag = 0;
+
+ if (smi.value.string.ptr)
+ delete [] smi.value.string.ptr;
+
+ ACE_NEW_RETURN(smi.value.string.ptr, SmiBYTE[size], 1);
+ ACE_OS::memcpy( smi.value.string.ptr, src, size);
+ smi.value.string.len = size;
+ valid_flag = 1;
+ return 0;
+}
+
+//============[ default constructor ]=========================
+OctetStr::OctetStr( const char * string, long size):
+ output_buffer(0), validity(0)
+{
+
+ init_octet_smi(smival);
+
+ // check for null string
+ if ( !string)
+ return;
+
+ if (size == -1) // calc if no length given - assume c style string
+ size = ACE_OS::strlen( string);
+
+ copy_octet_smi(smival, size, string, validity);
+}
+
+
+//============[ set the data on an already constructed Octet ]============
+// TODO: should return status since it can fail in so many places
+void OctetStr::set_data( const SmiBYTE* string, long size)
+{
+ // invalid args, set octetStr to not valid
+ if ( !string || !size) {
+ validity = 0;
+ return;
+ }
+
+ // assume non-zero terminated string
+ if (size == -1) // calc if no length given - assume c style string
+ size = ACE_OS::strlen( (char *)string);
+
+ // free up already used space
+ if ( smival.value.string.ptr ) {
+ reset_octet_smi(smival);
+ }
+ smival.value.string.len = 0;
+
+
+ copy_octet_smi(smival, size, (const char *)string, validity);
+}
+
+//============[ constructor using another octet object ]==============
+OctetStr::OctetStr ( const OctetStr &octet):
+ SnmpSyntax (octet), output_buffer(0), validity(1)
+{
+ init_octet_smi(smival);
+ // check for zero len case
+ if ( octet.smival.value.string.len == 0) {
+ return;
+ }
+
+ // must be a valid object
+ if ( octet.validity == 0) {
+ validity = 0;
+ return;
+ }
+
+ // get the mem needed
+ copy_octet_smi(smival, octet.smival.value.string.len,
+ (const char *)octet.smival.value.string.ptr, validity);
+}
+
+//=============[ destructor ]=========================================
+OctetStr::~OctetStr()
+{
+ reset_octet_smi(smival);
+ delete [] output_buffer;
+}
+
+
+//=============[ assignment to a string operator overloaded ]=========
+OctetStr& OctetStr::operator=( const char *string)
+{
+ // get the string size
+ size_t nz;
+
+ // free up previous memory if needed
+ if ( smival.value.string.ptr ) {
+ reset_octet_smi(smival);
+ }
+
+ // if empty then we are done
+ if (!string || !(nz = ACE_OS::strlen( string))) {
+ validity = 1;
+ return *this;
+ }
+
+ // get memory needed
+ copy_octet_smi(smival, nz, string, validity);
+ return *this;
+}
+
+//=============[ assignment to another oid object overloaded ]========
+OctetStr& OctetStr::operator=( const OctetStr &octet)
+{
+ // protect against assignment from self
+ if ( this == &octet )
+ return *this;
+
+ // don't assign from invalid objs
+ if (!octet.validity) {
+ return *this;
+ }
+
+ // free up previous memory if needed
+ if ( smival.value.string.len ) {
+ reset_octet_smi(smival);
+ }
+
+ if (!octet.smival.value.string.len) {
+ validity = 1;
+ return *this;
+ }
+
+ // get some memory
+ copy_octet_smi(smival, octet.smival.value.string.len,
+ (const char*) octet.smival.value.string.ptr, validity);
+ return *this; // return self reference
+}
+
+//==============[ equivlence operator overloaded ]====================
+bool operator==( const OctetStr &lhs, const OctetStr &rhs)
+{
+ if( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0)
+ return true;
+ else
+ return false;
+}
+
+//==============[ not equivlence operator overloaded ]================
+bool operator!=( const OctetStr &lhs, const OctetStr &rhs)
+{
+ if( lhs.left_comparison( rhs.smival.value.string.len, rhs)!=0)
+ return true;
+ else
+ return false;
+}
+
+//==============[ less than < overloaded ]============================
+bool operator<( const OctetStr &lhs, const OctetStr &rhs)
+{
+ if( lhs.left_comparison( rhs.smival.value.string.len, rhs)<0)
+ return true;
+ else
+ return false;
+}
+
+//==============[ less than <= overloaded ]===========================
+bool operator<=( const OctetStr &lhs, const OctetStr &rhs)
+{
+ if(( lhs.left_comparison( rhs.smival.value.string.len, rhs)<0) ||
+ ( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0))
+ return true;
+ else
+ return false;
+}
+
+//===============[ greater than > overloaded ]========================
+bool operator>( const OctetStr &lhs, const OctetStr &rhs)
+{
+ if( lhs.left_comparison( rhs.smival.value.string.len, rhs)>0)
+ return true;
+ else
+ return false;
+}
+
+//===============[ greater than >= overloaded ]=======================
+bool operator>=( const OctetStr &lhs, const OctetStr &rhs)
+{
+ if(( lhs.left_comparison( rhs.smival.value.string.len, rhs)>0) ||
+ ( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0))
+ return true;
+ else
+ return false;
+}
+
+//===============[ equivlence operator overloaded ]===================
+bool operator==( const OctetStr &lhs,const char *rhs)
+{
+ OctetStr to( rhs);
+ if( lhs.left_comparison( to.smival.value.string.len,to)==0)
+ return true;
+ else
+ return false;
+}
+
+//===============[ not equivlence operator overloaded ]===============
+bool operator!=( const OctetStr &lhs,const char *rhs)
+{
+ OctetStr to( rhs);
+ if ( lhs.left_comparison( to.smival.value.string.len,to)!=0)
+ return true;
+ else
+ return false;
+}
+
+//===============[ less than < operator overloaded ]==================
+bool operator<( const OctetStr &lhs,const char *rhs)
+{
+ OctetStr to( rhs);
+ if ( lhs.left_comparison( to.smival.value.string.len,to)<0)
+ return true;
+ else
+ return false;
+}
+
+//===============[ less than <= operator overloaded ]=================
+bool operator<=( const OctetStr &lhs,char *rhs)
+{
+ OctetStr to( rhs);
+ if (( lhs.left_comparison( to.smival.value.string.len,to)<0) ||
+ ( lhs.left_comparison( to.smival.value.string.len,to)==0))
+ return true;
+ else
+ return false;
+}
+
+//===============[ greater than > operator overloaded ]===============
+bool operator>( const OctetStr &lhs,const char *rhs)
+{
+ OctetStr to( rhs);
+ if ( lhs.left_comparison( to.smival.value.string.len,to)>0)
+ return true;
+ else
+ return false;
+}
+
+//===============[ greater than >= operator overloaded ]==============
+bool operator>=( const OctetStr &lhs,const char *rhs)
+{
+ OctetStr to( rhs);
+ if (( lhs.left_comparison( to.smival.value.string.len,to)>0) ||
+ ( lhs.left_comparison( to.smival.value.string.len,to)==0))
+ return true;
+ else
+ return false;
+}
+
+//===============[ append operator, appends a string ]================
+OctetStr& OctetStr::operator+=( const char *a)
+{
+ SmiBYTE *tmp; // temp pointer
+ size_t slen,nlen;
+
+ // get len of string
+ if ( !a || ((slen = ACE_OS::strlen( a)) == 0))
+ return *this;
+
+ // total len of octet
+ nlen = slen + (size_t) smival.value.string.len;
+ ACE_NEW_RETURN(tmp, SmiBYTE [ nlen], *this);
+ ACE_OS::memcpy ( tmp, smival.value.string.ptr,
+ (size_t) smival.value.string.len);
+ ACE_OS::memcpy( tmp + smival.value.string.len, a, (size_t) slen);
+ // delete the original
+ if ( smival.value.string.ptr )
+ reset_octet_smi(smival);
+ smival.value.string.ptr = tmp;
+ smival.value.string.len = nlen;
+ return *this;
+}
+
+//================[ append one OctetStr to another ]==================
+OctetStr& OctetStr::operator+=( const OctetStr& octetstr)
+{
+ SmiBYTE *tmp; // temp pointer
+ size_t slen,nlen;
+
+ if (!octetstr.validity ||
+ !(slen = (size_t)octetstr.length()))
+ return *this;
+
+ // total len of octet
+ nlen = slen + (size_t) smival.value.string.len;
+ // get mem needed
+ ACE_NEW_RETURN(tmp, SmiBYTE[ nlen], *this);
+ ACE_OS::memcpy ( tmp, smival.value.string.ptr,
+ (size_t) smival.value.string.len);
+ ACE_OS::memcpy( tmp + smival.value.string.len, octetstr.data(),
+ (size_t) slen);
+ if ( smival.value.string.ptr )
+ reset_octet_smi(smival);
+ smival.value.string.ptr = tmp;
+ smival.value.string.len = nlen;
+ return *this;
+}
+
+//================[ appends an int ]==================================
+OctetStr& OctetStr::operator+=( const char c)
+{
+ SmiBYTE *tmp;
+ // get the memory needed plus one extra byte
+ ACE_NEW_RETURN(tmp, SmiBYTE[ smival.value.string.len + 1], *this);
+ ACE_OS::memcpy ( tmp, smival.value.string.ptr,
+ (size_t) smival.value.string.len); // len of original
+ tmp[ smival.value.string.len ] = c; // assign in byte
+ if ( smival.value.string.ptr ) // delete the original
+ reset_octet_smi(smival);
+
+ smival.value.string.ptr = tmp; // point to one
+ smival.value.string.len++; // up the len
+ return *this;
+}
+
+
+//================[ compare n elements of an Octet ]==================
+int OctetStr::left_comparison( const long n, const OctetStr &o) const
+{
+ long z, w;
+
+ // both are empty, they are equal
+ if (( smival.value.string.len == 0) &&
+ ( o.smival.value.string.len == 0))
+ return 0; // equal
+
+ // self is empty and param has something
+ if (( smival.value.string.len == 0) &&
+ ( o.smival.value.string.len >0) &&
+ (n>0))
+ return -1;
+
+ // self has something and param has nothing
+ if (( smival.value.string.len > 0) &&
+ ( o.smival.value.string.len ==0) &&
+ (n>0))
+ return 1;
+
+ // special case
+ if (( smival.value.string.len == 0) &&
+ ( o.smival.value.string.len > 0) &&
+ ( n == 0))
+ return 0;
+
+ // pick the Min of n, this and the param len
+ // this is the maximum # to iterate a search
+ w = smival.value.string.len < o.smival.value.string.len
+ ? smival.value.string.len : o.smival.value.string.len;
+ if (n<w) w=n;
+
+ z = 0;
+ while( z < w) {
+ if ( smival.value.string.ptr[z] < o.smival.value.string.ptr[z])
+ return -1; // less than
+ if ( smival.value.string.ptr[z] > o.smival.value.string.ptr[z])
+ return 1; // greater than
+ z++;
+ }
+
+ if (( z == 0) &&
+ ( smival.value.string.len == 0) &&
+ ( o.smival.value.string.len > 0))
+ return -1;
+
+ if (( z == 0) &&
+ ( o.smival.value.string.len == 0) &&
+ ( smival.value.string.len > 0))
+ return 1;
+
+ return 0;
+}
+
+//================[ return the length of the oid ]=======================
+size_t OctetStr::length() const
+{
+ return (size_t) smival.value.string.len;
+}
+
+//================[ operator[]: access as if array ]==================
+SmiBYTE& OctetStr::operator[]( int position)
+{
+ return smival.value.string.ptr[position];
+}
+
+//===============[ reuturns pointer to internal data ]===============
+SmiBYTE * OctetStr::data() const
+{
+ return smival.value.string.ptr;
+}
+
+//================[ returns validity ]================================
+int OctetStr::valid() const
+{
+ return validity;
+}
+
+//================[ clone() ]=========================================
+SnmpSyntax * OctetStr::clone() const
+{
+ OctetStr *tmp = new OctetStr(*this);
+ return ( SnmpSyntax *) tmp;
+}
+
+//================[ ASCII format return ]=============================
+const char * OctetStr::to_string()
+{
+ for ( unsigned long i=0; i < smival.value.string.len; i++) {
+ if (( smival.value.string.ptr[i] != '\r')&&
+ ( smival.value.string.ptr[i] != '\n')&&
+ (ACE_OS::ace_isprint((int) (smival.value.string.ptr[i]))==0))
+ return(to_string_hex());
+ }
+
+ if ( output_buffer != 0)
+ delete [] output_buffer;
+
+ ACE_NEW_RETURN(output_buffer, char[smival.value.string.len + 1], "");
+ if (smival.value.string.len)
+ ACE_OS::memcpy(output_buffer, smival.value.string.ptr,
+ (int) smival.value.string.len);
+ output_buffer[smival.value.string.len] = '\0';
+ return output_buffer;
+}
+
+
+//================[ general Value = operator ]========================
+SnmpSyntax& OctetStr::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from self
+ if ( this == &val )
+ return *this;
+
+ // blow away the old value
+ validity=0;
+ if (smival.value.string.ptr) {
+ reset_octet_smi(smival);
+ }
+ smival.value.string.len = 0;
+ if (val.valid()){
+ switch (val.get_syntax()) {
+ case sNMP_SYNTAX_OCTETS:
+ case sNMP_SYNTAX_IPADDR:
+ set_data( ((OctetStr &)val).smival.value.string.ptr,
+ ((OctetStr &)val).smival.value.string.len);
+ break;
+ }
+ }
+ return *this;
+}
+
+//================[ format the output into hex ]========================
+const char *OctetStr::to_string_hex()
+{
+ int cnt;
+ char char_buf[80]; // holds ASCII representation of data
+ char *buf_ptr; // pointer into ASCII listing
+ char *line_ptr; // pointer into Hex listing
+ int storageNeeded; // how much space do we need ?
+ int local_len = (int) smival.value.string.len;
+ SmiBYTE *bytes = smival.value.string.ptr;
+
+
+ storageNeeded = (int) ((smival.value.string.len/16)+1) * 72 + 1;
+
+ if ( output_buffer != 0)
+ delete [] output_buffer;
+
+ ACE_NEW_RETURN(output_buffer, char[storageNeeded], "");
+
+ line_ptr = output_buffer;
+
+ /*----------------------------------------*/
+ /* processing loop for entire data buffer */
+ /*----------------------------------------*/
+ while (local_len > 0) {
+ cnt = 16; /* print 16 bytes per line */
+ buf_ptr = char_buf;
+ sprintf(line_ptr, " ");
+ line_ptr += 2; /* indent */
+
+ /*-----------------------*/
+ /* process a single line */
+ /*-----------------------*/
+ while (cnt-- > 0 && local_len-- > 0) {
+ sprintf(line_ptr, "%2.2X ", *bytes);
+
+ line_ptr +=3; /* the display of a byte always 3 chars long */
+ if (isprint(*bytes))
+ sprintf(buf_ptr, "%c", *bytes);
+ else
+ sprintf(buf_ptr, ".");
+ bytes++;
+ buf_ptr++;
+ }
+ cnt++;
+
+ /*----------------------------------------------------------*/
+ /* this is to make sure that the ASCII displays line up for */
+ /* incomplete lines of hex */
+ /*----------------------------------------------------------*/
+ while (cnt-- > 0) {
+ sprintf(line_ptr," ");
+ line_ptr += 3;
+ }
+
+ /*------------------------------------------*/
+ /* append the ASCII display to the Hex line */
+ /*------------------------------------------*/
+
+// TODO: verify ACE_OS:: on NT works like this or not
+
+#if defined(_WIN32)
+ const char *fmt = " %s\r\n";
+#else
+ const char *fmt = " %s\n";
+#endif // _WIN32
+
+ ACE_OS::sprintf(line_ptr, fmt, char_buf);
+ line_ptr += 3 + ACE_OS::strlen(char_buf);
+ }
+
+ return output_buffer;
+}
diff --git a/ACE/ASNMP/asnmp/octet.h b/ACE/ASNMP/asnmp/octet.h
new file mode 100644
index 00000000000..5e8c8d63d98
--- /dev/null
+++ b/ACE/ASNMP/asnmp/octet.h
@@ -0,0 +1,152 @@
+
+
+#ifndef OCTET_CLS_
+#define OCTET_CLS_
+//=============================================================================
+/**
+ * @file octet.h
+ *
+ * $Id$
+ *
+ * This class is fully contained and does not rely on or any other
+ * SNMP libraries. This class is portable across any platform
+ * which supports C++.
+ *
+ *
+ * @author Peter E Mellquist / design/original code Michael R. MacFaden / modified for ACE
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+//------------------------------------------------------------------------
+#include "asnmp/smival.h"
+
+/**
+ * @class OctetStr
+ *
+ * @brief Implement RFC1155 Octet SMI data object
+ */
+class ASNMP_Export OctetStr : public SnmpSyntax
+
+{
+public:
+ /// construct octet from byte buffer, assume c style string if size == -1
+ OctetStr( const char *string = "", long size = -1);
+
+ /// constructor using another octet object
+ OctetStr ( const OctetStr &octet);
+
+ /// destructor
+ ~OctetStr();
+
+ /// syntax type
+ SmiUINT32 get_syntax();
+
+ /// set octet from byte buffer, assume c style string if size == -1
+ void set_data( const SmiBYTE* string, long int size = -1);
+
+ /// assignment to a string operator overloaded
+ OctetStr& operator=( const char *string);
+
+ /// assignment to another oid object overloaded
+ OctetStr& operator=( const OctetStr &octet);
+
+ /// equivlence operator overloaded
+ friend ASNMP_Export bool operator==( const OctetStr &lhs, const OctetStr &rhs);
+
+ /// not equivlence operator overloaded
+ friend ASNMP_Export bool operator!=( const OctetStr &lhs, const OctetStr &rhs);
+
+ /// less than < overloaded
+ friend ASNMP_Export bool operator<( const OctetStr &lhs, const OctetStr &rhs);
+
+ /// less than <= overloaded
+ friend ASNMP_Export bool operator<=( const OctetStr &lhs,const OctetStr &rhs);
+
+ /// greater than > overloaded
+ friend ASNMP_Export bool operator>( const OctetStr &lhs, const OctetStr &rhs);
+
+ /// greater than >= overloaded
+ friend ASNMP_Export bool operator>=( const OctetStr &lhs, const OctetStr &rhs);
+
+ /// equivlence operator overloaded
+ friend ASNMP_Export bool operator==( const OctetStr &lhs,const char *rhs);
+
+ /// not equivlence operator overloaded
+ friend ASNMP_Export bool operator!=( const OctetStr &lhs,const char *rhs);
+
+ /// less than < operator overloaded
+ friend ASNMP_Export bool operator<( const OctetStr &lhs,const char *rhs);
+
+ /// less than <= operator overloaded
+ friend ASNMP_Export bool operator<=( const OctetStr &lhs,char *rhs);
+
+ /// greater than > operator overloaded
+ friend ASNMP_Export bool operator>( const OctetStr &lhs,const char *rhs);
+
+ /// greater than >= operator overloaded
+ friend ASNMP_Export bool operator>=( const OctetStr &lhs,const char *rhs);
+
+ /// append operator, appends a string
+ OctetStr& operator+=( const char *a);
+
+ /// appends an int
+ OctetStr& operator+=( const char c);
+
+ /// append one octetStr to another
+ OctetStr& operator+=( const OctetStr& octetstr);
+
+ /// for non const [], allows reading and writing
+ SmiBYTE& operator[]( int position);
+
+ /**
+ * compare the n leftmost bytes (left-to-right)
+ * returns 0, equal
+ * returns -1, <
+ * returns 1 , >
+ */
+ int left_comparison( const long n, const OctetStr &o) const;
+
+ /// return the len of the oid
+ size_t length() const ;
+
+ /// returns validity
+ int valid() const;
+
+ /// returns pointer to internal data
+ SmiBYTE *data() const;
+
+ /// get a printable ASCII value
+ const char *to_string();
+
+ /// get an ASCII formattted hex dump of the contents
+ const char *to_string_hex();
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+protected:
+ //----[ instance variables ]
+ char *output_buffer; // formatted Octet value
+ int validity; // validity boolean
+};
+
+#endif // OCTET_CLS_
diff --git a/ACE/ASNMP/asnmp/oid.cpp b/ACE/ASNMP/asnmp/oid.cpp
new file mode 100644
index 00000000000..b5999a1fcbd
--- /dev/null
+++ b/ACE/ASNMP/asnmp/oid.cpp
@@ -0,0 +1,803 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// oid.cpp
+//
+// = DESCRIPTION
+// This module contains the implementation of the oid class. This
+// includes all protected and public member functions. The oid class
+// may be compiled stand alone without the use of any other library.
+//
+// = AUTHOR
+// Peter E Mellquist
+// Michael R MacFaden mrm@cisco.com - rework & ACE port
+// ============================================================================
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS" without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+//---------[ external C libaries used ]--------------------------------
+
+#include "asnmp/oid.h" // include def for oid class
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_Memory.h"
+#include "ace/os_include/os_ctype.h"
+
+ACE_RCSID(asnmp, oid, "$Id$")
+
+enum Defs {SNMPBUFFSIZE=300,
+ SNMPCHARSIZE=15}; // max oid value (4294967295UL)
+
+#define NO_MEM_STR "ERROR: Oid::to_string: memory allocation failure"
+
+//=============[Oid::get_syntax(void)]====================================
+SmiUINT32 Oid::get_syntax()
+{
+ return sNMP_SYNTAX_OID;
+}
+
+
+//=============[Oid::Oid( const char *dotted_string ]=====================
+// constructor using a dotted string
+//
+// do a string to oid using the string passed in
+Oid::Oid( const char * dotted_oid_string, size_t size)
+{
+ // can't init enum SmiValue so just memset it clean
+ set_null();
+
+ size_t z;
+ if ((z = ACE_OS::strlen(dotted_oid_string)) == 0) {
+ set_invalid();
+ return;
+ }
+
+ if (size == (unsigned int)-1)
+ size = z;
+ if (size > z)
+ size = z;
+
+ char *ptr = (char *)dotted_oid_string;;
+ if (size < z) {
+ // create new buffer if needed
+ ACE_NEW(ptr, char [size]);
+
+ // sz should be in StrToOid?
+ ACE_OS::memcpy( (void *)ptr, dotted_oid_string, size);
+ }
+
+ size_t byte_counter;
+ if (StrToOid( (char *) ptr, &smival.value.oid, byte_counter) < 0)
+ set_invalid();
+ if (ptr != dotted_oid_string)
+ delete [] ptr;
+}
+
+
+//=============[Oid::Oid( const Oid &oid) ]================================
+// constructor using another oid object
+//
+// do an oid copy using the oid object passed in
+Oid::Oid ( const Oid &oid)
+ : SnmpSyntax (oid)
+{
+ set_null();
+
+ // allocate some memory for the oid
+ // in this case the size to allocate is the same
+ // size as the source oid
+ if (oid.smival.value.oid.len) {
+ ACE_NEW(smival.value.oid.ptr, SmiUINT32[ oid.smival.value.oid.len]);
+ size_t byte_counter;
+ OidCopy( (SmiLPOID) &(oid.smival.value.oid),(SmiLPOID)
+ &smival.value.oid, byte_counter);
+ }
+}
+
+
+//=============[Oid::Oid( const unsigned long *raw_oid, int oid_len) ]====
+// constructor using raw numeric form
+//
+// copy the integer values into the private member
+Oid::Oid(const unsigned long *raw_oid, size_t oid_len)
+{
+ set_null();
+
+ smival.syntax = sNMP_SYNTAX_OID;
+ set_invalid();
+
+ if (raw_oid && oid_len > 0) {
+ ACE_NEW(smival.value.oid.ptr, SmiUINT32[ oid_len]);
+ smival.value.oid.len = oid_len;
+ for (size_t i=0; i < oid_len; i++)
+ smival.value.oid.ptr[i] = raw_oid[i];
+ }
+}
+
+//=============[Oid::~Oid]==============================================
+// destructor
+//
+// free up the descriptor space
+Oid::~Oid()
+{
+ // free up the octet deep memory
+ if ( smival.value.oid.ptr ) {
+ set_invalid();
+ }
+
+ // free up the output string
+ if ( iv_str != 0)
+ delete [] iv_str;
+}
+
+
+//=============[Oid::operator = const char * dotted_string ]==============
+// assignment to a string operator overloaded
+//
+// free the existing oid
+// create the new oid from the string
+// return this object
+void Oid::set_data( const char *dotted_oid_string)
+{
+ // delete the old value
+ if ( smival.value.oid.ptr ) {
+ set_invalid();
+ }
+
+ // assign the new value
+ size_t byte_counter;
+ if (StrToOid( (char *) dotted_oid_string, &smival.value.oid, byte_counter) <0)
+ set_invalid();
+}
+
+
+//=============[Oid:: operator = const Oid &oid ]==========================
+// assignment to another oid object overloaded
+//
+// free the existing oid
+// create a new one from the object passed in
+// TODO: measure perf vs memory of no realloc in case where len >= oid.len
+Oid& Oid::operator=( const Oid &oid)
+{
+ // protect against assignment from self
+ if ( this == &oid)
+ return *this;
+
+ set_invalid();
+
+ // check for zero len on source
+ if ( oid.smival.value.oid.len == 0)
+ return *this;
+
+ const SmiLPOID srcOid = (SmiLPOID) &(oid.smival.value.oid);
+ init_value(srcOid, oid.smival.value.oid.len);
+ return *this;
+}
+
+// assign this object the oid, set to invalid if copy fails
+void Oid::init_value(const SmiLPOID srcOid, size_t len)
+{
+ // allocate some memory for the oid
+ ACE_NEW(smival.value.oid.ptr, SmiUINT32[ len]);
+ size_t byte_counter;
+ OidCopy( srcOid, (SmiLPOID) &smival.value.oid, byte_counter);
+}
+
+void Oid::init_value(const unsigned long *raw_oid, size_t oid_len)
+{
+ if (smival.value.oid.ptr)
+ delete [] smival.value.oid.ptr;
+
+ ACE_NEW(smival.value.oid.ptr, SmiUINT32[ oid_len]);
+ ACE_OS::memcpy((SmiLPBYTE) smival.value.oid.ptr,
+ (SmiLPBYTE) raw_oid,
+ (size_t) (oid_len * sizeof(SmiUINT32)));
+ smival.value.oid.len = oid_len;
+}
+
+//==============[Oid:: operator += const char *a ]=========================
+// append operator, appends a string
+//
+// allocate some space for a max oid string
+// extract current string into space
+// concat new string
+// free up existing oid
+// make a new oid from string
+// delete allocated space
+Oid& Oid::operator+=( const char *a)
+{
+ unsigned long n;
+
+ if (!a)
+ return *this;
+
+ if ( *a=='.')
+ a++;
+ size_t sz = ACE_OS::strlen(a);
+
+ if (valid()) {
+ n = (smival.value.oid.len *SNMPCHARSIZE) + smival.value.oid.len + 1 + sz;
+ char *ptr;
+ ACE_NEW_RETURN(ptr, char[ n], *this);
+ size_t byte_counter;
+ if (OidToStr(&smival.value.oid, n,ptr, byte_counter) > 0) {
+ delete [] ptr;
+ set_invalid();
+ return *this;
+ }
+
+ if (ACE_OS::strlen(ptr))
+ ACE_OS::strcat(ptr,".");
+ ACE_OS::strcat(ptr,a);
+ if ( smival.value.oid.len !=0) {
+ set_invalid();
+ }
+
+ if (StrToOid( (char *) ptr, &smival.value.oid, byte_counter) < 0) {
+ set_invalid();
+ }
+ delete [] ptr;
+ }
+ else {
+ size_t byte_counter;
+ if (StrToOid( (char *) a, &smival.value.oid, byte_counter) < 0) {
+ set_invalid();
+ }
+ }
+
+ return *this;
+}
+
+//=============[ bool operator == oid,oid ]=================================
+// equivlence operator overloaded
+bool operator==( const Oid &lhs, const Oid &rhs)
+{
+ // ensure same len, then use left_comparison
+ if (rhs.length() != lhs.length())
+ return false;
+ if( lhs.left_comparison( rhs.length(), rhs) == 0)
+ return true;
+ else
+ return false;
+}
+
+//==============[ bool operator!=( Oid &x,Oid &y) ]=======================
+//not equivlence operator overloaded
+bool operator!=( const Oid &lhs,const Oid &rhs)
+{
+ return (!(lhs == rhs));
+}
+
+//==============[ bool operator<( Oid &x,Oid &y) ]========================
+// less than < overloaded
+bool operator<( const Oid &lhs,const Oid &rhs)
+{
+ int result;
+
+ // call left_comparison with the current
+ // Oidx, Oidy and len of Oidx
+ if ((result = lhs.left_comparison( rhs.length(), rhs)) < 0)
+ return true;
+ else if (result > 0)
+ return false;
+
+ else{
+ // if here, equivalent substrings, call the shorter one <
+ if (lhs.length() < rhs.length())
+ return true;
+ else
+ return false;
+ }
+}
+
+//==============[ bool operator<=( Oid &x,Oid &y) ]=======================
+// less than <= overloaded
+bool operator<=( const Oid &x,const Oid &y)
+{
+ if ( (x < y) || (x == y) )
+ return true;
+ else
+ return false;
+}
+
+//==============[ bool operator>( Oid &x,Oid &y) ]========================
+// greater than > overloaded
+bool operator>( const Oid &x,const Oid &y)
+{
+ // just invert existing <=
+ if (!(x<=y))
+ return true;
+ else
+ return false;
+}
+
+//==============[ bool operator>=( Oid &x,Oid &y) ]=======================
+// greater than >= overloaded
+bool operator>=( const Oid &x,const Oid &y)
+{
+ // just invert existing <
+ if (!(x<y))
+ return true;
+ else
+ return false;
+}
+
+//===============[Oid::oidval ]=============================================
+// return the WinSnmp oid part
+SmiLPOID Oid::oidval()
+{
+ return (SmiLPOID) &smival.value.oid;
+}
+
+//===============[Oid::set_data ]==---=====================================
+// copy data from raw form...
+void Oid::set_data( const unsigned long *raw_oid, const size_t oid_len)
+{
+ if (smival.value.oid.len < oid_len) {
+ if ( smival.value.oid.ptr) {
+ set_invalid();
+ }
+ }
+ init_value(raw_oid, oid_len);
+}
+
+
+//===============[Oid::len ]================================================
+// return the len of the oid
+size_t Oid::length() const
+{
+ return smival.value.oid.len;
+}
+
+//===============[Oid::trim( unsigned int) ]============================
+// trim off the n leftmost values of an oid
+// Note!, does not adjust actual space for
+// speed
+void Oid::trim( const size_t n)
+{
+ // verify that n is legal
+ if ((n<=smival.value.oid.len)&&(n>0)) {
+ smival.value.oid.len -= n;
+
+ if (smival.value.oid.len == 0) {
+ set_invalid();
+ }
+ }
+}
+
+//===============[Oid::set_invalid() ]====================
+// make this object invalid by resetting all values
+void Oid::set_invalid() {
+ delete [] smival.value.oid.ptr;
+ smival.value.oid.ptr = 0;
+ smival.value.oid.len = 0;
+ delete [] iv_str;
+ iv_str = 0;
+}
+
+//===============[Oid::set_null() ]====================
+void Oid::set_null() {
+ smival.syntax = sNMP_SYNTAX_OID;
+ smival.value.oid.ptr = 0;
+ smival.value.oid.len = 0;
+ iv_str = 0;
+}
+
+//===============[Oid::operator += const unsigned int) ]====================
+// append operator, appends an int
+//
+// allocate some space for a max oid string
+// extract current string into space
+// concat new string
+// free up existing oid
+// make a new oid from string
+// delete allocated space
+Oid& Oid::operator+=( const unsigned long i)
+{
+ unsigned long n = (smival.value.oid.len * SNMPCHARSIZE)
+ + ( smival.value.oid.len -1) + 1 + 4;
+ char buffer[SNMPBUFFSIZE];
+
+ // two cases: null oid, existing oid
+ if (valid()) {
+ // allocate some temporary space
+ char *ptr;
+ ACE_NEW_RETURN(ptr, char[ n], *this);
+ size_t byte_counter;
+ if (OidToStr(&smival.value.oid, n, ptr, byte_counter) < 0) {
+ set_invalid();
+ delete [] ptr;
+ return *this;
+ }
+
+ if (ACE_OS::strlen(ptr))
+ ACE_OS::strcat(ptr,".");
+
+ if (ACE_OS::sprintf( buffer,"%lu",i) != -1) {
+ ACE_OS::strcat(ptr, buffer);
+ if ( smival.value.oid.ptr ) {
+ set_invalid();
+ }
+ if (StrToOid( (char *) ptr, &smival.value.oid, byte_counter) < 0) {
+ set_invalid();
+ }
+ delete [] ptr;
+ }
+ }
+ else {
+ init_value((const unsigned long *)&i, (size_t)1);
+ }
+
+ return *this;
+}
+
+//===============[Oid::operator += const Oid) ]========================
+// append operator, appends an Oid
+//
+// allocate some space for a max oid string
+// extract current string into space
+// concat new string
+// free up existing oid
+// make a new oid from string
+// delete allocated space
+Oid& Oid::operator+=( const Oid &o)
+{
+ SmiLPUINT32 new_oid;
+
+ if (o.smival.value.oid.len == 0)
+ return *this;
+
+ ACE_NEW_RETURN(new_oid,
+ SmiUINT32[ smival.value.oid.len + o.smival.value.oid.len], *this);
+ if (smival.value.oid.ptr) {
+ ACE_OS::memcpy((SmiLPBYTE) new_oid,
+ (SmiLPBYTE) smival.value.oid.ptr,
+ (size_t) (smival.value.oid.len*sizeof(SmiUINT32)));
+
+ delete [] smival.value.oid.ptr;
+ }
+
+ // out with the old, in with the new...
+ smival.value.oid.ptr = new_oid;
+
+ ACE_OS::memcpy((SmiLPBYTE) &new_oid[smival.value.oid.len],
+ (SmiLPBYTE) o.smival.value.oid.ptr,
+ (size_t) (o.smival.value.oid.len*sizeof(SmiUINT32)));
+
+ smival.value.oid.len += o.smival.value.oid.len;
+ return *this;
+}
+
+// return string portion of the oid
+//
+const char * Oid::to_string()
+{
+ unsigned long n;
+ if (!valid())
+ return ""; // be consistent with other classes
+
+ // the worst case char len of an oid can be..
+ // oid.len*3 + dots in between if each oid is XXXX
+ // so.. size = (len*4) + (len-1) + 1 , extra for a null
+
+ n = (smival.value.oid.len *SNMPCHARSIZE) + ( smival.value.oid.len -1) + 1 ;
+ if (n == 0)
+ n = 1; // need at least 1 byte for a null string
+
+ // adjust the len of output array in case size was adjusted
+ if ( iv_str != 0)
+ delete [] iv_str;
+ // allocate some space for the output string
+ ACE_NEW_RETURN(iv_str, char[ n], "");
+
+ // convert to an output string
+ size_t how_many;
+ if ( valid() && iv_str != 0)
+ if (OidToStr(&smival.value.oid,n,iv_str, how_many) < 0)
+ return "ERROR: Oid::OidToStr failed";
+ return iv_str;
+}
+
+//==============[Oid::suboid( unsigned int start, n) ]=============
+int Oid::suboid(Oid& new_oid, size_t start, size_t how_many)
+{
+ if (how_many == 0)
+ return 0;
+ else
+ if (how_many == (size_t)-1)
+ how_many = length();
+ else
+ if (how_many > length())
+ how_many = length();
+
+ // reset new_oid
+ new_oid.set_invalid();
+
+ size_t new_size = how_many - start;
+ if (new_size == 0)
+ new_size++;
+ new_oid.smival.value.oid.len = new_size;
+ ACE_NEW_RETURN(new_oid.smival.value.oid.ptr,
+ SmiUINT32 [ new_oid.smival.value.oid.len], -1);
+ // copy source to destination
+ ACE_OS::memcpy( (SmiLPBYTE) new_oid.smival.value.oid.ptr,
+ (SmiLPBYTE) (smival.value.oid.ptr + start),
+ new_size * sizeof(SmiLPBYTE));
+ return 0;
+}
+
+
+//=============[Oid::StrToOid( char *string, SmiLPOID dst) ]==============
+// convert a string to an oid
+int Oid::StrToOid( const char *string, SmiLPOID dstOid, size_t& how_many)
+{
+ size_t index = 0;
+ size_t number = 0;
+
+ // make a temp buffer to copy the data into first
+ SmiLPUINT32 temp;
+ unsigned long nz;
+
+ if (string && *string) {
+ nz = ACE_OS::strlen( string);
+ }
+ else {
+ dstOid->len = 0;
+ dstOid->ptr = 0;
+ return -1;
+ }
+
+ ACE_NEW_RETURN(temp, SmiUINT32[ nz], -1);
+ while (*string!=0 && index<nz) {
+ // init the number for each token
+ number = 0;
+ // skip over the dot
+ if (*string=='.')
+ string++;
+
+ // grab a digit token and convert it to a long int
+ while (isdigit(*string))
+ number=number*10 + *(string++)-'0';
+
+ // check for invalid chars
+ if (*string!=0 && *string!='.') {
+ // Error: Invalid character in string
+ delete [] temp;
+ return -1;
+ }
+
+ // stuff the value into the array
+ temp[index] = number;
+ index++; // bump the counter
+ }
+
+
+ // get some space for the real oid
+ ACE_NEW_RETURN(dstOid->ptr, SmiUINT32[ index], -1);
+ // TODO: make tmp autoptr type delete [] temp to prevent leak
+
+ // copy in the temp data
+ ACE_OS::memcpy((SmiLPBYTE) dstOid->ptr, (SmiLPBYTE) temp,
+ (size_t) (index*sizeof(SmiUINT32)));
+
+ // set the len of the oid
+ dstOid->len = index;
+
+ // free up temp data
+ delete [] temp;
+
+ how_many = index;
+ return 0;
+}
+
+
+//===============[Oid::OidCopy( source, destination) ]====================
+// Copy an oid, return bytes copied
+int Oid::OidCopy( SmiLPOID srcOid, SmiLPOID dstOid, size_t& how_many_bytes)
+{
+ // check source len ! zero
+ if (srcOid->len == 0)
+ return -1;
+
+ // copy source to destination
+ ACE_OS::memcpy((SmiLPBYTE) dstOid->ptr,
+ (SmiLPBYTE) srcOid->ptr,
+ (size_t) (srcOid->len * sizeof(SmiUINT32)));
+
+ //set the new len
+ dstOid->len = srcOid->len;
+ how_many_bytes = srcOid->len;
+
+ return 0;
+}
+
+
+//===============[Oid::left_comparison( n, Oid) ]=================================
+// compare the n leftmost values of two oids ( left-to_right )
+//
+// self == Oid then return 0, they are equal
+// self < Oid then return -1, <
+// self > Oid then return 1, >
+int Oid::left_comparison( const unsigned long n, const Oid &o) const
+{
+ unsigned long z;
+ unsigned long len = n;
+ int reduced_len = 0;
+
+ // 1st case they both are null
+ if (( len==0)&&( this->smival.value.oid.len==0))
+ return 0; // equal
+
+ // verify that n is valid, must be >= 0
+ if ( len <=0)
+ return 1; // ! equal
+
+ // only compare for the minimal length
+ if (len > this->smival.value.oid.len) {
+ len = this->smival.value.oid.len;
+ reduced_len = 1;
+ }
+ if (len > o.smival.value.oid.len) {
+ len = o.smival.value.oid.len;
+ reduced_len = 1;
+ }
+
+ z = 0;
+ while(z < len) {
+ if ( this->smival.value.oid.ptr[z] < o.smival.value.oid.ptr[z])
+ return -1; // less than
+ if ( this->smival.value.oid.ptr[z] > o.smival.value.oid.ptr[z])
+ return 1; // greater than
+ z++;
+ }
+
+ // if we truncated the len then these may not be equal
+ if (reduced_len) {
+ if (this->smival.value.oid.len < o.smival.value.oid.len)
+ return -1;
+ if (this->smival.value.oid.len > o.smival.value.oid.len)
+ return 1;
+ }
+ return 0; // equal
+
+}
+
+
+//===============[Oid::left_comparison( n, Oid) ]=================================
+// compare the n rightmost bytes (right-to-left)
+// returns 0, equal
+// returns -1, <
+// returns 1 , >
+int Oid::right_comparison( const unsigned long n, const Oid &o) const
+{
+ // oid to compare must have at least the same number
+ // of sub-ids to comparison else the argument Oid is
+ // less than THIS
+ if ( o.length() < n)
+ return -1;
+
+ // also can't compare argument oid for sub-ids which
+ // THIS does not have
+ if ( this->length() < n)
+ return -1;
+
+ int start = (int) this->length();
+ int end = (int) start - (int) n;
+ for ( int z=start;z< end;z--)
+ {
+ if ( o.smival.value.oid.ptr[z] < this->smival.value.oid.ptr[z])
+ return -1;
+ if ( o.smival.value.oid.ptr[z] > this->smival.value.oid.ptr[z])
+ return 1;
+ }
+
+ return 0; // they are equal
+
+}
+
+
+//================[ Oid::valid() ]========================================
+// is the Oid object valid
+// returns validity
+int Oid::valid() const
+{
+ return ( smival.value.oid.ptr ? 1 : 0 );
+}
+
+//================[Oid::OidToStr ]=========================================
+// convert an oid to a string
+int Oid::OidToStr( SmiLPOID srcOid, unsigned long size,
+ char *string, size_t& how_many_bytes)
+{
+ unsigned long index = 0;
+ unsigned totLen = 0;
+ char szNumber[SNMPBUFFSIZE];
+
+ // init the string
+ string[totLen] = 0;
+
+ // verify there is something to copy
+ if (srcOid->len == 0)
+ return -1;
+
+ // loop through and build up a string
+ for (index=0; index < srcOid->len; index++) {
+
+ // convert data element to a string
+ if (ACE_OS::sprintf( szNumber,"%lu", srcOid->ptr[index]) == -1)
+ return -1;
+
+ // verify len is not over
+ if (totLen + ACE_OS::strlen(szNumber) + 1 >= size)
+ return -2;
+
+ // if not at end, pad with a dot
+ if (totLen!=0)
+ string[totLen++] = '.';
+
+ // copy the string token into the main string
+ ACE_OS::strcpy(string + totLen, szNumber);
+
+ // adjust the total len
+ totLen += ACE_OS::strlen(szNumber);
+ }
+
+ how_many_bytes = totLen + 1;
+ return 0;
+}
+
+
+//================[ general Value = operator ]========================
+SnmpSyntax& Oid::operator=( SnmpSyntax &val)
+{
+ // protect against assignment from self
+ if ( this == &val )
+ return *this;
+
+ // blow away old value
+ smival.value.oid.len = 0;
+ if (smival.value.oid.ptr) {
+ set_invalid();
+ }
+
+ // assign new value
+ if (val.valid()) {
+ switch (val.get_syntax()) {
+ case sNMP_SYNTAX_OID:
+ set_data( ((Oid &)val).smival.value.oid.ptr,
+ (unsigned int)((Oid &)val).smival.value.oid.len);
+ break;
+ }
+ }
+ return *this;
+}
+
+//================[ [] operator ]=====================================
+unsigned long& Oid::operator[](size_t position)
+{
+ return smival.value.oid.ptr[position];
+}
+
+//================[ clone ]===========================================
+SnmpSyntax *Oid::clone() const
+{
+ return (SnmpSyntax *) new Oid(*this);
+}
diff --git a/ACE/ASNMP/asnmp/oid.h b/ACE/ASNMP/asnmp/oid.h
new file mode 100644
index 00000000000..77118b518f0
--- /dev/null
+++ b/ACE/ASNMP/asnmp/oid.h
@@ -0,0 +1,175 @@
+
+
+#ifndef OID_CLS_
+#define OID_CLS_
+//=============================================================================
+/**
+ * @file oid.h
+ *
+ * $Id$
+ *
+ * This class is fully contained and does not rely on or any other
+ * SNMP libraries. This class is portable across any platform
+ * which supports C++. Ported to ACE by Mike MacFaden mrm@cisco.com
+ * and modified for MT. Some API cleanup: collapse constructors,
+ * add suboid() method remove unnecessary overload, and update a few
+ * names and types to improve clarity.
+ *
+ *
+ * @author Peter E Mellquist
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+//----------[ extern C libraries Needed ]---------------------------------
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "asnmp/smival.h" // derived class for all values
+
+/**
+ * @class Oid
+ *
+ * @brief Implement RFC 1155 Object Identifier (OID) datatype
+ */
+class ASNMP_Export Oid : public SnmpSyntax
+{
+public:
+ /// constructor using a dotted string
+ Oid( const char * dotted_oid_string = "", size_t size = unsigned(-1) );
+
+ /// constructor using another oid object
+ Oid ( const Oid &oid);
+
+ /// constructor from raw form
+ Oid(const unsigned long *raw_oid, size_t oid_len);
+
+ /// destructor
+ ~Oid();
+
+ /// syntax type
+ SmiUINT32 get_syntax();
+
+ /// assignment to another oid object overloaded
+ Oid& operator=( const Oid &oid);
+
+ /// equal operator overloaded
+ friend ASNMP_Export bool operator==( const Oid &lhs,const Oid &rhs);
+
+ /// not equal operator overloaded
+ friend ASNMP_Export bool operator!=( const Oid &lhs,const Oid &rhs);
+
+ /// less than < overloaded
+ friend ASNMP_Export bool operator<( const Oid &lhs,const Oid &rhs);
+
+ /// less than <= overloaded
+ friend ASNMP_Export bool operator<=( const Oid &lhs,const Oid &rhs);
+
+ /// greater than > overloaded
+ friend ASNMP_Export bool operator>( const Oid &lhs,const Oid &rhs);
+
+ /// greater than >= overloaded
+ friend ASNMP_Export bool operator>=( const Oid &lhs,const Oid &rhs);
+
+ /// append operator, appends a string
+ Oid& operator+=( const char *a);
+
+ /// appends an int
+ Oid& operator+=( const unsigned long i);
+
+ /// appends an Oid
+ Oid& operator+=( const Oid &o);
+
+ /// allows element access
+ unsigned long & operator[]( size_t position);
+
+ /// return the WinSnmp oid part
+ SmiLPOID oidval();
+
+ /// reset the data from raw 1 byte format
+ void set_data( const char *dotted_oid_string);
+
+ /// reset the data from raw 4byte integer format
+ void set_data( const unsigned long *raw_oid, const size_t oid_len);
+
+ /// return the len of the oid
+ size_t length() const;
+
+ /// trim off the n rightmost values of an oid
+ void trim( const size_t how_many = 1);
+
+ /// the equivalent of a substr(new_str, 0, 1)
+ int suboid(Oid& oid, size_t start = 0, size_t how_many = size_t (-1));
+
+ /**
+ * compare the n leftmost bytes (left-to-right)
+ * returns 0, equal
+ * returns -1, <
+ * returns 1 , >
+ */
+ int left_comparison( const unsigned long n, const Oid &o) const;
+
+
+ /**
+ * compare the n rightmost bytes (right-to-left)
+ * returns 0, equal
+ * returns -1, <
+ * returns 1 , >
+ */
+ int right_comparison( const unsigned long n, const Oid &o) const;
+
+ /// is the Oid object valid
+ int valid() const;
+
+ /// return dotted string value from the right
+ /// where the user specifies how many positions to print
+ const char *to_string();
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=( SnmpSyntax &val);
+
+protected:
+ /// used for returning oid string
+ char *iv_str;
+
+ /// convert a string to an smi oid
+ int StrToOid( const char *string, SmiLPOID dstOid, size_t& how_many_bytes);
+
+ /// clone an smi oid
+ int OidCopy( SmiLPOID srcOid, SmiLPOID dstOid, size_t& how_many_bytes);
+
+ /// convert an smi oid to its string representation
+ int OidToStr(SmiLPOID srcOid, SmiUINT32 size, char *string, size_t& how_many_bytes);
+
+ private:
+ /// release memory, re-init data members
+ void set_invalid();
+
+ /// initialize object data members
+ void set_null();
+ void init_value( const SmiLPOID srcOid, size_t len);
+ void init_value(const unsigned long *raw_oid, size_t oid_len);
+};
+
+#endif //OID_CLS_
diff --git a/ACE/ASNMP/asnmp/oid_def.h b/ACE/ASNMP/asnmp/oid_def.h
new file mode 100644
index 00000000000..31ccbfa3e4a
--- /dev/null
+++ b/ACE/ASNMP/asnmp/oid_def.h
@@ -0,0 +1,84 @@
+/* -*-C++-*- */
+#ifndef OID_DEF
+#define OID_DEF
+//=============================================================================
+/**
+ * @file oid_def.h
+ *
+ * $Id$
+ *
+ * Well known Oids defined in RFC 1215
+ *
+ *
+ * @author Peter E Mellquist
+ */
+//=============================================================================
+
+/*===================================================================
+
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+// SMI trap oid def
+class snmpTrapsOid: public Oid {
+ public:
+ snmpTrapsOid (void):Oid("1.3.6.1.6.3.1.1.5"){};
+};
+
+// SMI Enterprose Oid
+class snmpTrapEnterpriseOid: public Oid {
+ public:
+ snmpTrapEnterpriseOid(void):Oid("1.3.6.1.6.3.1.1.4.3.0"){};
+};
+
+// SMI Cold Start Oid
+class coldStartOid: public snmpTrapsOid {
+ public:
+ coldStartOid( void){*this+=".1";};
+};
+
+// SMI WarmStart Oid
+class warmStartOid: public snmpTrapsOid {
+ public:
+ warmStartOid( void){*this+=".2";};
+};
+
+// SMI LinkDown Oid
+class linkDownOid: public snmpTrapsOid {
+ public:
+ linkDownOid( void){*this+=".3";};
+};
+
+
+// SMI LinkUp Oid
+class linkUpOid: public snmpTrapsOid {
+ public:
+ linkUpOid( void){*this+=".4";};
+};
+
+// SMI Authentication Failure Oid
+class authenticationFailureOid: public snmpTrapsOid {
+ public:
+ authenticationFailureOid( void){*this+=".5";};
+};
+
+// SMI egpneighborloss Oid
+class egpNeighborLossOid: public snmpTrapsOid {
+ public:
+ egpNeighborLossOid( void){*this+=".6";};
+};
+
+
+#endif // OID_DEF
diff --git a/ACE/ASNMP/asnmp/pdu.cpp b/ACE/ASNMP/asnmp/pdu.cpp
new file mode 100644
index 00000000000..cbe67dcbbab
--- /dev/null
+++ b/ACE/ASNMP/asnmp/pdu.cpp
@@ -0,0 +1,499 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// pdu.cpp
+//
+// = DESCRIPTION
+// Pdu class implementation. Encapsulation of an SMI Protocol
+// Data Unit (PDU) in C++.
+//
+// = AUTHOR
+// Peter E Mellquist
+// Michael R MacFaden mrm@cisco.com - rework & ACE port
+// ============================================================================
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/snmp.h"
+#include "asnmp/pdu.h" // include Pdu class definition
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_stdio.h"
+
+ACE_RCSID(asnmp, pdu, "$Id$")
+
+//=====================[ constructor no args ]=========================
+Pdu::Pdu( void): vb_count_(0), error_status_(0), error_index_(0),
+validity_(0), request_id_(0), pdu_type_(0), notify_timestamp_(0),
+output_(0)
+{
+}
+
+//=====================[ constructor with vbs_ and count ]==============
+Pdu::Pdu( Vb* pvbs, const int pvb_count): vb_count_(0), error_index_(0),
+validity_(0), request_id_(0), pdu_type_(0), notify_timestamp_(0),
+output_(0)
+{
+ int z = 0; // looping variable
+
+ // zero is ok
+ if ( pvb_count == 0) {
+ validity_ = 1;
+ return;
+ }
+
+ // check for over then max
+ if ( pvb_count > MAX_VBS) {
+ validity_ = 0;
+ return;
+ }
+
+ // loop through and assign internal vbs_
+ for (z = 0;z < pvb_count; z++) {
+ validity_ = 0;
+ ACE_NEW(vbs_[z], Vb( pvbs[z]));
+ validity_ = 1;
+ }
+
+ // assign the vb count
+ vb_count_ = pvb_count;
+
+ validity_ = 1;
+}
+
+//=====================[ constructor with another Pdu instance ]========
+Pdu::Pdu( const Pdu &pdu): vb_count_(0),
+error_index_(0), validity_(0), request_id_(0), pdu_type_(0),
+notify_timestamp_(0), output_(0)
+{
+ *this = pdu;
+ return;
+}
+
+//=====================[ destructor ]====================================
+Pdu::~Pdu()
+{
+ delete_all_vbs();
+ delete [] output_;
+}
+
+
+//=====================[ assignment to another Pdu object overloaded ]===
+Pdu& Pdu::operator=( const Pdu &pdu)
+{
+ int z; // looping variable
+
+ // Initialize all mv's
+ error_status_ = pdu.error_status_;
+ error_index_ = pdu.error_index_;
+ request_id_ = pdu.request_id_;
+ pdu_type_ = pdu.pdu_type_;
+ notify_id_ = pdu.notify_id_;
+ notify_timestamp_ = pdu.notify_timestamp_;
+ notify_enterprise_ = pdu.notify_enterprise_;
+ validity_ = 1;
+
+ // free up old vbs_
+ for ( z = 0;z < vb_count_; z++)
+ delete vbs_[z];
+ vb_count_ = 0;
+
+ // check for zero case
+ if ( pdu.vb_count_ == 0) {
+ return *this;
+ }
+
+ // loop through and fill em up
+ for (z = 0; z < pdu.vb_count_; z++) {
+ validity_ = 0;
+ ACE_NEW_RETURN(vbs_[z], Vb ( *(pdu.vbs_[z])), *this);
+ validity_ = 1;
+ }
+
+ vb_count_ = pdu.vb_count_;
+ return *this;
+}
+
+// append operator, appends a string
+Pdu& Pdu::operator+=( Vb &vb)
+{
+
+ // do we have room?
+ if ( vb_count_ + 1 > MAX_VBS)
+ return *this;
+
+ // add the new one
+ validity_ = 0;
+ ACE_NEW_RETURN(vbs_[vb_count_], Vb (vb), *this);
+ // set up validity_
+ validity_ = 1;
+
+ // up the vb count
+ vb_count_++;
+
+ // return self reference
+ return *this;
+
+}
+
+// return fomatted version of this object
+const char * Pdu::to_string()
+{
+ // determine how big a buffer and allocate it
+ const int HEADER_STR = 100;
+ unsigned size = HEADER_STR; // header takes up this much room
+ int z;
+
+ for ( z = 0; z < vb_count_; z++)
+ size += ACE_OS::strlen(vbs_[z]->to_string());
+
+ ACE_NEW_RETURN(output_, char[size], "");
+
+ // print pdu header info
+ sprintf(output_, "pdu: valid: %d type:%d, req:%d, cnt: %d, err stat: %d \
+ err idx: %d\n", validity_, pdu_type_, (int) request_id_,
+ vb_count_, error_status_, error_index_ );
+
+ // now append vb pairs in this object
+ for ( z = 0; z < vb_count_; z++) {
+ ACE_OS::strcat(output_, vbs_[z]->to_string());
+ ACE_OS::strcat(output_, "\n\t");
+ }
+
+ return output_;
+}
+
+
+//=====================[ extract Vbs from Pdu ]==========================
+// how do you know that the caler has enough memory???
+// should I self allocate this in here and require the
+// caller then to free it up at soem later time
+int Pdu::get_vblist( Vb* pvbs, const int pvb_count)
+{
+ if ((!pvbs) || ( pvb_count < 0) || ( pvb_count > vb_count_))
+ return 0;
+
+ // loop through all vbs_ and assign to params
+ int z;
+ for (z = 0; z < pvb_count; z++)
+ pvbs[z] = *vbs_[z];
+
+ return 1;
+
+}
+
+//=====================[ deposit Vbs ]===================================
+int Pdu::set_vblist( Vb* pvbs, const int pvb_count)
+{
+
+ // if invalid then don't destroy
+ if ((!pvbs) || ( pvb_count < 0) || ( pvb_count > MAX_VBS))
+ return 0;
+
+ // free up current vbs_
+ int z;
+ for ( z = 0; z < vb_count_; z++)
+ delete vbs_[z];
+ vb_count_ = 0;
+
+ // check for zero case
+ if ( pvb_count == 0) {
+ validity_ = 1;
+ error_status_ = 0;
+ error_index_ = 0;
+ request_id_ = 0;
+ return 0;
+ }
+
+
+ // loop through all vbs_ and reassign them
+ for ( z = 0; z < pvb_count; z++) {
+ validity_ = 0;
+ ACE_NEW_RETURN(vbs_[z], Vb (pvbs[z]), 0);
+ validity_ = 1;
+ }
+
+ vb_count_ = pvb_count;
+
+ // clear error status and index since no longer valid
+ // request id may still apply so don't reassign it
+ error_status_ = 0;
+ error_index_ = 0;
+ validity_ = 1;
+
+ return 1;
+}
+
+//===================[ get a particular vb ]=============================
+// here the caller has already instantiated a vb object
+// index is zero based
+int Pdu::get_vb( Vb &vb, const int index) const
+{
+ // can't have an index less than 0
+ if ( index < 0)
+ return 0;
+
+ // can't ask for something not there
+ if ( index > (vb_count_ - 1))
+ return 0;
+
+ // asssign it
+ vb = *vbs_[index];
+
+ return 1;
+}
+
+//===================[ set a particular vb ]=============================
+int Pdu::set_vb( Vb &vb, const int index)
+{
+ // can't set a vb at index less than 0
+ if ( index < 0)
+ return 0;
+
+ // can't ask for something not there
+ if ( index > (vb_count_ - 1))
+ return 0;
+
+ // delete what is there
+ delete vbs_[index];
+
+ // assign it
+ validity_ = 0;
+ ACE_NEW_RETURN(vbs_[index], Vb (vb), 0);
+ validity_ = 1;
+
+ return 1;
+
+}
+
+//=====================[ return number of vbs_ ]==========================
+int Pdu::get_vb_count() const
+{
+ return vb_count_;
+}
+
+//=====================[ return the error status ]=======================
+int Pdu::get_error_status() const
+{
+ return error_status_;
+}
+
+const char *Pdu::agent_error_reason()
+{
+ int pdu_err = get_error_status();
+ if (pdu_err == 0) // any real error?
+ return "not in error state";
+
+ int n_vbs = get_vb_count();
+ Vb bad;
+ get_vb(bad, get_error_index() -1); // not zero based??
+ const char *pmsg = Snmp::error_string(get_error_status());
+ const char *id = bad.to_string_oid();
+ const char *val = bad.to_string_value();
+ const int HDR_SZ = 100;
+
+ if (!output_) {
+ int size = ACE_OS::strlen(pmsg) + ACE_OS::strlen(id) +
+ ACE_OS::strlen(val);
+ ACE_NEW_RETURN(output_, char[size + HDR_SZ], "");
+ }
+
+ ACE_OS::sprintf(output_,
+ "FAIL PDU REPORT: pdu id: %lu vb cnt: %d vb idx: %d\n"
+ " msg: %s vb oid: %s value: %s\n",
+ get_request_id(), n_vbs, get_error_index(),
+ pmsg, id, val);
+
+ return output_;
+}
+
+//=====================[ set the error status ]==========================
+// friend
+void set_error_status( Pdu *pdu, const int status)
+{
+ if (pdu)
+ pdu->error_status_ = status;
+}
+
+//=====================[ return the error index ]========================
+int Pdu::get_error_index() const
+{
+ return error_index_;
+}
+
+//=====================[ set the error index ]===========================
+// friend
+void set_error_index( Pdu *pdu, const int index)
+{
+ if (pdu)
+ pdu->error_index_ = index;
+}
+
+//=====================[ clear error status ]=============================
+void clear_error_status( Pdu *pdu)
+{
+ if (pdu)
+ pdu->error_status_ = 0;
+}
+
+//=====================[ clear error index ]==============================
+void clear_error_index( Pdu *pdu)
+{
+ if (pdu)
+ pdu->error_index_ = 0;
+}
+
+//=====================[ return the request id ]==========================
+unsigned long Pdu::get_request_id() const
+{
+ return request_id_;
+}
+
+//=====================[ set the request id ]=============================
+// friend function
+void set_request_id( Pdu *pdu, const unsigned long rid)
+{
+ if (pdu)
+ pdu->request_id_ = rid;
+}
+
+//=====================[ returns validity_ of Pdu instance ]===============
+int Pdu::valid() const
+{
+ return validity_;
+}
+
+//=====================[ get the pdu type ]===============================
+unsigned short Pdu::get_type()const
+{
+ return pdu_type_;
+}
+
+// set the pdu type
+void Pdu::set_type( unsigned short type)
+{
+ pdu_type_ = type;
+}
+
+
+// trim off the last vb
+int Pdu::trim(const int p)
+{
+ int lp = p;
+
+ // verify that lp is legal
+ if ( lp < 0 || lp > vb_count_)
+ return 0;
+
+ while ( lp != 0) {
+ if ( vb_count_ > 0) {
+ delete vbs_[vb_count_ - 1];
+ vb_count_--;
+ }
+ lp--;
+ }
+ return 1;
+}
+
+
+
+// delete a Vb anywhere within the Pdu
+int Pdu::delete_vb( const int p)
+{
+ // position has to be in range
+ if (( p < 0) || ( p > (vb_count_ - 1)))
+ return 0;
+
+ // safe to remove it
+ delete vbs_[ p];
+
+ for ( int z=p;z < (vb_count_-1);z++) {
+ vbs_[z] = vbs_[z+1];
+ }
+ vb_count_--;
+
+ return 1;
+}
+
+void Pdu::delete_all_vbs()
+{
+ for ( int z = 0; z < vb_count_; z++)
+ delete vbs_[z];
+ vb_count_ = 0;
+}
+
+
+// set notify timestamp
+void Pdu::set_notify_timestamp( const TimeTicks & timestamp)
+{
+ notify_timestamp_ = timestamp;
+}
+
+
+// get notify timestamp
+void Pdu::get_notify_timestamp( TimeTicks & timestamp) const
+{
+ timestamp = notify_timestamp_;
+}
+
+// set the notify id
+void Pdu::set_notify_id( const Oid id)
+{
+ notify_id_ = id;
+}
+
+// get the notify id
+void Pdu::get_notify_id( Oid &id) const
+{
+ id = notify_id_;
+}
+
+// set the notify enterprise
+void Pdu::set_notify_enterprise( const Oid &enterprise)
+{
+ notify_enterprise_ = enterprise;
+}
+
+// get the notify enterprise
+void Pdu::get_notify_enterprise( Oid & enterprise) const
+{
+ enterprise = notify_enterprise_;
+}
+
+// ------ class VbIter -------------------
+VbIter::VbIter(Pdu& pdu): idx_(-1), pdu_(&pdu)
+{
+}
+
+// returns 1 if ok, else 0 if none left
+int VbIter::next(Vb& vb)
+{
+ if (idx_ == -1) {
+ idx_ = 0;
+ pdu_->get_vb(vb, idx_++);
+ return 1;
+ }
+ else
+ if (idx_ < pdu_->get_vb_count()) {
+ pdu_->get_vb(vb, idx_++);
+ return 1;
+ }
+ return 0; // non left
+}
diff --git a/ACE/ASNMP/asnmp/pdu.h b/ACE/ASNMP/asnmp/pdu.h
new file mode 100644
index 00000000000..a2d84388da0
--- /dev/null
+++ b/ACE/ASNMP/asnmp/pdu.h
@@ -0,0 +1,219 @@
+/* -*-C++-*- */
+#ifndef PDU_CLS_
+#define PDU_CLS_
+//=============================================================================
+/**
+ * @file pdu.h
+ *
+ * $Id$
+ *
+ * Pdu class definition. Encapsulation of an SMI Protocol
+ * Data Unit (PDU) aka Packet in C++.
+ *
+ *
+ * @author Peter E Mellquist original code Michael MacFaden mrm@cisco.com ACE port
+ * @author add iterator class for pdus
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+// TODO: this needs to be moved into the CLASS and modifyable at runtime
+// TODO: define an iterator object to traverse the vbs in a pdu
+
+#define MAX_VBS 25
+#include "asnmp/vb.h" // include Vb class definition
+
+/**
+ * @class Pdu
+ *
+ * @brief Protocol Data Unit (PDU) concrete class. An abstraction of the
+ * data packet used to by two SNMP sessions to communicate.
+ */
+class ASNMP_Export Pdu
+{
+public:
+ /// constructor no args
+ Pdu( void);
+
+ /// constructor with vbs and count
+ Pdu( Vb* pvbs, const int pvb_count);
+
+ /// constructor with another Pdu instance
+ Pdu( const Pdu &pdu);
+
+ /// destructor
+ ~Pdu();
+
+ /// assignment to another Pdu object overloaded
+ Pdu& operator=( const Pdu &pdu);
+
+ /// append a vb to the pdu
+ Pdu& operator+=( Vb &vb);
+
+ // TODO: add Pdu& operator-=(const Vb &vb);
+
+ /// extract all Vbs from Pdu
+ int get_vblist( Vb* pvbs, const int pvb_count);
+
+ /// deposit all Vbs to Pdu
+ int set_vblist( Vb* pvbs, const int pvb_count);
+
+ /// get a particular vb
+ /// where 0 is the first vb
+ int get_vb( Vb &vb, const int index = 0) const;
+
+ /// set a particular vb
+ /// where 0 is the first vb
+ int set_vb( Vb &vb, const int index);
+
+ /// return number of vbs
+ int get_vb_count() const;
+
+ /// return the error status
+ int get_error_status() const;
+
+ /// return the complete error info from this pdu
+ const char *agent_error_reason();
+
+ /// set the error status
+ friend ASNMP_Export void set_error_status( Pdu *pdu, const int status);
+
+ /// return the error index
+ int get_error_index() const;
+
+ /// set the error index
+ friend ASNMP_Export void set_error_index( Pdu *pdu, const int index);
+
+ /// clear error status
+ friend ASNMP_Export void clear_error_status( Pdu *pdu);
+
+ /// clear error index
+ friend ASNMP_Export void clear_error_index( Pdu *pdu);
+
+ /// return the request id
+ unsigned long get_request_id() const;
+
+ /// set the request id
+ friend void set_request_id( Pdu *pdu, const unsigned long rid);
+
+ /// get the pdu type
+ unsigned short get_type() const;
+
+ /// set the pdu type
+ void set_type( unsigned short type);
+
+ /// returns validity of Pdu instance
+ int valid() const;
+
+ /// trim off count vbs from the end of the vb list
+ int trim(const int count=1);
+
+ /// delete a Vb anywhere within the Pdu
+ int delete_vb( const int position);
+
+ /// delete_all vbs in pdu
+ void delete_all_vbs();
+
+ /// set notify timestamp
+ void set_notify_timestamp( const TimeTicks & timestamp);
+
+ /// get notify timestamp
+ void get_notify_timestamp( TimeTicks & timestamp) const;
+
+ /// set the notify id
+ void set_notify_id( const Oid id);
+
+ /// get the notify id
+ void get_notify_id( Oid &id) const;
+
+ /// set the notify enterprise
+ void set_notify_enterprise( const Oid &enterprise);
+
+ /// get the notify enterprise
+ void get_notify_enterprise( Oid & enterprise) const;
+
+ /// return fomatted version of this object
+ const char *to_string();
+
+
+ protected:
+ /// pointer to array of Vbs
+ Vb *vbs_[MAX_VBS];
+
+ /// count of Vbs
+ int vb_count_;
+
+ /// SMI error status
+ int error_status_;
+
+ /// SMI error index
+ int error_index_;
+
+ /// valid boolean status of object construction
+ /// SMI request id
+ int validity_;
+ unsigned long request_id_;
+
+ /// derived at run time based on request type
+ unsigned short pdu_type_;
+
+ /**
+ * a timestamp associated with an infor
+ * for notify Pdu objects only
+ * traps & notifies
+ */
+ TimeTicks notify_timestamp_;
+
+ /// an id
+ Oid notify_id_;
+
+ Oid notify_enterprise_;
+
+ private:
+ /// buffer for to_string()
+ char *output_;
+};
+
+
+/**
+ * @class VbIter
+ *
+ * @brief Utility class to iterate once through a PDU varbind list
+ */
+class ASNMP_Export VbIter
+{
+ public:
+ /// default constructor
+ VbIter(Pdu& pdu);
+
+ /// returns 1 if ok, else 0 if none left
+ int next(Vb& vb);
+
+ private:
+ /// disallow copy constructor use
+ VbIter(const VbIter&);
+
+ /// current object in list
+ int idx_;
+
+ /// ptr to pdu being interated over
+ Pdu *pdu_;
+};
+
+#endif //PDU_CLS_
+
diff --git a/ACE/ASNMP/asnmp/sagent.cpp b/ACE/ASNMP/asnmp/sagent.cpp
new file mode 100644
index 00000000000..8ee2fdb5b8d
--- /dev/null
+++ b/ACE/ASNMP/asnmp/sagent.cpp
@@ -0,0 +1,97 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// sagent.cpp
+//
+// = DESCRIPTION
+// SNMP agent class definition. The sagent class provides an object oriented
+// approach for creating SNMP Agents. The sagent class is an encapsulation
+// of SNMP sessions, gets, sets, etc.
+//
+// = AUTHOR
+// Michael R. MacFaden
+//
+// ============================================================================
+#include "ace/Reactor.h"
+#include "ace/SOCK_Dgram.h"
+
+#include "asnmp/oid.h" // snmp++ oid class
+#include "asnmp/vb.h" // snbmp++ vb class
+#include "asnmp/target.h" // snmp++ target class
+#include "asnmp/pdu.h" // snmp++ pdu class
+#include "asnmp/snmperrs.h" // error macros and strings
+#include "asnmp/address.h" // snmp++ address class defs
+#include "asnmp/snmp.h" // manager snmp interface
+#include "asnmp/sagent.h" // agent interface
+#include "asnmp/transaction.h" // convert from wire to API
+
+ACE_RCSID(asnmp, sagent, "$Id$")
+
+sagent::sagent(unsigned short port): Snmp(port)
+{
+ ACE_TRACE("sagent::sagent(short)");
+}
+
+sagent::~sagent()
+{
+ ACE_TRACE("sagent::~sagent");
+}
+
+int sagent::handle_input(ACE_HANDLE fd)
+{
+ ACE_TRACE("sagent::handle_input");
+
+ transaction tr(iv_snmp_session_); // this section needs a better design
+ tr.handle_input(fd);
+ char rcv_com_str[MAX_COMM_STR_LEN];
+ if (tr.result(pdu_, rcv_com_str) < 0)
+ return 0;
+ OctetStr community(rcv_com_str);
+ const ACE_INET_Addr &ta = tr.get_from_addr();
+ ACE_TCHAR buf_tmp[MAXHOSTNAMELEN + 1];
+ ta.addr_to_string (buf_tmp, MAXHOSTNAMELEN);
+ UdpAddress ra (ACE_TEXT_ALWAYS_CHAR (buf_tmp));
+ tgt_.set_address(ra);
+
+
+ // process msg here by calling subclass's implementation
+ switch (pdu_.get_type()){
+ case sNMP_PDU_GET:
+ tgt_.set_read_community(community);
+ this->handle_get(pdu_, tgt_);
+ break;
+
+ case sNMP_PDU_GETNEXT:
+ tgt_.set_read_community(community);
+ this->handle_get_next(pdu_, tgt_);
+ break;
+
+ case sNMP_PDU_SET:
+ tgt_.set_write_community(community);
+ this->handle_set(pdu_, tgt_);
+ break;
+
+ default:
+ ACE_ASSERT(0);
+ }
+ return 0;
+}
+
+ACE_HANDLE sagent::get_handle() const
+{
+ ACE_TRACE("sagent::get_handle");
+ return iv_snmp_session_.get_handle();
+}
+
+int sagent::respond(Pdu& pdu,UdpTarget& tgt)
+{
+ pdu.set_type(sNMP_PDU_RESPONSE);
+ transaction tr(pdu, tgt, iv_snmp_session_);
+ tr.send();
+ return 0;
+}
diff --git a/ACE/ASNMP/asnmp/sagent.h b/ACE/ASNMP/asnmp/sagent.h
new file mode 100644
index 00000000000..d220c3ed459
--- /dev/null
+++ b/ACE/ASNMP/asnmp/sagent.h
@@ -0,0 +1,82 @@
+/* -*-C++-*- */
+#ifndef SAGENT_CLS_
+#define SAGENT_CLS_
+//=============================================================================
+/**
+ * @file sagent.h
+ *
+ * $Id$
+ *
+ * SNMP agent class defintion. The sagent class provides an object oriented
+ * approach for creating SNMP Agents. The sagent class is an encapsulation of SNMP
+ * sessions, gets, sets, etc.
+ *
+ * @author Michael R. MacFaden
+ */
+//=============================================================================
+
+#include "ace/Reactor.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/SOCK_Dgram.h"
+
+#include "asnmp/oid.h" // snmp++ oid class
+#include "asnmp/vb.h" // snbmp++ vb class
+#include "asnmp/target.h" // snmp++ target class
+#include "asnmp/pdu.h" // snmp++ pdu class
+#include "asnmp/snmperrs.h" // error macros and strings
+#include "asnmp/address.h" // snmp++ address class defs
+#include "asnmp/snmp.h" // snmp interface
+
+// sagent - supports Version 1 operations in blocking mode
+
+#define DEF_AGENT_PORT (161)
+
+/**
+ * @class sagent
+ *
+ * @brief Concrete class sagent defines the session and interface to
+ * communicate with another SNMP Version 1 manager
+ */
+class ASNMP_Export sagent : public ACE_Event_Handler, private Snmp
+{
+ public:
+
+
+ // override the next three methods (callbacks) to implment your agent
+ //
+
+ /// retrieve data from a peer agent for a given list of oid values
+ virtual int handle_get( Pdu &pdu, UdpTarget &target) = 0;
+
+ /// retrieve data lexically adjacent to the oids specified in the pdu
+ /// from the peer agent
+ virtual int handle_get_next( Pdu &pdu, UdpTarget &target) = 0;
+
+ /// set data in the agent from the list of oids in the pdu
+ virtual int handle_set( Pdu &pdu, UdpTarget &target) = 0;
+
+ /// new pdu received from mgr (reactor calls this)
+ virtual int handle_input(ACE_HANDLE);
+
+ /// retrieve io descriptor (reactor uses this)
+ virtual ACE_HANDLE get_handle() const;
+
+ /// send a response pdu to the mgr
+ int respond(Pdu& pdu, UdpTarget& tgt);
+
+ protected:
+ sagent(unsigned short port = DEF_AGENT_PORT);
+ virtual ~sagent();
+
+private:
+ sagent(const sagent&);
+ Pdu pdu_; // current input pdu
+ UdpTarget tgt_; // addr & com strs
+};
+
+#endif //SAGENT_CLS_
+
diff --git a/ACE/ASNMP/asnmp/smi.h b/ACE/ASNMP/asnmp/smi.h
new file mode 100644
index 00000000000..3e505c64cb8
--- /dev/null
+++ b/ACE/ASNMP/asnmp/smi.h
@@ -0,0 +1,147 @@
+/* -*-C++-*- */
+#ifndef SMIDEF_
+#define SMIDEF_
+//=============================================================================
+/**
+ * @file smi.h
+ *
+ * $Id$
+ *
+ * Address class definition. Encapsulates various network
+ * addresses into easy to use, safe and portable classes.
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+
+=====================================================================*/
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+//----------[ ASN/BER Base Types ]-----------------------------------------
+// Basic Encoding Rules (BER)
+// (used in forming SYNTAXes and certain SNMP types/values)
+#define aSN_UNIVERSAL (0x00)
+#define aSN_APPLICATION (0x40)
+#define aSN_CONTEXT (0x80)
+#define aSN_PRIVATE (0xC0)
+#define aSN_PRIMITIVE (0x00)
+#define aSN_CONSTRUCTOR (0x20)
+
+//------[ SNMP ObjectSyntax Values ]---------------------------------------
+#define sNMP_SYNTAX_SEQUENCE (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x10)
+
+
+//-------------------------------------------------------------------------
+// These values are used in the "syntax" member
+// of the smiVALUE structure which follows.
+// Note: UInt32 is indistinguishable from Gauge32 per SNMPv2 Draft Standard
+// NsapAddr is obsoleted as unique SMI type per SNMPv2 Draft Standard
+#define sNMP_SYNTAX_INT (aSN_UNIVERSAL | aSN_PRIMITIVE | 0x02)
+#define sNMP_SYNTAX_BITS (aSN_UNIVERSAL | aSN_PRIMITIVE | 0x03)
+#define sNMP_SYNTAX_OCTETS (aSN_UNIVERSAL | aSN_PRIMITIVE | 0x04)
+#define sNMP_SYNTAX_NULL (aSN_UNIVERSAL | aSN_PRIMITIVE | 0x05)
+#define sNMP_SYNTAX_OID (aSN_UNIVERSAL | aSN_PRIMITIVE | 0x06)
+#define sNMP_SYNTAX_INT32 sNMP_SYNTAX_INT
+#define sNMP_SYNTAX_IPADDR (aSN_APPLICATION | aSN_PRIMITIVE | 0x00)
+#define sNMP_SYNTAX_CNTR32 (aSN_APPLICATION | aSN_PRIMITIVE | 0x01)
+#define sNMP_SYNTAX_GAUGE32 (aSN_APPLICATION | aSN_PRIMITIVE | 0x02)
+#define sNMP_SYNTAX_TIMETICKS (aSN_APPLICATION | aSN_PRIMITIVE | 0x03)
+#define sNMP_SYNTAX_OPAQUE (aSN_APPLICATION | aSN_PRIMITIVE | 0x04)
+#define sNMP_SYNTAX_CNTR64 (aSN_APPLICATION | aSN_PRIMITIVE | 0x06)
+#define sNMP_SYNTAX_UINT32 (aSN_APPLICATION | aSN_PRIMITIVE | 0x07)
+
+//-------------------------------------------------------------------------
+
+//---------------[ Exception conditions for SNMPv2 ]-----------------------
+// support SNMP v2
+#define sNMP_SYNTAX_NOSUCHOBJECT (aSN_CONTEXT | aSN_PRIMITIVE | 0x00)
+#define sNMP_SYNTAX_NOSUCHINSTANCE (aSN_CONTEXT | aSN_PRIMITIVE | 0x01)
+#define sNMP_SYNTAX_ENDOFMIBVIEW (aSN_CONTEXT | aSN_PRIMITIVE | 0x02)
+
+
+//--------------[ different types of PDU's ]-------------------------------
+#define sNMP_PDU_GET (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x0)
+#define sNMP_PDU_GETNEXT (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x1)
+#define sNMP_PDU_RESPONSE (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x2)
+#define sNMP_PDU_SET (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x3)
+#define sNMP_PDU_V1TRAP (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x4)
+#define sNMP_PDU_GETBULK (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x5)
+#define sNMP_PDU_INFORM (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x6)
+#define sNMP_PDU_TRAP (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x7)
+
+
+//------[ smi typedefs ]---------------------------------------------------
+// SNMP-related types from RFC1442 (SMI)
+
+typedef unsigned char SmiBYTE, *SmiLPBYTE;
+
+//-------------------------------------------------------------------------
+// SNMP-related types from RFC1442 (SMI)
+
+// int
+typedef long SmiINT, *SmiLPINT;
+
+// int 32
+typedef SmiINT SmiINT32, *SmiLPINT32;
+
+// unit32
+typedef unsigned long SmiUINT32, *SmiLPUINT32;
+
+// octet struct
+typedef struct {
+ SmiUINT32 len;
+ SmiLPBYTE ptr;} SmiOCTETS, *SmiLPOCTETS;
+
+// bits
+typedef SmiOCTETS SmiBITS, *SmiLPBITS;
+
+// SMI oid struct
+typedef struct {
+ SmiUINT32 len;
+ SmiLPUINT32 ptr;} SmiOID, *SmiLPOID;
+
+// ipaddr
+typedef SmiOCTETS SmiIPADDR, *SmiLPIPADDR;
+
+// 32bit counter
+typedef SmiUINT32 SmiCNTR32, *SmiLPCNTR32;
+
+// gauge
+typedef SmiUINT32 SmiGAUGE32, *SmiLPGAUGE32;
+
+// timeticks
+typedef SmiUINT32 SmiTIMETICKS, *SmiLPTIMETICKS;
+
+// opaque
+typedef SmiOCTETS SmiOPAQUE, *SmiLPOPAQUE;
+
+// nsapaddr
+typedef SmiOCTETS SmiNSAPADDR, *SmiLPNSAPADDR;
+
+// 64 bit counter
+typedef struct {
+ SmiUINT32 hipart;
+ SmiUINT32 lopart;
+} SmiCNTR64, *SmiLPCNTR64;
+
+#endif // SMIDEF_
+
+
diff --git a/ACE/ASNMP/asnmp/smival.h b/ACE/ASNMP/asnmp/smival.h
new file mode 100644
index 00000000000..e754206f506
--- /dev/null
+++ b/ACE/ASNMP/asnmp/smival.h
@@ -0,0 +1,102 @@
+/* -*-C++-*- */
+#ifndef SMIVALUE_
+#define SMIVALUE_
+//=============================================================================
+/**
+ * @file smival.h
+ *
+ * $Id$
+ *
+ * SMIValue class definition. Superclass for the various types
+ * of SNMP values (Address, Oid, Octet, etc.). Provides
+ * only a few functions, most info is in subclass.
+ *
+ *
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+//----[ includes ]-----------------------------------------------------
+#include "asnmp/smi.h"
+#include "asnmp/ASNMP_Export.h"
+#include "ace/os_include/os_stddef.h"
+
+//----[ macros ]-------------------------------------------------------
+
+//======================================================================
+// SMI value structure conforming with SMI RFC
+//
+typedef struct { /* smiVALUE portion of VarBind */
+ SmiUINT32 syntax; /* Insert SNMP_SYNTAX_<type> */
+ union {
+ SmiINT sNumber; /* SNMP_SYNTAX_INT
+ SNMP_SYNTAX_INT32 */
+ SmiUINT32 uNumber; /* SNMP_SYNTAX_UINT32
+ SNMP_SYNTAX_CNTR32
+ SNMP_SYNTAX_GAUGE32
+ SNMP_SYNTAX_TIMETICKS */
+ SmiCNTR64 hNumber; /* SNMP_SYNTAX_CNTR64 */
+ SmiOCTETS string; /* SNMP_SYNTAX_OCTETS
+ SNMP_SYNTAX_BITS
+ SNMP_SYNTAX_OPAQUE
+ SNMP_SYNTAX_IPADDR
+ SNMP_SYNTAX_NSAPADDR */
+ SmiOID oid; /* SNMP_SYNTAX_OID */
+ SmiBYTE empty; /* SNMP_SYNTAX_NULL
+ SNMP_SYNTAX_NOSUCHOBJECT
+ SNMP_SYNTAX_NOSUCHINSTANCE
+ SNMP_SYNTAX_ENDOFMIBVIEW */
+ } value;
+} SmiVALUE, *SmiLPVALUE;
+
+// An "abstract" (pure virtual) class that serves as the base class
+// for all specific SNMP syntax types.
+//
+class ASNMP_Export SnmpSyntax {
+
+public:
+ virtual const char * to_string() = 0;
+ // virtual function for getting a printable ASCII value for any SNMP Value
+
+ virtual SmiUINT32 get_syntax() = 0;
+ // return the current syntax
+
+ virtual SnmpSyntax * clone() const = 0;
+ // virtual clone operation for creating a new Value from an existing
+ // value. The caller MUST use the delete operation on the return
+ // value when done.
+
+ virtual ~SnmpSyntax() {};
+ // virtual destructor to ensure deletion of derived classes...
+
+ virtual SnmpSyntax& operator=(SnmpSyntax &/*val*/)
+ {
+ return *this;
+ }
+ // overloaded assignment operator
+ // This should be pure virtual, but WinNT compiler
+ // complains about unresolved reference at link time.
+
+ virtual int valid() const = 0;
+ // return validity of value object.
+
+protected:
+ SmiVALUE smival;
+};
+
+#endif // SMIVALUE_
diff --git a/ACE/ASNMP/asnmp/snmp.cpp b/ACE/ASNMP/asnmp/snmp.cpp
new file mode 100644
index 00000000000..cc2e1dd4179
--- /dev/null
+++ b/ACE/ASNMP/asnmp/snmp.cpp
@@ -0,0 +1,286 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// snmp.cpp
+//
+// = DESCRIPTION
+// The basic SNMPv1 API - blocking version using UDP/IPv4 transport
+// and addressing.
+//
+// = AUTHOR
+// Peter E Mellquist class design/orig code
+// Michael R MacFaden mrm@cisco.com / rework API, use ACE facilities
+// ============================================================================
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+
+#define INCLUDE_SNMP_ERR_STRINGS_
+
+//----[ snmp++ includes ]----------------------------------------------
+#include "asnmp/snmp.h" // class def for this module
+#include "asnmp/oid.h" // class def for oids
+#include "asnmp/enttraps.h" // class def for well known trap oids
+#include "asnmp/vb.h" // class def for vbs
+#include "asnmp/address.h" // class def for addresses
+#include "asnmp/wpdu.h" // adapter to cmu_library / wire protocol
+#include "asnmp/transaction.h" // synchronous transaction processor
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_time.h"
+
+ACE_RCSID(asnmp, snmp, "$Id$")
+
+const coldStartOid coldStart;
+const warmStartOid warmStart;
+const linkDownOid linkDown;
+const linkUpOid linkUp;
+const authenticationFailureOid authenticationFailure;
+const egpNeighborLossOid egpNeighborLoss;
+const snmpTrapEnterpriseOid snmpTrapEnterprise;
+
+char Snmp::host_name_[MAXHOSTNAMELEN] = "";
+
+Snmp::Snmp(unsigned short port): result_(0), construct_status_(SNMP_CLASS_ERROR), last_transaction_status_(0)
+{
+ ACE_TRACE("Snmp::Snmp");
+
+ ACE_INET_Addr addr(port); // any port,address is ok
+ if (iv_snmp_session_.open(addr) < 0) {
+ last_transaction_status_ = errno; // open udp/ipv4 socket
+ ACE_DEBUG((LM_DEBUG, "Snmp::snmp::open port %d failed", port));
+ return;
+ }
+
+ // initial request id randomly generated then monotonically incremented
+ req_id_ = (unsigned) ACE_OS::time(0);
+
+ construct_status_ = SNMP_CLASS_SUCCESS;
+ return;
+}
+
+Snmp::~Snmp()
+{
+ ACE_TRACE("Snmp::~Snmp");
+ iv_snmp_session_.close();
+}
+
+int Snmp::valid() const
+{
+ return construct_status_;
+}
+
+// given error code, return string definition
+// class version
+// static
+const char * Snmp::error_string(int last_transaction_status_)
+{
+ ACE_TRACE("Snmp::error_string");
+
+ return ((last_transaction_status_ < 0) ?
+ ((last_transaction_status_ < MAX_NEG_ERROR)?
+ nErrs[ abs(MAX_NEG_ERROR) + 1] : nErrs[abs(last_transaction_status_)]):
+ ((last_transaction_status_ > MAX_POS_ERROR)?
+ pErrs[MAX_POS_ERROR+1] : pErrs[last_transaction_status_]));
+}
+
+// instance version
+const char * Snmp::error_string()
+{
+ return Snmp::error_string(last_transaction_status_);
+}
+
+void Snmp::check_default_port(UdpTarget& target, unsigned short port)
+{
+ UdpAddress tmp;
+ target.get_address(tmp);
+ if (tmp.get_port() == 0) {
+ tmp.set_port(port);
+ target.set_address(tmp);
+ }
+}
+
+int Snmp::run_transaction(Pdu& pdu, UdpTarget& target)
+{
+ int rc, done = 0;
+
+ // 1. set unique id to match this packet on return
+ size_t hold_req_id = req_id_++;
+ set_request_id(&pdu, hold_req_id);
+
+ // 2. write request to agent
+ transaction trans(pdu, target, iv_snmp_session_);
+
+ // this call blocks while it attempts to retrieve agent response
+ while (!done) {
+ if ((rc = trans.run()) < 0) {
+ last_transaction_status_ = rc;
+ return rc;
+ }
+ else {
+ trans.result(pdu);
+ // verify this is the pdu we are after
+ if (pdu.get_request_id() == hold_req_id)
+ done = 1 ;
+ }
+ }
+ return 0;
+}
+
+int Snmp::run_transaction(Pdu& pdu, UdpTarget& target, Snmp_Result * cb)
+{
+ if (!cb)
+ return run_transaction(pdu, target);
+
+ // 1. set unique id to match this packet on return
+ hold_req_id_ = req_id_++;
+ set_request_id(&pdu, hold_req_id_);
+ pdu_ = &pdu;
+ result_ = cb;
+
+ // 2. write request to agent
+ transaction * trans = new transaction(pdu, target, iv_snmp_session_);
+ return trans->run(this);
+}
+
+void Snmp::result(transaction *t, int rc)
+{
+ t->result(*pdu_);
+ // verify this is the pdu we are after
+ if (pdu_->get_request_id() == hold_req_id_)
+ {
+ last_transaction_status_ = rc;
+ delete t;
+ result_->result(this, rc);
+ }
+ else
+ {
+ rc = t->run(this);
+ if (rc < 0)
+ {
+ delete t;
+ result_->result(this, rc);
+ }
+ }
+}
+
+int Snmp::validate_args(const Pdu& pdu, const UdpTarget& target) const
+{
+ // 0. check object status
+ if (construct_status_ != SNMP_CLASS_SUCCESS)
+ return construct_status_;
+
+ // 1. check args passed
+ if ( !pdu.valid() || !target.valid() )
+ return SNMP_INVALID_ARGS;
+ return 0;
+}
+
+// SYNC API: write request to wire then wait for reply or timeout
+int Snmp::get( Pdu &pdu, UdpTarget &target, Snmp_Result * cb)
+{
+ ACE_TRACE("Snmp::get");
+ int rc;
+ if ((rc = validate_args(pdu, target)) != 0)
+ return rc;
+
+ pdu.set_type( sNMP_PDU_GET);
+ check_default_port(target);
+ return run_transaction(pdu, target, cb);
+}
+
+int Snmp::get_next( Pdu &pdu, UdpTarget &target, Snmp_Result * cb)
+{
+ ACE_TRACE("Snmp::get_next");
+ int rc;
+ if ((rc = validate_args(pdu, target)) != 0)
+ return rc;
+
+ pdu.set_type( sNMP_PDU_GETNEXT);
+ check_default_port(target);
+ return run_transaction(pdu, target, cb);
+}
+
+int Snmp::set( Pdu &pdu, UdpTarget &target, Snmp_Result * cb)
+{
+ ACE_TRACE("Snmp::set");
+ int rc;
+ if ((rc = validate_args(pdu, target)) != 0)
+ return rc;
+
+ pdu.set_type( sNMP_PDU_SET);
+ check_default_port(target);
+ return run_transaction(pdu, target, cb);
+}
+
+// one way, best of luck, non-confirmed alert
+int Snmp::trap( Pdu &pdu, UdpTarget &target)
+{
+ ACE_TRACE("Snmp::trap");
+ int rc;
+ if ((rc = validate_args(pdu, target)) != 0)
+ return rc;
+
+ pdu.set_type( sNMP_PDU_V1TRAP);
+ check_default_port(target, DEF_TRAP_PORT);
+
+ // 2. write request to agent
+ transaction trans(pdu, target, iv_snmp_session_);
+ if (trans.send() > 0) // expect number of bytes sent on
+ return 0;
+
+ last_transaction_status_ = SNMP_CLASS_INTERNAL_ERROR;
+ return -1;
+}
+
+// Allow host name to be overriden. Supplying a null pointer or zero
+// length string removes the override.
+void Snmp::override_host_name(const char* name)
+{
+ if (name)
+ {
+ ACE_OS::strncpy(host_name_, name, MAXHOSTNAMELEN);
+ host_name_[MAXHOSTNAMELEN-1] = 0;
+ }
+ else {
+ host_name_[0] = 0;
+ }
+}
+
+// Returns the current host name in the supplied string.
+void Snmp::get_host_name(char* name, int len)
+{
+ if (name)
+ {
+ if (ACE_OS::strlen(host_name_) > 0)
+ {
+ ACE_OS::strncpy(name, host_name_, len);
+ name[len-1] = 0;
+ }
+ else
+ {
+ if (ACE_OS::hostname(name, len-1) == -1)
+ name[0] = 0;
+ }
+ }
+}
+
+Snmp_Result::~Snmp_Result() {}
diff --git a/ACE/ASNMP/asnmp/snmp.h b/ACE/ASNMP/asnmp/snmp.h
new file mode 100644
index 00000000000..5bae232baa0
--- /dev/null
+++ b/ACE/ASNMP/asnmp/snmp.h
@@ -0,0 +1,137 @@
+/* -*-C++-*- */
+#ifndef SNMP_CLS_
+#define SNMP_CLS_
+//=============================================================================
+/**
+ * @file snmp.h
+ *
+ * $Id$
+ *
+ * SNMP class defintion. The Snmp class provides an object oriented
+ * approach to SNMP. The SNMP class is an encapsulation of SNMP
+ * sessions, gets, sets, etc. The class manages all SNMP
+ * resources and provides complete retry and timeout capability.
+ *
+ *
+ * @author Peter E Mellquist design
+ * @author first implementation Michael R. MacFaden port to ACE / use Reactor pattern
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "ace/Reactor.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/SOCK_Dgram.h"
+
+#include "asnmp/oid.h" // snmp++ oid class
+#include "asnmp/vb.h" // snbmp++ vb class
+#include "asnmp/target.h" // snmp++ target class
+#include "asnmp/pdu.h" // snmp++ pdu class
+#include "asnmp/snmperrs.h" // error macros and strings
+#include "asnmp/address.h" // snmp++ address class defs
+#include "asnmp/transaction_result.h"
+#include "asnmp/ASNMP_Export.h"
+
+class Snmp;
+class ASNMP_Export Snmp_Result
+{
+ public:
+ virtual ~Snmp_Result();
+ virtual void result(Snmp *snmp, int result) = 0;
+};
+
+// Snmp session class - supports Version 1 operations in blocking mode
+/**
+ * @class Snmp
+ *
+ * @brief Concrete class Snmp defined the session and interface to
+ * communicate with another SNMP Version 1 agent
+ */
+class ASNMP_Export Snmp : public transaction_result
+{
+ Snmp_Result * result_;
+ Pdu * pdu_;
+ unsigned hold_req_id_;
+public:
+ Snmp(unsigned short port = INADDR_ANY);
+ virtual ~Snmp();
+
+ /// retrieve data from a peer agent for a given list of oid values
+ /// default port 161
+ int get( Pdu &pdu, UdpTarget &target, Snmp_Result * cb = 0);
+
+ /**
+ * retrieve data lexically adjacent to the oids specified in the pdu
+ * from the peer agent
+ * default port 161
+ */
+ int get_next( Pdu &pdu, UdpTarget &target, Snmp_Result * cb = 0);
+
+ /// set data in the agent from the list of oids in the pdu
+ /// default port 161
+ int set( Pdu &pdu, UdpTarget &target, Snmp_Result * cb = 0);
+
+ /// send an SNMPv1 trap (unreliable) to a remote system (def port 162)
+ int trap( Pdu &pdu, UdpTarget &target);
+
+ /// status of object after construction
+ int valid() const;
+
+ /// given error code, return string reason
+ static const char * error_string(int code);
+
+ /// retrieve a reason string if any of the above commands fail
+ const char * error_string();
+
+ /// for async transaction results
+ void result(transaction * t, int rc);
+
+ /// allow the host name to be overriden
+ static void override_host_name(const char* name);
+
+ /// returns the overriden host name
+ static void get_host_name(char* name, int len);
+
+protected:
+ void check_default_port(UdpTarget& target,unsigned short port=DEF_AGENT_PORT);
+ int run_transaction(Pdu& pdu, UdpTarget& target);
+ int run_transaction(Pdu& pdu, UdpTarget& target, Snmp_Result * cb);
+ int validate_args(const Pdu& pdu, const UdpTarget& target) const;
+
+ Snmp(const Snmp&);
+
+ /// io object
+ ACE_SOCK_Dgram iv_snmp_session_;
+
+ /// status of construction
+ int construct_status_;
+
+ /// result code from last transaction
+ int last_transaction_status_;
+
+ /// transaction request id
+ unsigned req_id_;
+
+ static char host_name_[MAXHOSTNAMELEN];
+};
+
+#endif //SNMP_CLS_
diff --git a/ACE/ASNMP/asnmp/snmperrs.h b/ACE/ASNMP/asnmp/snmperrs.h
new file mode 100644
index 00000000000..7aafdc0619a
--- /dev/null
+++ b/ACE/ASNMP/asnmp/snmperrs.h
@@ -0,0 +1,210 @@
+/* -*-C++-*- */
+#ifndef SNMPERRS_H_
+#define SNMPERRS_H_
+//=============================================================================
+/**
+ * @file snmperrs.h
+ *
+ * $Id$
+ *
+ * Definition of error macros and error strings
+ *
+ *
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+============================================================================*/
+
+
+//-------[ Positive ASNMP Error Return Codes ]------------------------------
+// These values are error status values from RFC 1905
+//
+// The values can be returned via Pdu::get_error_status()
+//
+#define SNMP_ERROR_SUCCESS 0 // Success Status
+#define SNMP_ERROR_TOO_BIG 1 // Pdu encoding too big
+#define SNMP_ERROR_NO_SUCH_NAME 2 // No such VB name, see error index
+#define SNMP_ERROR_BAD_VALUE 3 // Bad Vb
+#define SNMP_ERROR_READ_ONLY 4 // VB is read only, see error index
+#define SNMP_ERROR_GENERAL_VB_ERR 5 // General VB error, see error index
+#define SNMP_ERROR_NO_ACCESS 6 // No access to MIBs data
+#define SNMP_ERROR_WRONG_TYPE 7 // Requested type was incorrect
+#define SNMP_ERROR_WRONG_LENGTH 8 // Request Pdu has inccorect length
+#define SNMP_ERROR_WRONG_ENCODING 9 // Request Pdu has wrong encoding
+#define SNMP_ERROR_WRONG_VALUE 10 // Request Pdu has wrong value
+#define SNMP_ERROR_NO_CREATION 11 // Unable to create object specified
+#define SNMP_ERROR_INCONSIST_VAL 12 // Inconsistent value in request
+#define SNMP_ERROR_RESOURCE_UNAVAIL 13 // Resources unavailable
+#define SNMP_ERROR_COMITFAIL 14 // Unable to comit
+#define SNMP_ERROR_UNDO_FAIL 15 // Unable to undo
+#define SNMP_ERROR_AUTH_ERR 16 // Authentication failure
+#define SNMP_ERROR_NOT_WRITEABLE 17 // Mib Object not writeable
+#define SNMP_ERROR_INCONSIS_NAME 18 // Inconsistent naming used
+
+
+//-------[ Negative ASNMP Result/Error Return Codes ]-------------------
+
+// General
+#define SNMP_CLASS_SUCCESS 0 // success
+#define SNMP_CLASS_ERROR -1 // general error
+#define SNMP_CLASS_RESOURCE_UNAVAIL -2 // e.g., malloc failed
+#define SNMP_CLASS_INTERNAL_ERROR -3 // unexpected / internal error
+#define SNMP_CLASS_UNSUPPORTED -4 // unsupported function
+
+// Callback reasons:
+#define SNMP_CLASS_TIMEOUT -5 // outstanding request timed out
+#define SNMP_CLASS_ASYNC_RESPONSE -6 // received response for outstd request
+#define SNMP_CLASS_NOTIFICATION -7 // received notification (trap/inform)
+#define SNMP_CLASS_SESSION_DESTROYED -8 // snmp::destroyed with oustanding reqs pending
+
+// Snmp Class:
+#define SNMP_CLASS_INVALID -10 // snmp::mf called on invalid instance
+#define SNMP_CLASS_INVALID_PDU -11 // invalid pdu passed to mf
+#define SNMP_CLASS_INVALID_TARGET -12 // invalid target passed to mf
+#define SNMP_CLASS_INVALID_CALLBACK -13 // invalid callback to mf
+#define SNMP_CLASS_INVALID_REQID -14 // invalid request id to cancel
+#define SNMP_CLASS_INVALID_NOTIFYID -15 // missing trap/inform oid
+#define SNMP_CLASS_INVALID_OPERATION -16 // snmp operation not allowed for specified target
+#define SNMP_CLASS_INVALID_OID -17 // invalid oid passed to mf
+#define SNMP_CLASS_INVALID_ADDRESS -18 // invalid address passed to mf
+#define SNMP_CLASS_ERR_STATUS_SET -19 // agent returned response pdu with error_status set
+
+// Transport Errors:
+#define SNMP_CLASS_TL_UNSUPPORTED -20 // transport unsupported
+#define SNMP_CLASS_TL_IN_USE -21 // transport in use
+#define SNMP_CLASS_TL_FAILED -22 // transport operation failed
+
+// extras
+#define SNMP_CLASS_SHUTDOWN -23 // used for back door shutdown
+#define SNMP_INVALID_ARGS -24 // invalid args passed
+
+#ifdef INCLUDE_SNMP_ERR_STRINGS_
+
+// ASCII strings returned through Snmp::error() function. NOTE: altering
+// the strings in this header file will not affect the return values of
+// Snmp::error(), unless you rebuild the ASNMP library from source.
+
+#define MAX_POS_ERROR SNMP_ERROR_INCONSIS_NAME
+#define MAX_NEG_ERROR SNMP_CLASS_SHUTDOWN
+
+static const char * pErrs[] = {
+ "Success", // 0
+ "SNMP: Response PDU Too Big", // 1
+ "SNMP: Variable does not exist", // 2
+ "SNMP: Cannot modify variable: Bad Value", // 3
+ "SNMP: Cannot modify object, Read Only", // 4
+ "SNMP: Cannot perform operation, General Error", // 5
+ "SNMP: Cannot access variable, No Access", // 6
+ "SNMP: Cannot create/modify variable, Wrong Type", // 7
+ "SNMP: Cannot create/set variable, Wrong Length", // 8
+ "SNMP: Cannot create/set variable, Wrong Encoding", // 9
+ "SNMP: Cannot create/set variable, Wrong Value", // 10
+ "SNMP: Cannot create variable, Creation Not Allowed", // 11
+ "SNMP: Cannot create/set variable, Inconsistent Value", // 12
+ "SNMP: Cannot create/set variable, Resource Unavailable", // 13
+ "SNMP: Cannot create/set variable, Commit Failed", // 14
+ "SNMP: Cannot create/set variable, Undo Failed", // 15
+ "SNMP: Cannot perform operation, Authorization Error", // 16
+ "SNMP: Cannot create/set variable, Not Writable", // 17
+ "SNMP: Cannot create variable, Inconsistent Name", // 18
+};
+
+
+static const char * nErrs[] = {
+ // General:
+ // 0 SNMP_CLASS_SUCCESS
+ "ASNMP: Success",
+
+ // 1 SNMP_CLASS_ERROR
+ "ASNMP: Operation failed",
+
+ // 2 SNMP_CLASS_RESOURCE_UNAVAIL
+ "ASNMP: Resource unavailable",
+
+ // 3 SNMP_CLASS_INTERNAL_ERROR
+ "ASNMP: Internal error",
+
+ // 4 SNMP_CLASS_UNSUPPORTED
+ "ASNMP: Unsupported function",
+
+ // Callback reasons:
+ // 5 SNMP_CLASS_TIMEOUT
+ "ASNMP: SNMP request timed out",
+
+ // 6 SNMP_CLASS_ASYNC_RESPONSE
+ "ASNMP: Received SNMP Response",
+
+ // 7 SNMP_CLASS_NOTIFICATION
+ "ASNMP: Received SNMP Notification (trap or inform)",
+
+ // 8 SNMP_CLASS_SESSION_DESTROYED
+ "ASNMP: Closing session with outstanding requests",
+
+ // 9 reserved for future
+ "Unknown error code",
+
+ // Snmp Class errors:
+ // 10 SNMP_CLASS_INVALID
+ "ASNMP: Class not valid",
+
+ // 11 SNMP_CLASS_INVALID_PDU
+ "ASNMP: Invalid Pdu",
+
+ // 12 SNMP_CLASS_INVALID_TARGET
+ "ASNMP: Invalid Target",
+
+ // 13 SNMP_CLASS_INVALID_CALLBACK
+ "ASNMP: Invalid (null) Callback Function",
+
+ // 14 SNMP_CLASS_INVALID_REQID
+ "ASNMP: Invalid Request Id",
+
+ // 15 SNMP_CLASS_INVALID_NOTIFYID
+ "ASNMP: Invalid Notification Id",
+
+ // 16 SNMP_CLASS_INVALID_OPERATION
+ "ASNMP: SNMP Operation not supported on specified Target",
+
+ // 17 SNMP_CLASS_INVALID_OID
+ "ASNMP: Invalid Object Identifier",
+
+ // 18 SNMP_CLASS_INVALID_ADDRESS
+ "ASNMP: Invalid Address",
+
+ // 19 SNMP_CLASS_ERR_STATUS_SET
+ "ASNMP: Agent indicates error in SNMP request",
+
+ // Transport Errors:
+ // 20 SNMP_CLASS_TL_UNSUPPORTED
+ "ASNMP: Transport is not supported",
+
+ // 21 SNMP_CLASS_TL_IN_USE
+ "ASNMP: Transport is in use",
+
+ // 22 SNMP_CLASS_TL_FAILED
+ "ASNMP: Transport operation failed",
+
+ // 23 SNMP_CLASS_SHUTDOWN
+ "ASNMP: Blocked Mode Shutdown",
+
+ // unknown error code
+ "Unknown error code",
+};
+
+#endif //INCLUDE_SNMP_ERR_STRINGS_
+
+#endif //SNMPERRS_H_
diff --git a/ACE/ASNMP/asnmp/target.cpp b/ACE/ASNMP/asnmp/target.cpp
new file mode 100644
index 00000000000..7c93a9275f9
--- /dev/null
+++ b/ACE/ASNMP/asnmp/target.cpp
@@ -0,0 +1,321 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// target.cpp
+//
+// = DESCRIPTION
+// Target class defines target SNMP agents.
+//
+// = AUTHOR
+// Peter E Mellquist
+// Michael R MacFaden mrm@cisco.com - rework & ACE port
+// ============================================================================
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+ =====================================================================*/
+
+#include "asnmp/target.h"
+
+ACE_RCSID(asnmp, target, "$Id$")
+
+//----------------------------------------------------------------------
+//--------[ Class default values ]----------------------
+//----------------------------------------------------------------------
+u_long SnmpTarget::default_timeout_ = DEF_TIMEOUT;
+int SnmpTarget::default_retries_ = DEF_RETRIES;
+u_long SnmpTarget::default_max_pdu_size_ = DEF_MAX_SNMP_PACKET;
+snmp_version SnmpTarget::default_version_ = version1;
+
+OctetStr UdpTarget::default_rd_community_(READ_COMM_STR);
+OctetStr UdpTarget::default_wr_community_(WRITE_COMM_STR);
+
+//----------------------------------------------------------------------
+//--------[ Abstract SnmpTarget Member Functions ]----------------------
+//----------------------------------------------------------------------
+SnmpTarget::SnmpTarget():
+ validity_(0), timeout_(default_timeout_), retries_(default_retries_),
+ max_pdu_size_(default_max_pdu_size_), version_(default_version_)
+{
+}
+
+// return validity of target
+int SnmpTarget::valid() const
+{
+ return validity_;
+}
+
+// allow destruction of derived classes
+SnmpTarget::~SnmpTarget()
+{
+}
+
+// set the timeout
+void SnmpTarget::set_timeout( const u_long t)
+{
+ timeout_ = t;
+}
+
+// change the default timeout
+void SnmpTarget::set_default_timeout( const u_long t)
+{
+ default_timeout_ = t;
+}
+
+// set the retry value
+void SnmpTarget::set_retry( const int r)
+{
+ retries_ = r;
+}
+
+// change the default retries
+void SnmpTarget::set_default_retry( const int r)
+{
+ default_retries_ = r;
+}
+
+void SnmpTarget:: set_max_pdu_size(const u_long max_pdu_sz)
+{
+ max_pdu_size_ = max_pdu_sz;
+}
+
+
+void SnmpTarget::set_default_max_pdu_size(const u_long max_pdu_sz)
+{
+ default_max_pdu_size_ = max_pdu_sz;
+}
+
+void SnmpTarget::set_version( const snmp_version v)
+{
+ version_ = v;
+}
+
+void SnmpTarget::set_default_version( const snmp_version v)
+{
+ default_version_ = v;
+}
+
+snmp_version SnmpTarget::get_version() const
+{
+ return version_;
+}
+
+snmp_version SnmpTarget::get_default_version() const
+{
+ return default_version_;
+}
+
+u_long SnmpTarget::get_max_pdu_size() const
+{
+ return max_pdu_size_;
+}
+
+// get the retry value
+int SnmpTarget::get_retry() const
+{
+ return retries_;
+}
+
+// get the retry value
+int SnmpTarget::get_default_retry() const
+{
+ return default_retries_;
+}
+
+// get the timeout
+u_long SnmpTarget::get_timeout() const
+{
+ return timeout_;
+}
+
+SnmpTarget& SnmpTarget::operator=(const SnmpTarget& lhs)
+{
+ if (this == &lhs)
+ return *this;
+
+ validity_ = lhs.validity_;
+ timeout_ = lhs.timeout_;
+ retries_ = lhs.retries_;
+ max_pdu_size_ =lhs.max_pdu_size_;
+ version_ = lhs.version_;
+ return *this;
+}
+
+bool operator==(const SnmpTarget& lhs, const SnmpTarget& rhs)
+{
+ if (lhs.timeout_ != rhs.timeout_)
+ return false;
+
+ if (lhs.retries_ != rhs.retries_)
+ return false;
+
+ if (lhs.max_pdu_size_ != rhs.max_pdu_size_)
+ return false;
+
+ if (lhs.version_ != rhs.version_)
+ return false;
+
+ return true;
+}
+
+
+//----------------------------------------------------------------------
+//--------[ IpTarget Member Functions ]----------------------------------
+//----------------------------------------------------------------------
+
+
+//---------[ UdpTarget::UdpTarget( void) ]----------------------------------
+
+UdpTarget::UdpTarget()
+{
+ validity_ = 0;
+ read_community_ = default_rd_community_; // assign by init fails
+ write_community_ = default_wr_community_;
+}
+
+UdpTarget::UdpTarget(const UdpAddress& udp) : udp_address_(udp)
+{
+ if (udp_address_.valid())
+ validity_ = 1;
+ read_community_ = default_rd_community_;
+ write_community_ = default_wr_community_;
+}
+
+// - copy constructor can be synthesised by compiler
+
+//-----------[ UdpTarget::~UdpTarget() ]--------------------------------
+UdpTarget::~UdpTarget()
+{
+}
+
+//-----------[ UdpTarget::clone() ]--------------------------------
+SnmpTarget * UdpTarget::clone() const
+{
+ return (SnmpTarget *) new UdpTarget(*this);
+}
+
+
+void UdpTarget::set_default_read_community(const OctetStr& rd_community)
+{
+ default_rd_community_ = rd_community;
+}
+
+void UdpTarget::set_default_write_community(const OctetStr& wr_community)
+{
+ default_wr_community_ = wr_community;
+}
+
+
+// get the read community name as an u_char and len
+void UdpTarget::get_read_community( OctetStr& read_community_oct) const
+{
+ read_community_oct = read_community_;
+}
+
+//---------[ UdpTarget::set_getcommunity ]---------------------------------
+// set the read community name
+void UdpTarget::set_read_community( const OctetStr& new_read_community)
+{
+ read_community_ = new_read_community;
+}
+
+//---------[ UdpTarget::get_writecommunity ]----------------------------
+// get the write community
+void UdpTarget::get_write_community( OctetStr &write_community_oct) const
+{
+ write_community_oct = write_community_;
+}
+
+//-----------[ UdpTarget::set_writecommunity ]---------------------------
+// set the write community
+void UdpTarget::set_write_community( const OctetStr& write_community_oct)
+{
+ write_community_ = write_community_oct;
+}
+
+//------------[ Address& UdpTarget::get_address() ]---------------------
+// get the address
+void UdpTarget::get_address( UdpAddress &address) const
+{
+ address = udp_address_;
+ return;
+}
+
+//-------------[ UdpTarget::set_address ]--------------------------------
+// set the address
+int UdpTarget::set_address( UdpAddress &udp_address)
+{
+ udp_address_ = udp_address;
+ if ( udp_address_.valid())
+ validity_ = 1;
+ else
+ validity_ = 0;
+
+ return validity_;
+}
+
+// overloaded assignment
+UdpTarget& UdpTarget::operator=( const UdpTarget& lhs)
+{
+ if (this == &lhs)
+ return *this;
+
+ // assign base part
+ *((SnmpTarget *) this) = *((SnmpTarget *)&lhs);
+
+ udp_address_ = lhs.udp_address_;
+ read_community_ = lhs.read_community_;
+ write_community_ = lhs.write_community_;
+ validity_ = lhs.validity_;
+
+ return *this;
+}
+
+const char *UdpTarget::to_string()
+{
+ sprintf(output_buffer_,"UdpTarget: [ valid: %d addr: %s rd: %s wr: %s \
+ver: %d, timeout: %d, retries: %d max_pdu_size: %d]",
+ valid(), udp_address_.to_string(), read_community_.to_string(),
+ write_community_.to_string(), version_, (int) timeout_,
+ retries_, max_pdu_size_);
+ return output_buffer_;
+}
+
+//=============[ int operator == UdpTarget, UdpTarget ]===============
+// equivlence operator overloaded
+bool operator==( const UdpTarget &lhs,const UdpTarget &rhs)
+{
+ // need to compare all the members of a UdpTarget
+ if ( lhs.read_community_ != rhs.read_community_)
+ return false; // !=
+
+ if ( lhs.write_community_ != rhs.write_community_)
+ return false; // !=
+
+ if ( lhs.udp_address_ != rhs.udp_address_)
+ return false;
+
+ if ( lhs.timeout_ != rhs.timeout_)
+ return false;
+
+ if ( lhs.retries_ != rhs.retries_)
+ return false;
+
+ return true; // they are equal
+}
diff --git a/ACE/ASNMP/asnmp/target.h b/ACE/ASNMP/asnmp/target.h
new file mode 100644
index 00000000000..084088e5f4f
--- /dev/null
+++ b/ACE/ASNMP/asnmp/target.h
@@ -0,0 +1,260 @@
+
+
+#ifndef TARGET_
+#define TARGET_
+//=============================================================================
+/**
+ * @file target.h
+ *
+ * $Id$
+ *
+ * @brief
+ *
+ * @author Peter E Mellquist Michael R. MacFaden (ported to ACE)
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS" without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+//----[ includes ]------------------------------------------------
+#include "ace/INET_Addr.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "asnmp/address.h"
+#include "asnmp/oid.h"
+#include "asnmp/octet.h"
+
+//----[ enumerated types for SNMP versions ]-------------------------
+enum snmp_version {
+ version1, // 0
+ version2c, // 1 (Cisco IOS does not have IOS v2c agent available yet)
+ version3 // 2 (IETF working on this version)
+};
+
+// targets contain the following default properties
+enum ASNMP_Defs {
+ DEF_TIMEOUT = 1, // unit: seconds
+ DEF_RETRIES = 1, // no retry default
+ DEF_MAX_SNMP_PACKET = 1430, // maximum pdu len on the wire (eth mtu-ip hdr)
+ // split bigger pdus (not implemented yet)
+ DEF_AGENT_PORT = 161, // port # for SNMP agent
+ DEF_TRAP_PORT = 162, // port # for SNMP trap receiver
+ DEF_VERSION = version1, // default SNMP version
+ MAX_COMM_STR_LEN = 255, // max value this impl will accept from client
+ MAX_TARGET_STRING_REP = 2048 // max value this impl will accept from client
+};
+
+#define READ_COMM_STR "public"
+#define WRITE_COMM_STR "private"
+
+// Abstract class used to provide a virtual interface into Targets
+//
+/**
+ * @class SnmpTarget
+ *
+ * @brief Abstract Base class SnmpTarget is used to Collect all transmission
+ * details to communicate with an SNMP
+ */
+class ASNMP_Export SnmpTarget
+{
+ public:
+
+ /// allow destruction of derived classes
+ virtual ~SnmpTarget();
+
+ /// return validity of target
+ int valid() const;
+
+ /// set the retry value
+ void set_retry( const int r);
+
+ /// set the object's timeout (in seconds)
+ void set_timeout( const unsigned long t);
+
+ /// set the instance version
+ void set_version( const snmp_version v);
+
+ /// all classes constructed will have this write community string
+ void set_max_pdu_size(const unsigned long max_pdu_sz);
+
+ /// change the "class" default default timeout (in seconds)
+ void set_default_timeout( const unsigned long t);
+
+ /// change the default send retries
+ void set_default_retry( const int r);
+
+ /// all classes constructed will have this write community string
+ void set_default_max_pdu_size(const unsigned long max_pdu_sz);
+
+ /// change class default
+ void set_default_version( const snmp_version v);
+
+ // *** get methods ***
+
+ /// get the retry value
+ int get_default_retry() const;
+
+ /// get the timeout (seconds)
+ unsigned long get_timeout() const;
+
+ /// get instance max buffer size
+ unsigned long get_max_pdu_size() const;
+
+ /// all classes constructed will have this write community string
+ void get_default_max_pdu_size(const unsigned long max_pdu_sz);
+
+ /// get the version
+ snmp_version get_version() const;
+
+ snmp_version get_default_version() const;
+
+ /// return send retry number for this instancd
+ int get_retry() const;
+
+ /**
+ * virtual clone operation for creating a new SnmpTarget from an existing
+ * SnmpTarget. The caller MUST use the delete operation on the return
+ * value when done.
+ */
+ virtual SnmpTarget *clone() const = 0;
+
+ /// manipulate the base part
+ friend bool operator==(const SnmpTarget& lhs, const SnmpTarget& rhs);
+
+ SnmpTarget& operator=(const SnmpTarget& lhs);
+
+ protected:
+ /// SnmpTarget(const SnmpTarget &);
+ SnmpTarget();
+
+ /// used by derived class instances
+ int validity_;
+
+ /// instance value xmit timeout in milli secs
+ unsigned long timeout_;
+
+ /// instance value number of retries
+ int retries_;
+
+ /// size of pdu
+ unsigned max_pdu_size_;
+
+ /// instance value the snmp version
+ snmp_version version_;
+
+ // class wide default values
+ /// xmit timeout in secs
+ static unsigned long default_timeout_;
+
+ /// number of retries
+ static int default_retries_;
+
+ /// snmp protocol version
+ static unsigned long default_max_pdu_size_;
+ static snmp_version default_version_;
+};
+
+//----[ UdpTarget class ]----------------------------------------------
+// UDP/IP transport using "community string" based agents (targets)
+//
+/**
+ * @class UdpTarget
+ *
+ * @brief Concrete class UdpTarget contains all Details for communicating
+ * with a SNMPv1 agent over UDP/IPv4 transport
+ */
+class ASNMP_Export UdpTarget : public SnmpTarget
+{
+ public:
+ UdpTarget();
+
+ /**
+ * constructor with only address
+ * assumes default as public, public
+ * can be constructed with IP address object
+ */
+ UdpTarget( const UdpAddress& udp);
+
+ /// can be constructed with Udp address object TODO: merge addresses
+ UdpTarget( ACE_INET_Addr& ace_inet_addr);
+
+ /// destructor
+ ~UdpTarget();
+
+ // ** set ***
+
+ /// set the read community using an OctetStr
+ void set_read_community( const OctetStr& new_read_community);
+
+ /// set the write community using an OctetStr
+ void set_write_community( const OctetStr& write_community);
+
+ /// set the address
+ int set_address( UdpAddress &udp_address);
+
+ // ** get ***
+
+ /// get the read community as an Octet Str object
+ void get_read_community( OctetStr& read_community_oct) const;
+
+ /// get the write community as an OctetStr
+ void get_write_community( OctetStr &write_community_oct) const;
+
+ /// get the address
+ void get_address( UdpAddress& address) const;
+
+ /// all classes constructed will have this read community string
+ void set_default_read_community(const OctetStr& rd_community);
+
+ /// all classes constructed will have this write community string
+ void set_default_write_community(const OctetStr& wr_community);
+
+ /// all classes constructed will have this read community string
+ void get_default_read_community(OctetStr& rd_community) const;
+
+ /// all classes constructed will have this write community string
+ void get_default_write_community(OctetStr& wr_community) const;
+
+ /// overloaded assignment
+ UdpTarget& operator=( const UdpTarget& target);
+
+ /// compare two C targets
+ friend bool operator==( const UdpTarget &lhs, const UdpTarget &rhs);
+
+ /// string representation of object
+ const char *to_string();
+
+ /// clone from existing UdpTarget
+ SnmpTarget *clone() const;
+
+ protected:
+ static OctetStr default_rd_community_;
+ static OctetStr default_wr_community_;
+ OctetStr read_community_;
+ OctetStr write_community_;
+ UdpAddress udp_address_;
+ snmp_version version_;
+
+ /// to_string() rep of data
+ char output_buffer_[MAX_TARGET_STRING_REP];
+};
+
+
+#endif //TARGET_
diff --git a/ACE/ASNMP/asnmp/timetick.cpp b/ACE/ASNMP/asnmp/timetick.cpp
new file mode 100644
index 00000000000..e6b2d0d2231
--- /dev/null
+++ b/ACE/ASNMP/asnmp/timetick.cpp
@@ -0,0 +1,144 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// timetick.cpp
+//
+// = DESCRIPTION
+// Class implentation for SMI Timeticks class.
+//
+// = AUTHOR
+// Peter E Mellquist
+// Michael R MacFaden mrm@cisco.com - rework & ACE port
+// ============================================================================
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/timetick.h" // include header file for timetick class
+#include "ace/OS_NS_stdio.h"
+
+ACE_RCSID(asnmp, timetick, "$Id$")
+
+// constructor with a value
+TimeTicks::TimeTicks( const unsigned long i):SnmpUInt32(i)
+{
+ smival.syntax = sNMP_SYNTAX_TIMETICKS;
+}
+
+// copy constructor
+TimeTicks::TimeTicks( const TimeTicks &t)
+ : SnmpUInt32 (t)
+{
+ smival.value.uNumber = t.smival.value.uNumber;
+ smival.syntax = sNMP_SYNTAX_TIMETICKS;
+}
+
+// destructor
+TimeTicks::~TimeTicks()
+{
+}
+
+// syntax type
+SmiUINT32 TimeTicks::get_syntax()
+{
+ return sNMP_SYNTAX_TIMETICKS;
+}
+
+// create a new instance of this Value
+SnmpSyntax *TimeTicks::clone() const
+{
+ return (SnmpSyntax *) new TimeTicks(*this);
+}
+
+// overloaded assignement from ulong
+TimeTicks& TimeTicks::operator=( const unsigned long int i)
+{
+ smival.value.uNumber =i; return *this;
+}
+
+// overloaded assignment from TimeTicks
+TimeTicks& TimeTicks::operator=( const TimeTicks &uli)
+{
+ this->smival.value.uNumber = uli.smival.value.uNumber; return *this;
+}
+
+// general assignment from any Value
+SnmpSyntax& TimeTicks::operator=( SnmpSyntax &in_val)
+{
+ if ( this == &in_val ) // handle assignement from itself
+ return *this;
+
+ valid_flag = 0; // will get set true if really valid
+ if (in_val.valid()) {
+ switch (in_val.get_syntax()) {
+ case sNMP_SYNTAX_UINT32:
+ // case sNMP_SYNTAX_GAUGE32: .. indistinquishable from UINT32
+ case sNMP_SYNTAX_CNTR32:
+ case sNMP_SYNTAX_TIMETICKS:
+ case sNMP_SYNTAX_INT32: // implied cast int -> uint
+ this->smival.value.uNumber =
+ ((TimeTicks &)in_val).smival.value.uNumber;
+ valid_flag = 1;
+ break;
+ }
+ }
+ return *this;
+}
+
+// otherwise, behave like an unsigned long
+TimeTicks::operator unsigned long()
+{
+ return smival.value.uNumber;
+}
+
+
+// ASCII format return
+const char * TimeTicks::to_string()
+ /* Should do something nicer like days:hours:minutes... */
+{
+ unsigned long tt, hseconds, seconds, minutes, hours, days;
+ tt = this->smival.value.uNumber;
+
+ // days
+ days = tt / 8640000;
+ tt %= 8640000;
+
+ // hours
+ hours = tt / 360000;
+ tt %= 360000;
+
+ // minutes
+ minutes = tt / 6000;
+ tt %= 6000;
+
+ seconds = tt / 100;
+ tt %= 100;
+
+ hseconds = tt;
+
+ if ( days ==0)
+ sprintf( output_buffer,"%ld:%02ld:%02ld.%02ld", hours, minutes,seconds,hseconds);
+ else if ( days==1)
+ sprintf( output_buffer,"1 day %ld:%02ld:%02ld.%02ld", hours, minutes,seconds,hseconds);
+ else
+ sprintf( output_buffer,"%ld days, %ld:%02ld:%02ld.%02ld", days,hours, minutes,seconds,hseconds);
+
+ return output_buffer;
+}
diff --git a/ACE/ASNMP/asnmp/timetick.h b/ACE/ASNMP/asnmp/timetick.h
new file mode 100644
index 00000000000..ca52a3e1d9d
--- /dev/null
+++ b/ACE/ASNMP/asnmp/timetick.h
@@ -0,0 +1,85 @@
+/* -*-C++-*- */
+#ifndef TIMETICKS_
+#define TIMETICKS_
+//=============================================================================
+/**
+ * @file timetick.h
+ *
+ * $Id$
+ *
+ * Class definition for SMI Timeticks class.
+ *
+ *
+ * @author Michael R. MacFaden <mrm@cisco.com>
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/integer.h"
+
+#define TICKOUTBUF 30 // max formatted time string
+
+//------------[ TimeTicks Class ]-----------------------------------
+// The timeticks class allows all the functionality of unsigned
+// integers but is recognized as a distinct SMI type. TimeTicks
+// objects may be get or set into Vb objects.
+//
+/**
+ * @class TimeTicks
+ *
+ * @brief Define RFC1155 TimeTicks Data object
+ */
+class ASNMP_Export TimeTicks : public SnmpUInt32
+
+{
+
+ public:
+ TimeTicks( const unsigned long i = 0);
+
+ /// copy constructor
+ TimeTicks( const TimeTicks &t);
+
+ /// destructor
+ ~TimeTicks();
+
+ /// syntax type
+ SmiUINT32 get_syntax();
+
+ /// get a printable ASCII value
+ const char *to_string();
+
+ /// create a new instance of this Value
+ SnmpSyntax *clone() const;
+
+ /// copy an instance of this Value
+ SnmpSyntax& operator=(SnmpSyntax &val);
+
+ /// overloaded assignment
+ TimeTicks& operator=( const TimeTicks &uli);
+
+ /// overloaded assignment
+ TimeTicks& operator=( const unsigned long int i);
+
+ /// otherwise, behave like an unsigned long
+ operator unsigned long();
+
+ protected:
+ /// for storing printed form
+ char output_buffer[TICKOUTBUF];
+};
+#endif // TIMETICKS_
diff --git a/ACE/ASNMP/asnmp/transaction.cpp b/ACE/ASNMP/asnmp/transaction.cpp
new file mode 100644
index 00000000000..2f29cf79544
--- /dev/null
+++ b/ACE/ASNMP/asnmp/transaction.cpp
@@ -0,0 +1,207 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// transaction.cpp
+//
+// = DESCRIPTION
+// implements blocking SNMPv1 API using a simple state machine
+// transactions over UDP/IP networks
+//
+// = AUTHOR
+// Michael R MacFaden mrm@cisco.com - remove v2c, async, rework for ACE
+// ============================================================================
+
+#include "ace/Reactor.h"
+#include "asnmp/transaction.h"
+#include "ace/OS_NS_string.h"
+
+ACE_RCSID(asnmp, transaction, "$Id$")
+
+// pre: pdu, target report valid() == 1
+// post: pdu sent out over the wire
+inline void reset_receive_buffer(iovec& io)
+{
+ io.iov_base = 0;
+ io.iov_len = 0;
+}
+
+transaction::transaction(const Pdu& pdu, const UdpTarget& target,
+ ACE_SOCK_Dgram& io):
+ result_(0),
+ wp_(pdu,target), params_(target), session_(io)
+{
+ // last step, convert address (get ride of this once we have merged address
+ UdpAddress udp;
+ target.get_address(udp);
+ // via string conversion "dotted-quad:port"
+ ACE_INET_Addr tmp(udp);
+ addr_ = tmp;
+ reset_receive_buffer(receive_iovec_);
+}
+
+transaction::~transaction()
+{
+ ACE_Reactor::instance()->remove_handler(this, READ_MASK | DONT_CALL);
+ ACE_Reactor::instance()->cancel_timer(this);
+
+ delete [] (char *) receive_iovec_.iov_base;
+}
+
+// implement state machine, send, wait (timeout/results) return
+int transaction::run()
+{
+ int rc, done = 0;
+ int retry_counter = 0;
+ ACE_Time_Value to(params_.get_timeout(), 0); // seconds
+ ACE_Reactor *reactor = ACE_Reactor::instance ();
+
+ // 1. register io port for read access
+ if (reactor->register_handler(session_.get_handle(), this,
+ ACE_Event_Handler::READ_MASK) == -1)
+ return SNMP_CLASS_INTERNAL_ERROR;
+
+ // register a time handler and a socket with this
+
+ while (!done) {
+
+ if ((rc = send()) < 0) // send pkt to agent
+ return rc;
+ else {
+ if (retry_counter++ > params_.get_retry())
+ return SNMP_CLASS_TIMEOUT;
+ }
+
+ // 2. wait for events (timeout, returned msg)
+ if (( rc = reactor->handle_events (to)) == 1) // one handler registered
+ return 0;
+ else {
+ if (rc == 0) {
+ to.set(params_.get_timeout(), 0);
+ }
+ else
+ return SNMP_CLASS_INTERNAL_ERROR;
+ }
+ }
+ return SNMP_CLASS_INTERNAL_ERROR;
+}
+
+// implement state machine, send, wait (timeout/results) return
+int transaction::run(transaction_result * r)
+{
+ result_ = r;
+ int rc;
+
+ // 1. register io port for read access
+ ACE_Reactor * reactor = ACE_Reactor::instance();
+ if (reactor->register_handler(session_.get_handle(),
+ this,
+ READ_MASK) == -1)
+ return SNMP_CLASS_INTERNAL_ERROR;
+
+ retry_counter_ = 0;
+
+ // register a time handler and a socket with this
+ ACE_Time_Value to (params_.get_timeout());
+ if (reactor->schedule_timer(this, 0, to, to) < 0)
+ return SNMP_CLASS_INTERNAL_ERROR;
+
+ if ((rc = send()) < 0) // send pkt to agent
+ return rc;
+ return 0;
+}
+
+// got back response from SNMPv1 agent - process it
+int transaction::handle_input (ACE_HANDLE)
+{
+ // OS allocates iovec_.iov_base ptr and len
+ delete [] (char*) receive_iovec_.iov_base;
+ reset_receive_buffer(receive_iovec_);
+ int rc = session_.recv(&receive_iovec_, receive_addr_, 0);
+ if (rc == -1)
+ {
+ delete [] (char*) receive_iovec_.iov_base;
+ reset_receive_buffer(receive_iovec_);
+ if (result_)
+ result_->result(this, SNMP_CLASS_RESOURCE_UNAVAIL);
+ return SNMP_CLASS_RESOURCE_UNAVAIL;
+ }
+ if (result_)
+ result_->result(this, rc);
+
+ return 0;
+}
+
+int transaction::handle_timeout(const ACE_Time_Value &,
+ const void *)
+{
+ if (send() < 0) // send pkt to agent
+ result_->result(this, 0);
+ else
+ if (retry_counter_++ > params_.get_retry())
+ result_->result(this, SNMP_CLASS_TIMEOUT);
+
+ return 0;
+}
+
+
+const ACE_INET_Addr& transaction::get_from_addr() const
+{
+ return receive_addr_;
+}
+
+
+// return pdu to caller
+int transaction::result(Pdu& pdu, char *comm_str, ACE_INET_Addr *from)
+{
+ // TODO: check to see the sender matches the receiver address..
+
+ // remove any vbs existing in this pdu
+ pdu.delete_all_vbs();
+
+ // any data to return?
+ if (receive_iovec_.iov_len == 0)
+ return -1;
+
+ wpdu tmp(receive_iovec_);
+
+ snmp_version ver;
+
+ // return comm str and from address of incomming pdu if requested
+ int rc = tmp.get_pdu(pdu, ver);
+ if (comm_str)
+ ACE_OS::strcpy(comm_str, (char *)tmp.get_community());
+ if (from)
+ *from = receive_addr_;
+ return rc;
+}
+
+transaction::transaction(ACE_SOCK_Dgram& io)
+: result_(0), session_(io)
+{
+ reset_receive_buffer(receive_iovec_);
+}
+
+
+int transaction::send()
+{
+ iovec io = wp_.get_buffer();
+ if (io.iov_len == 0) {
+ // NO DATA ?
+ return -1;
+ }
+ ssize_t rc = session_.send (io.iov_base, io.iov_len, addr_ , 0);
+ return rc;
+}
+
+transaction_result::~transaction_result() {}
+
+ACE_HANDLE
+transaction::get_handle () const
+{
+ return session_.get_handle ();
+}
diff --git a/ACE/ASNMP/asnmp/transaction.h b/ACE/ASNMP/asnmp/transaction.h
new file mode 100644
index 00000000000..d114bd40d1f
--- /dev/null
+++ b/ACE/ASNMP/asnmp/transaction.h
@@ -0,0 +1,83 @@
+/* -*-C++-*- */
+#ifndef TRANSACTION_
+#define TRANSACTION_
+//=============================================================================
+/**
+ * @file transaction.h
+ *
+ * $Id$
+ *
+ * @brief
+ *
+ * @author Michael R. MacFaden port to ACE / use Reactor pattern
+ */
+//=============================================================================
+
+
+#include "ace/Event_Handler.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "asnmp/target.h"
+#include "asnmp/pdu.h"
+#include "asnmp/transaction_result.h"
+#include "asnmp/wpdu.h" // cmu adapter class
+#include "ace/SOCK_Dgram.h"
+
+/**
+ * @class transaction
+ *
+ * @brief Used to manage the details of a particular transaction betwen
+ * two SNMP agents. Uses SnmpTarget class to implement retry/timeout
+ */
+class ASNMP_Export transaction : public ACE_Event_Handler
+
+{
+ int retry_counter_;
+ transaction_result * result_;
+
+public:
+ /// constructor
+ /// destructor
+ transaction(const Pdu& pdu, const UdpTarget& target, ACE_SOCK_Dgram& io);
+ transaction(ACE_SOCK_Dgram& io);
+ ~transaction();
+
+ /// begin polling for values
+ int run();
+ int run(transaction_result *r); // Async interface, with callback object
+
+ /// return pdu with result from agent after run() is completed rc = 0
+ /// optionally get community str
+ int result(Pdu& pdu, char *comm_str = 0, ACE_INET_Addr *from_addr = 0);
+
+ /// called by reactor when data is ready to be read in from OS memory
+ /// used for resend in asynchronous run()
+ virtual int handle_input (ACE_HANDLE fd);
+ virtual int handle_timeout (const ACE_Time_Value &, const void *);
+
+ /// transmit buffer command to network...
+ int send();
+
+ /// pre: handle_input called
+ /// retrieve the sender's from address from the last pkt
+ const ACE_INET_Addr& get_from_addr() const;
+
+ /// Return session_ handle.
+ ACE_HANDLE get_handle () const;
+
+private:
+ /// disallow copy construction
+ transaction(const transaction&);
+
+ wpdu wp_; // wire pdu
+ UdpTarget params_; // params
+ ACE_INET_Addr addr_; // to address
+ ACE_SOCK_Dgram session_; // io object
+ iovec receive_iovec_; // receive buffer
+ ACE_INET_Addr receive_addr_; // from address
+};
+
+#endif // TRANSACTION_
diff --git a/ACE/ASNMP/asnmp/transaction_result.h b/ACE/ASNMP/asnmp/transaction_result.h
new file mode 100644
index 00000000000..9ea94c60e8e
--- /dev/null
+++ b/ACE/ASNMP/asnmp/transaction_result.h
@@ -0,0 +1,26 @@
+/* -*-C++-*- */
+#ifndef TRANSACTION_RESULT_H_
+#define TRANSACTION_RESULT_H_
+//=============================================================================
+/**
+ * @file transaction_result.h
+ *
+ * $Id$
+ *
+ * An object respresenting a request/reply operation between mgr/agent
+ *
+ *
+ * @author Michael R. MacFaden
+ */
+//=============================================================================
+
+
+class transaction;
+class ASNMP_Export transaction_result
+{
+ public:
+ virtual ~transaction_result();
+ virtual void result(transaction * trans, int) = 0;
+};
+
+#endif
diff --git a/ACE/ASNMP/asnmp/vb.cpp b/ACE/ASNMP/asnmp/vb.cpp
new file mode 100644
index 00000000000..4e94b5e81b9
--- /dev/null
+++ b/ACE/ASNMP/asnmp/vb.cpp
@@ -0,0 +1,399 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// vb.h
+//
+// = DESCRIPTION
+// The Vb class is an encapsulation of the snmp variable binding.
+// This module contains the class definition for the variable binding (VB)
+// class. The VB class is an encapsulation of a SNMP VB. A VB object is
+// composed of one SNMP++ Oid and one SMI value. The Vb class utilizes Oid
+// objects and thus requires the Oid class. To use this class,
+// set oid, value then call valid() to be sure object was constructed correctly.
+//
+// = AUTHOR
+// Peter E Mellquist
+// Michael R MacFaden mrm@cisco.com - rework & ACE port
+// ============================================================================
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+#include "asnmp/oid.h" // include oid class defs
+#include "asnmp/vb.h" // include vb class defs
+#include "asnmp/snmperrs.h" // error codes
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_Memory.h"
+
+ACE_RCSID(asnmp, vb, "$Id$")
+
+//---------------[ Vb::Vb( void) ]--------------------------------------
+// constructor with no arguments
+// makes an vb, unitialized
+Vb::Vb( void): output_(0), iv_vb_value_(0),
+ exception_status_(SNMP_CLASS_SUCCESS)
+{
+}
+
+//---------------[ Vb::Vb( const Oid &oid) ]-----------------------------
+// constructor to initialize the oid
+// makes a vb with oid portion initialized
+Vb::Vb( const Oid &oid): output_(0), iv_vb_oid_(oid), iv_vb_value_(0),
+ exception_status_(SNMP_CLASS_SUCCESS)
+{
+}
+
+//---------------[ Vb::Vb( const Oid &oid, const SmiSyntax &val) ]-------
+Vb::Vb( const Oid &oid, const SnmpSyntax &val, const SmiUINT32 status):
+ output_(0), iv_vb_oid_(oid), iv_vb_value_(0), exception_status_(status)
+{
+ // iv_vb_value_ = recast_smi_object(val); // allocate and construct object
+ iv_vb_value_ = val.clone();
+}
+
+//---------------[ Vb::Vb( const Vb &vb) ]-----------------------------
+// copy constructor
+Vb::Vb( const Vb &vb): output_(0), iv_vb_value_(0)
+{
+ *this = vb;
+}
+
+//---------------[ Vb::~Vb() ]------------------------------------------
+// destructor
+// if the vb has a oid or an octect string then
+// the associated memory needs to be freed
+Vb::~Vb()
+{
+ free_vb();
+ delete [] output_; // formatting buffer if it exists
+}
+
+
+//--------------[ Vb::valid() ]-----------------------------------------
+// returns validity of a Vb object
+// must have a valid oid and value
+int Vb::valid() const
+{
+ if ( iv_vb_oid_.valid() && (iv_vb_value_ && iv_vb_value_->valid()) )
+ return 1;
+ else
+ return 0;
+}
+
+
+//---------------[ Vb& Vb::operator=( const Vb &vb) ]--------------------
+// overloaded assignment allows assigning one Vb to another
+// this involves deep memory thus target vb needs to be freed
+// before assigning source
+Vb& Vb::operator=( const Vb &vb)
+{
+ free_vb(); // free up target to begin with
+
+ //-----[ reassign the Oid portion 1st ]
+ vb.get_oid( iv_vb_oid_);
+
+ //-----[ next set the vb value portion ]
+ if (vb.iv_vb_value_ == 0) {
+ iv_vb_value_ = 0;
+ }
+ else {
+ iv_vb_value_ = vb.iv_vb_value_->clone();
+ }
+ exception_status_ = vb.exception_status_;
+
+ return *this; // return self reference
+}
+
+ // set a Vb null, if its not already
+void Vb::set_null()
+{
+ free_vb();
+}
+
+//---------------[ Vb::set_oid( const Oid oid ) ]-----------------------
+// set value oid only with another oid
+void Vb::set_oid( const Oid& oid)
+{
+ iv_vb_oid_ = oid;
+}
+
+//---------------[ Vb::get_oid( Oid &oid) ]-----------------------------
+// get oid portion
+void Vb::get_oid( Oid &oid) const
+{
+ oid = iv_vb_oid_;
+}
+
+//----------------[ void Vb::free_vb() ]--------------------------------
+// protected method to free memory
+// this methos is used to free memory when assigning new vbs
+// or destructing
+// in the case of oids and octets, we need to do a deep free
+void Vb::free_vb()
+{
+ if (iv_vb_value_)
+ delete iv_vb_value_;
+ exception_status_ = SNMP_CLASS_SUCCESS;
+ iv_vb_value_ = 0;
+}
+
+void Vb::set_value( const SnmpInt32& i)
+{
+ free_vb();
+ iv_vb_value_ = (SnmpSyntax *)new SnmpInt32(i);
+}
+
+void Vb::set_value( const SnmpUInt32& u)
+{
+ free_vb();
+ iv_vb_value_ = (SnmpSyntax *)new SnmpUInt32(u);
+}
+
+void Vb::set_value( const Gauge32& g)
+{
+ free_vb();
+ iv_vb_value_ = (SnmpSyntax *)new Gauge32(g);
+}
+
+void Vb::set_value( const Counter32& c)
+{
+ free_vb();
+ iv_vb_value_ = (SnmpSyntax *)new Counter32(c);
+}
+
+void Vb::set_value( const Counter64& c)
+{
+ free_vb();
+ iv_vb_value_ = (SnmpSyntax *)new Counter64(c);
+}
+
+void Vb::set_value( const TimeTicks& t)
+{
+ free_vb();
+ iv_vb_value_ = (SnmpSyntax *)new TimeTicks(t);
+}
+
+void Vb::set_value( const OctetStr& s)
+{
+ free_vb();
+ iv_vb_value_ = (SnmpSyntax *)new OctetStr(s);
+}
+
+void Vb::set_value( const Oid& o)
+{
+ free_vb();
+ iv_vb_value_ = (SnmpSyntax *)new Oid(o);
+}
+
+void Vb::set_value ( const SnmpSyntax &val)
+{
+ free_vb();
+ iv_vb_value_ = val.clone();
+}
+
+int Vb::get_value( SnmpInt32 &i)
+{
+ if (iv_vb_value_ &&
+ iv_vb_value_->valid() &&
+ (iv_vb_value_->get_syntax() == sNMP_SYNTAX_INT32 )) {
+ i = *((SnmpInt32 *) iv_vb_value_);
+ return SNMP_CLASS_SUCCESS;
+ }
+ else
+ return SNMP_CLASS_INVALID;
+}
+
+int Vb::get_value( SnmpUInt32 &u)
+{
+ if (iv_vb_value_ && iv_vb_value_->valid())
+ {
+ SmiUINT32 syntax = iv_vb_value_->get_syntax();
+ if (syntax == sNMP_SYNTAX_GAUGE32 ||
+ syntax == sNMP_SYNTAX_CNTR32 ||
+ syntax == sNMP_SYNTAX_TIMETICKS ||
+ syntax == sNMP_SYNTAX_UINT32)
+ {
+ u = *((SnmpUInt32 *) iv_vb_value_);
+ return SNMP_CLASS_SUCCESS;
+ }
+ }
+ return SNMP_CLASS_INVALID;
+}
+
+/* return a uint or a gauge. this is casting, but no semantic difference
+ * at this level
+ */
+int Vb::get_value( Gauge32 &g)
+{
+ if (iv_vb_value_ &&
+ iv_vb_value_->valid() &&
+ ((iv_vb_value_->get_syntax() == sNMP_SYNTAX_GAUGE32) ||
+ iv_vb_value_->get_syntax() == sNMP_SYNTAX_UINT32) ) {
+ g = *((Gauge32 *) iv_vb_value_);
+ return SNMP_CLASS_SUCCESS;
+ }
+ else
+ return SNMP_CLASS_INVALID;
+}
+
+int Vb::get_value( Counter32 &c)
+{
+ if (iv_vb_value_ &&
+ iv_vb_value_->valid() &&
+ (iv_vb_value_->get_syntax() == sNMP_SYNTAX_CNTR32 )) {
+ c = *((Counter32 *) iv_vb_value_);
+ return SNMP_CLASS_SUCCESS;
+ }
+ else
+ return SNMP_CLASS_INVALID;
+}
+
+int Vb::get_value( Counter64 &c)
+{
+ if (iv_vb_value_ &&
+ iv_vb_value_->valid() &&
+ (iv_vb_value_->get_syntax() == sNMP_SYNTAX_CNTR64 )) {
+ c = *((Counter32 *) iv_vb_value_);
+ return SNMP_CLASS_SUCCESS;
+ }
+ else
+ return SNMP_CLASS_INVALID;
+}
+
+int Vb::get_value( TimeTicks &t)
+{
+ if (iv_vb_value_ &&
+ iv_vb_value_->valid() &&
+ (iv_vb_value_->get_syntax() == sNMP_SYNTAX_TIMETICKS )) {
+ t = *((TimeTicks *) iv_vb_value_);
+ return SNMP_CLASS_SUCCESS;
+ }
+ else
+ return SNMP_CLASS_INVALID;
+}
+
+int Vb::get_value( OctetStr &s)
+{
+ if (iv_vb_value_ &&
+ iv_vb_value_->valid() &&
+ (iv_vb_value_->get_syntax() == sNMP_SYNTAX_OCTETS )) {
+ s = *((OctetStr *) iv_vb_value_);
+ return SNMP_CLASS_SUCCESS;
+ }
+ else
+ return SNMP_CLASS_INVALID;
+}
+
+int Vb::get_value( Oid &s)
+{
+ if (iv_vb_value_ &&
+ iv_vb_value_->valid() &&
+ (iv_vb_value_->get_syntax() == sNMP_SYNTAX_OID )) {
+ s = *((Oid *) iv_vb_value_);
+ return SNMP_CLASS_SUCCESS;
+ }
+ else
+ return SNMP_CLASS_INVALID;
+}
+
+
+//---------------[ Vb::get_value( Value &val) ]--------
+int Vb::get_value( SnmpSyntax &val)
+{
+ if (iv_vb_value_) {
+ val = *iv_vb_value_;
+ if (val.valid())
+ return SNMP_CLASS_SUCCESS;
+ else
+ return SNMP_CLASS_INVALID;
+ }
+ else
+ {
+//TM: should set val to be invalid
+ return SNMP_CLASS_INVALID;
+ }
+}
+
+
+
+//-----[ misc]--------------------------------------------------------
+
+// return the current syntax
+// This method violates Object Orientation but may be useful if
+// the caller has a vb object and does not know what it is.
+// This would be useful in the implementation of a browser.
+SmiUINT32 Vb::get_syntax()
+{
+ if ( exception_status_ != SNMP_CLASS_SUCCESS)
+ return exception_status_;
+ else
+ return ( iv_vb_value_ ? iv_vb_value_->get_syntax() : sNMP_SYNTAX_NULL);
+}
+
+// return the printabel value
+const char *Vb::to_string_value()
+{
+ if (iv_vb_value_)
+ return iv_vb_value_->to_string();
+ else
+ return "";
+}
+
+// return the printable oid
+const char *Vb::to_string_oid()
+{
+ return iv_vb_oid_.to_string();
+}
+
+// generate string with name/ value format
+const char *Vb::to_string()
+{
+ int len = ACE_OS::strlen(iv_vb_oid_.to_string());
+ const char *ptr = iv_vb_value_ ? iv_vb_value_->to_string() : "";
+ len += ACE_OS::strlen(ptr) + 3 + 1; // " / " + null
+ ACE_NEW_RETURN(output_, char[len], "");
+ ACE_OS::sprintf(output_, "%s / %s", iv_vb_oid_.to_string(), ptr);
+ return output_;
+}
+
+// friend function to set exception status
+void set_exception_status( Vb *vb, const SmiUINT32 status)
+{
+ vb->exception_status_ = status;
+}
+
+// equivlence operator overloaded
+// hack, by side effect, compare based on string formatting output_
+bool operator==( const Vb &lhs, const Vb &rhs)
+{
+ if ( lhs.iv_vb_oid_ != rhs.iv_vb_oid_)
+ return false;
+
+ if (lhs.iv_vb_value_ != 0 && rhs.iv_vb_value_ != 0)
+ {
+ const int val =
+ ACE_OS::strcmp (lhs.iv_vb_value_->to_string(),
+ rhs.iv_vb_value_->to_string());
+ return !val;
+ }
+ else
+ return false;
+}
diff --git a/ACE/ASNMP/asnmp/vb.h b/ACE/ASNMP/asnmp/vb.h
new file mode 100644
index 00000000000..b82adb2bc0e
--- /dev/null
+++ b/ACE/ASNMP/asnmp/vb.h
@@ -0,0 +1,207 @@
+
+
+#ifndef VB_CLS_
+#define VB_CLS_
+//=============================================================================
+/**
+ * @file vb.h
+ *
+ * $Id$
+ *
+ * This module contains the class definition for the variable binding (VB)
+ * class. The VB class is an encapsulation of a SNMP VB. A VB object is
+ * composed of one SNMP++ Oid and one SMI value. The Vb class utilizes Oid
+ * objects and thus requires the Oid class. To use this class,
+ * set oid, value then call valid() to be sure object was constructed correctly.
+ *
+ *
+ * @author Peter E Mellquist
+ */
+//=============================================================================
+
+/*===================================================================
+ Copyright (c) 1996
+ Hewlett-Packard Company
+
+ ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
+ Permission to use, copy, modify, distribute and/or sell this software
+ and/or its documentation is hereby granted without fee. User agrees
+ to display the above copyright notice and this license notice in all
+ copies of the software and any documentation of the software. User
+ agrees to assume all liability for the use of the software; Hewlett-Packard
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS-IS without warranty of any kind,either express
+ or implied. User hereby grants a royalty-free license to any and all
+ derivatives based upon this software code base.
+=====================================================================*/
+
+//----[ external calls ]----------------------------------------------
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "asnmp/smival.h"
+#include "asnmp/snmperrs.h" // V2c error def
+#include "asnmp/oid.h" // oid class def
+#include "asnmp/timetick.h" // time ticks
+#include "asnmp/counter.h" // counter
+#include "asnmp/gauge.h" // gauge class
+#include "asnmp/ctr64.h" // 64 bit counters
+#include "asnmp/octet.h" // octet class
+#include "asnmp/address.h" // address class def
+#include "asnmp/integer.h" // integer class
+
+
+//------------[ VB Class Def ]-------------------------------------
+// The Vb class is the encapsulation of the SNMP variable binding.
+// Variable binding lists in SNMP++ are represented as arrays of
+// Vb objects. Vb objects are passed to and from SNMP objects to
+// provide getting or setting MIB values.
+// The vb class keeps its own memory for objects and does not
+// utilize pointers to external data structures.
+//
+/**
+ * @class Vb
+ *
+ * @brief Implement the concrete Variable Bindings aka Varbind
+ * composite type. Varbinds hold 1 Oid and 1 Value (Any SMI value)
+ */
+class ASNMP_Export Vb
+{
+public:
+ /// constructor with no arguments
+ /// makes an vb, unitialized (does not make object valid)
+ Vb( void);
+
+ /// constructor to initialize the oid
+ /// makes a vb with oid portion initialized (does not make object valid)
+ Vb( const Oid &oid);
+
+ /// constructor to initialize the oid
+ /// makes a vb with oid portion and value portion initialized, (valid)
+ Vb( const Oid& vb, const SnmpSyntax &val, const SmiUINT32=SNMP_CLASS_SUCCESS);
+
+ /// copy constructor
+ Vb( const Vb &vb);
+
+ /**
+ * destructor
+ * if the vb has a oid or an octect string then
+ * the associated memory needs to be freed
+ */
+ ~Vb();
+
+ /// return validity of Vb object (both oid and value set return 1 else 0)
+ int valid() const;
+
+ /// assignment to another Vb object overloaded
+ Vb& operator=( const Vb &vb);
+
+ /// equivlence operator overloaded
+ friend ASNMP_Export bool operator==( const Vb &lhs, const Vb &rhs);
+
+ //-----[ set oid / get oid part]------------------------------------------
+
+ /// set value oid only with another oid
+ void set_oid( const Oid& oid);
+
+ /// get oid portion
+ void get_oid( Oid &oid) const;
+
+ //-----[ set value part]--------------------------------------------------
+
+ /// set a Vb null, if its not already
+ void set_null();
+
+ /// returns 0 on success and a value
+ void set_value( const TimeTicks& ticks);
+
+ /// returns 0 on success and a value
+ void set_value( const Oid& oid);
+
+ /// returns 0 on success and a value
+ void set_value( const Counter32& ctr);
+
+ /// returns 0 on success and a value
+ void set_value( const Counter64& ctr);
+
+ /// returns 0 on success and a value
+ void set_value( const Gauge32& ctr);
+
+ /// returns 0 on success and a value
+ void set_value( const SnmpUInt32& ctr);
+
+ /// returns 0 on success and a value
+ void set_value( const SnmpInt32& ctr);
+
+ /// get an octet string object
+ void set_value( const OctetStr& oct_str);
+
+ //----[ get value ]------------------------------------------------
+
+ /// returns 0 on success and a value
+ int get_value( TimeTicks& ticks);
+
+ /// returns 0 on success and a value
+ int get_value( Oid& oid);
+
+ /// returns 0 on success and a value
+ int get_value( Counter32& ctr);
+
+ /// returns 0 on success and a value
+ int get_value( Counter64& ctr);
+
+ /// returns 0 on success and a value
+ int get_value( Gauge32& ctr);
+
+ /// returns 0 on success and a value
+ int get_value( SnmpUInt32& ctr);
+
+ /// returns 0 on success and a value
+ int get_value( SnmpInt32& ctr);
+
+ /// get an octet string object
+ int get_value( OctetStr& oct_str);
+
+ // escape hatch
+ /// for other derived types that can be casted
+ void set_value( const SnmpSyntax &val);
+
+ /// gets a general value
+ int get_value( SnmpSyntax &val);
+
+ /// return the current syntax
+ /// Or.. if a V2 VB exception is present then return the exception value
+ SmiUINT32 get_syntax();
+
+ /// set the exception status
+ friend ASNMP_Export void set_exception_status( Vb *vb, const SmiUINT32 status);
+
+ /// return fomatted version of this object
+ const char *to_string();
+
+ /// returns a formatted version of the value
+ const char *to_string_value();
+
+ /// returns a formatted version of the value
+ const char *to_string_oid();
+
+protected:
+ /// display vb as [ oid / value ]
+ char *output_;
+
+ /// a vb is made up of a oid
+ Oid iv_vb_oid_;
+
+ /// and a value...
+ SnmpSyntax *iv_vb_value_;
+
+ /// are there any vb exceptions??
+ SmiUINT32 exception_status_;
+
+ void free_vb();
+};
+
+#endif // VB_CLS_
diff --git a/ACE/ASNMP/asnmp/wpdu.cpp b/ACE/ASNMP/asnmp/wpdu.cpp
new file mode 100644
index 00000000000..d05a750970f
--- /dev/null
+++ b/ACE/ASNMP/asnmp/wpdu.cpp
@@ -0,0 +1,521 @@
+// $Id$
+
+// ============================================================================
+// = LIBRARY
+// asnmp
+//
+// = FILENAME
+// wpdu.cpp
+//
+// = DESCRIPTION
+// Adapter class. Converts between raw wire format and Pdu objects
+// that can be stuffed out a I/O port or reconstructed
+//
+// = AUTHOR
+// Michael R. MacFaden rework the class api and impl using ACE
+// Peter E Mellquist implementation/code from snmp++ snmpmsg class
+//
+// ============================================================================
+
+#include "asnmp/wpdu.h"
+#include <ace/Log_Msg.h>
+#include "ace/OS_NS_string.h"
+
+#define DEFINE_TRAP_CONSTANTS_
+#include "asnmp/enttraps.h"
+
+ACE_RCSID(asnmp, wpdu, "$Id$")
+
+#define MAX_COMM_STR_LEN 255
+#define V1_COLD_START 0
+#define V1_WARM_START 1
+#define V1_LINK_DOWN 2
+#define V1_LINK_UP 3
+#define V1_AUTH_FAILURE 4
+#define V1_EGP_NEIGHBOR_LOSS 5
+#define V1_ENT_SPECIFIC 6
+
+inline
+void reset_iov(iovec& iov)
+{
+ iov.iov_base = 0;
+ iov.iov_len = 0;
+}
+
+wpdu::wpdu(const Pdu& pdu, const UdpTarget& target):
+ valid_flag_(SNMP_CLASS_INVALID ), comm_len(MAX_COMM_STR_LEN)
+{
+ reset_iov(iovec_);
+ version_ = target.get_version();
+ int status;
+ OctetStr comm_str;
+
+ community_name[0] = 0;
+
+ snmp_pdu *raw_pdu; // create a raw pdu
+ raw_pdu = cmu_snmp::pdu_create( (int) pdu.get_type());
+ if (!raw_pdu) {
+ valid_flag_ = SNMP_CLASS_RESOURCE_UNAVAIL;
+ return;
+ }
+
+ raw_pdu->reqid = pdu.get_request_id();
+ raw_pdu->errstat= (unsigned long) pdu.get_error_status();
+ raw_pdu->errindex= (unsigned long) pdu.get_error_index();
+
+ switch (raw_pdu->command) {
+ case sNMP_PDU_GET:
+ case sNMP_PDU_GETNEXT:
+ target.get_read_community(comm_str);
+ break;
+
+ case sNMP_PDU_SET:
+ target.get_write_community(comm_str);
+ break;
+
+ case sNMP_PDU_V1TRAP:
+ target.get_read_community(comm_str);
+ if (set_trap_info(raw_pdu, pdu)) // will free raw_pdu
+ return;
+ break;
+ case sNMP_PDU_RESPONSE:
+ break;
+
+ default:
+ ACE_ASSERT(0);
+ return;
+ }
+
+ if (load_vbs(raw_pdu, pdu)) {
+ cmu_snmp::free_pdu( raw_pdu);
+ valid_flag_ = SNMP_CLASS_RESOURCE_UNAVAIL;
+ return;
+ }
+
+ // TODO: determine how big raw_pdu serializes out to
+ iovec_.iov_len = target.get_max_pdu_size();
+ ACE_NEW(iovec_.iov_base, char [iovec_.iov_len]);
+
+ // create raw byte stream
+ status = cmu_snmp::build( raw_pdu,
+ (unsigned char *)iovec_.iov_base,
+ (int *) &iovec_.iov_len,
+ target.get_version(),
+ comm_str.data(), comm_str.length());
+ if ( status != 0) {
+ valid_flag_ = SNMP_ERROR_WRONG_ENCODING;
+ cmu_snmp::free_pdu( raw_pdu);
+ return;
+ }
+
+ cmu_snmp::free_pdu( raw_pdu);
+ valid_flag_ = SNMP_CLASS_SUCCESS;
+}
+
+int wpdu::set_trap_info(snmp_pdu *raw_pdu, const Pdu& pdu) const
+{
+ Oid enterprise;
+ Oid trapid; // validate caller has set this correctly
+ pdu.get_notify_id( trapid);
+ if ( !trapid.valid() || trapid.length() < 2 ) {
+ cmu_snmp::free_pdu( raw_pdu);
+ return SNMP_CLASS_INVALID_NOTIFYID;
+ }
+
+
+ raw_pdu->specific_type=0;
+
+ // TODO: object should emit numeric instead of this kind of mess...
+ if ( trapid == coldStart)
+ raw_pdu->trap_type = V1_COLD_START; // cold start
+ else if ( trapid == warmStart)
+ raw_pdu->trap_type = V1_WARM_START; // warm start
+ else if( trapid == linkDown)
+ raw_pdu->trap_type = V1_LINK_DOWN; // link down
+ else if ( trapid == linkUp)
+ raw_pdu->trap_type = V1_LINK_UP; // link up
+ else if ( trapid == authenticationFailure )
+ raw_pdu->trap_type = V1_AUTH_FAILURE; // authentication failure
+ else if ( trapid == egpNeighborLoss)
+ raw_pdu->trap_type = V1_EGP_NEIGHBOR_LOSS; // egp neighbor loss
+ else {
+ raw_pdu->trap_type = V1_ENT_SPECIFIC; // enterprise specific
+ // last oid subid is the specific value
+ // if 2nd to last subid is "0", remove it
+ // enterprise is always the notify oid prefix
+ raw_pdu->specific_type = (int) trapid[(int) (trapid.length() - 1)];
+ trapid.trim(1);
+ if ( trapid[(int)(trapid.length() - 1)] == 0 )
+ trapid.trim(1);
+ enterprise = trapid;
+ }
+
+ if ( raw_pdu->trap_type != V1_ENT_SPECIFIC)
+ pdu.get_notify_enterprise( enterprise);
+ if ( enterprise.length() > 0) {
+ // note!! To the contrary, enterprise OID val is
+ // copied here and raw_pdu->enterprise is freed in free_pdu
+ // as it should be (HDN)
+ // these are hooks into an SNMP++ oid
+ // and therefor the raw_pdu enterprise
+ // should not free them. null them out!!
+ SmiLPOID rawOid;
+ rawOid = enterprise.oidval();
+ // HDN - enterprise is a local object, cannot simply assign pointer
+ //raw_pdu->enterprise = rawOid->ptr;
+ raw_pdu->enterprise_length = (int) rawOid->len;
+ ACE_NEW_RETURN(raw_pdu->enterprise,
+ oid[raw_pdu->enterprise_length],-1);
+ ACE_OS::memcpy((char *)raw_pdu->enterprise,(char *)rawOid->ptr,
+ raw_pdu->enterprise_length * sizeof(oid));
+ }
+
+ TimeTicks timestamp;
+ pdu.get_notify_timestamp( timestamp);
+ raw_pdu->time = ( unsigned long) timestamp;
+
+ // HDN - set agent addr using the local hostname if possible
+ char localHostName[MAXHOSTNAMELEN];
+ Snmp::get_host_name(localHostName, MAXHOSTNAMELEN);
+ if (ACE_OS::strlen(localHostName) > 0) {
+ GenAddress addr(localHostName);
+ OctetStr octet;
+ addr.to_octet(octet);
+ ACE_OS::memcpy(&(raw_pdu->agent_addr.sin_addr),
+ octet.data(),
+ octet.length());
+ }
+
+ return 0;
+}
+
+wpdu::wpdu(const iovec& iov): valid_flag_(0),comm_len(MAX_COMM_STR_LEN)
+{
+ community_name[0] = 0;
+ reset_iov(iovec_);
+ version_ = version1; // TODO: figure where this should come from
+ ACE_NEW(iovec_.iov_base, char[iov.iov_len]);
+ if (!iovec_.iov_base) {
+ valid_flag_ = SNMP_CLASS_RESOURCE_UNAVAIL;
+ return;
+ }
+
+ copy_iovec(iovec_, iov);
+ valid_flag_ = SNMP_CLASS_SUCCESS;
+}
+
+wpdu::wpdu(): valid_flag_(0), comm_len(MAX_COMM_STR_LEN)
+{
+ community_name[0] = 0;
+ reset_iov(iovec_);
+ version_ = version1; // TODO: figure where this should come from
+}
+
+int wpdu::valid() const
+{
+ return (valid_flag_ == SNMP_CLASS_SUCCESS);
+}
+
+int wpdu::load_vbs(snmp_pdu *raw_pdu, const Pdu& pdu)
+{
+ int status = 0;
+
+ // load up the payload
+ // for all Vbs in list, add them to the pdu
+ int vb_count;
+ Vb tempvb;
+ Oid tempoid;
+ SmiLPOID smioid;
+ SmiVALUE smival;
+
+ vb_count = pdu.get_vb_count();
+
+ for (int z = 0; z < vb_count; z++) {
+ pdu.get_vb( tempvb, z);
+ tempvb.get_oid( tempoid);
+ smioid = tempoid.oidval();
+ // what are we trying to convert here (vb oid part or value part)
+ status = convert_vb_to_smival( tempvb, &smival );
+ if ( status != SNMP_CLASS_SUCCESS)
+ return status;
+
+ // add the var to the raw pdu
+ cmu_snmp::add_var(raw_pdu, smioid->ptr, (int) smioid->len, &smival);
+ free_smival_descriptor( &smival);
+ }
+
+ return status;
+}
+
+// supports overlapped copies
+// static
+void wpdu::copy_iovec(iovec& dest, const iovec& src)
+{
+ if (&dest == &src)
+ return;
+
+ ACE_OS:: memmove( dest.iov_base, src.iov_base, src.iov_len);
+ dest.iov_len = src.iov_len;
+}
+
+int wpdu::convert_vb_to_smival( Vb &tempvb, SmiVALUE *smival )
+{
+ smival->syntax = tempvb.get_syntax();
+
+ switch ( smival->syntax ) {
+
+ case sNMP_SYNTAX_NULL:
+ break;
+
+ // case sNMP_SYNTAX_INT32:
+ case sNMP_SYNTAX_INT:
+ {
+ SnmpInt32 tmp;
+ tempvb.get_value(tmp);
+ smival->value.sNumber = tmp;
+ }
+ break;
+
+ // case sNMP_SYNTAX_UINT32:
+ case sNMP_SYNTAX_GAUGE32:
+ case sNMP_SYNTAX_CNTR32:
+ case sNMP_SYNTAX_TIMETICKS:
+ {
+ SnmpUInt32 tmp;
+ tempvb.get_value(tmp);
+ smival->value.uNumber = tmp;
+ }
+ break;
+
+ // case Counter64
+ case sNMP_SYNTAX_CNTR64:
+ {
+ Counter64 c64;
+ tempvb.get_value(c64);
+ smival->value.hNumber.hipart = c64.high();
+ smival->value.hNumber.lopart = c64.low();
+ }
+ break;
+
+ // OID syntax
+ case sNMP_SYNTAX_OID:
+ {
+ Oid tmpoid;
+ tmpoid.oidval();
+ tempvb.get_value(tmpoid);
+ SmiLPOID smi = tmpoid.oidval();
+ smival->value.oid.len = tmpoid.length();
+ ACE_NEW_RETURN(smival->value.oid.ptr,
+ SmiUINT32 [smival->value.oid.len], 1);
+ ACE_OS::memcpy(smival->value.oid.ptr, smi->ptr,
+ smival->value.oid.len *sizeof(SmiUINT32));
+ }
+ break;
+
+ case sNMP_SYNTAX_BITS:
+ case sNMP_SYNTAX_OCTETS:
+ case sNMP_SYNTAX_IPADDR:
+ {
+ OctetStr os;
+ tempvb.get_value(os);
+ smival->value.string.ptr = 0;
+ smival->value.string.len = os.length();
+ if ( smival->value.string.len > 0 ) {
+ ACE_NEW_RETURN(smival->value.string.ptr,
+ SmiBYTE [smival->value.string.len], 1);
+ if ( smival->value.string.ptr ) {
+ for (int i=0; i<(int) smival->value.string.len ; i++)
+ smival->value.string.ptr[i] = os[i];
+ }
+ else {
+ smival->syntax = sNMP_SYNTAX_NULL; // invalidate the smival
+ return SNMP_CLASS_RESOURCE_UNAVAIL;
+ }
+ }
+ }
+ break;
+
+ default:
+ ACE_DEBUG((LM_DEBUG, "wpdu::convert_vb_to_smival did not convert vb\n"));
+ // ACE_ASSERT(0);
+ } // switch
+
+ return 0;
+}
+
+// free a SMI value
+void wpdu::free_smival_descriptor( SmiVALUE *smival )
+{
+ switch ( smival->syntax ) {
+ case sNMP_SYNTAX_OCTETS:
+ case sNMP_SYNTAX_OPAQUE:
+ case sNMP_SYNTAX_IPADDR:
+ case sNMP_SYNTAX_BITS: // obsoleted in SNMPv2 Draft Std
+ delete [] smival->value.string.ptr;
+ break;
+
+ case sNMP_SYNTAX_OID:
+ delete [] smival->value.oid.ptr;
+ break;
+ }
+ smival->syntax = sNMP_SYNTAX_NULL;
+}
+
+
+wpdu::~wpdu()
+{
+ delete [] (char*) iovec_.iov_base;
+}
+
+const iovec& wpdu::get_buffer() const
+{
+ return iovec_;
+}
+
+// return a pdu from a buffer
+int wpdu::get_pdu(Pdu& pdu, snmp_version& version)
+{
+ if (iovec_.iov_len == 0)
+ return -1; // NO DATA
+
+ snmp_pdu *raw_pdu;
+ raw_pdu = cmu_snmp::pdu_create(0);
+ if (!raw_pdu) {
+ return SNMP_CLASS_RESOURCE_UNAVAIL;
+ }
+
+ // max value a client can send us - TODO: replace this with an
+ // api to get actual string length
+ int status = cmu_snmp::parse( raw_pdu, (unsigned char *)iovec_.iov_base,
+ community_name, comm_len,
+ version, iovec_.iov_len);
+ if (status != 0)
+ return SNMP_CLASS_INTERNAL_ERROR;
+
+ community_name[comm_len] = 0; // set null based on returned length
+ set_request_id( &pdu, raw_pdu->reqid);
+ set_error_status( &pdu, (int) raw_pdu->errstat);
+ set_error_index( &pdu, (int) raw_pdu->errindex);
+ pdu.set_type( raw_pdu->command);
+
+ if (restore_vbs(pdu, raw_pdu)) {
+ cmu_snmp::free_pdu(raw_pdu);
+ return SNMP_CLASS_INTERNAL_ERROR;
+ }
+
+ cmu_snmp::free_pdu(raw_pdu);
+ return 0;
+}
+
+int wpdu::restore_vbs(Pdu& pdu, const snmp_pdu *raw_pdu) const
+{
+ Vb tempvb;
+ Oid tempoid;
+ struct variable_list *vp;
+
+ for(vp = raw_pdu->variables; vp; vp = vp->next_variable) {
+
+ // extract the oid portion
+ tempoid.set_data( (unsigned long *)vp->name,
+ ( unsigned int) vp->name_length);
+ tempvb.set_oid( tempoid);
+
+ // extract the value portion
+ switch(vp->type) {
+
+ // octet string
+ case sNMP_SYNTAX_OCTETS:
+ case sNMP_SYNTAX_OPAQUE:
+ {
+ OctetStr octets( (char *) vp->val.string,
+ (long) vp->val_len);
+ tempvb.set_value( octets);
+ }
+ break;
+
+ // object id
+ case sNMP_SYNTAX_OID:
+ {
+ Oid oid( (unsigned long*) vp->val.objid,
+ (int) vp->val_len);
+ tempvb.set_value( oid);
+ }
+ break;
+
+ // timeticks
+ case sNMP_SYNTAX_TIMETICKS:
+ {
+ TimeTicks timeticks( (unsigned long) *(vp->val.integer));
+ tempvb.set_value( timeticks);
+ }
+ break;
+
+ // 32 bit counter
+ case sNMP_SYNTAX_CNTR32:
+ {
+ Counter32 counter32( (unsigned long) *(vp->val.integer));
+ tempvb.set_value( counter32);
+ }
+ break;
+
+ // ip address
+ case sNMP_SYNTAX_IPADDR:
+ {
+ char buffer[20];
+ sprintf( buffer,"%d.%d.%d.%d",
+ vp->val.string[0],
+ vp->val.string[1],
+ vp->val.string[2],
+ vp->val.string[3]);
+ IpAddress ipaddress( buffer);
+ tempvb.set_value( ipaddress);
+ }
+ break;
+
+ // 32 bit integer
+ case sNMP_SYNTAX_INT:
+ {
+ SnmpInt32 int32( (long) *(vp->val.integer));
+ tempvb.set_value( int32);
+ }
+ break;
+
+ // 32 bit unsigned integer
+ case sNMP_SYNTAX_UINT32:
+ {
+ SnmpUInt32 uint32( (unsigned long) *(vp->val.integer));
+ tempvb.set_value( uint32);
+ }
+ break;
+
+ // v2 counter 64's
+ case sNMP_SYNTAX_CNTR64:
+ break;
+
+ case sNMP_SYNTAX_NULL:
+ tempvb.set_null();
+ break;
+
+ // v2 vb exceptions
+ case sNMP_SYNTAX_NOSUCHOBJECT:
+ case sNMP_SYNTAX_NOSUCHINSTANCE:
+ case sNMP_SYNTAX_ENDOFMIBVIEW:
+ set_exception_status( &tempvb, vp->type);
+ break;
+
+ default:
+ tempvb.set_null();
+
+ } // end switch
+
+ // append the vb to the pdu
+ pdu += tempvb;
+ }
+
+ return 0;
+}
+
+const unsigned char *wpdu::get_community() const
+{
+ return community_name;
+}
diff --git a/ACE/ASNMP/asnmp/wpdu.h b/ACE/ASNMP/asnmp/wpdu.h
new file mode 100644
index 00000000000..7feec356bc8
--- /dev/null
+++ b/ACE/ASNMP/asnmp/wpdu.h
@@ -0,0 +1,84 @@
+/* -*-C++-*- */
+#ifndef WPDU_H_
+#define WPDU_H_
+//=============================================================================
+/**
+ * @file wpdu.h
+ *
+ * $Id$
+ *
+ * Adapter class. Converts a Pdu and GenTarget into a format
+ * that can be stuffed out a I/O port
+ *
+ *
+ * @author Michael R. MacFaden re-worked api
+ * @author use ACE APIPeter E Mellquist wrote original class snmpmsg
+ */
+//=============================================================================
+
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "asnmp/asn1.h"
+#include "asnmp/pdu.h"
+#include "asnmp/target.h"
+
+// this is an adapter class, it peforms the following transformations
+// PDU / Target -> iovec buffer
+// iovec buffer -> PDU / Target
+struct snmp_pdu;
+/**
+ * @class wpdu
+ *
+ * @brief Implement an Adapter pattern between CMU SNMP and HP SNMP++
+ */
+class ASNMP_Export wpdu
+{
+public:
+
+ /// construct CMU data from HP SNMP++ objects
+ /// construct HP SNMP++ objects from raw buffer via CMU SNMP datatypes
+ wpdu(const Pdu& pdu, const UdpTarget& target);
+ wpdu(const iovec& buffer);
+ wpdu(); // same as using iovec?
+
+ ~wpdu();
+
+ /// constructor completed ok? rc = 1 else 0
+ int valid() const;
+
+ /// return raw data stream via CMU code
+ const iovec& get_buffer() const;
+
+ /// return HP SNMP++ pdu
+ int get_pdu(Pdu& pdu, snmp_version& version);
+
+ /// return community strptr
+ const unsigned char *get_community() const;
+
+private:
+ int convert_vb_to_smival( Vb &tempvb, SmiVALUE *smival );
+ int load_vbs(snmp_pdu *raw_pdu, const Pdu& pdu);
+ int restore_vbs(Pdu& pdu, const snmp_pdu *raw_pdu) const;
+ void free_smival_descriptor( SmiVALUE *smival );
+ static void copy_iovec(iovec& dest, const iovec& src);
+ int set_trap_info(snmp_pdu *raw_pdu, const Pdu& pdu) const;
+
+ /// raw format
+ iovec iovec_;
+
+ /// object construction state
+ int valid_flag_;
+
+ /// snmp version
+ snmp_version version_;
+
+ unsigned char community_name[MAX_COMM_STR_LEN];
+ unsigned long comm_len; // = MAX_COMM_STR_LEN;
+};
+
+#endif // WPDU_H_