diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-08-04 08:25:27 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-08-04 08:25:27 +0000 |
commit | 93b4311ec91b2d008ecc3a26200e4a44481494e8 (patch) | |
tree | c8f6ac63d26985c0b40ef84e7611871cfffb0b4b /ASNMP | |
parent | 95433e3dbe5d6d6fc4ba640a14d290b609b90a73 (diff) | |
download | ATCD-93b4311ec91b2d008ecc3a26200e4a44481494e8.tar.gz |
*** empty log message ***
Diffstat (limited to 'ASNMP')
69 files changed, 16042 insertions, 0 deletions
diff --git a/ASNMP/COPYRIGHT b/ASNMP/COPYRIGHT new file mode 100644 index 00000000000..ad880b9cf90 --- /dev/null +++ b/ASNMP/COPYRIGHT @@ -0,0 +1,68 @@ +Mon Jul 14 12:12:32 PDT 1997 + +These copyrights apply to the SNMP++ module shipped with the ACE library: + + +/*=================================================================== + 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. + +=====================================================================*/ + +/********************************************************************** + 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. +******************************************************************/ + +Certain portions of this version of HP's SNMP++ are: + +/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Copyright 1997 Cisco Systems, Inc. + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this +copyright and permission notice appear on all copies of the software and +supporting documentation, the name of Cisco Systems, Inc. not be used +in advertising or publicity pertaining to distribution of the +program without specific prior permission, and notice be given +in supporting documentation that modification, copying and distribution is by +permission of Cisco Systems, Inc. + +Cisco Systems, Inc. makes no representations about the suitability of this +software for any purpose. THIS SOFTWARE IS PROVIDED ``AS IS'' +AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT +LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGMENT AND +FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL CISCO SYSTEMS, INC. BE +LIABLE FOR ANY DAMAGES ARISING OUT OF THIS LICENSE OR YOUR USE OF THE +SOFTWARE INCLUDING WITHOUT LIMITATION, DIRECT, INDIRECT OR CONSEQUENTIAL +DAMAGES. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ + diff --git a/ASNMP/ChangeLog b/ASNMP/ChangeLog new file mode 100644 index 00000000000..13017e371ce --- /dev/null +++ b/ASNMP/ChangeLog @@ -0,0 +1,44 @@ +Sat Aug 2 12:07:43 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> + + * Started to integrate the code into a more ACE-like style, e.g., + added a the "asnmp/" prefix to all the header files so that we + don't need to play games with the -I flags and so we can always + know where we're getting the headers from. + +Sat Jul 5 19:13:30 1997 Mike MacFaden (mrm@mrm-ss20) + + * unpacked snmp++.tar.Z into ACE_wrappers, remove X11 support. If + you need GUI support in a communications package, something's + wrong, very wrong.... + + * Change HP-UX Makefiles to use ACE makefile system + + * Change includes to use ACE OS Adaption Layer + + * change all OS calls to use ACE_OS:: versions + + * Add ACE_TRACE macros to all functions. + + * clean up the global namespace by puting all global functions + into C++ classes as static member functions and make public only + those that are used (uxsnmp.cpp, eventlist.cpp) + + * create README from readme.txt, COPYRIGHT files. + + * create tests/ directory rename ConsoleExamples to examples + + * cull out dead code modules and dump them into misc dir: + oidname.cpp, ipresolv.cpp + + * ipresolv.cpp had broken hostname buffer size (200), when DNS has + aways defined a max FQDN as 256...go figure. + + * add General Error handler since existing ones are not very + useful in and of themselves. + + * change all _DEF to DEF_ since _ANYTHING is reserved for compiler + writer namespace, NOT app writer + + * convert cmu code to use C++ new/delete from malloc/free so + entire library uses C++ new constructor + diff --git a/ASNMP/Makefile b/ASNMP/Makefile new file mode 100644 index 00000000000..220bf714114 --- /dev/null +++ b/ASNMP/Makefile @@ -0,0 +1,28 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the SNMP+ACE examples directory +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = asnmp \ + examples \ + tests + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + + + diff --git a/ASNMP/README b/ASNMP/README new file mode 100644 index 00000000000..a33c635a764 --- /dev/null +++ b/ASNMP/README @@ -0,0 +1,158 @@ +Sat Jul 5 15:20:20 PDT 1997 + +==================================================================== +ASNMP = ACE+SNMP++ Version 1.0 +By Michael R. MacFaden mrm@acm.org mrm@cisco.com +==================================================================== + +What is ASNMP ? ==> ACE+SNMP! aka Another SNMP API + HP's SNMP++ 2.5 freely available C++ SNMP class library + has been adapted to the ACE 4.2 Framework. + +What was changed from HP version? + See src/ChangeLog file. + +Is HP SNMP++ compatible with ASNMP? + It is neither source nor binary compatible. About 10% of the API has changed. + There have been API changes to make the interface more orthogonal + and to reduce implementation complexity such as consolidating constructors + with default formal values, and to remove some inconsistencies + with the HP interface as well as locking down valid() semantics, etc. + +What platforms have the test programs been verified on? + Solaris 2.4, 2.5.1 using SUN C++ 4.1 compiler + +Why use this version? + The SNMP++ version ships only for HP-UX and for Windows. + It is not very portable nor does it do a good job at checking + for out of memory exhaustion conditions (asn1.cpp). There is some great + code here. ACE needs an SNMP library to build NM type + communications applications. Hence ASNMP was born in my spare time. + +How does ASNMP differ from SNMP? + Current version uses ACE OS Adaption layer. All memory + allocation is now consistent, uses ACE_NEW(). + Standard ACE Debugging (ACE_TRACE) has been inserted. + ASNMP has less global namespace pollution by moving all non-class + functions into interface classes or made into static locals. + + X11 GUI support removed from this version since this is + not the place to include GUI support in the new world of + multi-threaded apps. + + No ASYNC interface. In this version the ASYNC interface has been + removed. A new one based on class callbacks will be added in + the future. Use ACE Threads if blocking doesn't suit you. + + SNMP V2c cmds (getbulk) has been hidden from the API until I + have an CISCO IOS agent that talks V2c to test with. + +How to build this library? + Set ACE_ROOT and platform_macros.GNU per ../INSTALL file. + create libasnmp.a, libasnmp.so and then run the tests + +Any Support for ASNMP? + As time permits from the mailing list. + +Where to ask questions? + Please use ace-users@cs.wustl.edu mailing list or mrm@acm.org + +NOTE: Please do not bother Eric Mellquist unless you are using + the original HP version of this library. + +Where can I get the original HP SNMP++? + From ftp://rosegarden.external.hp.com:/pub/snmp++ + +What version of SNMP is fully supported? + SNMP Version 1 (RFC 1155,1157, 1215) + +What about SNMP Version 2c? + V2c is defined in RFC 1901 - 1908 + These bits are added to v1 code in this library: GetBulk PDU, Counter64 + These bits are missing Inform (RFC 1905) + RFC 1903 defined new datatypes using existing SMI via macros. + These should be coded as if they were SMI datatypes to encapsulate + their behavior. V2c hasn't been deployed + +What copyrights/legal requirements are required when using this code? + See ./COPYRIGHT + +Does this really work? + See tests/ directory for the current test reports (purify/purecov/...). + +Any Future Plans? + The ASNMP library will be improved for performance and made to use + higher level design patterns. Hopefully it will be used as a + vehicle for grad students to learn something about network mgmt + code work related distributed programming. + + +Regards, +Michael R. MacFaden +Software Engineer III +Cisco Systems, Inc. +Network Management Business Unit +170 West Tasman Drive +San Jose, CA 95120 +408-526-6228 +mrm@cisco.com +Fri Jul 25 12:36:32 PDT 1997 + +==================================================================== +SNMP++ For UNIX Source Code and Examples: +==================================================================== +Included within this package can be found the source code and +examples for SNMP++. The following represents the directories which +are included within the compressed tar file and their contents. + +For more details on the API , please refer to the API specification. + +This library is a complete implementation of SNMP++ and does not +require other SNMP libraries to be present. + +Required Tools: +--------------------------------------------------------------------- + + +readme.txt ( this file) +| +| +|------ src ( .cpp files and Makefile for building libraries ) +| +|------ examples ( a variety of apps, .cpp and Makefile included ) +| +|------ tests - unit test routines + + +src Directory Contents: +-------------------------------------------------------------------- +Makefile - make file for ACE/Solaris 2. build +target.cpp - Collection of attributes(address, timeout, etc) used + to define a command session +snmp.cpp - A logical session between NM app and agent +pdu.cpp - Pdu class source (vb list and API command) +wpdu.cpp - Adapter pattern based class between CMU and HP code +transaction.cpp - synchronous transaction clss +vb.cpp - Variable Binding class source (oid + value) + +<< SMI datatypes used to get/set values in SNMPv1 agents>> + +address.cpp - Address class source +gauge.cpp - Gauge32 class source +integer.cpp - Integer32 class source +counter.cpp - Counter32 class source +ctr64.cpp - Counter64 class source +timetick.cpp - TimeTicks class source +octet.cpp - Octet String class source +oid.cpp - Oid class source +asn1.cpp - ASN1 encoding and decoding code. CMU code. + +examples Directory Contents: +--------------------------------------------------------------------- +Makefile - make file for building console apps +get.cpp - source for SNMP get program +next.cpp - source for SNMP get Next program +set.cpp - source for SNMP set program +trap.cpp - source for SNMP trap send program +walk.cpp - source for SNMP walk program + diff --git a/ASNMP/TO-DO b/ASNMP/TO-DO new file mode 100644 index 00000000000..3e04d1673d1 --- /dev/null +++ b/ASNMP/TO-DO @@ -0,0 +1,4 @@ +TODO: + - Attempt to make all subroutines thread safe + - work on test suite - validate basic stuff doesn't leak + - change SNMP++ to ASNMP diff --git a/ASNMP/asnmp-overview.html b/ASNMP/asnmp-overview.html new file mode 100644 index 00000000000..a70e872ad11 --- /dev/null +++ b/ASNMP/asnmp-overview.html @@ -0,0 +1,106 @@ +<html> +<! by Michael R. MacFaden mrm@cisco.com > +<title>ASNMP Overview</title> + +<h1>ASNMP Overview</h1> + +<p>The Another SNMP class library is an Object Oriented programming +toolkit for using IETF standard network management protocols in the +Internet. The SNMP protocol is perhaps the most ubiquitous management +protocol running on most very device or application deployed in the +modern network today. + +<p>ASNMP is targeted to programmers that want to write command and +control (C&C) applications. C&C Applications communicate with +a variety of objects: +<sl> +<li>network devices such as ATM switches, Internet routers, +LAN bridges and LAN printers +<li>Routing protocols such as OSPF +<li>database servers such as ORACLE or Informix. + +<p>ASNMP Version 1 implements a blocking SNMP Version 1 with some +Version 2c additions (Counter32, Counter64 SMI values). See +SNMP Version 1 as defined in the IETF Request for Comments (RFC) +<sl> +<li>1155 +<li>1157 +<li>1215 +<sl> +<p>Also see the RFC 1902 spec for new SMI datatypes such as Counter64. + +<p>ASNMP is built using the CMU SNMP and HP SNMP++ as the base +classes then modified for use in the ACE framework. About 10% of the API +changed during code rework. See ASNMP/asnmp/ChangeLog for details. + +<h2>Class Heirarchy</h2> + +<pre> +UdpTarget - defines Collection of attributes(address, timeout, etc) used + to define a command session. +Snmp - A logical session between NM app and agent +Pdu - Pdu contains a vb list , community string, and a command +Vb - Varbind. A pdu can have zero, one or more of these + consists of an Oid to identify the variable and a datatype + of one of the SMI values. The oid/value binding is defined + in a MIB file (RFC 1155) + +<p>The Structure of Managment Information (SMI) datatypes +and related types are: +<ul> +<li>Address->IpAddress->UdpAddress as well as MAC, IPX, IPXSOCK, Netbios +<li>Unsigned Integer +<li>Gauge32 +<li>Integer32 +<li>Counter32 +<li>Counter64 +<li>TimeTicks +<li>OctetStr +<li>Oid +</ul> + +<hr> + +<h2>Sample program</h2> +<p>A sample Object to get obtain an Agent's Systems' Description +given an network address and a community string. + +class system_id { + public: + system_id(UdpAddress addr, OctetStr read_community_string) + { + UdpTarget tgt; + Snmp snmp; + Pdu pdu; + Oid oid("1.3.6.1.2.1.1.1.0"); + Vb vb(oid); + tgt.set_address(addr); + tgt.set_read_community(read_community_string); + pdu += vb; + + if (snmp.get(pdu, tgt) == 0) { + pdu.get_vb(vb, 0); + vb.get_value(desc_); + } + else + desc_ = "<error - no value set>" + } + + int get_description(OctetStr& description) { + description = desc_; + return 0; + } + +private: + OctetStr desc_; +}; + +<h1>Future Directions</h1> +<p>Here are some areas for further work +<sl> +<li>Add OO mib parser and mib code generator +<li>Collapse the CMU/HP code into one set of classes. +<li>Add full V2c support. +<li>Size/Speed improvements +</sl> +</html> diff --git a/ASNMP/asnmp/ChangeLog b/ASNMP/asnmp/ChangeLog new file mode 100644 index 00000000000..ad15926923c --- /dev/null +++ b/ASNMP/asnmp/ChangeLog @@ -0,0 +1,106 @@ +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 + diff --git a/ASNMP/asnmp/Makefile b/ASNMP/asnmp/Makefile new file mode 100644 index 00000000000..6b55de15871 --- /dev/null +++ b/ASNMP/asnmp/Makefile @@ -0,0 +1,65 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the SNMP+ACE Release +#---------------------------------------------------------------------------- + +MAKEFILE = Makefile +LIB = libasnmp.a +SHLIB = libasnmp.$(SOEXT) + +FILES = address \ + asn1 \ + counter \ + ctr64 \ + gauge \ + integer \ + octet \ + oid \ + pdu \ + snmp \ + target \ + timetick \ + transaction \ + vb \ + wpdu + +TEMPLATE_FILES = + +DEFS = $(addsuffix .h,$(FILES)) +DEFS += $(addsuffix .i,$(FILES)) +LSRC = $(addsuffix .cpp,$(FILES)) +#LSRC2 = $(addsuffix .cpp,$(TEMPLATE_FILES)) + +#### Build the SNMP++ shared library _before_ the static library. +#### This works around an apparent problem with template +#### instantiation with Sun C++ 4.1 and 4.2 (the symptom is link +#### error due to ACE_TimeValue::normalize () not being found). +BUILD = $(VSHLIB) $(SHLIBA) $(VLIB) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +CCFLAGS += -I$(WRAPPER_ROOT)/ASNMP/ + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + + + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/ASNMP/asnmp/TODO b/ASNMP/asnmp/TODO new file mode 100644 index 00000000000..d7a99821c03 --- /dev/null +++ b/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 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/ASNMP/asnmp/address.cpp b/ASNMP/asnmp/address.cpp new file mode 100644 index 00000000000..513c350ba14 --- /dev/null +++ b/ASNMP/asnmp/address.cpp @@ -0,0 +1,2269 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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" + +//================================================================= +//======== 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? +int operator==( const Address &lhs, const Address &rhs) +{ + if ( strcmp( (const char*) lhs, (const char*)rhs)==0) + return TRUE; + else + return FALSE; +} + +//----------------------------------------------------------------------- +// overloaded equivlence operator, are two addresses equal? +int operator!=( const Address &lhs, const Address &rhs) +{ + return (!( lhs == rhs)); +} + + +//------------------------------------------------------------------ +// overloaded > operator, is a1 > a2 +int operator>( const Address &lhs, const Address &rhs) +{ + if ( strcmp( (const char*) lhs, (const char*)rhs)>0) + return TRUE; + else + return FALSE; +} + +// overloaded >= operator, is a1 > a2 +int operator>=( const Address &lhs,const Address &rhs) +{ + if (( lhs > rhs) || ( lhs == rhs)) + return TRUE; + else + return FALSE; +} + +// overloaded < operator, is a1 <= a2 +int operator<=( const Address &lhs,const Address &rhs) +{ + if (( lhs < rhs) || ( lhs == rhs)) + return TRUE; + else + return FALSE; + +} + + +//----------------------------------------------------------------- +// overloaded < operator, is a1 < a2 +int operator<( const Address &lhs, const Address &rhs) +{ + if ( strcmp( (const char*) lhs, (const char*)rhs)<0) + return TRUE; + else + return FALSE; +} + +//------------------------------------------------------------------ +// equivlence operator overloaded, are an address and a string equal? +int operator==( const Address &lhs,const char *rhs) +{ + if (!rhs && !lhs.valid()) + return TRUE; + if (strcmp( (const char *) lhs, rhs)== 0) + return TRUE; + else + return FALSE; +} + +//------------------------------------------------------------------ +// not equal operator overloaded, are an address and a string not equal? +int operator!=( const Address &lhs,const char *rhs) +{ + return (!( lhs == rhs)); +} + +//------------------------------------------------------------------ +// overloaded > , is a > inaddr +int operator>( const Address &lhs,const char *rhs) +{ + if (!rhs) + return lhs.valid(); // if lhs valid then > NULL, else invalid !> NULL + if (strcmp( (const char *) lhs, rhs)> 0) + return TRUE; + else + return FALSE; +} + +//------------------------------------------------------------------ +// overloaded >= , is a >= inaddr +int operator>=( const Address &lhs,const char *rhs) +{ + if (!rhs) + return TRUE; // always >= NULL + if (strcmp( (const char *) lhs, rhs)>= 0) + return TRUE; + else + return FALSE; +} + +//----------------------------------------------------------------- +// overloaded < , are an address and a string equal? +int operator<( const Address &lhs,const char *rhs) +{ + if (!rhs) + return FALSE; // always >= NULL + if (strcmp( (const char *) lhs, rhs)< 0) + return TRUE; + else + return FALSE; +} + +//----------------------------------------------------------------- +// overloaded <= , is a <= inaddr +int operator<=( const Address &lhs,const char *rhs) +{ + if (!rhs) + return !lhs.valid(); // invalid == NULL, else valid > NULL + if (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) +{ + // 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) { + // copy the address data + ACE_OS::memcpy(address_buffer, ipaddr.address_buffer,IPV4LEN); + // and the friendly name + 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 = FALSE; + 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 = FALSE; + 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 FALSE; +} + +int IpAddress::is_multicast() const +{ + if (valid()) { + return (IN_MULTICAST(*(u_long *)&address_buffer)); + } + return FALSE; +} + +// The old ARPA net used 10.x.x.x. But now it is not assignable in the Internet +// even though it is no longer used. Some companies use it +// internally and apply NAT to allow translation instead of paying for +// ip networks. Cisco IOS can provide NAT or 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_arpanet() const +{ + if (valid()) { + return (address_buffer[0] == 10); + } + return FALSE; +} + +int IpAddress::is_broadcast() const +{ + if (valid()) { + return ( (*(u_long *)&address_buffer) & INADDR_BROADCAST); + } + return FALSE; +} + +//-----[ 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 TRUE 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 friendly name ]---------------------------------- +char *IpAddress::friendly_name(int &status) +{ + if ((iv_friendly_name[0]==0) && (valid_flag)) + this->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 = FALSE; + 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 FALSE; + ACE_OS::strcpy( temp, inaddr); + trim_white_space( temp); + if ( ACE_OS::strlen( temp) > 15) + return FALSE; + + // 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 FALSE; + + // look for dot token separator + ip_token = strtok( (char *) temp,"."); + + // while more tokens.. + while ( ip_token != NULL) { + // verify that the token is all numerics + w = ACE_OS::strlen( ip_token); + if (w>3) + return FALSE; + for (z=0;z<w;z++) + if (( ip_token[z] < '0') || ( ip_token[z] > '9')) + return FALSE; + + value = ( unsigned int) strtod(ip_token,NULL); + if (( value > 0)&& ( value <=255)) + address_buffer[token_count] = (unsigned char) value; + else + if ( strcmp(ip_token,"0")==0) + address_buffer[token_count]= (unsigned char) 0; + else + error_status = TRUE; + token_count++; + ip_token = strtok( NULL, "."); + } + + // gota be four in len + if ( token_count != 4) + return FALSE; + + // any parsing errors? + if ( error_status) + return FALSE; + + return TRUE; +} + +//-----[ 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; + hostent *lookupResult; + char *namePtr = NULL; + 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 + return TRUE; + } + else { + // not a dotted string, try to resolve it via DNS + // if its an ipx or a mac then get out + // and don't do DNS + IpxAddress ipxtest( inaddr); + if ( ipxtest.valid()) + return FALSE; + + MacAddress mactest( inaddr); + if ( mactest.valid()) + return FALSE; + + 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 FALSE; + + // save the friendly name + ACE_OS::strcpy( iv_friendly_name, inaddr); + return TRUE; + + } // end if lookup result + else { + iv_friendly_name_status = rc; + return FALSE; + } + } // end else not a dotted string + return TRUE; +} + +// using the currently defined address, do a DNS +// and try to fill up the name +int IpAddress::addr_to_friendly() +{ + in_addr ipAddr; + char *namePtr = NULL; + char ds[MAXHOSTNAMELEN + 1]; + + // can't look up an invalid address + if ( !valid_flag) + return -1; + + // otherwise lets look it up + // lets try and get the friendly name + // from the DNS + ACE_OS::strncpy( ds, IpAddress::to_string(), MAXHOSTNAMELEN); + + if ((ipAddr.s_addr = ACE_OS::inet_addr((char *) ds)) == -1) + return -1; // bad address + + // if we found the name, then update the + // iv friendly name + if (resolve_to_hostname(ipAddr, iv_friendly_name) == 0) { + return 0; + } + else { + iv_friendly_name_status = h_errno; + 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; + + if (ACE_OS::gethostbyaddr_r((const char *)&quad_addr.s_addr, IPV4LEN, + AF_INET, &lookupResult, buffer, &loc_errno)) { + ACE_OS::strcpy( hostname, lookupResult.h_name); + return 0; + } + + 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; + int loc_errno = 0; + if (ACE_OS::gethostbyname_r ( hostname, &lookupResult, buffer, &loc_errno)) { + if (lookupResult.h_length == sizeof(in_addr)) { + 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 ]-------------------------- +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(); + } + +} + + +//======================================================================= +//========== 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 = FALSE; + + // 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 TRUE 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 = FALSE; + return FALSE; + } + // 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==NULL) + tmp = ACE_OS::strstr(buffer,"/"); + + if ( tmp != NULL) { + *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 ]-------------------------- +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=FALSE; + 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) +{ + // 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 = FALSE; + // 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() +{ +} + +char *NetbiosAddress::to_string() +{ + return (char *)output_buffer; +} + +NetbiosAddress& NetbiosAddress::operator=( const NetbiosAddress &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + valid_flag = 0; // will set to TRUE 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(); +} + +char *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 TRUE 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=FALSE; + 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) +{ + // 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 = FALSE; + // 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 TRUE 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 TRUE or FALSE +// +// 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 FALSE; + 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 FALSE; + + // 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 FALSE; + + // 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 FALSE; + + // check len of mac portion + if ( ACE_OS::strlen( (char *) str2) != 12) + return FALSE; + + // 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 FALSE; + + // 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 FALSE; + + // 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 TRUE; +} + +//----[ IPX address char * cast ]-------------------------------------- +IpxAddress::operator const char *() const +{ + return (char *)output_buffer; +} + +//----[ IPX address get char representation ]-------------------------- +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 TRUE; + else + return FALSE; + } + else + return FALSE; +} + + +//------[ return the type ]---------------------------------- +addr_type IpxAddress::get_type() const +{ + return type_ipx; +} + + +//======================================================================== +//======== 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 = FALSE; + 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 TRUE 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 ]-------------------------- +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 = FALSE; + return FALSE; + } + // 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 != NULL) + { + *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) +{ + // 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=FALSE; + 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 = FALSE; + // 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 TRUE 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 TRUE or FALSE +// +// 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 FALSE; + ACE_OS::strcpy( temp, inaddr); + trim_white_space( temp); + + // bad total length check + if ( ACE_OS::strlen(temp) != 17) + return FALSE; + + // check for colons + if ((temp[2] != ':')||(temp[5] != ':')||(temp[8]!=':')||(temp[11]!=':') + ||(temp[14] !=':')) + return FALSE; + + // 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 FALSE; + + // 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 TRUE; +} + +//----[ MAC address char * cast ]-------------------------------------- +MacAddress::operator const char *() const +{ + return (char *)output_buffer; +} +//----[ MAC address get char representation ]-------------------------- +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]) * HASH0) + + (((address_buffer[2] << 8) + address_buffer[3]) * HASH1) + + (((address_buffer[4] << 8) + address_buffer[5]) * HASH2)); +} + +//======================================================================== +//========== Generic Address Implementation ============================== +//======================================================================== + +//-----------[ get the syntax]---------------------------------------------- +SmiUINT32 GenAddress::get_syntax() +{ + if (address != 0) + return address->get_syntax(); + + return sNMP_SYNTAX_NULL; +} + +//-----------[ constructor with a string argument ]---------------------- +GenAddress::GenAddress( const char *addr) +{ + if (ACE_OS::strlen(addr) == 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. + smival.syntax = sNMP_SYNTAX_NULL; // to be overridden + smival.value.string.len = 0; // to be overridden + smival.value.string.ptr = address_buffer; // constant + + valid_flag = FALSE; + address = 0; + format_output(); + return; + } + + // 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. + smival.syntax = sNMP_SYNTAX_NULL; // to be overridden + smival.value.string.len = 0; // to be overridden + smival.value.string.ptr = address_buffer; // constant + + address = 0; + 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) +{ + // 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. + smival.syntax = sNMP_SYNTAX_NULL; // to be overridden + smival.value.string.len = 0; // to be overridden + smival.value.string.ptr = address_buffer; // constant + + valid_flag = FALSE; + // make sure that the object is valid + if (!addr.valid()) { + address = 0; + 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) +{ + + // 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. + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = 0; + smival.value.string.ptr = address_buffer; + + valid_flag = FALSE; + // make sure that the object is valid + if (!addr.valid_flag) { + address = 0; + 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 = FALSE; + 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 = FALSE; // will get set to TRUE 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]. + // 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! + 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); + } + 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 +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 TRUE; // 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 TRUE; // 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 TRUE; // 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 TRUE; // 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 TRUE; // ok, its a mac + } + // otherwise its invalid + delete address; + address = 0; + format_output(); + return FALSE; +} + +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 +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(); +} + diff --git a/ASNMP/asnmp/address.h b/ASNMP/asnmp/address.h new file mode 100644 index 00000000000..f2190e7c5c7 --- /dev/null +++ b/ASNMP/asnmp/address.h @@ -0,0 +1,642 @@ +/* -*-C++-*- */ +#ifndef ADDRESS_ +#define ADDRESS_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// address.h +// +// = DESCRIPTION +// 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.h" +#include "asnmp/smival.h" + +//----[ enumerated types ] -------------------------------- +enum address_lengths { + IPV4LEN=4, + UDPIPV4LEN=6, + IPV6LEN=16, + UDPIPV6LEN=18, + NETBIOSLEN=16, + IPXLEN=10, + IPXSOCKLEN=12, + MACLEN=6, + HASH0=19, + HASH1=13, + HASH2=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_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 ACE_Export Address: public SnmpSyntax + // = TITLE + // Defines the member functions for the abstract base class + // Address. An Address is a unique network endpoint. +{ + +public: + virtual ~Address(); + // allow destruction of derived classes + + friend int operator==( const Address &lhs,const Address &rhs); + // overloaded equivlence operator, are two addresses equal? + + friend int operator!=( const Address &lhs,const Address &rhs); + // overloaded not equivlence operator, are two addresses not equal? + + friend int operator>( const Address &lhs,const Address &rhs); + // overloaded > operator, is a1 > a2 + + friend int operator>=( const Address &lhs,const Address &rhs); + // overloaded >= operator, is a1 >= a2 + + friend int operator<( const Address &lhs,const Address &rhs); + // overloaded < operator, is a1 < a2 + + friend int operator<=( const Address &lhs,const Address &rhs); + // overloaded <= operator, is a1 <= a2 + + friend int operator==( const Address &lhs,const char *rhs); + // equivlence operator overloaded, are an address and a string equal? + + friend int operator!=( const Address &lhs,const char *rhs); + // overloaded not equivlence operator, are an address and string not equal? + + friend int operator>( const Address &lhs,const char *rhs); + // overloaded < , is an address greater than a string? + + friend int operator>=( const Address &lhs,const char *rhs); + // overloaded >=, is an address greater than or equal to a string? + + friend int operator<( const Address &lhs,const char *rhs); + // overloaded < , is an address less than a string? + + friend int operator<=( const Address &lhs,const char *rhs); + // overloaded <=, is an address less than or equal to a string? + + virtual operator const char *() const = 0; + // overloaded const char * cast + + virtual int valid() const; + // verify the is the address object constructed ok + + virtual SmiUINT32 get_syntax() = 0; + // (pure virtual) syntax type + + unsigned char& operator[]( const int position); + // for non const [], allows reading and writing + + virtual char *to_string() = 0; + // get a printable ASCII value + + virtual SnmpSyntax *clone() const = 0; + // create a new instance of this Value + + virtual addr_type get_type() const = 0; + // return the type of address + + virtual SnmpSyntax& operator=( SnmpSyntax &val) = 0; + // overloaded assignment operator + + virtual unsigned int hashFunction() const { return 0;}; + // return a hash key + +protected: + int valid_flag; + // state of constructed object (TRUE/FALSE) + unsigned char address_buffer[MAX_ADDR_SZ]; + // addr internal representation + + virtual int parse_address( const char * inaddr) =0; + // parse the address string + // redefined for each specific address subclass + + virtual void format_output() =0; + // format the output + // redefined for each specific address subclass + + void trim_white_space( char * ptr); + // a reused trimm white space method +}; + + +//----------------------------------------------------------------------- +//---------[ IPv4 Address Class ]---------------------------------------- +//----------------------------------------------------------------------- +class ACE_Export IpAddress : public Address + // = TITLE + // 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. +{ +public: + IpAddress( const char *inaddr = ""); + // default construct an IP address with a string + + IpAddress( const IpAddress &ipaddr); + // construct an IP address with another IP address + + IpAddress( const GenAddress &genaddr); + // construct an IP address with a GenAddress + + ~IpAddress(); + // destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden) + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + + IpAddress& operator=( const IpAddress &ipaddress); + // assignment to another IpAddress object overloaded + + SnmpSyntax *clone() const; + // create a new instance of this Value + + char *friendly_name(int &status); + // return the friendly name + // returns a NULL string if there isn't one + + virtual char *to_string() ; + // return string representation of object + + virtual operator const char *() const; + // const char * operator overloaded for streaming output + + void mask( const IpAddress& ipaddr); + // logically AND two IPaddresses and + // return the new one + + virtual addr_type get_type() const; + // return the type + + virtual SmiUINT32 get_syntax(); + // syntax type + + int is_loopback() const; + // is this the loopback address? 127.0.0.1/loopback/1.0.0.127.in-addr.arpa + + int is_multicast() const; + // determine if this is a multicast address + + int is_broadcast() const; + // determine if this a broadcast address + + int is_arpanet() const; + // determine if this is ip network 10.x.x.x + +protected: + char output_buffer[MAX_DISPLAY_SZ]; // output buffer + + char iv_friendly_name[MAX_DISPLAY_SZ]; + // friendly name storage + + int iv_friendly_name_status; + // did resolver call work? some addrs won't resolve + + virtual int parse_address( const char *inaddr); + // redefined parse address + // specific to IP addresses + + virtual void format_output(); + // redefined format output + // specific to IP addresses + + int parse_dotted_ipstring( const char *inaddr); + // parse a dotted string + + int addr_to_friendly(); + // using the currently defined address, do a gethostbyname() + // and try to fill up the name + + static int resolve_to_address(const char *hostname, in_addr& quad_addr); + // thread safe routine to lookup ip address given hostname + // return <> 0 on error + + static int resolve_to_hostname(const in_addr& quad_addr, char *hostname); + // thread safe routine to lookup name given ip address + // return <> 0 on error +}; + +//------------------------------------------------------------------------ +//---------[ UDP/IPv4 Address Class ]------------------------------------- +//------------------------------------------------------------------------ +class ACE_Export UdpAddress : public IpAddress + // = TITLE + // 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 +{ +public: + UdpAddress( const char *inaddr = ""); + // default constructor with a dotted string in the form of addr:port + + UdpAddress( const UdpAddress &udpaddr); + // construct an Udp address with another Udp address + + UdpAddress( const GenAddress &genaddr); + // construct a Udp address with a GenAddress + + UdpAddress( const IpAddress &ipaddr); + // construct a Udp address with an IpAddress + // default port # to zero + + ~UdpAddress(); + // destructor + + SmiUINT32 get_syntax(); + // syntax type + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + + UdpAddress& operator=( const UdpAddress &udpaddr); + // assignment to another IpAddress object overloaded + + SnmpSyntax *clone() const; + // create a new instance of this Value + + virtual char *to_string() ; + // output in the form of address:port + + virtual operator const char *() const; + // const char * operator overloaded for streaming output + + void set_port( const unsigned short p); + // set the port number + + unsigned short get_port() const; + // get the port number + + virtual addr_type get_type() const; + // return the type + +protected: + char output_buffer[MAX_DISPLAY_SZ]; + // output buffer + + virtual int parse_address( const char *inaddr); + // redefined parse address + // specific to IP addresses + + virtual void format_output(); + // redefined format output + // specific to IP addresses +}; + + +//------------------------------------------------------------------------- +//---------[ 802.3 MAC Address Class ]------------------------------------- +//------------------------------------------------------------------------- +class ACE_Export MacAddress : public Address + // = TITLE + // 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. +{ +public: + MacAddress( const char *inaddr = ""); + // constructor with a string argument + + MacAddress( const MacAddress &macaddr); + // constructor with another MAC object + + MacAddress( const GenAddress &genaddr); + // construct a MacAddress with a GenAddress + + ~MacAddress(); + // destructor + + SmiUINT32 get_syntax(); + // syntax type + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + + MacAddress& operator=( const MacAddress &macaddress); + // assignment to another IpAddress object overloaded + + SnmpSyntax *clone() const; + // create a new instance of this Value + + virtual char *to_string(); + // create a string to internal class storage representing object + + virtual operator const char *() const; + // const char * operator overloaded for streaming output + + virtual addr_type get_type() const; + // return the type + + unsigned int hashFunction() const; + // return a hash key + + +protected: + char output_buffer[MAX_DISPLAY_SZ]; + // output buffer containing string representation of object + + virtual int parse_address( const char *inaddr); + // redefined parse address for macs + + virtual void format_output(); + // redefined format output for MACs +}; + +//------------------------------------------------------------------------ +//---------[ Netbios Address Class ]-------------------------------------- +//------------------------------------------------------------------------ +class ACE_Export NetbiosAddress : public Address + // = TITLE + // Defines the member functions for the concrete class NetbiosAddress. + // The IBM/Microsoft address for NETBIOS, NETBEUI protocol tranport. +{ +public: + + NetbiosAddress( const char *inaddr = ""); + // default constructor with string arg + + NetbiosAddress( const char *inaddr, nb_service svc); + // set name and service type + + NetbiosAddress( const NetbiosAddress& nbaddr); + // copy constructor + + NetbiosAddress( const GenAddress& genaddr); + // construct with a GenAddress + + ~NetbiosAddress(); + + virtual char *to_string(); + + NetbiosAddress& operator=( const NetbiosAddress &nbaddr); + + nb_service get_service_type() const; + // retrieve the network service type + + void set_service_type(nb_service nbservice); + // set the service type (workstation, server, etc) + + virtual operator const char *() const; + // const char * operator overloaded for streaming output + + virtual SmiUINT32 get_syntax(); + // syntax type + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + + SnmpSyntax *clone() const; + // create a new instance of this Value + +protected: + void InitNBAddr(const char *inaddr); + char output_buffer[MAX_DISPLAY_SZ]; + + virtual void format_output(); + // output buffer to hold string representation + virtual int parse_address( const char *inaddr); + virtual addr_type get_type() const; +}; + +//------------------------------------------------------------------------ +//---------[ IPX Address Class ]------------------------------------------ +//------------------------------------------------------------------------ +class ACE_Export IpxAddress : public Address + // = TITLE + // Defines the member functions for the concrete class IpxAddress. + // Novell's IPX (version ?) network protocol endpoint +{ +public: + IpxAddress( const char *inaddr = ""); + // default constructor with a string arg + + IpxAddress( const IpxAddress &ipxaddr); + // constructor with another ipx object + + IpxAddress( const GenAddress &genaddr); + // construct with a GenAddress + + ~IpxAddress(); + // destructor + + virtual SmiUINT32 get_syntax(); + // syntax type + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + + IpxAddress& operator=( const IpxAddress &ipxaddress); + // assignment to another IpAddress object overloaded + + int get_hostid( MacAddress& mac); + // get the host id portion of an ipx address + + SnmpSyntax *clone() const; + // create a new instance of this Value + + virtual char *to_string(); + // create string represtation of object value + + virtual operator const char *() const; + // const char * operator overloaded for streaming output + + virtual addr_type get_type() const; + // return the type + +protected: + char separator; + // ipx format separator {:,/} + + char output_buffer[MAX_DISPLAY_SZ]; + // output buffer to hold string representation + + virtual int parse_address( const char *inaddr); + // redefined parse address for ipx strings + + virtual void format_output(); + // redefined format output for ipx strings + // uses same separator as when constructed +}; + + + +//------------------------------------------------------------------------ +//---------[ IpxSock Address Class ]-------------------------------------- +//------------------------------------------------------------------------ +class ACE_Export IpxSockAddress : public IpxAddress + // = TITLE + // Defines the member functions for the concrete class IpxAddress. + // Novell's IPX (version ?) network protocol endpoint +{ +public: + IpxSockAddress( const char *inaddr = ""); + // constructor with a dotted string + + IpxSockAddress( const IpxSockAddress &ipxaddr); + // construct an Udp address with another Udp address + + IpxSockAddress( const GenAddress &genaddr); + //constructor with a GenAddress + + IpxSockAddress( const IpxAddress &ipxaddr); + //constructor with a IpxAddress + // default socket # is 0 + + ~IpxSockAddress(); + // destructor + + virtual SmiUINT32 get_syntax(); + // syntax type + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + + IpxSockAddress& operator=( const IpxSockAddress &ipxaddr); + // assignment to another IpAddress object overloaded + + SnmpSyntax *clone() const; + // create a new instance of this Value + + void set_socket( const unsigned short s); + // set the socket number + + unsigned short get_socket() const; + // get the socket number + + virtual char *to_string(); + // create string representation of object value + + virtual operator const char *() const; + // const char * operator overloaded for streaming output + + virtual addr_type get_type() const; + // return the type + +protected: + char output_buffer[MAX_DISPLAY_SZ]; + // output buffer to hold string representation of object + + virtual int parse_address( const char *inaddr); + // redefined parse address for ipx strings + + virtual void format_output(); + // redefined format output + // specific to IP addresses +}; + +//------------------------------------------------------------------------- +//--------[ Generic Address ]---------------------------------------------- +//------------------------------------------------------------------------- +class ACE_Export GenAddress : public Address + // = TITLE + // Defines the member functions for the concrete class GenAddress. + // This class attempts to determine an address type given a char string. +{ +public: + GenAddress( const char *addr = ""); + // constructor with a string argument + + GenAddress( const Address &addr); + // constructor with an Address + + GenAddress( const GenAddress &addr); + // constructor with another GenAddress + + ~GenAddress(); + // destructor + + SmiUINT32 get_syntax(); + // get the snmp syntax of the contained address + + SnmpSyntax *clone() const; + // create a new instance of this Value + + GenAddress& operator=( const GenAddress &addr); + // assignment of a GenAddress + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + + virtual char *to_string(); + // string representation of object value + + virtual operator const char *() const; + // const char * operator overloaded for streaming output + + virtual addr_type get_type() const; + // return the type + +protected: + Address *address; + // pointer to a a concrete address + + char output_buffer[MAX_DISPLAY_SZ]; + // output buffer of objects value + + virtual int parse_address( const char *addr); + // redefined parse address for macs + + virtual void format_output(); + // format output for a generic address +}; + +#endif //_ADDRESS diff --git a/ASNMP/asnmp/asn1.cpp b/ASNMP/asnmp/asn1.cpp new file mode 100644 index 00000000000..ee17210d1e3 --- /dev/null +++ b/ASNMP/asnmp/asn1.cpp @@ -0,0 +1,1730 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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" + +/* + * 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 NULL 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 NULL; + } + *type = *bufp++; + bufp =asn1::parse_length(bufp, &asn_length); + if (bufp == NULL){ + ASNERROR("bad length"); + return NULL; + } + if ((int)(asn_length + (bufp - data)) > *datalength){ + ASNERROR("overflow of message"); + return NULL; + } + if ((int)asn_length > intsize){ + ASNERROR("I don't support such large integers"); + return NULL; + } + *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 NULL 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 NULL; + } + *type = *bufp++; + bufp = asn1::parse_length(bufp, &asn_length); + if (bufp == NULL){ + ASNERROR("bad length"); + return NULL; + } + if ((int)(asn_length + (bufp - data)) > *datalength){ + ASNERROR("overflow of message"); + return NULL; + } + if (((int)asn_length > (intsize + 1)) || + (((int)asn_length == intsize + 1) && *bufp != 0x00)){ + ASNERROR("I don't support such large integers"); + return NULL; + } + *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 NULL 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 NULL; + 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 = 0x1FF << ((8 * (sizeof(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 == NULL) + return NULL; + if (*datalength < intsize) + return NULL; + *datalength -= intsize; + mask = 0xFF << (8 * (sizeof(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 NULL 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 NULL; + integer = *intp; + mask = 0xFF << (8 * (sizeof(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 = 0x1FF << ((8 * (sizeof(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 == NULL) + return NULL; + if (*datalength < intsize) + return NULL; + *datalength -= intsize; + if (add_null_byte == 1){ + *data++ = '\0'; + intsize--; + } + mask = 0xFF << (8 * (sizeof(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 NULL 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 == NULL) + return NULL; + if ((int)(asn_length + (bufp - data)) > *datalength){ + ASNERROR("overflow of message"); + return NULL; + } + if ((int)asn_length > *strlength){ + ASNERROR("I don't support such long strings"); + return NULL; + } + // 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 NULL 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 == NULL) + return NULL; + if (*datalength < strlength) + return NULL; + // 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 NULL 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 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 NULL; + } + *type = *bufp; + bufp = asn1::parse_length(bufp + 1, &asn_length); + if (bufp == NULL) + return NULL; + header_len = bufp - data; + if ((int)(header_len + asn_length) > *datalength){ + ASNERROR("asn length too long"); + return NULL; + } + *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 NULL 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 NULL; + *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 NULL 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 NULL; + } + *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 NULL 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 NULL; + } + if (lengthbyte > sizeof(long)){ + ASNERROR("we can't support data lengths that long"); + return NULL; + } + // 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 NULL; + } + *data++ = (u_char)length; + } else if (length <= 0xFF){ + if (*datalength < 2){ + ASNERROR("build_length"); + return NULL; + } + *data++ = (u_char)(0x01 | ASN_LONG_LEN); + *data++ = (u_char)length; + } else { /* 0xFF < length <= 0xFFFF */ + if (*datalength < 3){ + ASNERROR("build_length"); + return NULL; + } + *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 NULL 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 == NULL) + return NULL; + if ((int)asn_length + (bufp - data) > *datalength){ + ASNERROR("overflow of message"); + return NULL; + } + *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 NULL; + } + *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 NULL 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 == NULL) + return NULL; + if (*datalength < asnlength) + return NULL; + // 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 NULL 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 == NULL) + return NULL; + if (asn_length != 0){ + ASNERROR("Malformed NULL"); + return NULL; + } + *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 NULL 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 NULL 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 == NULL) + return NULL; + if ((int)(asn_length + (bufp - data)) > *datalength){ + ASNERROR("overflow of message"); + return NULL; + } + if ((int) asn_length > *strlength){ + ASNERROR("I don't support such long bitstrings"); + return NULL; + } + if (asn_length < 1){ + ASNERROR("Invalid bitstring"); + return NULL; + } + if (*bufp < 0 || *bufp > 7){ + ASNERROR("Invalid bitstring"); + return NULL; + } + // 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 NULL 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 < 0 || *string > 7){ + ASNERROR("Building invalid bitstring"); + return NULL; + } + data = asn1::build_header(data, datalength, type, strlength); + if (data == NULL) + return NULL; + if (*datalength < strlength) + return NULL; + // 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 NULL 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 NULL; + } + *type = *bufp++; + bufp = asn1::parse_length(bufp, &asn_length); + if (bufp == NULL){ + ASNERROR("bad length"); + return NULL; + } + if ((int)(asn_length + (bufp - data)) > *datalength){ + ASNERROR("overflow of message"); + return NULL; + } + if (((int)asn_length > (intsize * 2 + 1)) || + (((int)asn_length == (intsize * 2) + 1) && *bufp != 0x00)){ + ASNERROR("I don't support such large integers"); + return NULL; + } + *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 NULL 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 NULL; + intsize = 8; + low = cp->low; + high = cp->high; + mask = 0xFF << (8 * (sizeof(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 = 0x1FF << ((8 * (sizeof(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 == NULL) + return NULL; + if (*datalength < intsize) + return NULL; + *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 = NULL; + pdu->enterprise_length = 0; + pdu->variables = NULL; + 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; + + // if we don't have a vb list ,create one + if (pdu->variables == NULL) { + 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 = NULL; + + // hook in the Oid portion + ACE_NEW(vars->name, oid[(name_length * sizeof(oid))]); + + // 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 = NULL; + 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 == NULL){ + ASNERROR("buildheader"); + return NULL; + } + data = asn1::build_int(data, + length, + (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), + (long *)&version, + sizeof(version)); + if (data == NULL){ + ASNERROR("buildint"); + return NULL; + } + + data = asn1::build_string(data, + length, + (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR), + params, + plen ); + if (data == NULL){ + ASNERROR("buildstring"); + return NULL; + } + + 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 NULL; + + 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 == NULL) { + ASNERROR(""); + return NULL; + } + + // 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 NULL; + } + if (data == NULL) { + ASNERROR(""); + return NULL; + } + 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; + long int zero = 0; + 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 == NULL) + 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 == NULL) + 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 == NULL) + 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 == NULL) + 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 == NULL) + 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 == NULL) + return -1; + + // agent-addr + cp = asn1::build_string(cp, + &length, + (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 == NULL) + 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 == NULL) + 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 == NULL) + return -1; + + // timestamp + cp = asn1::build_int(cp, + &length, + (u_char )(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), + (long *)&pdu->time, + sizeof(pdu->time)); + if (cp == NULL) + 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 == NULL) + 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 == NULL) + 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 == NULL){ + ASNERROR("bad header"); + return NULL; + } + + if (type != (ASN_SEQUENCE | ASN_CONSTRUCTOR)) { + ASNERROR("wrong auth header type"); + return NULL; + } + + // get the version + data = asn1::parse_int(data, length, &type, version, sizeof(*version)); + if (data == NULL) { + ASNERROR("bad parse of version"); + return NULL; + } + + // get the community name + data = asn1::parse_string(data, length, &type, sid, slen); + if (data == NULL) { + ASNERROR("bad parse of community"); + return NULL; + } + + 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 == NULL){ + ASNERROR(""); + return NULL; + } + if (var_op_type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)) + return NULL; + data = asn1::parse_objid(data, &var_op_len, &var_op_type, var_name, var_name_len); + if (data == NULL) { + ASNERROR(""); + return NULL; + } + if (var_op_type != (u_char) + (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID)) + return NULL; + *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 == NULL) { + ASNERROR(""); + return NULL; + } + *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; + oid objid[MAX_NAME_LEN], *op; + u_char *origdata = data; + int origlength = length; + u_char *save_data; + + // authenticates message and returns length if valid + data = cmu_snmp::auth_parse(data, + &length, + community, + &community_length, + &version); + if (data == NULL) + 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; + + save_data = data; + + data = asn1::parse_header(data, + &length, + &msg_type); + if (data == NULL) + 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 == NULL) + return -1; + // get the error status + data = asn1::parse_int(data, + &length, + &type, + (long *)&pdu->errstat, + sizeof(pdu->errstat)); + if (data == NULL) + return -1; + // get the error index + data = asn1::parse_int(data, + &length, + &type, + (long *)&pdu->errindex, + sizeof(pdu->errindex)); + if (data == NULL) + 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 == NULL) + 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 == NULL) + return -1; + + // get trap type + data = asn1::parse_int(data, &length, &type, (long *)&pdu->trap_type, + sizeof(pdu->trap_type)); + if (data == NULL) + return -1; + + // trap type + data = asn1::parse_int(data, &length, &type, (long *)&pdu->specific_type, + sizeof(pdu->specific_type)); + if (data == NULL) + return -1; + + // timestamp + data = asn1::parse_int(data, &length, &type, (long *)&pdu->time, + sizeof(pdu->time)); + if (data == NULL) + return -1; + } + + // get the vb list + data = asn1::parse_header(data, &length, &type); + if (data == NULL) + return -1; + + if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)) + return -1; + + while((int)length > 0) { + if (pdu->variables == NULL) { + 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 = NULL; + vp->val.string = NULL; + vp->name = NULL; + 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 == NULL) + 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); + 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/ASNMP/asnmp/asn1.h b/ASNMP/asnmp/asn1.h new file mode 100644 index 00000000000..d1a644e8890 --- /dev/null +++ b/ASNMP/asnmp/asn1.h @@ -0,0 +1,336 @@ +/* -*-C++-*- */ +#ifndef ASN1 +#define ASN1 +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// asn1.h +// +// = DESCRIPTION +// 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/OS.h" +#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; // NULL 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 ACE_Export asn1 + // = TITLE + // Defines the member functions for the asn1 concrete interface class + // CMU routines for performing ASN.1 data marshalling / representation + +{ +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 ACE_Export cmu_snmp + // = TITLE + // Defines the static functions for the cmu_snmp concrete class. + // These routine create cmu pdu's that can be sent/received on/from agents +{ + 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/ASNMP/asnmp/collect.h b/ASNMP/asnmp/collect.h new file mode 100644 index 00000000000..f2d416806b9 --- /dev/null +++ b/ASNMP/asnmp/collect.h @@ -0,0 +1,370 @@ +/* -*-C++-*- */ +#ifndef _COLLECTION +#define _COLLECTION +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// collect.h +// +// = DESCRIPTION +// 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. +=====================================================================*/ + + + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define MAXT 25 // elements per block + + +#ifdef WIN32 +template <class T> class SnmpCollection +{ + class cBlock + { + public: + T *item[MAXT]; + cBlock *next; + cBlock *prev; + }; + +public: + + // create an empty collection + SnmpCollection( void):count(0) + { + data.next=0; + data.prev=0; + }; + + + // create a collection using a single template object + SnmpCollection( const T &t):count( 1) + { + data.item[0] = new T( t); + data.next=0; + data.prev=0; + }; + + // create a collection with another collection + // copy constructor + SnmpCollection( const SnmpCollection<T> &c) + { + count = 0; + data.next=0; + data.prev=0; + + if ( c.count == 0) { + count = 0; + return; + } + + // load up the new collection + cBlock *current = &data; + cBlock *nextBlock; + int cn = 0; + count = 0; + while ( count < c.count) { + if ( cn >= MAXT) { + nextBlock = new cBlock; + nextBlock->prev = current; + nextBlock->next = 0; + current->next = nextBlock; + current = nextBlock; + cn=0; + } + current->item[cn] = new T(c[count]); + count++; + cn++; + } + }; + + // destroy the collection + ~SnmpCollection() + { + if ( count == 0) + return; + + // delete the data + cBlock *current = &data; + int z=0; + int cn=0; + while ( z< count) { + if (cn >= MAXT) { + cn =0; + current = current->next; + } + delete current->item[cn]; + cn++; + z++; + } + + + // delete the blocks + while ( current->next != 0) + current = current->next; + while ( current->prev != 0) { + current = current->prev; + delete current->next; + } + + }; + + // get the size of the collection + int size() + { + return count; + }; + + // append an item to the collection + SnmpCollection& operator +=( const T &i) + { + + cBlock *current = &data; + cBlock *add; + int cn = (int) count % MAXT; + while (current->next != 0) + current = current->next; + if ((count > 0) && ((count % MAXT)== 0)) { + add = new cBlock; + current->next = add; + add->prev = current; + add->next = 0; + add->item[0] = new T(i); + } + else { + current->item[cn] = new T(i); + cn++; + } + count++; + + return *this; + }; + + + // assign one collection to another + SnmpCollection & operator = ( const SnmpCollection<T> &c) + { + + // delete the data + cBlock *current = &data; + int z=0; + int cn=0; + while ( z< count) { + if (cn >= MAXT) { + cn =0; + current = current->next; + } + delete current->item[cn]; + cn++; + z++; + } + // delete the blocks + while ( current->next != 0) + current = current->next; + while ( current->prev != 0) { + current = current->prev; + delete current->next; + } + count=0; + + if ( c.count ==0) + return *this; + + + // load up the new collection + current = &data; + cBlock *nextBlock; + cn = 0; + count = 0; + while ( count < c.count) { + if ( cn >= MAXT) { + nextBlock = new cBlock; + nextBlock->prev = current; + nextBlock->next = 0; + current->next = nextBlock; + current = nextBlock; + cn=0; + } + current->item[cn] = new T( c[count]); + count++; + cn++; + } + + return *this; + }; + + // access an element in the collection + T operator[]( int p) const + { + if (p<count) { + cBlock const *current = &data; + int bn = (int) (p / MAXT); + for (int z=0; z<bn; z++) + current = current->next; + int cn = (int) p % MAXT; + return (T) *(current->item[cn]); + } + else { // return an instance of nothing!! + T t; + return (T) (t); + } + + }; + + // set an element in the collection + int set_element( const T& i, const int p) + { + + cBlock *current = &data; + if ( p > count) + return -1; // not found! + int bn = (int) p / MAXT; + int cn = (int) p % MAXT; + for (int z=0; z<bn; z++) + current = current->next; + delete current->item[cn]; + current->item[cn] = new T(i); + return 0; + + }; + + // get an element in the collection + int get_element( T& i, const int p) const + { + + cBlock const *current = &data; + if ( p > count) + return -1; // not found! + int bn = (int) p / MAXT; + int cn = (int) p % MAXT; + for (int z=0; z<bn; z++) + current = current->next; + i = *(current->item[cn]); + return 0; + }; + + // apply an function to the entire collection, iterator + void apply( void f( T&)) + { + T temp; + for ( int z=0;z<count;z++) { + this->get_element( temp,z); + f( temp); + } + } + + // looks for an element in the collection + // returns TRUE if found + int find( const T& i) + { + T temp; + for ( int z=0;z<count;z++) { + this->get_element( temp,z); + if ( temp == i) + return TRUE; + } + return FALSE; + } + + +private: + int count; + cBlock data; + +}; // end template collection class def +#endif // end if WIN32 + +#ifdef __unix + +template <class T> class SnmpCollection +{ + + class cBlock { + public: + T *item[MAXT]; + cBlock *next; + cBlock *prev; + }; + +public: + + // create an empty collection + SnmpCollection( void); + + + // create a collection using a single template object + SnmpCollection( const T &t); + + // create a collection with another collection + // copy constructor + SnmpCollection( const SnmpCollection<T> &c); + + // destroy the collection + ~SnmpCollection(); + + // get the size of the collection + int size(); + + // append an item to the collection + SnmpCollection& operator +=( const T &i); + + // assign one collection to another + SnmpCollection & operator = ( const SnmpCollection<T> &c); + + // access an element in the collection + T operator[]( int p) const; + + // set an element in the collection + int set_element( const T& i, const int p); + + // get an element in the collection + int get_element( T& i, const int p) const; + + // apply an function to the entire collection, iterator + void apply( void f( T&)); + + // looks for an element in the collection + // returns TRUE if found + int find( const T& i); + +private: + int count; + cBlock data; + +}; // end template collection class def + +#endif // end if __unix + +#endif // end if _COLLECTION + diff --git a/ASNMP/asnmp/counter.cpp b/ASNMP/asnmp/counter.cpp new file mode 100644 index 00000000000..1dc36008fce --- /dev/null +++ b/ASNMP/asnmp/counter.cpp @@ -0,0 +1,104 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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" + +// constructor with a value +Counter32::Counter32( const unsigned long i):SnmpUInt32(i) +{ + smival.syntax = sNMP_SYNTAX_CNTR32; +} + +// copy constructor +Counter32::Counter32( const Counter32 &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/ASNMP/asnmp/counter.h b/ASNMP/asnmp/counter.h new file mode 100644 index 00000000000..368cf983c90 --- /dev/null +++ b/ASNMP/asnmp/counter.h @@ -0,0 +1,78 @@ +/* -*-C++-*- */ +#ifndef _COUNTER +#define _COUNTER +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// counter.h +// +// = DESCRIPTION +// 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 ACE_Export Counter32: public SnmpUInt32 + // = TITLE + // 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 +{ + public: + Counter32( const unsigned long i = 0); + // constructor with a value + + Counter32( const Counter32 &c); + // copy constructor + + SmiUINT32 get_syntax(); + // syntax type + + SnmpSyntax *clone() const; + // create a new instance of this Value + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + + Counter32& operator=( const Counter32 &uli); + // overloaded assignment + + Counter32& operator=( const unsigned long i); + // overloaded assignment + + operator unsigned long(); + // otherwise, behave like an unsigned long int +}; + +#endif // _COUNTER diff --git a/ASNMP/asnmp/ctr64.cpp b/ASNMP/asnmp/ctr64.cpp new file mode 100644 index 00000000000..30cb02bdd1c --- /dev/null +++ b/ASNMP/asnmp/ctr64.cpp @@ -0,0 +1,208 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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" + +#define MAX32 4294967295 + +//-----------[ 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( unsigned long long llw ) +{ + smival.syntax = sNMP_SYNTAX_CNTR64; + smival.value.hNumber.hipart = (unsigned long) llw >> 32; + smival.value.hNumber.lopart = (unsigned long) llw; +} + +//------------------[ copy constructor ]--------------------------------- +Counter64::Counter64( const Counter64 &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 unsigned long long 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 unsigned long long() +{ + unsigned long long 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 +char * Counter64::to_string() +{ + if ( high() != 0 ) + sprintf(output_buffer, "0x%X%08X", high(), low()); + else + sprintf(output_buffer, "%d", low()); + return output_buffer; +} + diff --git a/ASNMP/asnmp/ctr64.h b/ASNMP/asnmp/ctr64.h new file mode 100644 index 00000000000..f64bffce690 --- /dev/null +++ b/ASNMP/asnmp/ctr64.h @@ -0,0 +1,109 @@ +/* -*-C++-*- */ +#ifndef CTR64_ +#define CTR64_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// ctr64.h +// +// = DESCRIPTION +// 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" + +#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 ACE_Export Counter64: public SnmpSyntax + // = TITLE + // Defines the member functions for the Counter64 concrete class + // This class implements RFC 1902 64 bit Counter Object. +{ +public: + Counter64( unsigned long long llw = 0); + // default constructor + + Counter64( unsigned long hiparm, unsigned long loparm); + // constructor with values + + Counter64( const Counter64 &ctr64); + // copy constructor + + ~Counter64(); + // destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden) + + SmiUINT32 get_syntax(); + // syntax type + + long double to_long_double() const; + // return a long double representation + + Counter64& assign( long double ld); + // assign a long double to a counter64 + + unsigned long high() const; + // return the high part + + unsigned long low() const; + // return the low part + + void set_high( const unsigned long h); + // set the high part + + void set_low( const unsigned long l); + // set the low part + + Counter64& operator=( const unsigned long long rhs); + // overloaded assignment + + Counter64& operator=( const Counter64 &rhs); + // overloaded assignment + + char *to_string(); + // get a printable ASCII representation + + SnmpSyntax *clone() const; + // create a new instance of this Value + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + + int valid() const; + // general validity test, always true + + operator unsigned long long(); + // otherwise, behave like an unsigned long long + +protected: + char output_buffer[CTR64OUTBUF]; +}; + +#endif // CTR64_ diff --git a/ASNMP/asnmp/enttraps.h b/ASNMP/asnmp/enttraps.h new file mode 100644 index 00000000000..66d095c8cbe --- /dev/null +++ b/ASNMP/asnmp/enttraps.h @@ -0,0 +1,117 @@ +/* -*-C++-*- */ +#ifndef ENTTRAPS_ +#define ENTTRAPS_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// enttraps.cpp +// +// = DESCRIPTION +// constants for Enterprise Traps +// +// = 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/asn1.h" // ASN.1 header file + +//--------------[ well known trap ids ]----------------------------------- +class ACE_Export snmpTrapsOid: public Oid + // = TITLE + // Defines the member functions for the snmpTrapsOid base class + // to implement the traps defined in RFC 1215 +{ + public: + snmpTrapsOid (void):Oid("1.3.6.1.6.3.1.1.5"){} +}; + +class ACE_Export snmpTrapEnterpriseOid: public Oid + // = TITLE + // Defines the default Enterprise Oid for this software package +{ + public: + snmpTrapEnterpriseOid(void): Oid("1.3.6.1.6.3.1.1.4.3.0") { } +}; + +class ACE_Export coldStartOid: public snmpTrapsOid + // = TITLE + // Defines the RFC 1215 agent cold start generic trap (system reboot) +{ + public: + coldStartOid( void){*this+=".1";} +}; + +class ACE_Export warmStartOid: public snmpTrapsOid + // = TITLE + // Defines the RFC 1215 agent warm start generic trap (agent reboot) +{ + public: + warmStartOid( void){*this+=".2";} +}; + +class ACE_Export linkDownOid: public snmpTrapsOid + // = TITLE + // Defines the RFC 1215 interface (link) down trap +{ + public: + linkDownOid( void){*this+=".3";} +}; + + +// SMI LinkUp Oid +class ACE_Export linkUpOid: public snmpTrapsOid + // = TITLE + // Defines the RFC 1215 interface (link) up trap +{ + public: + linkUpOid( void){*this+=".4";} +}; + +class ACE_Export authenticationFailureOid: public snmpTrapsOid + // = TITLE + // Defines the RFC 1215 device/agent invalid access trap +{ + public: + authenticationFailureOid( void){*this+=".5";} +}; + +class ACE_Export egpNeighborLossOid: public snmpTrapsOid + // = TITLE + // Defines the RFC 1215 Exterior Gateway Protocol neighbor loss trap +{ + public: + egpNeighborLossOid( void){*this+=".6";} +}; + +#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/ASNMP/asnmp/gauge.cpp b/ASNMP/asnmp/gauge.cpp new file mode 100644 index 00000000000..560d0bf929f --- /dev/null +++ b/ASNMP/asnmp/gauge.cpp @@ -0,0 +1,111 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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 + +// constructor with a value +Gauge32::Gauge32( const unsigned long i):SnmpUInt32(i) +{ + smival.syntax = sNMP_SYNTAX_GAUGE32; +} + +// copy constructor +Gauge32::Gauge32 ( const Gauge32 &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/ASNMP/asnmp/gauge.h b/ASNMP/asnmp/gauge.h new file mode 100644 index 00000000000..fd5f1232b79 --- /dev/null +++ b/ASNMP/asnmp/gauge.h @@ -0,0 +1,79 @@ +/* -*-C++-*- */ +#ifndef GAUGE_ +#define GAUGE_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// gauge32.cpp +// +// = DESCRIPTION +// 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 ACE_Export Gauge32: public SnmpUInt32 + // = TITLE + // Define RFC1902 Gauge datatype from RFC 1155 section 3.2.3.4 + // Note that this datatype does not behave exactly (acts like a long) +{ + public: + Gauge32( const unsigned long i = 0); + // constructor with a value + + Gauge32 ( const Gauge32 &g); + // copy constructor + + ~Gauge32(); + // destructor for a Gauge32 (ensure that Value::~Value() is overridden) + + SmiUINT32 get_syntax(); + // syntax type + + SnmpSyntax *clone() const; + // create a new instance of this Value + + Gauge32& operator=( const Gauge32 &uli); + // overloaded assignment + + Gauge32& operator=( const unsigned long i); + // overloaded assignment + + operator unsigned long(); + // otherwise, behave like an unsigned int + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value +}; +#endif //GAUGE_ + diff --git a/ASNMP/asnmp/integer.cpp b/ASNMP/asnmp/integer.cpp new file mode 100644 index 00000000000..69ffc81446e --- /dev/null +++ b/ASNMP/asnmp/integer.cpp @@ -0,0 +1,225 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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 + +// constructor with value +SnmpUInt32::SnmpUInt32 (const u_long i) +{ + smival.value.uNumber=i; + smival.syntax = sNMP_SYNTAX_UINT32; + valid_flag = 1; +} + +// copy constructor +SnmpUInt32::SnmpUInt32( const SnmpUInt32 &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 +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 +char * SnmpUInt32::to_string() +{ + sprintf(output_buffer, "%d", 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) +{ + 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 + +char *SnmpInt32::to_string() +{ + sprintf(output_buffer, "%d", (long) this->smival.value.sNumber); + return output_buffer; +} + diff --git a/ASNMP/asnmp/integer.h b/ASNMP/asnmp/integer.h new file mode 100644 index 00000000000..be17240c22c --- /dev/null +++ b/ASNMP/asnmp/integer.h @@ -0,0 +1,139 @@ +/* -*-C++-*- */ +#ifndef SNMPINTEGER_ +#define SNMPINTEGER_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// integer.cpp +// +// = DESCRIPTION +// Class definition for Integer classes convertable to SMI. +// +// = AUTHOR +// Jeff Meyer +// +// ============================================================================ +/*=================================================================== + 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 ACE_Export SnmpUInt32: public SnmpSyntax + // = TITLE + // Implement RFC 1920 Unsigned Integer SMI datatype +{ + + public: + SnmpUInt32 (const unsigned long i = 0); + // default constructor + + SnmpUInt32( const SnmpUInt32 &c); + // copy constructor + + virtual ~SnmpUInt32(); + // destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden) + + virtual SmiUINT32 get_syntax(); + // syntax type + + SnmpUInt32& operator=( const unsigned long i); + // overloaded assignment + + SnmpUInt32& operator=( const SnmpUInt32 &uli); + // overloaded assignment + + operator unsigned long(); + // otherwise, behave like an unsigned long int + + virtual char *to_string(); + // get a printable ASCII value + + virtual SnmpSyntax *clone() const; + // create a new instance of this Value + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + + int valid() const; + // did object construct properly + + protected: + int valid_flag; + char output_buffer[INTOUTBUF]; + // contain string representation of object +}; + + +// 32 bit signed integer class +class ACE_Export SnmpInt32: public SnmpSyntax +{ + // = TITLE + // Implement RFC 1902 32 bit Integer SMI data object + public: + SnmpInt32 (const long i = 0); + // constructor with value + + SnmpInt32 (const SnmpInt32 &c); + // constructor with value + + virtual ~SnmpInt32(); + // destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden) + + virtual SmiUINT32 get_syntax(); + // syntax type + + SnmpInt32& operator=( const long i); + // overloaded assignment + + SnmpInt32& operator=( const SnmpInt32 &li); + // overloaded assignment + + operator long(); + // otherwise, behave like a long int + + SnmpSyntax *clone() const; + // create a new instance of this Value + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + + char *to_string(); + // get a printable ASCII value + + int valid() const; + // logical state of object + + protected: + int valid_flag; + char output_buffer[INTOUTBUF]; + // contain string representation of object +}; + +#endif diff --git a/ASNMP/asnmp/octet.cpp b/ASNMP/asnmp/octet.cpp new file mode 100644 index 00000000000..c76f5df3b97 --- /dev/null +++ b/ASNMP/asnmp/octet.cpp @@ -0,0 +1,594 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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 "ace/OS.h" +#include "asnmp/octet.h" // include definition for octet class + +//============[ 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 = NULL; + smi.value.string.len = 0; +} + +inline +int copy_octet_smi(SmiVALUE& smi, int size, const char *src, int& valid_flag) +{ + valid_flag = FALSE; + ACE_NEW_RETURN(smi.value.string.ptr, SmiBYTE[size], 1); + ACE_OS::memcpy( smi.value.string.ptr, src, (size_t) size); + smi.value.string.len = size; + valid_flag = TRUE; + return 0; +} + +//============[ default constructor ]========================= +OctetStr::OctetStr( const char * string, long size): + output_buffer(NULL), validity(FALSE) +{ + + size_t z; + init_octet_smi(smival); + + // check for null string + if ( !string || !(z = ACE_OS::strlen( string))) + return; + + if (size == -1) + size = z; + + if (size > z) + size = z; + + 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) +{ + size_t z; + // check for null string + if ( !string || !(z = ACE_OS::strlen( (char *)string))) + return; + + if (size == -1) + size = z; + + if (size > z) + return; + + // free up already used space + if ( smival.value.string.ptr ) { + reset_octet_smi(smival); + } + smival.value.string.len = 0; + + // check for zero len + if ( !string || !size) { + validity = TRUE; + return; + } + + copy_octet_smi(smival, size, (const char *)string, validity); +} + +//============[ constructor using another octet object ]============== +OctetStr::OctetStr ( const OctetStr &octet): + output_buffer(NULL), validity(TRUE) +{ + 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 == FALSE) { + validity = FALSE; + 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 = TRUE; + 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 = TRUE; + 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 ]==================== +int 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 ]================ +int 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 ]============================ +int 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 ]=========================== +int 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 ]======================== +int 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 ]======================= +int 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 ]=================== +int 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 ]=============== +int 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 ]================== +int 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 ]================= +int 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 ]=============== +int 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 ]============== +int 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 ]============================= +char * OctetStr::to_string() +{ + for ( long i=0; i < smival.value.string.len; i++) { + if (( smival.value.string.ptr[i] != '\r')&& + ( smival.value.string.ptr[i] != '\n')&& + (isprint((int) (smival.value.string.ptr[i]))==0)) + return(to_string_hex()); + } + + if ( output_buffer != NULL) + 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=FALSE; + 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 ]======================== +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 != NULL) + 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(__unix) + char *fmt = " %s\n"; +#endif // __unix + +#if defined(_WIN32) + char *fmt = " %s\r\n"; +#endif // _WIN32 + + ACE_OS::sprintf(line_ptr, fmt, char_buf); + line_ptr += 3 + strlen(char_buf); + } + + return output_buffer; +} diff --git a/ASNMP/asnmp/octet.h b/ASNMP/asnmp/octet.h new file mode 100644 index 00000000000..3b3c9f6273f --- /dev/null +++ b/ASNMP/asnmp/octet.h @@ -0,0 +1,149 @@ +/* -*-C++-*- */ +#ifndef OCTET_CLS_ +#define OCTET_CLS_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// octet.h +// +// = DESCRIPTION +// 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, added suboid(),collapse ctor's +// +// ============================================================================ +/*=================================================================== + 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 ACE_Export OctetStr: public SnmpSyntax + // = TITLE + // Implement RFC1155 Octet SMI data object + +{ +public: + OctetStr( const char *string = "", long size = -1); + // constructor using a string, -1 will calc/use full string length + + OctetStr ( const OctetStr &octet); + // constructor using another octet object + + ~OctetStr(); + // destructor + + SmiUINT32 get_syntax(); + // syntax type + + void set_data( const SmiBYTE* string, long int size = -1); + // set the data on an already constructed Octet + + OctetStr& operator=( const char *string); + // assignment to a string operator overloaded + + OctetStr& operator=( const OctetStr &octet); + // assignment to another oid object overloaded + + friend int operator==( const OctetStr &lhs, const OctetStr &rhs); + // equivlence operator overloaded + + friend int operator!=( const OctetStr &lhs, const OctetStr &rhs); + // not equivlence operator overloaded + + friend int operator<( const OctetStr &lhs, const OctetStr &rhs); + // less than < overloaded + + friend int operator<=( const OctetStr &lhs,const OctetStr &rhs); + // less than <= overloaded + + friend int operator>( const OctetStr &lhs, const OctetStr &rhs); + // greater than > overloaded + + friend int operator>=( const OctetStr &lhs, const OctetStr &rhs); + // greater than >= overloaded + + friend int operator==( const OctetStr &lhs,const char *rhs); + // equivlence operator overloaded + + friend int operator!=( const OctetStr &lhs,const char *rhs); + // not equivlence operator overloaded + + friend int operator<( const OctetStr &lhs,const char *rhs); + // less than < operator overloaded + + friend int operator<=( const OctetStr &lhs,char *rhs); + // less than <= operator overloaded + + friend int operator>( const OctetStr &lhs,const char *rhs); + // greater than > operator overloaded + + friend int operator>=( const OctetStr &lhs,const char *rhs); + // greater than >= operator overloaded + + OctetStr& operator+=( const char *a); + // append operator, appends a string + + OctetStr& operator+=( const char c); + // appends an int + + OctetStr& operator+=( const OctetStr& octetstr); + // append one octetStr to another + + SmiBYTE& operator[]( int position); + // for non const [], allows reading and writing + + int left_comparison( const long n, const OctetStr &o) const; + // compare the n leftmost bytes (left-to-right) + // returns 0, equal + // returns -1, < + // returns 1 , > + + size_t length() const ; + // return the len of the oid + + int valid() const; + // returns validity + + SmiBYTE *data() const; + // returns pointer to internal data + + char *to_string(); + // get a printable ASCII value + + char *to_string_hex(); + // get an ASCII formattted hex dump of the contents + + SnmpSyntax *clone() const; + // create a new instance of this Value + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + +protected: + //----[ instance variables ] + char *output_buffer; // formatted Octet value + int validity; // validity boolean +}; + +#endif // OCTET_CLS_ diff --git a/ASNMP/asnmp/oid.cpp b/ASNMP/asnmp/oid.cpp new file mode 100644 index 00000000000..403ad492af7 --- /dev/null +++ b/ASNMP/asnmp/oid.cpp @@ -0,0 +1,794 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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 +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 == -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) +{ + 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 (int 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; + + init_value((const SmiLPOID) &(oid.smival.value.oid), + 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) +{ + 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(); + delete [] smival.value.oid.ptr; + smival.value.oid.len = 0; + } + + 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; +} + +//=============[ int operator == oid,oid ]================================= +// equivlence operator overloaded +int operator==( const Oid &lhs, const Oid &rhs) +{ + // ensure same len, then use left_comparison + if (rhs.length() != lhs.length()) + return 0; + if( lhs.left_comparison( rhs.length(), rhs) == 0) + return 1; + else + return 0; +} + +//==============[ operator!=( Oid &x,Oid &y) ]============================= +//not equivlence operator overloaded +int operator!=( const Oid &lhs,const Oid &rhs) +{ + return (!(lhs == rhs)); +} + +//==============[ operator<( Oid &x,Oid &y) ]============================= +// less than < overloaded +int 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 1; + else if (result > 0) + return 0; + + else{ + // if here, equivalent substrings, call the shorter one < + if (lhs.length() < rhs.length()) + return 1; + else + return 0; + } +} + +//==============[ operator<=( Oid &x,Oid &y) ]============================= +// less than <= overloaded +int operator<=( const Oid &x,const Oid &y) +{ + if ( (x < y) || (x == y) ) + return 1; + else + return 0; +} + +//==============[ operator>( Oid &x,Oid &y) ]============================= +// greater than > overloaded +int operator>( const Oid &x,const Oid &y) +{ + // just invert existing <= + if (!(x<=y)) + return 1; + else + return 0; +} + +//==============[ operator>=( Oid &x,Oid &y) ]============================= +// greater than >= overloaded +int operator>=( const Oid &x,const Oid &y) +{ + // just invert existing < + if (!(x<y)) + return 1; + else + return 0; +} + +//===============[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 = NULL; + 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 = NULL; + 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,"%u",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 +// +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 == -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 = NULL; + 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 ? TRUE : FALSE ); +} + +//================[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,"%u", 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/ASNMP/asnmp/oid.h b/ASNMP/asnmp/oid.h new file mode 100644 index 00000000000..5c416a72399 --- /dev/null +++ b/ASNMP/asnmp/oid.h @@ -0,0 +1,164 @@ +/* -*-C++-*- */ +#ifndef OID_CLS_ +#define OID_CLS_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// oid.h +// +// = DESCRIPTION +// 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/OS.h" +#include "asnmp/smival.h" // derived class for all values + +class ACE_Export Oid: public SnmpSyntax + // = TITLE + // Implement RFC 1155 Object Identifier (OID) datatype +{ +public: + Oid( const char * dotted_oid_string = "", size_t size = -1); + // constructor using a dotted string + + Oid ( const Oid &oid); + // constructor using another oid object + + Oid(const unsigned long *raw_oid, size_t oid_len); + // constructor from raw form + + ~Oid(); + // destructor + + SmiUINT32 get_syntax(); + // syntax type + + Oid& operator=( const Oid &oid); + // assignment to another oid object overloaded + + friend int operator==( const Oid &lhs,const Oid &rhs); + // equal operator overloaded + + friend int operator!=( const Oid &lhs,const Oid &rhs); + // not equal operator overloaded + + friend int operator<( const Oid &lhs,const Oid &rhs); + // less than < overloaded + + friend int operator<=( const Oid &lhs,const Oid &rhs); + // less than <= overloaded + + friend int operator>( const Oid &lhs,const Oid &rhs); + // greater than > overloaded + + friend int operator>=( const Oid &lhs,const Oid &rhs); + // greater than >= overloaded + + Oid& operator+=( const char *a); + // append operator, appends a string + + Oid& operator+=( const unsigned long i); + // appends an int + + Oid& operator+=( const Oid &o); + // appends an Oid + + unsigned long & operator[]( size_t position); + // allows element access + + SmiLPOID oidval(); + // return the WinSnmp oid part + + void set_data( const char *dotted_oid_string); + // reset the data from raw 1 byte format + + void set_data( const unsigned long *raw_oid, const size_t oid_len); + // reset the data from raw 4byte integer format + + size_t length() const; + // return the len of the oid + + void trim( const size_t how_many = 1); + // trim off the n rightmost values of an oid + + int suboid(Oid& oid, size_t start = 0, size_t how_many = -1); + // the equivalent of a substr(new_str, 0, 1) + + int left_comparison( const unsigned long n, const Oid &o) const; + // compare the n leftmost bytes (left-to-right) + // returns 0, equal + // returns -1, < + // returns 1 , > + + + int right_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 valid() const; + // is the Oid object valid + + char *to_string(); + // return dotted string value from the right + // where the user specifies how many positions to print + + SnmpSyntax *clone() const; + // create a new instance of this Value + + SnmpSyntax& operator=( SnmpSyntax &val); + // copy an instance of this Value + +protected: + char *iv_str; + // used for returning oid string + + int StrToOid( const char *string, SmiLPOID dstOid, size_t& how_many_bytes); + // convert a string to an smi oid + + int OidCopy( SmiLPOID srcOid, SmiLPOID dstOid, size_t& how_many_bytes); + // clone an smi oid + + int OidToStr(SmiLPOID srcOid, SmiUINT32 size, char *string, size_t& how_many_bytes); + // convert an smi oid to its string representation + + private: + void set_invalid(); + // release memory, re-init data members + + void set_null(); + // initialize object data members + 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/ASNMP/asnmp/oid_def.h b/ASNMP/asnmp/oid_def.h new file mode 100644 index 00000000000..ece88846ba3 --- /dev/null +++ b/ASNMP/asnmp/oid_def.h @@ -0,0 +1,86 @@ +/* -*-C++-*- */ +#ifndef OID_DEF +#define OID_DEF +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// address.cpp +// +// = DESCRIPTION +// 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/ASNMP/asnmp/pdu.cpp b/ASNMP/asnmp/pdu.cpp new file mode 100644 index 00000000000..39ad25b8bd1 --- /dev/null +++ b/ASNMP/asnmp/pdu.cpp @@ -0,0 +1,486 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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 + +//=====================[ constructor no args ]========================= +Pdu::Pdu( void): vb_count_(0), pdu_type_(0), validity_(FALSE), +error_index_(0), request_id_(0), notify_timestamp_(0) +{ +} + +//=====================[ constructor with vbs_ and count ]============== +Pdu::Pdu( Vb* pvbs, const int pvb_count): vb_count_(0), pdu_type_(0), +validity_(FALSE), error_index_(0), request_id_(0), notify_timestamp_(0) +{ + int z; // looping variable + + // zero is ok + if ( pvb_count == 0) { + validity_ = TRUE; + return; + } + + // check for over then max + if ( pvb_count > MAX_VBS) { + validity_ = FALSE; + return; + } + + // loop through and assign internal vbs_ + for (z = 0;z < pvb_count; z++) { + validity_ = FALSE; + ACE_NEW(vbs_[z], Vb( pvbs[z])); + validity_ = TRUE; + } + + // assign the vb count + vb_count_ = pvb_count; + + validity_ = TRUE; +} + +//=====================[ constructor with another Pdu instance ]======== +Pdu::Pdu( const Pdu &pdu): vb_count_(0), pdu_type_(0), +validity_(FALSE), error_index_(0), request_id_(0), notify_timestamp_(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_ = TRUE; + + // 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_ = FALSE; + ACE_NEW_RETURN(vbs_[z], Vb ( *(pdu.vbs_[z])), *this); + validity_ = TRUE; + } + + 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_ = FALSE; + ACE_NEW_RETURN(vbs_[vb_count_], Vb (vb), *this); + // set up validity_ + validity_ = TRUE; + + // up the vb count + vb_count_++; + + // return self reference + return *this; + +} + +// return fomatted version of this object +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 + for ( int 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_, 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 FALSE; + + // loop through all vbs_ and assign to params + for (int z = 0; z < pvb_count; z++) + pvbs[z] = *vbs_[z]; + + return TRUE; + +} + +//=====================[ 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 FALSE; + + // free up current vbs_ + for ( int z = 0; z < vb_count_; z++) + delete vbs_[z]; + vb_count_ = 0; + + // check for zero case + if ( pvb_count == 0) { + validity_ = TRUE; + error_status_ = 0; + error_index_ = 0; + request_id_ = 0; + return FALSE; + } + + + // loop through all vbs_ and reassign them + for ( z = 0; z < pvb_count; z++) { + validity_ = FALSE; + ACE_NEW_RETURN(vbs_[z], Vb (pvbs[z]), FALSE); + validity_ = TRUE; + } + + 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_ = TRUE; + + return TRUE; +} + +//===================[ 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 FALSE; + + // can't ask for something not there + if ( index > (vb_count_ - 1)) + return FALSE; + + // asssign it + vb = *vbs_[index]; + + return TRUE; +} + +//===================[ 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 FALSE; + + // can't ask for something not there + if ( index > (vb_count_ - 1)) + return FALSE; + + // delete what is there + delete vbs_[index]; + + // assign it + validity_ = FALSE; + ACE_NEW_RETURN(vbs_[index], Vb (vb), FALSE); + validity_ = TRUE; + + return TRUE; + +} + +//=====================[ 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_; +} + +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?? + char *pmsg = Snmp::error_string(get_error_status()); + char *id = bad.to_string_oid(); + 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: %d vb cnt: %d vb idx: %d \n\ +msg: %s vb oid: %s value: %s", + 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 FALSE; + + while ( lp != 0) { + if ( vb_count_ > 0) { + delete vbs_[vb_count_ - 1]; + vb_count_--; + } + lp--; + } + return TRUE; +} + + + +// 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 FALSE; + + // safe to remove it + delete vbs_[ p]; + + for ( int z=p;z < (vb_count_-1);z++) { + vbs_[z] = vbs_[z+1]; + } + vb_count_--; + + return TRUE; +} + +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/ASNMP/asnmp/pdu.h b/ASNMP/asnmp/pdu.h new file mode 100644 index 00000000000..234580cec00 --- /dev/null +++ b/ASNMP/asnmp/pdu.h @@ -0,0 +1,210 @@ +/* -*-C++-*- */ +#ifndef PDU_CLS_ +#define PDU_CLS_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// pdu.h +// +// = DESCRIPTION +// 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, 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 ACE_Export Pdu + // = TITLE + // Protocol Data Unit (PDU) concrete class. An abstraction of the + // data packet used to by two SNMP sessions to communicate. +{ +public: + Pdu( void); + // constructor no args + + Pdu( Vb* pvbs, const int pvb_count); + // constructor with vbs and count + + Pdu( const Pdu &pdu); + // constructor with another Pdu instance + + ~Pdu(); + // destructor + + Pdu& operator=( const Pdu &pdu); + // assignment to another Pdu object overloaded + + Pdu& operator+=( Vb &vb); + // append a vb to the pdu + + int get_vblist( Vb* pvbs, const int pvb_count); + // extract all Vbs from Pdu + + int set_vblist( Vb* pvbs, const int pvb_count); + // deposit all Vbs to Pdu + + int get_vb( Vb &vb, const int index = 0) const; + // get a particular vb + // where 0 is the first vb + + int set_vb( Vb &vb, const int index); + // set a particular vb + // where 0 is the first vb + + int get_vb_count() const; + // return number of vbs + + int get_error_status() const; + // return the error status + + char *agent_error_reason(); + // return the complete error info from this pdu + + friend void set_error_status( Pdu *pdu, const int status); + // set the error status + + int get_error_index() const; + // return the error index + + friend void set_error_index( Pdu *pdu, const int index); + // set the error index + + friend void clear_error_status( Pdu *pdu); + // clear error status + + friend void clear_error_index( Pdu *pdu); + // clear error index + + unsigned long get_request_id() const; + // return the request id + + friend void set_request_id( Pdu *pdu, const unsigned long rid); + // set the request id + + unsigned short get_type() const; + // get the pdu type + + void set_type( unsigned short type); + // set the pdu type + + int valid() const; + // returns validity of Pdu instance + + int trim(const int position=1); + // trim off the last vb, if present + + int delete_vb( const int position); + // delete a Vb anywhere within the Pdu + + void delete_all_vbs(); + // delete_all vbs in pdu + + void set_notify_timestamp( const TimeTicks & timestamp); + // set notify timestamp + + void get_notify_timestamp( TimeTicks & timestamp) const; + // get notify timestamp + + void set_notify_id( const Oid id); + // set the notify id + + void get_notify_id( Oid &id) const; + // get the notify id + + void set_notify_enterprise( const Oid &enterprise); + // set the notify enterprise + + void get_notify_enterprise( Oid & enterprise) const; + // get the notify enterprise + + char *to_string(); + // return fomatted version of this object + + + protected: + Vb *vbs_[MAX_VBS]; + // pointer to array of Vbs + + int vb_count_; + // count of Vbs + + int error_status_; + // SMI error status + + int error_index_; + // SMI error index + + int validity_; + // valid boolean status of object construction + unsigned long request_id_; + // SMI request id + + unsigned short pdu_type_; + // derived at run time based on request type + + TimeTicks notify_timestamp_; + // a timestamp associated with an infor + // for notify Pdu objects only + // traps & notifies + + Oid notify_id_; + // an id + + Oid notify_enterprise_; + + private: + char *output; + // buffer for to_string() +}; + + +class VbIter + // = TITLE + // Utility class to iterate once through a PDU varbind list +{ + public: + VbIter(Pdu& pdu); + // default constructor + + int next(Vb& vb); + // returns 1 if ok, else 0 if none left + + private: + VbIter(const VbIter&); + // disallow copy constructor use + + int idx_; + // current object in list + + Pdu *pdu_; + // ptr to pdu being interated over +}; + +#endif //PDU_CLS_ + diff --git a/ASNMP/asnmp/smi.h b/ASNMP/asnmp/smi.h new file mode 100644 index 00000000000..1071b1e6832 --- /dev/null +++ b/ASNMP/asnmp/smi.h @@ -0,0 +1,148 @@ +/* -*-C++-*- */ +#ifndef SMIDEF_ +#define SMIDEF_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// smi.h +// +// = DESCRIPTION +// Address class definition. Encapsulates various network +// addresses into easy to use, safe and portable classes. +// +// = AUTHOR +// ?? +// +// ============================================================================ +/*=================================================================== + 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/OS.h" + +//----------[ 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/ASNMP/asnmp/smival.h b/ASNMP/asnmp/smival.h new file mode 100644 index 00000000000..3906e084dd9 --- /dev/null +++ b/ASNMP/asnmp/smival.h @@ -0,0 +1,103 @@ +/* -*-C++-*- */ +#ifndef SMIVALUE_ +#define SMIVALUE_ +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// smival.h +// +// = DESCRIPTION +// 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. +// +// = AUTHOR +// Jeff Meyer +// +// ============================================================================ +/*=================================================================== + 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" + +//----[ 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 ACE_Export SnmpSyntax { + +public: + virtual 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/ASNMP/asnmp/snmp.cpp b/ASNMP/asnmp/snmp.cpp new file mode 100644 index 00000000000..083b773911b --- /dev/null +++ b/ASNMP/asnmp/snmp.cpp @@ -0,0 +1,206 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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 + +const coldStartOid coldStart; +const warmStartOid warmStart; +const linkDownOid linkDown; +const linkUpOid linkUp; +const authenticationFailureOid authenticationFailure; +const egpNeighborLossOid egpNeighborLoss; +const snmpTrapEnterpriseOid snmpTrapEnterprise; + +Snmp::Snmp(): construct_status_(SNMP_CLASS_ERROR), last_transaction_status_(0) +{ + ACE_TRACE("Snmp::Snmp"); + + ACE_INET_Addr addr; // any port,address is ok + if (iv_snmp_session_.open(addr) < 0) { + last_transaction_status_ = errno; // open udp/ipv4 socket + } + + // initial request id randomly generated then monotonically incremented + req_id_ = (unsigned) ACE_OS::time(NULL); + + construct_status_ = SNMP_CLASS_SUCCESS; + return; +} + +Snmp::~Snmp() +{ + ACE_TRACE("Snmp::~Snmp"); +} + +int Snmp::valid() const +{ + return construct_status_; +} + +// given error code, return string definition +// class version +// static +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 +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 + int 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::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) +{ + 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); +} + +int Snmp::get_next( Pdu &pdu, UdpTarget &target) +{ + 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); +} + +int Snmp::set( Pdu &pdu, UdpTarget &target) +{ + 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); +} + +// 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; +} + + diff --git a/ASNMP/asnmp/snmp.h b/ASNMP/asnmp/snmp.h new file mode 100644 index 00000000000..b1ece5bab5f --- /dev/null +++ b/ASNMP/asnmp/snmp.h @@ -0,0 +1,105 @@ +/* -*-C++-*- */ +#ifndef SNMP_CLS_ +#define SNMP_CLS_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// snmp.h +// +// = DESCRIPTION +// 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, 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" +#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 + +// Snmp session class - supports Version 1 operations in blocking mode +class ACE_Export Snmp + // = TITLE + // Concrete class Snmp defined the session and interface to + // communicate with another SNMP Version 1 agent +{ + public: + Snmp(); + ~Snmp(); + + int get( Pdu &pdu, UdpTarget &target); + // retrieve data from a peer agent for a given list of oid values + // default port 161 + + int get_next( Pdu &pdu, UdpTarget &target); + // retrieve data lexically adjacent to the oids specified in the pdu + // from the peer agent + // default port 161 + + int set( Pdu &pdu, UdpTarget &target); + // set data in the agent from the list of oids in the pdu + // default port 161 + + int trap( Pdu &pdu, UdpTarget &target); + // send an SNMPv1 trap (unreliable) to a remote system (def port 162) + + int valid() const; + // status of object after construction + + static char * error_string(int code); + // given error code, return string reason + + char * error_string(); + // retrieve a reason string if any of the above commands fail + +private: + void check_default_port(UdpTarget& target,unsigned short port=DEF_AGENT_PORT); + int run_transaction(Pdu& pdu, UdpTarget& target); + int validate_args(const Pdu& pdu, const UdpTarget& target) const; + + Snmp(const Snmp&); + + ACE_SOCK_Dgram iv_snmp_session_; + // io object + + int construct_status_; + // status of construction + + int last_transaction_status_; + // result code from last transaction + + unsigned req_id_; + // transaction request id +}; + +#endif //SNMP_CLS_ + diff --git a/ASNMP/asnmp/snmperrs.h b/ASNMP/asnmp/snmperrs.h new file mode 100644 index 00000000000..a6374052e57 --- /dev/null +++ b/ASNMP/asnmp/snmperrs.h @@ -0,0 +1,213 @@ +/* -*-C++-*- */ +#ifndef SNMPERRS_H_ +#define SNMPERRS_H_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// snmperrs.h +// +// = DESCRIPTION +// Definition of error macros and error strings +// +// = AUTHOR +// Jeff Meyer +// +// ============================================================================ +/*=================================================================== + 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 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 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/ASNMP/asnmp/target.cpp b/ASNMP/asnmp/target.cpp new file mode 100644 index 00000000000..e5825791c26 --- /dev/null +++ b/ASNMP/asnmp/target.cpp @@ -0,0 +1,321 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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" + +//---------------------------------------------------------------------- +//--------[ 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(): timeout_(default_timeout_), + retries_(default_retries_), validity_(FALSE), version_(default_version_), + max_pdu_size_(default_max_pdu_size_) +{ +} + +// 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; +} + +const snmp_version SnmpTarget::get_version() const +{ + return version_; +} + +const 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; +} + +int operator==(const SnmpTarget& lhs, const SnmpTarget& rhs) +{ + if (lhs == rhs) + return 1; + + if (lhs.timeout_ != rhs.timeout_) + return 0; + + if (lhs.retries_ != rhs.retries_) + return 0; + + if (lhs.max_pdu_size_ != rhs.max_pdu_size_) + return 0; + + if (lhs.version_ != rhs.version_) + return 0; + + return 1; +} + + +//---------------------------------------------------------------------- +//--------[ IpTarget Member Functions ]---------------------------------- +//---------------------------------------------------------------------- + + +//---------[ UdpTarget::UdpTarget( void) ]---------------------------------- + +UdpTarget::UdpTarget() +{ + validity_ = FALSE; + 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_ = TRUE; + 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_ = TRUE; + else + validity_ = FALSE; + + 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; +} + +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_, timeout_, + retries_, max_pdu_size_); + return output_buffer_; +} + +//=============[ int operator == UdpTarget, UdpTarget ]=============== +// equivlence operator overloaded +int operator==( const UdpTarget &lhs,const UdpTarget &rhs) +{ + // need to compare all the members of a UdpTarget + if ( lhs.read_community_ != rhs.read_community_) + return 0; // != + + if ( lhs.write_community_ != rhs.write_community_) + return 0; // != + + if ( lhs.udp_address_ != rhs.udp_address_) + return 0; + + if ( lhs.timeout_ != rhs.timeout_) + return 0; + + if ( lhs.retries_ != rhs.retries_) + return 0; + + return 1; // they are equal +} diff --git a/ASNMP/asnmp/target.h b/ASNMP/asnmp/target.h new file mode 100644 index 00000000000..27b65640401 --- /dev/null +++ b/ASNMP/asnmp/target.h @@ -0,0 +1,246 @@ +/* -*-C++-*- */ +#ifndef TARGET_ +#define TARGET_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// target.h +// +// = DESCRIPTION +// +// = 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" +#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 ACE_Export SnmpTarget + // = TITLE + // Abstract Base class SnmpTarget is used to Collect all transmission + // details to communicate with an SNMP +{ + public: + + virtual ~SnmpTarget(); + // allow destruction of derived classes + + int valid() const; + // return validity of target + + void set_retry( const int r); + // set the retry value + + void set_timeout( const unsigned long t); + // set the object's timeout (in seconds) + + void set_version( const snmp_version v); + // set the instance version + + void set_max_pdu_size(const unsigned long max_pdu_sz); + // all classes constructed will have this write community string + + void set_default_timeout( const unsigned long t); + // change the "class" default default timeout (in seconds) + + void set_default_retry( const int r); + // change the default send retries + + void set_default_max_pdu_size(const unsigned long max_pdu_sz); + // all classes constructed will have this write community string + + void set_default_version( const snmp_version v); + // change class default + + // *** get methods *** + + int get_default_retry() const; + // get the retry value + + unsigned long get_timeout() const; + // get the timeout (seconds) + + unsigned long get_max_pdu_size() const; + // get instance max buffer size + + void get_default_max_pdu_size(const unsigned long max_pdu_sz); + // all classes constructed will have this write community string + + const snmp_version get_version() const; + // get the version + + const snmp_version get_default_version() const; + + int get_retry() const; + // return send retry number for this instancd + + virtual SnmpTarget *clone() const = 0; + // 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. + + friend int operator==(const SnmpTarget& lhs, const SnmpTarget& rhs); + // manipulate the base part + + SnmpTarget& operator=(const SnmpTarget& lhs); + + protected: + SnmpTarget(); + SnmpTarget(const& SnmpTarget); + + int validity_; + // used by derived class instances + + unsigned long timeout_; + // instance value xmit timeout in milli secs + + int retries_; + // instance value number of retries + + unsigned max_pdu_size_; + // size of pdu + + snmp_version version_; + // instance value the snmp version + + // class wide default values + static unsigned long default_timeout_; + // xmit timeout in secs + + static int default_retries_; + // number of retries + + static unsigned long default_max_pdu_size_; + static snmp_version default_version_; + // snmp protocol version +}; + +//----[ UdpTarget class ]---------------------------------------------- +// UDP/IP transport using "community string" based agents (targets) +// +class ACE_Export UdpTarget: public SnmpTarget + // = TITLE + // Concrete class UdpTarget contains all Details for communicating + // with a SNMPv1 agent over UDP/IPv4 transport +{ + public: + UdpTarget(); + + UdpTarget( const UdpAddress& udp); + // constructor with only address + // assumes default as public, public + // can be constructed with IP address object + + UdpTarget( ACE_INET_Addr& ace_inet_addr); + // can be constructed with Udp address object TODO: merge addresses + + ~UdpTarget(); + // destructor + + // ** set *** + + void set_read_community( const OctetStr& new_read_community); + // set the read community using an OctetStr + + void set_write_community( const OctetStr& write_community); + // set the write community using an OctetStr + + int set_address( UdpAddress &udp_address); + // set the address + + // ** get *** + + void get_read_community( OctetStr& read_community_oct) const; + // get the read community as an Octet Str object + + void get_write_community( OctetStr &write_community_oct) const; + // get the write community as an OctetStr + + void get_address( UdpAddress& address) const; + // get the address + + void set_default_read_community(const OctetStr& rd_community); + // all classes constructed will have this read community string + + void set_default_write_community(const OctetStr& wr_community); + // all classes constructed will have this write community string + + void get_default_read_community(OctetStr& rd_community) const; + // all classes constructed will have this read community string + + void get_default_write_community(OctetStr& wr_community) const; + // all classes constructed will have this write community string + + UdpTarget& operator=( const UdpTarget& target); + // overloaded assignment + + friend int operator==( const UdpTarget &lhs, const UdpTarget &rhs); + // compare two C targets + + char *to_string(); + // string representation of object + + SnmpTarget *clone() const; + // clone from existing UdpTarget + + protected: + static OctetStr default_rd_community_; + static OctetStr default_wr_community_; + OctetStr read_community_; + OctetStr write_community_; + UdpAddress udp_address_; + snmp_version version_; + + char output_buffer_[MAX_TARGET_STRING_REP]; + // to_string() rep of data +}; + + +#endif //TARGET_ diff --git a/ASNMP/asnmp/timetick.cpp b/ASNMP/asnmp/timetick.cpp new file mode 100644 index 00000000000..da83945e83a --- /dev/null +++ b/ASNMP/asnmp/timetick.cpp @@ -0,0 +1,140 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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 + +// constructor with a value +TimeTicks::TimeTicks( const unsigned long i):SnmpUInt32(i) +{ + smival.syntax = sNMP_SYNTAX_TIMETICKS; +} + +// copy constructor +TimeTicks::TimeTicks( const TimeTicks &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 +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/ASNMP/asnmp/timetick.h b/ASNMP/asnmp/timetick.h new file mode 100644 index 00000000000..0d9b9b9f171 --- /dev/null +++ b/ASNMP/asnmp/timetick.h @@ -0,0 +1,84 @@ +/* -*-C++-*- */ +#ifndef TIMETICKS_ +#define TIMETICKS_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// timetick.h +// +// = DESCRIPTION +// 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 ACE_Export TimeTicks: public SnmpUInt32 + // = TITLE + // Define RFC1155 TimeTicks Data object + +{ + + public: + TimeTicks( const unsigned long i = 0); + + TimeTicks( const TimeTicks &t); + // copy constructor + + ~TimeTicks(); + // destructor + + SmiUINT32 get_syntax(); + // syntax type + + char *to_string(); + // get a printable ASCII value + + SnmpSyntax *clone() const; + // create a new instance of this Value + + SnmpSyntax& operator=(SnmpSyntax &val); + // copy an instance of this Value + + TimeTicks& operator=( const TimeTicks &uli); + // overloaded assignment + + TimeTicks& operator=( const unsigned long int i); + // overloaded assignment + + operator unsigned long(); + // otherwise, behave like an unsigned long + + protected: + char output_buffer[TICKOUTBUF]; + // for storing printed form +}; +#endif // TIMETICKS_ diff --git a/ASNMP/asnmp/transaction.cpp b/ASNMP/asnmp/transaction.cpp new file mode 100644 index 00000000000..9c09836ff82 --- /dev/null +++ b/ASNMP/asnmp/transaction.cpp @@ -0,0 +1,126 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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" + +// 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): + 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() +{ + delete [] receive_iovec_.iov_base; +} + +// implement state machine, send, wait (timeout/results) return +int transaction::run() +{ + int rc, done = FALSE; + unsigned retry_counter = 0; + ACE_Time_Value to(params_.get_timeout(), 0); // seconds + ACE_Reactor reactor; + + // 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; + } + } + +} + +// got back response from SNMPv1 agent - process it +int transaction::handle_input (ACE_HANDLE fd) +{ + // OS allocates iovec_.iov_base ptr and len + int rc = session_.recv(&receive_iovec_, receive_addr_, 0); + if (rc == -1) { + return SNMP_CLASS_RESOURCE_UNAVAIL; + } + + return rc; +} + +// return pdu to caller +int transaction::result(Pdu& pdu) +{ + // 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; + if (tmp.get_pdu(pdu, ver) == 0) + return 0; + else + return -1; +} + +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; +} diff --git a/ASNMP/asnmp/transaction.h b/ASNMP/asnmp/transaction.h new file mode 100644 index 00000000000..d94cc6798ea --- /dev/null +++ b/ASNMP/asnmp/transaction.h @@ -0,0 +1,70 @@ +/* -*-C++-*- */ +#ifndef TRANSACTION_ +#define TRANSACTION_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// snmp.h +// +// = DESCRIPTION +// 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 +// Michael R. MacFaden port to ACE / use Reactor pattern +// +// ============================================================================ + +#include "ace/Event_Handler.h" +#include "asnmp/target.h" +#include "asnmp/pdu.h" +#include "asnmp/wpdu.h" // cmu adapter class +#include "ace/SOCK_Dgram.h" + +class ACE_Export transaction : public ACE_Event_Handler + // = TITLE + // Used to manage the details of a particular transaction betwen + // two SNMP agents. Uses SnmpTarget class to implement retry/timeout + +{ + public: + transaction(const Pdu& pdu, const UdpTarget& target, ACE_SOCK_Dgram& io); + // constructor + + ~transaction(); + // destructor + + int run(); + // begin polling for values + + int result(Pdu& pdu); + // return pdu with result from agent after run() is completed rc = 0 + + virtual int handle_input (ACE_HANDLE fd); + // called by reactor when data read on session_ + + int send(); + // transmit buffer command to network... + + private: + transaction(const transaction&); + // disallow copy construction + + wpdu wp_; + UdpTarget params_; + ACE_INET_Addr addr_; + ACE_SOCK_Dgram session_; + // io object + + iovec receive_iovec_; // receive buffer + // incomming msg details + ACE_Addr receive_addr_; + // address msg received from +}; + +#endif // TRANSACTION_ diff --git a/ASNMP/asnmp/vb.cpp b/ASNMP/asnmp/vb.cpp new file mode 100644 index 00000000000..923381121dc --- /dev/null +++ b/ASNMP/asnmp/vb.cpp @@ -0,0 +1,385 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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 + +//---------------[ Vb::Vb( void) ]-------------------------------------- +// constructor with no arguments +// makes an vb, unitialized +Vb::Vb( void): iv_vb_value_(NULL), exception_status_(SNMP_CLASS_SUCCESS), + output_(NULL) +{ +} + +//---------------[ Vb::Vb( const Oid &oid) ]----------------------------- +// constructor to initialize the oid +// makes a vb with oid portion initialized +Vb::Vb( const Oid &oid): iv_vb_oid_(oid), iv_vb_value_(NULL), + exception_status_(SNMP_CLASS_SUCCESS), output_(NULL) +{ +} + +//---------------[ Vb::Vb( const Oid &oid, const SmiSyntax &val) ]------- +Vb::Vb( const Oid &oid, const SnmpSyntax &val, const SmiUINT32 status): + iv_vb_oid_(oid), iv_vb_value_(NULL), exception_status_(status), output_(NULL) +{ + // 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): iv_vb_value_(NULL), output_(NULL) +{ + *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 TRUE; + else + return FALSE; +} + + +//---------------[ 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_ == NULL) { + iv_vb_value_ = NULL; + } + 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_ = NULL; +} + +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() && + (iv_vb_value_->get_syntax() == sNMP_SYNTAX_UINT32 )) { + u = *((SnmpUInt32 *) iv_vb_value_); + return SNMP_CLASS_SUCCESS; + } + else + return SNMP_CLASS_INVALID; +} + +int Vb::get_value( Gauge32 &g) +{ + if (iv_vb_value_ && + iv_vb_value_->valid() && + (iv_vb_value_->get_syntax() == sNMP_SYNTAX_GAUGE32 )) { + 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 +char *Vb::to_string_value() +{ + if (iv_vb_value_) + return iv_vb_value_->to_string(); + else + return ""; +} + +// return the printable oid +char *Vb::to_string_oid() +{ + return iv_vb_oid_.to_string(); +} + +// generate string with name/ value format +char *Vb::to_string() +{ + int len = ACE_OS::strlen(iv_vb_oid_.to_string()); + char *ptr = ""; + if (iv_vb_value_) + ptr = iv_vb_value_->to_string(); + len += ACE_OS::strlen(ptr); + 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_ +int 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) { + int val = strcmp(lhs.iv_vb_value_->to_string(), + rhs.iv_vb_value_->to_string()); + return !val; + } + else + return FALSE; +} + diff --git a/ASNMP/asnmp/vb.h b/ASNMP/asnmp/vb.h new file mode 100644 index 00000000000..2aa5150c84c --- /dev/null +++ b/ASNMP/asnmp/vb.h @@ -0,0 +1,199 @@ +/* -*-C++-*- */ +#ifndef VB_CLS_ +#define VB_CLS_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// vb.h +// +// = DESCRIPTION +// 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/OS.h" + +#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 ACE_Export Vb + // = TITLE + // Implement the concrete Variable Bindings aka Varbind + // composite type. Varbinds hold 1 Oid and 1 Value (Any SMI value) +{ +public: + Vb( void); + // constructor with no arguments + // makes an vb, unitialized (does not make object valid) + + Vb( const Oid &oid); + // constructor to initialize the oid + // makes a vb with oid portion initialized (does not make object valid) + + Vb( const Oid& vb, const SnmpSyntax &val, const SmiUINT32=SNMP_CLASS_SUCCESS); + // constructor to initialize the oid + // makes a vb with oid portion and value portion initialized, (valid) + + Vb( const Vb &vb); + // copy constructor + + ~Vb(); + // destructor + // if the vb has a oid or an octect string then + // the associated memory needs to be freed + + int valid() const; + // return validity of Vb object (both oid and value set return 1 else 0) + + Vb& operator=( const Vb &vb); + // assignment to another Vb object overloaded + + friend int operator==( const Vb &lhs, const Vb &rhs); + // equivlence operator overloaded + + //-----[ set oid / get oid part]------------------------------------------ + + void set_oid( const Oid& oid); + // set value oid only with another oid + + void get_oid( Oid &oid) const; + // get oid portion + + //-----[ set value part]-------------------------------------------------- + + void set_null(); + // set a Vb null, if its not already + + 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); + // returns 0 on success and a value + + void set_value( const OctetStr& oct_str); + // get an octet string object + + //----[ get 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); + // returns 0 on success and a value + + int get_value( OctetStr& oct_str); + // get an octet string object + + // escape hatch + void set_value( const SnmpSyntax &val); + // for other derived types that can be casted + + int get_value( SnmpSyntax &val); + // gets a general value + + SmiUINT32 get_syntax(); + // return the current syntax + // Or.. if a V2 VB exception is present then return the exception value + + friend void set_exception_status( Vb *vb, const SmiUINT32 status); + // set the exception status + + char *to_string(); + // return fomatted version of this object + + char *to_string_value(); + // returns a formatted version of the value + + char *to_string_oid(); + // returns a formatted version of the value + +protected: + char *output_; + // display vb as [ oid / value ] + + Oid iv_vb_oid_; + // a vb is made up of a oid + + SnmpSyntax *iv_vb_value_; + // and a value... + + SmiUINT32 exception_status_; + // are there any vb exceptions?? + + void free_vb(); +}; + +#endif // VB_CLS_ + diff --git a/ASNMP/asnmp/wpdu.cpp b/ASNMP/asnmp/wpdu.cpp new file mode 100644 index 00000000000..e11a26256fb --- /dev/null +++ b/ASNMP/asnmp/wpdu.cpp @@ -0,0 +1,462 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = 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" + +#define DEFINE_TRAP_CONSTANTS_ +#include "asnmp/enttraps.h" + +#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 ) +{ + reset_iov(iovec_); + version_ = target.get_version(); + int status; + OctetStr comm_str; + + 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: + if (set_trap_info(raw_pdu, pdu)) // will free raw_pdu + return; + 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 != 6) // TODO: fix these magic numbers with defines + pdu.get_notify_enterprise( enterprise); + if ( enterprise.length() > 0) { + // note!! + // 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(); + raw_pdu->enterprise = rawOid->ptr; + raw_pdu->enterprise_length = (int) rawOid->len; + } + + TimeTicks timestamp; + pdu.get_notify_timestamp( timestamp); + raw_pdu->time = ( unsigned long) timestamp; +} + +wpdu::wpdu(const iovec& iov): valid_flag_(FALSE) +{ + 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; +} + +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; + + case sNMP_SYNTAX_BITS: + case sNMP_SYNTAX_OCTETS: + case sNMP_SYNTAX_IPADDR: + { + OctetStr os; + tempvb.get_value(os); + smival->value.string.ptr = NULL; + 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; + } + } + } + } // 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 [] 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) const +{ + 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 + unsigned char community_name[MAX_COMM_STR_LEN]; + unsigned long comm_len = MAX_COMM_STR_LEN; + 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; + // TODO: something with community - verify against params_? + + 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; +} + + diff --git a/ASNMP/asnmp/wpdu.h b/ASNMP/asnmp/wpdu.h new file mode 100644 index 00000000000..6a3eeb75876 --- /dev/null +++ b/ASNMP/asnmp/wpdu.h @@ -0,0 +1,73 @@ +/* -*-C++-*- */ +#ifndef WPDU_H_ +#define WPDU_H_ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// wpdu.h +// +// = DESCRIPTION +// 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, use ACE API +// Peter E Mellquist wrote original class snmpmsg +// +// ============================================================================ + +#include "ace/OS.h" +#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 + +class ACE_Export wpdu + // = TITLE + // Implement an Adapter pattern between CMU SNMP and HP SNMP++ + // +{ +public: + + wpdu(const Pdu& pdu, const UdpTarget& target); + // construct CMU data from HP SNMP++ objects + + wpdu(const iovec& buffer); + // construct HP SNMP++ objects from raw buffer via CMU SNMP datatypes + + ~wpdu(); + + int valid() const; + // constructor completed ok? rc = 1 else 0 + + const iovec& get_buffer() const; + // return raw data stream via CMU code + + int get_pdu(Pdu& pdu, snmp_version& version) const; + // return HP SNMP++ pdu + +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; + + iovec iovec_; + // raw format + + int valid_flag_; + // object construction state + + snmp_version version_; + // snmp version +}; + +#endif // WPDU_H_ diff --git a/ASNMP/examples/Makefile b/ASNMP/examples/Makefile new file mode 100644 index 00000000000..8af1dce1e24 --- /dev/null +++ b/ASNMP/examples/Makefile @@ -0,0 +1,26 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the ACE+SNMP examples directory +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = get \ + next \ + set \ + trap \ + info \ + walk + +#---------------------------------------------------------------------------- +# macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/ASNMP/examples/get/Makefile b/ASNMP/examples/get/Makefile new file mode 100644 index 00000000000..669015aa115 --- /dev/null +++ b/ASNMP/examples/get/Makefile @@ -0,0 +1,40 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for get application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + + +# ACE+SNMP +BIN = get +CCFLAGS = -I$(WRAPPER_ROOT)/ASNMP/ +LSRC = $(addsuffix .cpp,$(BIN)) +VLDLIBS = -R$(WRAPPER_ROOT)/ASNMP/asnmp -L$(WRAPPER_ROOT)/ASNMP/asnmp -lasnmp $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/ASNMP/examples/get/get.cpp b/ASNMP/examples/get/get.cpp new file mode 100644 index 00000000000..7b639a73d5e --- /dev/null +++ b/ASNMP/examples/get/get.cpp @@ -0,0 +1,190 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// get.cpp +// +// = DESCRIPTION +// Sample application demonstrating synchronous Snmp::get API +// to access an SNMP Version 1 agent. +// +// = AUTHOR +// Peter E. Mellquist original code +// Michael R MacFaden mrm@cisco.com rework API/ACE integration +// +// ============================================================================ +/*=================================================================== + 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 "ace/Get_Opt.h" + +// +// SNMPv1 Get Application +// +class getapp { + public: + getapp(int argc, char **argv); // process command line args + int valid() const; // verify transaction can proceed + int run(); // issue transaction + static void usage(); // operator help message + + private: + getapp(const getapp&); + + UdpAddress address_; + Pdu pdu_; // construct a request Pdu + Oid oid_; + OctetStr community_; + Snmp snmp_; + UdpTarget target_; + int valid_; +}; + + +// main entry point +int main( int argc, char *argv[]) +{ + getapp get(argc, argv); + if (get.valid()) + return get.run(); + else + getapp::usage(); + return 1; +} + +getapp::valid() const +{ + return valid_; +} +getapp::getapp(int argc, char *argv[]): valid_(0) +{ + Oid req, def_oid("1.3.6.1.2.1.1.1.0"); // default is sysDescr + if ( argc < 2) + return; + + address_ = argv[argc - 1]; + if ( !address_.valid()) { + cout << "ERROR: Invalid IPv4 address or DNS hostname: " \ + << argv[argc] << "\n"; + return; + } + + ACE_Get_Opt get_opt (argc, argv, "o:c:r:t:"); + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'o': + req = get_opt.optarg; + if (req.valid() == 0) + cout << "ERROR: oid value: " <<get_opt.optarg \ + << "is not valid. using default.\n"; + break; + + case 'c': + community_ = get_opt.optarg; + target_.set_read_community(community_); + break; + + case 'r': + target_.set_retry(ACE_OS::atoi (get_opt.optarg)); + break; + + case 't': + target_.set_timeout(ACE_OS::atoi (get_opt.optarg)); + break; + + default: + break; + } + + Vb vb; // construct a Vb object + if (req.valid()) + vb.set_oid( req); // set the Oid portion of the Vb + else { + vb.set_oid( def_oid); // set the Oid portion of the Vb + } + pdu_ += vb; + vb.get_oid(oid_); // store for later use + valid_ = 1; +} + +void getapp::usage() +{ + cout << "Usage:\n"; + cout << "get [options] dotted-quad | DNSName[:port]\n"; + cout << " -o OID defaults to 1.3.6.1.2.1.1.1.0 (mibII sysDescr.0) \n"; + cout << " -c Community_name, default is 'public' \n"; + cout << " -r N retries default is N = 1 retry\n"; + cout << " -t N timeout in seconds default is 1 second" << endl; +} + + +int getapp::run() +{ + + //----------[ create a ASNMP session ]----------------------------------- + if ( snmp_.valid() != SNMP_CLASS_SUCCESS) { + cout << "\nASNMP:ERROR:Create session failed: "<< + snmp_.error_string()<< "\n"; + return 1; + } + + //--------[ build up ASNMP object needed ]------------------------------- + if (address_.get_port() == 0) + address_.set_port(DEF_AGENT_PORT); + target_.set_address( address_); // make a target using the address + + //-------[ issue the request, blocked mode ]----------------------------- + cout << "\nASNMP:INFO:SNMP Version " << (target_.get_version()+ 1) << \ + " GET SAMPLE PROGRAM \nOID: " << oid_.to_string() << "\n"; + target_.get_address(address_); // target updates port used + int rc; + char *name = address_.friendly_name(rc); + if (rc) + name = "<< did not resolve via gethostbyname() >>"; + + cout << "Device: " << address_ << " " << name << "\n"; + cout << "[ Retries=" << target_.get_retry() << " \ + Timeout=" << target_.get_timeout() <<" ms " << "Community=" << \ + community_.to_string() << " ]"<< endl; + + if (snmp_.get( pdu_, target_) == SNMP_CLASS_SUCCESS) { + Vb vb; + // check to see if there are any errors + if (pdu_.get_error_status()) { + cout << "ERROR: agent replied as follows\n"; + cout << pdu_.agent_error_reason() << endl; + } + else { + VbIter iter(pdu_); + while (iter.next(vb)) { + cout << "\tOid = " << vb.to_string_oid() << "\n"; + cout << "\tValue = " << vb.to_string_value() << "\n"; + } + } + } + else { + char *ptr = snmp_.error_string(); + cout << "ASNMP:ERROR: get command failed reason: " << ptr << endl; + } + cout << "ASNMP:INFO:command completed normally. ACE RULES!\n"<< endl; + return 0; +} + diff --git a/ASNMP/examples/next/Makefile b/ASNMP/examples/next/Makefile new file mode 100644 index 00000000000..100b72da689 --- /dev/null +++ b/ASNMP/examples/next/Makefile @@ -0,0 +1,41 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for next sample application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + + +# ACE+SNMP +BIN = next +CCFLAGS = -I$(WRAPPER_ROOT)/ASNMP/ +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = -R$(WRAPPER_ROOT)/ASNMP/asnmp -L$(WRAPPER_ROOT)/ASNMP/asnmp -lasnmp $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/ASNMP/examples/next/next.cpp b/ASNMP/examples/next/next.cpp new file mode 100644 index 00000000000..75bb39a3c46 --- /dev/null +++ b/ASNMP/examples/next/next.cpp @@ -0,0 +1,190 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// next.cpp +// +// = DESCRIPTION +// Sample application demonstrating synchronous Snmp::get_next API +// to access an SNMP Version 1 agent. +// +// = AUTHOR +// Peter E. Mellquist original code +// Michael R MacFaden mrm@cisco.com rework API/ACE integration +// +// ============================================================================ +/*=================================================================== + 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 "ace/Get_Opt.h" + +// +// SNMPv1 Get Next Application +// +class nextapp { + public: + nextapp(int argc, char **argv); // process command line args + int valid() const; // verify transaction can proceed + int run(); // issue transaction + static void usage(); // operator help message + + private: + nextapp(const nextapp&); + + UdpAddress address_; + Pdu pdu_; // construct a request Pdu + Oid oid_; + OctetStr community_; + Snmp snmp_; + UdpTarget target_; + int valid_; +}; + + +// main entry point +int main( int argc, char *argv[]) +{ + nextapp get(argc, argv); + if (get.valid()) + return get.run(); + else + nextapp::usage(); + return 1; +} + +nextapp::valid() const +{ + return valid_; +} +nextapp::nextapp(int argc, char *argv[]): valid_(0) +{ + Oid req, def_oid("1.3.6.1.2.1.1.1.0"); // default is sysDescr + if ( argc < 2) + return; + + address_ = argv[argc - 1]; + if ( !address_.valid()) { + cout << "ERROR: Invalid IPv4 address or DNS hostname: " \ + << argv[argc] << "\n"; + return; + } + + ACE_Get_Opt get_opt (argc, argv, "o:c:r:t:"); + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'o': + req = get_opt.optarg; + if (req.valid() == 0) + cout << "ERROR: oid value: " <<get_opt.optarg \ + << "is not valid. using default.\n"; + break; + + case 'c': + community_ = get_opt.optarg; + target_.set_read_community(community_); + break; + + case 'r': + target_.set_retry(ACE_OS::atoi (get_opt.optarg)); + break; + + case 't': + target_.set_timeout(ACE_OS::atoi (get_opt.optarg)); + break; + + default: + break; + } + + Vb vb; // construct a Vb object + if (req.valid()) + vb.set_oid( req); // set the Oid portion of the Vb + else { + vb.set_oid( def_oid); // set the Oid portion of the Vb + } + pdu_ += vb; + vb.get_oid(oid_); // store for later use + valid_ = 1; +} + +void nextapp::usage() +{ + cout << "Usage:\n"; + cout << "next [options] dotted-quad | DNSName[:port]\n"; + cout << " -o OID starts with oid after 1.3.6.1.2.1.1.1.0 (mibII sysDescr.0) \n"; + cout << " -c Community_name, default is 'public' \n"; + cout << " -r N retries default is N = 1 retry\n"; + cout << " -t N timeout in seconds default is 1 second" << endl; +} + + +int nextapp::run() +{ + + //----------[ create a ASNMP session ]----------------------------------- + if ( snmp_.valid() != SNMP_CLASS_SUCCESS) { + cout << "\nASNMP:ERROR:Create session failed: "<< + snmp_.error_string()<< "\n"; + return 1; + } + + //--------[ build up ASNMP object needed ]------------------------------- + if (address_.get_port() == 0) + address_.set_port(DEF_AGENT_PORT); + target_.set_address( address_); // make a target using the address + + //-------[ issue the request, blocked mode ]----------------------------- + cout << "\nASNMP:INFO:SNMP Version " << (target_.get_version()+ 1) << \ + " GET_NEXT SAMPLE PROGRAM \nOID: " << oid_.to_string() << "\n"; + target_.get_address(address_); // target updates port used + int rc; + char *name = address_.friendly_name(rc); + if (rc) + name = "<< did not resolve via gethostbyname() >>"; + + cout << "Device: " << address_ << " " << name << "\n"; + cout << "[ Retries=" << target_.get_retry() << " \ + Timeout=" << target_.get_timeout() <<" ms " << "Community=" << \ + community_.to_string() << " ]"<< endl; + + if (snmp_.get_next( pdu_, target_) == SNMP_CLASS_SUCCESS) { + Vb vb; + // check to see if there are any errors + if (pdu_.get_error_status()) { + cout << "ERROR: agent replied as follows\n"; + cout << pdu_.agent_error_reason() << endl; + } + else { + VbIter iter(pdu_); + while (iter.next(vb)) { + cout << "\tOid = " << vb.to_string_oid() << "\n"; + cout << "\tValue = " << vb.to_string_value() << "\n"; + } + } + } + else { + char *ptr = snmp_.error_string(); + cout << "ASNMP:ERROR: get_next command failed reason: " << ptr << endl; + } + cout << "ASNMP:INFO:command completed normally. ACE Rocks...\n"<< endl; + return 0; +} + diff --git a/ASNMP/examples/set/Makefile b/ASNMP/examples/set/Makefile new file mode 100644 index 00000000000..eb38a22520b --- /dev/null +++ b/ASNMP/examples/set/Makefile @@ -0,0 +1,41 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for set sample application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + + +# ACE+SNMP +BIN = set +CCFLAGS = -I$(WRAPPER_ROOT)/ASNMP/ +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = -R$(WRAPPER_ROOT)/ASNMP/asnmp -L$(WRAPPER_ROOT)/ASNMP/asnmp -lasnmp $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/ASNMP/examples/set/set.cpp b/ASNMP/examples/set/set.cpp new file mode 100644 index 00000000000..f0522cbff8d --- /dev/null +++ b/ASNMP/examples/set/set.cpp @@ -0,0 +1,260 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// set.cpp +// +// = DESCRIPTION +// Sample application demonstrating synchronous Snmp::set API +// to update an oid in an SNMP Version 1 agent. +// +// = AUTHOR +// Peter E. Mellquist original code +// Michael R MacFaden mrm@cisco.com rework API/ACE integration +// +// ============================================================================ +/*=================================================================== + 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 "ace/Get_Opt.h" + +// +// SNMPv1 Set Application +// +class set { + public: + set(int argc, char **argv); // process command line args + int valid() const; // verify transaction can proceed + int run(); // issue transaction + static void usage(); // operator help message + + private: + set(const set&); + + UdpAddress address_; + Pdu pdu_; // construct a request Pdu + Oid oid_; + OctetStr community_; + Snmp snmp_; + UdpTarget target_; + int valid_; +}; + + +// main entry point +int main( int argc, char *argv[]) +{ + set get(argc, argv); + if (get.valid()) + return get.run(); + else + set::usage(); + return 1; +} + +set::valid() const +{ + return valid_; +} + +set::set(int argc, char *argv[]): valid_(0) +{ + Vb vb; // construct a Vb object + Oid req; + if ( argc < 2) + return; + target_.get_write_community(community_); + address_ = argv[argc - 1]; + if ( !address_.valid()) { + cout << "ERROR: Invalid IPv4 address or DNS hostname: " \ + << argv[argc] << "\n"; + return; + } + + ACE_Get_Opt get_opt (argc, argv, "o:c:r:t:I:U:C:G:T:O:S:P:"); + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'o': + req = get_opt.optarg; + if (req.valid() == 0) + cout << "ERROR: oid value: " <<get_opt.optarg \ + << "is not valid. using default.\n"; + break; + + case 'c': + community_ = get_opt.optarg; + target_.set_write_community(community_); + break; + + case 'r': + target_.set_retry(ACE_OS::atoi (get_opt.optarg)); + break; + + case 't': + target_.set_timeout(ACE_OS::atoi (get_opt.optarg)); + break; + + case 'I': // Integer32 + { + SnmpInt32 o(ACE_OS::atoi(get_opt.optarg)); + vb.set_value(o); + pdu_ += vb; + } + break; + + case 'U': // Unsigned32 + { + SnmpUInt32 o(ACE_OS::atoi(get_opt.optarg)); + vb.set_value(o); + pdu_ += vb; + } + break; + + case 'C': // Counter32 + { + Counter32 o(ACE_OS::atoi(get_opt.optarg)); + vb.set_value(o); + pdu_ += vb; + } + break; + + case 'G': // Gauge32 + { + Gauge32 o(ACE_OS::atoi(get_opt.optarg)); + vb.set_value(o); + pdu_ += vb; + } + break; + + case 'T': // TimeTicks + { + TimeTicks o(ACE_OS::atoi(get_opt.optarg)); + vb.set_value(o); + pdu_ += vb; + } + break; + + case 'O': // Oid as a variable identifier + { + oid_ = get_opt.optarg; + vb.set_oid(oid_); // when value is set, pdu updated + } + break; + + case 'S': // Octet String + { + OctetStr o(get_opt.optarg); + vb.set_value(o); // set the Oid portion of the Vb + pdu_ += vb; + } + break; + + case 'P': // Oid String as a value + { + Oid o(get_opt.optarg); + vb.set_value(o); // set the Oid portion of the Vb + pdu_ += vb; + } + break; + + default: + break; + } + + // if user didn't set anything use defaults + if (pdu_.get_vb_count() == 0) { + Oid def_oid("1.3.6.1.2.1.1.4.0"); // defualt is sysName + OctetStr def_value("sysName.0 updated by ASNMP set command"); + vb.set_oid(def_oid); + vb.set_value(def_value); + pdu_ += vb; + cout << "INFO: using defaults, setting sysName to : " << \ + def_value.to_string() << endl; + } + + valid_ = 1; +} + +void set::usage() +{ + cout << "Usage:\n"; + cout << "next [options] dotted-quad | DNSName[:port]\n"; + cout << " -o OID starts with oid after 1.3.6.1.2.1.1.1.0 (mibII sysDescr.0) \n"; + cout << " -c Community_name, default is 'private' \n"; + cout << " -r N retries default is N = 1 retry\n"; + cout << " -t N timeout in seconds default is 1 second\n"; + cout << " -O oid_to_set -{I,U,G,S,P} value\n"; + cout << " where I=int32, U=uint32, G=gauge32, S=octet, P=oid" << endl; +} + + +int set::run() +{ + + //----------[ create a ASNMP session ]----------------------------------- + if ( snmp_.valid() != SNMP_CLASS_SUCCESS) { + cout << "\nASNMP:ERROR:Create session failed: "<< + snmp_.error_string()<< "\n"; + return 1; + } + + //--------[ build up ASNMP object needed ]------------------------------- + if (address_.get_port() == 0) + address_.set_port(DEF_AGENT_PORT); + target_.set_address( address_); // make a target using the address + + //-------[ issue the request, blocked mode ]----------------------------- + cout << "\nASNMP:INFO:SNMP Version " << (target_.get_version()+ 1) << \ + " SET SAMPLE PROGRAM \nOID: " << oid_.to_string() << "\n"; + target_.get_address(address_); // target updates port used + int rc; + char *name = address_.friendly_name(rc); + if (rc) + name = "<< did not resolve via gethostbyname() >>"; + + cout << "Device: " << address_ << " " << name << "\n"; + cout << "[ Retries=" << target_.get_retry() << " \ + Timeout=" << target_.get_timeout() <<" ms " << "Community=" << \ + community_.to_string() << " ]"<< endl; + + if (snmp_.set( pdu_, target_) == SNMP_CLASS_SUCCESS) { + Vb vb; + // check to see if there are any errors + if (pdu_.get_error_status()) { + cout << "ERROR: agent replied as follows\n"; + cout << pdu_.agent_error_reason() << endl; + } + else { + VbIter iter(pdu_); + while (iter.next(vb)) { + cout << "\tOid = " << vb.to_string_oid() << "\n"; + cout << "\tValue = " << vb.to_string_value() << "\n"; + } + } + } + else { + char *ptr = snmp_.error_string(); + cout << "ASNMP:ERROR: set command failed reason: " << ptr << endl; + } + cout << "ASNMP:INFO:command completed normally.\n"<< endl; + return 0; +} + diff --git a/ASNMP/examples/trap/Makefile b/ASNMP/examples/trap/Makefile new file mode 100644 index 00000000000..09523f48940 --- /dev/null +++ b/ASNMP/examples/trap/Makefile @@ -0,0 +1,41 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for trap sample application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + + +# ACE+SNMP +BIN = trap +CCFLAGS = -I$(WRAPPER_ROOT)/ASNMP/ +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = -R$(WRAPPER_ROOT)/ASNMP/asnmp -L$(WRAPPER_ROOT)/ASNMP/asnmp -lasnmp $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/ASNMP/examples/trap/trap.cpp b/ASNMP/examples/trap/trap.cpp new file mode 100644 index 00000000000..55ad2127377 --- /dev/null +++ b/ASNMP/examples/trap/trap.cpp @@ -0,0 +1,179 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// trap.cpp +// +// = DESCRIPTION +// Sample application demonstrating synchronous Snmp::trap API +// to send to an SNMP Version 1 trap listener app. +// +// = AUTHOR +// Peter E. Mellquist original code +// Michael R MacFaden mrm@cisco.com rework OO, API/ACE integration +// +// ============================================================================ +/*=================================================================== + 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" +#define DEFINE_TRAP_CONSTANTS_ +#include "asnmp/enttraps.h" // enterprise standard traps +#include "ace/Get_Opt.h" + +// +// SNMPv1 Trap Application +// +class trapapp { + public: + trapapp(int argc, char **argv); // process command line args + int valid() const; // verify transaction can proceed + int run(); // issue transaction + static void usage(); // operator help message + + private: + trapapp(const trapapp&); + + UdpAddress address_; + Pdu pdu_; // construct a request Pdu + Oid oid_; + OctetStr community_; + Snmp snmp_; + UdpTarget target_; + int valid_; +}; + + +// main entry point +int main( int argc, char *argv[]) +{ + trapapp get(argc, argv); + if (get.valid()) + return get.run(); + else + trapapp::usage(); + return 1; +} + +trapapp::valid() const +{ + return valid_; +} +trapapp::trapapp(int argc, char *argv[]): valid_(0) +{ + Oid def_ent_oid("1.3.6.1.2.1.1.1.2.0.1"); // def enterprise oid + Oid ent, trap; // user specified values + + if ( argc < 2) // hostname mandatory + return; + + address_ = argv[argc - 1]; + if ( !address_.valid()) { + cout << "ERROR: Invalid IPv4 address or DNS hostname: " \ + << argv[argc] << "\n"; + return; + } + + ACE_Get_Opt get_opt (argc, argv, "c:e:t:"); + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'c': // community string + community_ = get_opt.optarg; + target_.set_read_community(community_); + break; + + case 'e': // trap oid to send + ent = get_opt.optarg; + break; + + case 't': // trap oid + trap = get_opt.optarg; + break;; + + default: + break; + } + + if (ent.valid()) + pdu_.set_notify_enterprise( ent); // set up the enterprise of the trap + else + pdu_.set_notify_enterprise( def_ent_oid); + + if (trap.valid()) + pdu_.set_notify_id( trap); // set the id of the trap + else + pdu_.set_notify_id( coldStart); // set the id of the trap + + Oid detail_oid("1.3.6.1.4.1.11.2.16.2"); + OctetStr detail_value("SNMP++ Trap Send Test"); + Vb vb(detail_oid, detail_value); + pdu_ += vb; + + pdu_.get_notify_id(oid_); // store for later use + valid_ = 1; +} + +void trapapp::usage() +{ + cout << "Usage:\n"; + cout << "trap [options] dotted-quad | DNSName[:port]\n"; + cout << " -c Community_name, default is 'public' \n"; + cout << " -r N retries default is N = 1 retry\n"; + cout << " -t N timeout in seconds default is 1 second" << endl; + cout << " -e oid enterprise oid default is 1.3.6.1.2.1.1.1.2.0.1\n"; + cout << " -O oid trap id default is coldStart 1.3.6.1.6.3.1.1.5.1\n"; +} + +int trapapp::run() +{ + if ( snmp_.valid() != SNMP_CLASS_SUCCESS) { + cout << "\nASNMP:ERROR:Create session failed: "<< + snmp_.error_string()<< "\n"; + return 1; + } + + if (address_.get_port() == 0) + address_.set_port(DEF_TRAP_PORT); + target_.set_address( address_); // make a target using the address + + //-------[ issue the request, blocked mode ]----------------------------- + cout << "\nASNMP:INFO:SNMP Version " << (target_.get_version()+ 1) << \ + " TRAP GENERATOR SAMPLE PROGRAM \nOID: " << oid_.to_string() << "\n"; + target_.get_address(address_); // target updates port used + int rc; + char *name = address_.friendly_name(rc); + if (rc) + name = "<< did not resolve via gethostbyname() >>"; + + cout << "Device: " << address_ << " " << name << "\n"; + cout << "[ Community=" << community_.to_string() << " ]"<< endl; + + if (snmp_.trap( pdu_, target_) == SNMP_CLASS_SUCCESS) { + cout << "Trap was written to network...\n"; + } + else { + char *ptr = snmp_.error_string(); + cout << "ASNMP:ERROR: trap command failed reason: " << ptr << endl; + } + + cout << "ASNMP:INFO:command completed normally.\n"<< endl; + return 0; +} + diff --git a/ASNMP/examples/walk/Makefile b/ASNMP/examples/walk/Makefile new file mode 100644 index 00000000000..bde5a38a5a6 --- /dev/null +++ b/ASNMP/examples/walk/Makefile @@ -0,0 +1,41 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for walk sample application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + + +# ACE+SNMP +BIN = walk +CCFLAGS = -I$(WRAPPER_ROOT)/ASNMP/ +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = -L$(WRAPPER_ROOT)/ASNMP/asnmp -lasnmp $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/ASNMP/examples/walk/walk.cpp b/ASNMP/examples/walk/walk.cpp new file mode 100644 index 00000000000..6f6ba1e2463 --- /dev/null +++ b/ASNMP/examples/walk/walk.cpp @@ -0,0 +1,257 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// walk.cpp +// +// = DESCRIPTION +// Sample application demonstrating synchronous Snmp::get, get_next API +// to access an SNMP Version 1 agent. +// +// = AUTHOR +// Peter E. Mellquist original code +// Michael R MacFaden mrm@cisco.com rework API/ACE integration +// +// ============================================================================ +/*=================================================================== + 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 "ace/Get_Opt.h" + +// +// SNMPv1 Walk Mib Application +// +class walkapp { + public: + walkapp(int argc, char **argv); // process command line args + int valid() const; // verify transaction can proceed + int run(); // issue transaction + static void usage(); // operator help message + + private: + walkapp(const walkapp&); + + UdpAddress address_; + Pdu pdu_; // construct a request Pdu + Oid oid_; + OctetStr community_; + Snmp snmp_; + UdpTarget target_; + int valid_; +}; + + +// main entry point +int main( int argc, char *argv[]) +{ + walkapp get(argc, argv); + if (get.valid()) + return get.run(); + else + walkapp::usage(); + return 1; +} + +walkapp::valid() const +{ + return valid_; +} + +walkapp::walkapp(int argc, char *argv[]): valid_(0) +{ + Oid req, def_oid("1.3.6.1.2.1.1.1.0"); // default begin walk with MIBII + if ( argc < 2) + return; + + address_ = argv[argc - 1]; + if ( !address_.valid()) { + cout << "ERROR: Invalid IPv4 address or DNS hostname: " \ + << argv[argc] << "\n"; + return; + } + + ACE_Get_Opt get_opt (argc, argv, "o:c:r:t:"); + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'o': + req = get_opt.optarg; + if (req.valid() == 0) + cout << "ERROR: oid value: " <<get_opt.optarg \ + << "is not valid. using default.\n"; + break; + + case 'c': + community_ = get_opt.optarg; + target_.set_read_community(community_); + break; + + case 'r': + target_.set_retry(ACE_OS::atoi (get_opt.optarg)); + break; + + case 't': + target_.set_timeout(ACE_OS::atoi (get_opt.optarg)); + break; + + default: + break; + } + + Vb vb; // construct a Vb object + if (req.valid()) + vb.set_oid( req); // set the Oid portion of the Vb + else { + vb.set_oid( def_oid); // set the Oid portion of the Vb + } + pdu_ += vb; + vb.get_oid(oid_); // store for later use + valid_ = 1; +} + +void walkapp::usage() +{ + cout << "Usage:\n"; + cout << "walk [options] dotted-quad | DNSName[:port]\n"; + cout << " -o OID starts with oid after 1.3.6.1.2.1.1.1.0 (mibII sysDescr.0) \n"; + cout << " -c Community_name, default is 'public' \n"; + cout << " -r N retries default is N = 1 retry\n"; + cout << " -t N timeout in seconds default is 1 second" << endl; +} + + +// +// simple mib iterator class +// +class MibIter { + public: + // Pdu must contain initial oid to begin with + MibIter(Snmp *snmp, Pdu& pdu, UdpTarget* target); + int next(Vb& vb, char *&err_reason); // return next oid in mib + + private: + Snmp *snmp_; + UdpTarget *target_; + Pdu pdu_; + Vb vb_; + int first_; // flag to obtain first entry + int valid_; // flag to obtain first entry +}; + +MibIter::MibIter(Snmp* snmp, Pdu& pdu, UdpTarget *target): + snmp_(snmp), pdu_(pdu), first_(0), + valid_(0), target_(target) +{ + // verify we have a valid oid to begin iterating with + Oid oid; + Vb vb; + pdu.get_vb(vb, 0); + vb.get_oid(oid); + if (oid.valid()) + valid_ = 1; +} + +// return vb of next oid in agent tree, return 1 else return 0, reason set +int MibIter::next(Vb& vb, char *& reason) +{ + int rc; + + if (valid_ == 0) // not valid object + return -1; + + // 1. poll for value + if (first_ == 0) { + rc = snmp_->get( pdu_, *target_); + first_++; + } + else { + rc = snmp_->get_next( pdu_, *target_); + } + + if (rc != SNMP_CLASS_SUCCESS) { + reason = snmp_->error_string(); + return 0; + } + + // 2. check for problems + if (pdu_.get_error_status()) { + reason = pdu_.agent_error_reason(); + return 0; + } + + // 3. return vb to caller + pdu_.get_vb(vb, 0); + Oid nextoid; + vb.get_oid(nextoid); // and setup next oid to get + Vb nextvb(nextoid); + pdu_.delete_all_vbs(); + pdu_ += nextvb; // can't do set_vb as there are no entries to replace + + return 1; // ok +} + +int walkapp::run() +{ + + //----------[ create a ASNMP session ]----------------------------------- + if ( snmp_.valid() != SNMP_CLASS_SUCCESS) { + cout << "\nASNMP:ERROR:Create session failed: "<< + snmp_.error_string()<< "\n"; + return 1; + } + + //--------[ build up ASNMP object needed ]------------------------------- + if (address_.get_port() == 0) + address_.set_port(DEF_AGENT_PORT); + target_.set_address( address_); // make a target using the address + + //-------[ issue the request, blocked mode ]----------------------------- + cout << "\nASNMP:INFO:SNMP Version " << (target_.get_version()+ 1) << \ + " WALK SAMPLE PROGRAM \nOID: " << oid_.to_string() << "\n"; + target_.get_address(address_); // target updates port used + int rc; + char *name = address_.friendly_name(rc); + if (rc) + name = "<< did not resolve via gethostbyname() >>"; + + cout << "Device: " << address_ << " " << name << "\n"; + cout << "[ Retries=" << target_.get_retry() << " \ + Timeout=" << target_.get_timeout() <<" ms " << "Community=" << \ + community_.to_string() << " ]"<< endl; + + MibIter iter(&snmp_, pdu_, &target_); + char *err_str = 0; + Vb vb; + unsigned ctr = 0; + while (iter.next(vb, err_str)) { + cout << "\tOid = " << vb.to_string_oid() << "\n"; + cout << "\tValue = " << vb.to_string_value() << "\n"; + ctr++; + } + + if (!err_str) { + cout << "ERROR: walk: " << err_str << endl; + return 0; + } + + cout << "ASNMP:INFO:command completed normally. ACE Rocks...\n"<< endl; + return 0; +} + diff --git a/ASNMP/tests/Address_Test.cpp b/ASNMP/tests/Address_Test.cpp new file mode 100644 index 00000000000..9017e6b7967 --- /dev/null +++ b/ASNMP/tests/Address_Test.cpp @@ -0,0 +1,546 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Address_Test.cpp +// +// = DESCRIPTION +// Test all the member functions of the Address family: +// GenAddress, MacAddress, IpxAddress, IpAddress, UdpAddress +// all which derive from abstract base class Address. +// +// = AUTHOR +// Michael R. MacFaden <mrm@cisco.com> +// +// ============================================================================ +/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Copyright 1997 Cisco Systems, Inc. + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this +copyright and permission notice appear on all copies of the software and +supporting documentation, the name of Cisco Systems, Inc. not be used +in advertising or publicity pertaining to distribution of the +program without specific prior permission, and notice be given +in supporting documentation that modification, copying and distribution is by +permission of Cisco Systems, Inc. + +Cisco Systems, Inc. makes no representations about the suitability of this +software for any purpose. THIS SOFTWARE IS PROVIDED ``AS IS'' +AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT +LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGMENT AND +FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL CISCO SYSTEMS, INC. BE +LIABLE FOR ANY DAMAGES ARISING OUT OF THIS LICENSE OR YOUR USE OF THE +SOFTWARE INCLUDING WITHOUT LIMITATION, DIRECT, INDIRECT OR CONSEQUENTIAL +DAMAGES. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ + +#include "asnmp/address.h" +#include "test_config.h" + +// hack: do this so when linking SUNC 4.x compiler will instantiate template +#include "ace/Containers.h" +ACE_Unbounded_Set<ACE_Log_Msg*> x; + +// test the GenAddress interface +/* + */ +static void TestGenAddr() +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress: Tests: var(expected) [actual]\n")); + + // the constructors and destructors + GenAddress *ga1 = new GenAddress("1.2.3.4"); // use ipv4 address + ACE_ASSERT(ga1->valid() == 1); + GenAddress ga2(*ga1); // copy constructor; + ACE_ASSERT(ga2.valid() == 1); + GenAddress ga3("localhost"); + ACE_ASSERT(ga3.valid() == 1); + GenAddress ga4; // default constructor + ACE_ASSERT(ga4.valid() == 0); + GenAddress ga5; // default constructor + ACE_ASSERT(ga5.valid() == 0); + GenAddress ga6("127.0.0.1:7"); // udp address + ACE_ASSERT(ga6.valid() == 1); + GenAddress ga7("01234567.89ABcDeF0123"); // ipx address + ACE_ASSERT(ga7.valid() == 1); + IpAddress ip("1.2.3.4"); + ACE_ASSERT(ip.valid() == 1); + GenAddress ga8(ip); // Address conversion + ACE_ASSERT(ga8.valid() == 1); + + const char *ptr = (const char *)ga8; + + ACE_ASSERT(ga1 != 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga1(\"1.2.3.4\") [%s]\n", + ga1->to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga2(ga1) [%s]\n", + ga2.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga3(\"localhost\") [%s]\n", + ga3.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga4(\"\") [%s]\n", + ga4.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga6(\"127.0.0.1:7\") [%s]\n", + ga6.to_string())); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga7(\"01234567.89ABcDeF0123\") [%s]\n", + ga7.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga8(\"1.2.3.4\") [%s]\n", + ga8.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga8(\"1.2.3.4\") [%s]\n", + ptr)); + + // Test Assignment x = y, y = x + ga5 = ga3; // regular assignment + ga3 = ga3; // self assignment + ACE_ASSERT(ga5 == ga3); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga5=ga3(\"localhost\") [%s]\n", + ga5.to_string())); + + addr_type a = ga2.get_type(); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga2.get_type(\"0\") [%d]\n", + a)); + // udp address string + a = ga6.get_type(); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga2.get_type(\"2\") [%d]\n", + a)); + + // udp address string + a = ga7.get_type(); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) GenAddress:ga2.get_type(\"1\") [%d]\n", + a)); + + delete ga1, ga1 = 0; +} + +/* public methods + IpAddress( const char *inaddr = ""); + IpAddress( const IpAddress &ipaddr); + IpAddress( const GenAddress &genaddr); + ~IpAddress(); + SnmpSyntax& operator=( SnmpSyntax &val); + IpAddress& operator=( const IpAddress &ipaddress); + SnmpSyntax *clone() const; + char *friendly_name(int &status); + virtual char *to_string() ; + virtual operator const char *() const; + void mask( const IpAddress& ipaddr); + virtual addr_type get_type() const; + virtual SmiUINT32 get_syntax(); + int is_loopback() const; + int is_multicast() const; + int is_broadcast() const; + int is_arpanet() const; + */ +static void TestIpAddress() +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpAddress: Tests\n")); + + // constructors + GenAddress ga("255.255.255.255"); + IpAddress ia1; + IpAddress ia2("224.2.3.4"); + ACE_ASSERT(ia2.is_multicast()); + ACE_ASSERT(!ia2.is_loopback()); + IpAddress ia3("localhost"); + ACE_ASSERT(ia3.is_loopback()); + ACE_ASSERT(!ia3.is_multicast()); + IpAddress ia4(ia3); + ACE_ASSERT(ia4.is_loopback()); + ACE_ASSERT(!ia4.is_multicast()); + IpAddress ia5(ga); + ACE_ASSERT(ia5.is_broadcast()); + IpAddress ia6 = IpAddress("10.0.0.2"); + ACE_ASSERT(ia6.is_arpanet()); + ACE_ASSERT(!ia6.is_multicast()); + ACE_ASSERT(!ia6.is_loopback()); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpAddress:ia1(\"\") [%s]\n", + ia1.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpAddress:ia2(\"1.2.3.4\") [%s]\n", + ia2.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpAddress:ia3(\"127.0.0.1\") [%s]\n", + ia3.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpAddress:ia4(\"ia3\") [%s]\n", + ia4.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpAddress:ia5(\"255.255.255.255\") [%s]\n", + ia5.to_string())); + + // other routines + int status = 1; + const char *ptr = ia5.friendly_name(status); + ACE_ASSERT(status == 0); + ACE_ASSERT(ptr != 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpAddress:ia5.friendly_name():(\"\") [%s]\n", + ptr)); + + // now lets try one we setup with a hostname + ptr = ia3.friendly_name(status); + ACE_ASSERT(status == 0); + ACE_ASSERT(ptr != 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpAddress:ia3.friendly_name()(\"localhost\") [%s]\n", + ptr)); + + ptr = (const char *)ia5; + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpAddress:(const char *)(\"255.255.255.255\") [%s]\n", + ptr)); + + ia2 = ia3; + ACE_ASSERT(ia2 == ia3); + + ia4.mask(ia3); // mask with equal value should return same + ACE_ASSERT(ia2 == ia3); + + ACE_ASSERT(ia1.get_type() == type_ip); + ACE_ASSERT(ia1.valid() == 0); + ACE_ASSERT(ia2.get_type() == type_ip); + ACE_ASSERT(ia2.valid() == 1); + ACE_ASSERT(ia3.get_type() == type_ip); + ACE_ASSERT(ia3.valid() == 1); + ACE_ASSERT(ia4.get_type() == type_ip); + ACE_ASSERT(ia4.valid() == 1); + ACE_ASSERT(ia5.get_type() == type_ip); + ACE_ASSERT(ia5.valid() == 1); +} + + +// --------------- Netbios --------------- +/* + NetbiosAddress( const char *inaddr = ""); + NetbiosAddress( const NetbiosAddress& nbaddr); + NetbiosAddress( const GenAddress& genaddr); + ~NetbiosAddress(); + virtual char *to_string(); + NetbiosAddress& operator=( const NetbiosAddress &nbaddr); + nb_service get_service_type() const; + void set_service_type(nb_service nbservice); + virtual operator const char *() const; + virtual SmiUINT32 get_syntax(); + SnmpSyntax& operator=( SnmpSyntax &val); + SnmpSyntax *clone() const; + */ +static void TestNetbiosAddress() +{ + NetbiosAddress n1; + ACE_ASSERT(n1.valid() == 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) NetbiosAddress:n1(\"\") [%s]\n", + n1.to_string())); + + NetbiosAddress n2(n1); + ACE_ASSERT(n2.valid() == 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) NetbiosAddress:n2(n1) [%s]\n", + n2.to_string())); + + NetbiosAddress n3("pcname"); + ACE_ASSERT(n3.valid() == 1); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) NetbiosAddress:n3(\"pcname\") [%s]\n", + n3.to_string())); + + NetbiosAddress n4("abcdefghigjklmn"); + n4.set_service_type(nb_workstation); + ACE_ASSERT(n4.valid() == 1); + ACE_ASSERT(n4.get_service_type() == nb_workstation); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) NetbiosAddress:n4(\"abcdefghigjklmn\") [%s]\n", + n4.to_string())); + + NetbiosAddress n5("abcdefghigjklmno0xx"); + ACE_ASSERT(n5.valid() == 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) NetbiosAddress:n4(\"abcdefghigjklmno0xx\") [%s]\n", + n5.to_string())); + + n1 = n4; + ACE_ASSERT(n1 == n4); + ACE_ASSERT(strcmp((const char *)n1, (const char *)n4) == 0); + + n1.set_service_type(nb_server); + nb_service x = n1.get_service_type(); + ACE_ASSERT(x == nb_server); +} + +// --------------- IPX --------------- +/* + IpxAddress( void); + IpxAddress( const char *inaddr); + IpxAddress( const IpxAddress &ipxaddr); + IpxAddress( const GenAddress &genaddr); + ~IpxAddress(); + virtual SmiUINT32 get_syntax(); + SnmpSyntax& operator=( SnmpSyntax &val); + IpxAddress& operator=( const IpxAddress &ipxaddress); + int get_hostid( MacAddress& mac); + SnmpSyntax *clone() const; + virtual operator const char *() const; + virtual addr_type get_type() const; + +Ipx Address semantics: 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 + + */ + +static void TestIpxAddress() +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpxAddress: Tests\n")); + IpxAddress xa1; + ACE_ASSERT(xa1.valid() == 0); + ACE_ASSERT(xa1.get_type() == type_ipx); + GenAddress gen("01234567.0123456789AB"); + ACE_ASSERT(gen.valid() == 1); + IpxAddress xa2("01234567.0123456789AB"); + ACE_ASSERT(xa2.get_type() == type_ipx); + ACE_ASSERT(xa2.valid() == 1); + IpxAddress xa3("01234567:0123456789AB"); + ACE_ASSERT(xa3.get_type() == type_ipx); + ACE_ASSERT(xa3.valid() == 1); + IpxAddress xa4("01234567-0123456789AB"); + ACE_ASSERT(xa4.get_type() == type_ipx); + ACE_ASSERT(xa4.valid() == 1); + IpxAddress xa5("01234567.012345-6789AB"); + ACE_ASSERT(xa5.get_type() == type_ipx); + ACE_ASSERT(xa5.valid() == 1); + IpxAddress xa6("01234567:012345-6789AB"); + ACE_ASSERT(xa6.get_type() == type_ipx); + ACE_ASSERT(xa6.valid() == 1); + IpxAddress xa7("01234567-012345-6789AB"); + ACE_ASSERT(xa7.get_type() == type_ipx); + ACE_ASSERT(xa7.valid() == 1); + IpxAddress xa8("01234567."); + ACE_ASSERT(xa8.get_type() == type_ipx); + ACE_ASSERT(xa8.valid() == 0); + IpxAddress xa9(gen); + ACE_ASSERT(xa9.valid() == 1); + IpxAddress *xa10 = new IpxAddress(xa9); + ACE_ASSERT(xa10->get_type() == type_ipx); + ACE_ASSERT(xa10->valid() == 1); + delete xa10; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpxAddress:xa1(\"\") [%s]\n", + xa1.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpxAddress:xa2(\"01234567.0123456789AB\") [%s]\n", + xa2.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpxAddress:xa3(\"01234567:0123456789A\") [%s]\n", + xa3.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpxAddress:xa4(\"01234567-0123456789AB\") [%s]\n", + xa4.to_string())); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpxAddress:xa5(\"01234567.012345-6789AB\") [%s]\n", + xa5.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpxAddress:xa6(\"01234567:012345-6789AB\") [%s]\n", + xa6.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpxAddress:xa7(\"01234567-012345-6789AB\") [%s]\n", + xa7.to_string())); + + // assignment + xa1 = xa3; + ACE_ASSERT(xa1 == xa3); + MacAddress mac; + ACE_ASSERT(xa4.get_hostid(mac) == 1); + ACE_ASSERT(mac.valid() == 1); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpxAddress:xa4:get_hostid(\"01:23:45:67:89:ab\") [%s]\n", mac.to_string())); + + const char *ptr = (const char *)xa7; + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpxAddress:xa7-ptr(\"01234567-012345-6789AB\") [%s]\n", ptr)); + +} + +/* + MacAddress( void); + + MacAddress( const char *inaddr); + MacAddress( const MacAddress &macaddr); + MacAddress( const GenAddress &genaddr); + ~MacAddress(); +* SmiUINT32 get_syntax(); +* SnmpSyntax& operator=( SnmpSyntax &val); + MacAddress& operator=( const MacAddress &macaddress); +* SnmpSyntax *clone() const; + virtual char *to_string(); + virtual operator const char *() const; + virtual addr_type get_type() const; + unsigned int hashFunction() const; + +// 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 +// + +*/ + +static void TestMacAddress() +{ + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) MacAddress: Tests\n")); + + MacAddress ma1; + ACE_ASSERT(ma1.valid() == 0); + ACE_ASSERT(ma1.get_type() == type_mac); + MacAddress ma2("01:23:45:67:89:AB"); + ACE_ASSERT(ma2.valid() == 1); + ACE_ASSERT(ma2.get_type() == type_mac); + MacAddress ma3("0123456789ABCEFGHI"); // invalid string + ACE_ASSERT(ma3.valid() == 0); + ACE_ASSERT(ma3.get_type() == type_mac); + GenAddress ga("01:23:45:67:89:AB"); // mac address + MacAddress ma4(ma2); + ACE_ASSERT(ma4.valid() == 1); + ACE_ASSERT(ma4.get_type() == type_mac); + MacAddress ma5(ga); + ACE_ASSERT(ma5.valid() == 0); + ACE_ASSERT(ma5.get_type() == type_mac); + + ma1 = ma2; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) MacAddress:ma1(\"01:23:45:67:89:AB\") [%s]\n", + ma1.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) MacAddress:ma2(\"01:23:45:67:89:AB\") [%s]\n", + ma2.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) MacAddress:ma3(\"\") [%s]\n", + ma3.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) MacAddress:ma4(\"01:23:45:67:89:AB\") [%s]\n", + ma4.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) MacAddress:ma5(\"\") [%s]\n", + ma5.to_string())); + const char * ptr = (const char *)ma5; + ACE_DEBUG ((LM_DEBUG, "(%P|%t) MacAddress:ma5(\"\") [%s]\n", + ptr)); + + // hashFunction crashes if not usedwith valid fn + int x = ma2.hashFunction(); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) MacAddress:ma2.hashFunction(\"483201\") [%d]\n", + x)); +} + +/* + UdpAddress( void); + UdpAddress( const char *inaddr); + UdpAddress( const UdpAddress &udpaddr); + UdpAddress( const GenAddress &genaddr); + UdpAddress( const IpAddress &ipaddr); + ~UdpAddress(); + SmiUINT32 get_syntax(); + SnmpSyntax& operator=( SnmpSyntax &val); + UdpAddress& operator=( const UdpAddress &udpaddr); + SnmpSyntax *clone() const; + virtual char *to_string() ; + virtual operator const char *() const; + void set_port( const unsigned short p); + unsigned short get_port() const; + virtual addr_type get_type() const; + + // 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 + + */ + +static void TestUdpAddress() +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpAddress: Tests\n")); + + UdpAddress ua1; + ACE_ASSERT(ua1.valid() == 0); + ACE_ASSERT(ua1.get_type() == type_udp); + + // semantics of not setting the port here are bizzare? + UdpAddress ua2("127.0.0.1:161"); + ACE_ASSERT(ua2.valid() == 1); + ACE_ASSERT(ua2.get_type() == type_udp); + + UdpAddress ua3(ua2); + ACE_ASSERT(ua3.valid() == 1); + ACE_ASSERT(ua3.get_type() == type_udp); + + GenAddress ga("localhost"); + UdpAddress ua4(ga); + ACE_ASSERT(ua4.valid() == 1); + ACE_ASSERT(ua4.get_type() == type_udp); + + IpAddress ia("localhost"); + UdpAddress ua5(ga); + ACE_ASSERT(ua5.valid() == 1); + ACE_ASSERT(ua5.get_type() == type_udp); + + UdpAddress *ua6 = new UdpAddress("localhost:161"); + ACE_ASSERT(ua6->valid() == 1); + ACE_ASSERT(ua6->get_type() == type_udp); + + UdpAddress ua7 = UdpAddress("localhost/162"); + ACE_ASSERT(ua7.valid() == 1); + ACE_ASSERT(ua7.get_type() == type_udp); + + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpAddress:ua1(\"\") [%s]\n", + ua1.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpAddress:ua2(\"127.0.0.1:161\") [%s]\n", + ua2.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpAddress:ua3(ua2)(\"127.0.0.1:161\") [%s]\n", + ua3.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpAddress:ua4(GenAddress)(\"127.0.0.1\") [%s]\n", + ua4.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpAddress:ua5(IpAddress)(\"127.0.0.1\") [%s]\n", + ua5.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpAddress:ua6()(\"localhost:161\") [%s]\n", + ua6->to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpAddress:ua7()(\"localhost/162\") [%s]\n", + ua7.to_string())); + + delete ua6; // destructor + + // assignement tests. + ua1 = ua2; + ACE_ASSERT(ua1 == ua2); + ACE_ASSERT(ua1.valid() == 1); + ua1 = ua1; + ACE_ASSERT(ua1 == ua1); + ACE_ASSERT(ua1.valid() == 1); + + // set/get port + ua1.set_port(333); + ACE_ASSERT(ua1.get_port() == 333); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpAddress:ua1.set_port()(\"333\") [%s]\n", + (const char *)ua1)); + +} + +int +main (int, char *[]) +{ + ACE_START_TEST ("Address_Test"); + + TestGenAddr(); + TestIpAddress(); + TestUdpAddress(); + TestMacAddress(); + TestNetbiosAddress(); + TestIpxAddress(); + + ACE_END_TEST; + return 0; +} diff --git a/ASNMP/tests/Counter64_Test.cpp b/ASNMP/tests/Counter64_Test.cpp new file mode 100644 index 00000000000..b3bbaa3920a --- /dev/null +++ b/ASNMP/tests/Counter64_Test.cpp @@ -0,0 +1,163 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Counter64_Test.cpp +// +// = DESCRIPTION +// Test all the member functions of the Counter64 class. An Object +// representing an ASN.1 Counter64 SMI 64 bit Integer SYNTAX. +// (SNMPv2c) +// = AUTHOR +// Michael R. MacFaden <mrm@cisco.com> +// +// ============================================================================ +/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Copyright 1997 Cisco Systems, Inc. + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this +copyright and permission notice appear on all copies of the software and +supporting documentation, the name of Cisco Systems, Inc. not be used +in advertising or publicity pertaining to distribution of the +program without specific prior permission, and notice be given +in supporting documentation that modification, copying and distribution is by +permission of Cisco Systems, Inc. + +Cisco Systems, Inc. makes no representations about the suitability of this +software for any purpose. THIS SOFTWARE IS PROVIDED ``AS IS'' +AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT +LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGMENT AND +FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL CISCO SYSTEMS, INC. BE +LIABLE FOR ANY DAMAGES ARISING OUT OF THIS LICENSE OR YOUR USE OF THE +SOFTWARE INCLUDING WITHOUT LIMITATION, DIRECT, INDIRECT OR CONSEQUENTIAL +DAMAGES. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ + + +#include "ace/OS.h" +#include "asnmp/ctr64.h" +#include "test_config.h" + +// hack: do this so when linking SUNC 4.x compiler will instantiate template +#include "ace/Containers.h" +ACE_Unbounded_Set<ACE_Log_Msg*> x; + +// TODO: verify this with ACE folks +#if defined(_WIN32) +#define LLONG __int64 +#else +#define LLONG long long +#define ULLONG unsigned long long +#endif + +/* + Counter64( unsigned long long llw = 0); + Counter64( unsigned long hiparm, unsigned long loparm); + Counter64( const Counter64 &ctr64); + ~Counter64(); + SmiUINT32 get_syntax(); + long double to_long_double() const; + Counter64& assign( long double ld); + unsigned long high() const; + unsigned long low() const; + void set_high( const unsigned long h); + void set_low( const unsigned long l); + Counter64& operator=( const unsigned long long rhs); + Counter64& operator=( const Counter64 &rhs); + char *to_string(); + SnmpSyntax *clone() const; + SnmpSyntax& operator=( SnmpSyntax &val); + int valid() const; + operator unsigned long long(); + */ + +static void TestCounter64() +{ + static long l = LONG_MAX, nl = LONG_MIN; // limits.h + static unsigned long ul = ULONG_MAX, def = 0; + static int i = INT_MAX, ni = INT_MIN; + static unsigned int ui = UINT_MAX; + static unsigned short us = 10; + static short si = 65535; + LLONG ll = (LLONG) 0x7fffffffffffffff; + LLONG mll = (LLONG) ((-ll) - 1); + ULLONG ull = (ULLONG) 0xffffffffffffffff; + long double ld = (LLONG) ll; + + cerr << "max unsigned long long is " << ull << endl; + cerr << "max long long is " << ll << endl; + cerr << "min long long is " << mll << endl; + + Counter64 c1; + ACE_ASSERT(c1.valid() == 1); + Counter64 c2(ul, ul); + ACE_ASSERT(c2.valid() == 1); + ACE_ASSERT(c2.high() == ul); + ACE_ASSERT(c2.low() == ul); + + Counter64 c3(ul); + ACE_ASSERT(c3.valid() == 1); + ACE_ASSERT(c3.low() == ul); + + Counter64 c4(c2); + ACE_ASSERT(c4.valid() == 1); + ACE_ASSERT(c4.high() == ul); + ACE_ASSERT(c4.low() == ul); + + Counter64 c5(0); + ACE_ASSERT(c5.valid() == 1); + + Counter64 c6; + c6.assign(ld); + ACE_ASSERT(c6.to_long_double() == ld); + + Counter64 c7(ull); + ACE_ASSERT(c7 == ull); + + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c1(\"\") [%s]\n", + c1.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c2(LONG_MAX,LONG_MAX) [%s]\n", + c2.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c3(LONG_MAX) [%s]\n", + c3.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c4(c2) [%s]\n", + c4.to_string())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c5(0) [%s]\n", + c5.to_string())); + + // misc routines + c1.set_low(1); + c1.set_high(2); + ACE_ASSERT(c1.low() == 1); + ACE_ASSERT(c1.high() == 2); + // assignment + c5 = c4; + ACE_ASSERT(c5 == c4); + c4 = c4; + ACE_ASSERT(c5 == c4); + c5 = ll; + ACE_ASSERT(c5 == ll); + // try simple arithmetic (needs more test cases) + c5 = mll; + c5 = c5 + (ULLONG) 10; + ACE_ASSERT(c5 == (mll + 10)); +} + +int +main (int, char *[]) +{ + ACE_START_TEST ("Counter64_Test"); + + TestCounter64(); + + ACE_END_TEST; + return 0; +} + diff --git a/ASNMP/tests/Counter_Test.cpp b/ASNMP/tests/Counter_Test.cpp new file mode 100644 index 00000000000..d4c78414b1c --- /dev/null +++ b/ASNMP/tests/Counter_Test.cpp @@ -0,0 +1,141 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Counter_Test.cpp +// +// = DESCRIPTION +// Test all the member functions of the Counter class. An Object +// representing an ASN.1 Counter SMI COUNTER SYNTAX. +// = AUTHOR +// Michael R. MacFaden <mrm@cisco.com> +// +// ============================================================================ +/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Copyright 1997 Cisco Systems, Inc. + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this +copyright and permission notice appear on all copies of the software and +supporting documentation, the name of Cisco Systems, Inc. not be used +in advertising or publicity pertaining to distribution of the +program without specific prior permission, and notice be given +in supporting documentation that modification, copying and distribution is by +permission of Cisco Systems, Inc. + +Cisco Systems, Inc. makes no representations about the suitability of this +software for any purpose. THIS SOFTWARE IS PROVIDED ``AS IS'' +AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT +LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGMENT AND +FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL CISCO SYSTEMS, INC. BE +LIABLE FOR ANY DAMAGES ARISING OUT OF THIS LICENSE OR YOUR USE OF THE +SOFTWARE INCLUDING WITHOUT LIMITATION, DIRECT, INDIRECT OR CONSEQUENTIAL +DAMAGES. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ + + +#include "ace/OS.h" +#include "asnmp/counter.h" +#include "test_config.h" + +// hack: do this so when linking SUNC 4.x compiler will instantiate template +#include "ace/Containers.h" +ACE_Unbounded_Set<ACE_Log_Msg*> x; + + +/* + Counter32( void); + Counter32( const unsigned long i); + Counter32( const Counter32 &c); +* SmiUINT32 get_syntax(); +* SnmpSyntax *clone() const; +* SnmpSyntax& operator=( SnmpSyntax &val); + Counter32& operator=( const Counter32 &uli); + Counter32& operator=( const unsigned long i); + operator unsigned long(); + + -- comments tyis type appears to be a wrapper class and not + a true SNMP counter. Practical for nms side,yet may lead to + some confusion if implementing an agent with this class. + + Per RFC 1155 sec 3.2.3.3 + This application-wide type represents a non-negative integer which + monotonically increases until it reaches a maximum value, when it + wraps around and starts increasing again from zero. This memo + specifies a maximum value of 2^32-1 for counters +*/ + +static void TestCounter() +{ + long l = LONG_MAX, nl = LONG_MIN; // limits.h + unsigned long ul = ULONG_MAX, def = 0; + int i = INT_MAX, ni = INT_MIN; + unsigned int ui = UINT_MAX; + unsigned short us = 10; + short si = 65535; + + // constructors + Counter32 c1; + ACE_ASSERT(c1 == def); + Counter32 c2(l); + ACE_ASSERT(c2 == l); + Counter32 c3(nl); + ACE_ASSERT(c3 == nl); + Counter32 c4(ul); + ACE_ASSERT(c4 == ul); + Counter32 c5(i); + ACE_ASSERT(c5 == i); + Counter32 c6(ni); + ACE_ASSERT(c6 == ni); + Counter32 c7(ui); + ACE_ASSERT(c7 == ui); + Counter32 *c8 = new Counter32(c5); + ACE_ASSERT(c8 != 0); + delete c8; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c1(\"\") [%u]\n", + (unsigned long)c1)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c2(\"%u\") [%u]\n", + l, (unsigned long)c2)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c3(\"%u\") [%u]\n", + nl, (unsigned long)c3)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c4(\"%u\") [%u]\n", + ul, (unsigned long)c4)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c5(\"%u\") [%u]\n", + i, (unsigned long)c5)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c6(\"%u\") [%u]\n", + ni, (unsigned long)c6)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) c7(\"%u\") [%u]\n", + ui, (unsigned long)c7)); + + // assignent + c1 = c2; // obj + ACE_ASSERT(c1 == c2); + c1 = c1; // self + ACE_ASSERT(c1 == c1); + c1 = def; // unsigned long + ACE_ASSERT(c1 == def); + c1 = us; // unsigned short + ACE_ASSERT(c1 == us); + c1 = si; // unsigned short + ACE_ASSERT(c1 == si); + +} + + +int +main (int, char *[]) +{ + ACE_START_TEST ("Counter_Test"); + + TestCounter(); + + ACE_END_TEST; + return 0; +} + diff --git a/ASNMP/tests/Gauge_Test.cpp b/ASNMP/tests/Gauge_Test.cpp new file mode 100644 index 00000000000..ad1d4fa2912 --- /dev/null +++ b/ASNMP/tests/Gauge_Test.cpp @@ -0,0 +1,132 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Guage_Test.cpp +// +// = DESCRIPTION +// Test all the member functions of the Guage class. An Object +// representing an ASN.1 Counter SMI GUAGE SYNTAX. +// = AUTHOR +// Michael R. MacFaden <mrm@cisco.com> +// +// ============================================================================ +/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Copyright 1997 Cisco Systems, Inc. + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this +copyright and permission notice appear on all copies of the software and +supporting documentation, the name of Cisco Systems, Inc. not be used +in advertising or publicity pertaining to distribution of the +program without specific prior permission, and notice be given +in supporting documentation that modification, copying and distribution is by +permission of Cisco Systems, Inc. + +Cisco Systems, Inc. makes no representations about the suitability of this +software for any purpose. THIS SOFTWARE IS PROVIDED ``AS IS'' +AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT +LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGMENT AND +FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL CISCO SYSTEMS, INC. BE +LIABLE FOR ANY DAMAGES ARISING OUT OF THIS LICENSE OR YOUR USE OF THE +SOFTWARE INCLUDING WITHOUT LIMITATION, DIRECT, INDIRECT OR CONSEQUENTIAL +DAMAGES. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ + +#include "ace/OS.h" +#include "asnmp/gauge.h" +#include "test_config.h" + +// hack: do this so when linking SUNC 4.x compiler will instantiate template +#include "ace/Containers.h" +ACE_Unbounded_Set<ACE_Log_Msg*> x; + +/* + Gauge32( void); + Gauge32( const unsigned long i); + Gauge32 ( const Gauge32 &g); + ~Gauge32(); + SmiUINT32 get_syntax(); + SnmpSyntax *clone() const; + Gauge32& operator=( const Gauge32 &uli); + Gauge32& operator=( const unsigned long i); + operator unsigned long(); + SnmpSyntax& operator=( SnmpSyntax &val); + +-- What is a Gauge? According to RFC 1155 section: 3.2.3.4 + This application-wide type represents a non-negative integer + which may increase or decreae, but which latches at a maximum + value of 2^32-1 (4294967295 dec) for gauges. + */ +static void TestGuage() +{ + long l = LONG_MAX, nl = LONG_MIN; // limits.h + unsigned long ul = ULONG_MAX, def = 0; + int i = INT_MAX, ni = INT_MIN; + unsigned int ui = UINT_MAX; + unsigned short us = 10; + short si = 65535; + + // constructors + Gauge32 g1; + ACE_ASSERT(g1 == def); + Gauge32 g2(l); + ACE_ASSERT(g2 == l); + Gauge32 g3(nl); + ACE_ASSERT(g3 == nl); + Gauge32 g4(ul); + ACE_ASSERT(g4 == ul); + Gauge32 g5(i); + ACE_ASSERT(g5 == i); + Gauge32 g6(ni); + ACE_ASSERT(g6 == ni); + Gauge32 g7(ui); + ACE_ASSERT(g7 == ui); + Gauge32 *g8 = new Gauge32(g5); + ACE_ASSERT(g8 != 0); + delete g8; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) g1(\"\") [%u]\n", + (unsigned long)g1)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) g2(\"%u\") [%u]\n", + l, (unsigned long)g2)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) g3(\"%u\") [%u]\n", + nl, (unsigned long)g3)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) g4(\"%u\") [%u]\n", + ul, (unsigned long)g4)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) g5(\"%u\") [%u]\n", + i, (unsigned long)g5)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) g6(\"%u\") [%u]\n", + ni, (unsigned long)g6)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) g7(\"%u\") [%u]\n", + ui, (unsigned long)g7)); + + // assignent + g1 = g2; // obj + ACE_ASSERT(g1 == g2); + g1 = g1; // self + ACE_ASSERT(g1 == g1); + g1 = def; // unsigned long + ACE_ASSERT(g1 == def); + g1 = us; // unsigned short + ACE_ASSERT(g1 == us); + g1 = si; // unsigned short + ACE_ASSERT(g1 == si); +} + +int +main (int, char *[]) +{ + ACE_START_TEST ("Guage_Test"); + + TestGuage(); + + ACE_END_TEST; + return 0; +} + diff --git a/ASNMP/tests/Integer_Test.cpp b/ASNMP/tests/Integer_Test.cpp new file mode 100644 index 00000000000..02758fb8705 --- /dev/null +++ b/ASNMP/tests/Integer_Test.cpp @@ -0,0 +1,198 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Integer_Test.cpp +// +// = DESCRIPTION +// Test all the member functions of the Integer class. An Object +// representing an ASN.1 Integer64 SMI 32 bit Integer SYNTAX. +// +// = AUTHOR +// Michael R. MacFaden <mrm@cisco.com> +// +// ============================================================================ +/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Copyright 1997 Cisco Systems, Inc. + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this +copyright and permission notice appear on all copies of the software and +supporting documentation, the name of Cisco Systems, Inc. not be used +in advertising or publicity pertaining to distribution of the +program without specific prior permission, and notice be given +in supporting documentation that modification, copying and distribution is by +permission of Cisco Systems, Inc. + +Cisco Systems, Inc. makes no representations about the suitability of this +software for any purpose. THIS SOFTWARE IS PROVIDED ``AS IS'' +AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT +LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGMENT AND +FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL CISCO SYSTEMS, INC. BE +LIABLE FOR ANY DAMAGES ARISING OUT OF THIS LICENSE OR YOUR USE OF THE +SOFTWARE INCLUDING WITHOUT LIMITATION, DIRECT, INDIRECT OR CONSEQUENTIAL +DAMAGES. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ + + +#include "ace/OS.h" +#include "asnmp/integer.h" +#include "test_config.h" + +static long l = LONG_MAX, nl = LONG_MIN; // limits.h +static unsigned long ul = ULONG_MAX, def = 0; +static int i = INT_MAX, ni = INT_MIN; +static unsigned int ui = UINT_MAX; +static unsigned short us = 10; +static short si = 65535; + +// hack: do this so when linking SUNC 4.x compiler will instantiate template +#include "ace/Containers.h" +ACE_Unbounded_Set<ACE_Log_Msg*> x; + +/* + SnmpInt32( void); + SnmpInt32 (const long i); + SnmpInt32 (const SnmpInt32 &c); + virtual ~SnmpInt32(); + virtual SmiUINT32 get_syntax(); + SnmpInt32& operator=( const long i); + SnmpInt32& operator=( const SnmpInt32 &li); + operator long(); + char *to_string(); + SnmpSyntax *clone() const; + SnmpSyntax& operator=( SnmpSyntax &val); + int valid() const; + */ + +static void TestInteger32() +{ + + // constructors + SnmpInt32 i1; + ACE_ASSERT(i1 == def); + SnmpInt32 i2(l); + ACE_ASSERT(i2 == l); + SnmpInt32 i3(nl); + ACE_ASSERT(i3 == nl); + SnmpInt32 i4(ul); + ACE_ASSERT(i4 == ul); + SnmpInt32 i5(i); + ACE_ASSERT(i5 == i); + SnmpInt32 i6(ni); + ACE_ASSERT(i6 == ni); + SnmpInt32 i7(ui); + ACE_ASSERT(i7 == ui); + SnmpInt32 *i8 = new SnmpInt32(i5); + ACE_ASSERT(i8 != 0); + delete i8; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) i1(\"\") [%u]\n", + (unsigned long)i1)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) i2(\"%u\") [%u]\n", + l, (unsigned long)i2)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) i3(\"%u\") [%u]\n", + nl, (unsigned long)i3)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) i4(\"%u\") [%u]\n", + ul, (unsigned long)i4)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) i5(\"%u\") [%u]\n", + i, (unsigned long)i5)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) i6(\"%u\") [%u]\n", + ni, (unsigned long)i6)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) i7(\"%u\") [%u]\n", + ui, (unsigned long)i7)); + + // assignent + i1 = i2; // obj + ACE_ASSERT(i1 == i2); + i1 = i1; // self + ACE_ASSERT(i1 == i1); + i1 = def; // unsigned long + ACE_ASSERT(i1 == def); + i1 = us; // unsigned short + ACE_ASSERT(i1 == us); + i1 = si; // unsigned short + ACE_ASSERT(i1 == si); +} + +/* + SnmpUInt32( void); + SnmpUInt32 (const unsigned long i); + SnmpUInt32( const SnmpUInt32 &c); + virtual ~SnmpUInt32(); + virtual SmiUINT32 get_syntax(); + SnmpUInt32& operator=( const unsigned long i); + SnmpUInt32& operator=( const SnmpUInt32 &uli); + operator unsigned long(); + virtual char *to_string(); + virtual SnmpSyntax *clone() const; + SnmpSyntax& operator=( SnmpSyntax &val); + int valid() const; + */ +static void TestUnsignedInteger32() +{ + // constructors + SnmpUInt32 u1; + ACE_ASSERT(u1 == def); + SnmpUInt32 u2(l); + ACE_ASSERT(u2 == l); + SnmpUInt32 u3(nl); + ACE_ASSERT(u3 == nl); + SnmpUInt32 u4(ul); + ACE_ASSERT(u4 == ul); + SnmpUInt32 u5(i); + ACE_ASSERT(u5 == i); + SnmpUInt32 u6(ni); + ACE_ASSERT(u6 == ni); + SnmpUInt32 u7(ui); + ACE_ASSERT(u7 == ui); + SnmpUInt32 *u8 = new SnmpUInt32(u5); + ACE_ASSERT(u8 != 0); + delete u8; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) u1(\"\") [%u]\n", + (unsigned long)u1)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) u2(\"%u\") [%u]\n", + l, (unsigned long)u2)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) u3(\"%u\") [%u]\n", + nl, (unsigned long)u3)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) u4(\"%u\") [%u]\n", + ul, (unsigned long)u4)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) u5(\"%u\") [%u]\n", + i, (unsigned long)u5)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) u6(\"%u\") [%u]\n", + ni, (unsigned long)u6)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) u7(\"%u\") [%u]\n", + ui, (unsigned long)u7)); + + // assignent + u1 = u2; // obj + ACE_ASSERT(u1 == u2); + u1 = u1; // self + ACE_ASSERT(u1 == u1); + u1 = def; // unsigned long + ACE_ASSERT(u1 == def); + u1 = us; // unsigned short + ACE_ASSERT(u1 == us); + u1 = si; // unsigned short + ACE_ASSERT(u1 == si); +} + +int +main (int, char *[]) +{ + ACE_START_TEST ("Integer_Test"); + + TestInteger32(); + + TestUnsignedInteger32(); + + ACE_END_TEST; + return 0; +} + diff --git a/ASNMP/tests/Makefile b/ASNMP/tests/Makefile new file mode 100644 index 00000000000..a09caea1497 --- /dev/null +++ b/ASNMP/tests/Makefile @@ -0,0 +1,48 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for all the ACE+SNMP ``one-button' tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +# ACE+SNMP before -lACE + +BIN = Oid_Test \ + Counter_Test \ + Counter64_Test \ + Integer_Test \ + Octet_Test \ + Gauge_Test \ + Address_Test \ + Target_Test \ + Varbind_Test +CCFLAGS = -I$(WRAPPER_ROOT)/ASNMP/ + +LSRC = $(addsuffix .cpp,$(BIN)) +VLDLIBS = -L$(WRAPPER_ROOT)/ASNMP/asnmp -lasnmp $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/ASNMP/tests/Octet_Test.cpp b/ASNMP/tests/Octet_Test.cpp new file mode 100644 index 00000000000..b32b112f64e --- /dev/null +++ b/ASNMP/tests/Octet_Test.cpp @@ -0,0 +1,160 @@ +/* -*- C++ -*- */ +// $Id$ +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Octet_Test.cpp +// +// = DESCRIPTION +// Test all the member functions of the OCTET class. An Object +// representing an ASN.1 Integer64 SMI OCTET STRING SYNTAX. +// +// = AUTHOR +// Michael R. MacFaden <mrm@cisco.com> +// +// ============================================================================ + +/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Copyright 1997 Cisco Systems, Inc. + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this +copyright and permission notice appear on all copies of the software and +supporting documentation, the name of Cisco Systems, Inc. not be used +in advertising or publicity pertaining to distribution of the +program without specific prior permission, and notice be given +in supporting documentation that modification, copying and distribution is by +permission of Cisco Systems, Inc. + +Cisco Systems, Inc. makes no representations about the suitability of this +software for any purpose. THIS SOFTWARE IS PROVIDED ``AS IS'' +AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT +LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGMENT AND +FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL CISCO SYSTEMS, INC. BE +LIABLE FOR ANY DAMAGES ARISING OUT OF THIS LICENSE OR YOUR USE OF THE +SOFTWARE INCLUDING WITHOUT LIMITATION, DIRECT, INDIRECT OR CONSEQUENTIAL +DAMAGES. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ + + + +#include "ace/OS.h" +#include "asnmp/octet.h" +#include "test_config.h" + +// hack: do this so when linking SUNC 4.x compiler will instantiate template +#include "ace/Containers.h" +ACE_Unbounded_Set<ACE_Log_Msg*> x; + +/* + OctetStr( const char *string, long size = -1); + OctetStr ( const OctetStr &octet); + ~OctetStr(); + + SmiUINT32 get_syntax(); + void set_data( const SmiBYTE* string, long int size = -1); + OctetStr& operator=( const char *string); + OctetStr& operator=( const OctetStr &octet); + + int operator==( const OctetStr &lhs, const OctetStr &rhs); + int operator!=( const OctetStr &lhs, const OctetStr &rhs); + int operator<( const OctetStr &lhs, const OctetStr &rhs); + int operator<=( const OctetStr &lhs,const OctetStr &rhs); + int operator>( const OctetStr &lhs, const OctetStr &rhs); + int operator>=( const OctetStr &lhs, const OctetStr &rhs); + int operator==( const OctetStr &lhs,const char *rhs); + int operator!=( const OctetStr &lhs,const char *rhs); + int operator<( const OctetStr &lhs,const char *rhs); + int operator<=( const OctetStr &lhs,char *rhs); + int operator>( const OctetStr &lhs,const char *rhs); + int operator>=( const OctetStr &lhs,const char *rhs); + OctetStr& operator+=( const SmiBYTE *a); + OctetStr& operator+=( const char c); + OctetStr& operator+=( const OctetStr& octetstr); + SmiBYTE& operator[]( int position); + int nCompare( const long n, const OctetStr &o) const; + size_t length() const ; + int valid() const; + SmiBYTE *data() const; + char *to_string(); + char *to_string_hex(); + SnmpSyntax *clone() const; + SnmpSyntax& operator=( SnmpSyntax &val); + */ + +static void TestOctet() +{ + char *str = "A test of octet strings...!@@#$%^&*()_+|~{}:,./<>?"; + OctetStr o1; + ACE_ASSERT(o1.valid() == 0); + ACE_ASSERT(o1.length() == 0); + ACE_ASSERT(o1.data() == (unsigned char *)0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Octet:o1(\"\") [%s]\n", + o1.to_string())); + o1.set_data((SmiBYTE *)str); + ACE_ASSERT(!ACE_OS::strcmp(str, (char *)o1.data())); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Octet:o1(\"str\") [%s]\n", + o1.to_string())); + + OctetStr o2(str); + ACE_ASSERT(o2.valid() == 1); + ACE_ASSERT(o2.data() != (unsigned char *)0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Octet:o2(\"str\") [%s]\n", + o2.to_string())); + + OctetStr o3(str, 4); // test setting less than full string length + ACE_ASSERT(o3.valid() == 1); + ACE_ASSERT(o3.length() == 4); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Octet:o3(\"A te\") [%s]\n", + o3.to_string())); + + OctetStr o4(o3); // test setting less than full string length + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Octet:o4(\"A te\") [%s]\n", + o4.to_string())); + ACE_ASSERT(o4.valid() == 1); + ACE_ASSERT(o4.length() == 4); + + OctetStr o5; + o5 = str; + ACE_ASSERT(o5.valid() == 1); + ACE_ASSERT(o5.length() == ACE_OS::strlen(str)); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Octet:o5(\"str\") [%s]\n", + o5.to_string())); + + OctetStr o6; + o6 = o5; + ACE_ASSERT(o6.valid() == 1); + ACE_ASSERT(o5.length() == o6.length()); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Octet:o6(\"str\") [%s]\n", + o6.to_string())); + + o6 += o3; + o6 = ""; + o6 += str; + o6 += '#'; + ACE_ASSERT(o6[0] == (SmiBYTE) 'A'); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Octet:o6(\"str\") [%s]\n", + o6.to_string())); + + ACE_ASSERT(!(o3 < o3)); + ACE_ASSERT(!(o3 > o3)); + ACE_ASSERT(o3 >= o3); + ACE_ASSERT(o3 <= o3); + ACE_ASSERT(o3 == o3); + ACE_ASSERT(!(o3 != o3)); + +} + +int +main (int, char *[]) +{ + ACE_START_TEST ("Octet_Test"); + + TestOctet(); + ACE_END_TEST; + return 0; +} + diff --git a/ASNMP/tests/Oid_Test.cpp b/ASNMP/tests/Oid_Test.cpp new file mode 100644 index 00000000000..1ea785ac69c --- /dev/null +++ b/ASNMP/tests/Oid_Test.cpp @@ -0,0 +1,185 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// Oid_Test.cpp +// +// = DESCRIPTION +// Test all the member functions of the Oid class. An Object +// representing an ASN.1 Integer64 SMI OID SYNTAX. +// +// = AUTHOR +// Michael R. MacFaden <mrm@cisco.com> +// +// ============================================================================ +/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Copyright 1997 Cisco Systems, Inc. + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this +copyright and permission notice appear on all copies of the software and +supporting documentation, the name of Cisco Systems, Inc. not be used +in advertising or publicity pertaining to distribution of the +program without specific prior permission, and notice be given +in supporting documentation that modification, copying and distribution is by +permission of Cisco Systems, Inc. + +Cisco Systems, Inc. makes no representations about the suitability of this +software for any purpose. THIS SOFTWARE IS PROVIDED ``AS IS'' +AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT +LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGMENT AND +FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL CISCO SYSTEMS, INC. BE +LIABLE FOR ANY DAMAGES ARISING OUT OF THIS LICENSE OR YOUR USE OF THE +SOFTWARE INCLUDING WITHOUT LIMITATION, DIRECT, INDIRECT OR CONSEQUENTIAL +DAMAGES. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ + +#include "ace/OS.h" +#include "asnmp/oid.h" +#include "test_config.h" + +// hack: do this so when linking SUNC 4.x compiler will instantiate template +#include "ace/Containers.h" +ACE_Unbounded_Set<ACE_Log_Msg*> x; + +/* + Oid( const char * dotted_oid_string = "", size_t size = -1); + Oid ( const Oid &oid); + Oid(const unsigned long *raw_oid, size_t oid_len); + ~Oid(); + + SmiUINT32 get_syntax(); + Oid& operator=( const Oid &oid); + int operator==( const Oid &lhs,const Oid &rhs); + int operator!=( const Oid &lhs,const Oid &rhs); + int operator<( const Oid &lhs,const Oid &rhs); + int operator<=( const Oid &lhs,const Oid &rhs); + int operator>( const Oid &lhs,const Oid &rhs); + int operator>=( const Oid &lhs,const Oid &rhs); + Oid& operator+=( const char *a); + Oid& operator+=( const unsigned long i); + Oid& operator+=( const Oid &o); + unsigned long & operator[]( size_t position); + SmiLPOID oidval(); + void set_data( const char *dotted_oid_string); + void set_data( const unsigned long *raw_oid, const size_t oid_len); + size_t length() const; + void trim( const size_t how_many = 1); + int suboid( const size_t start, const size_t end, Oid& new_oid); + int left_comparison( const unsigned long n, const Oid &o) const; + int right_comparison( const unsigned long n, const Oid &o) const; + int valid() const; + char *to_string(); + SnmpSyntax *clone() const; + SnmpSyntax& operator=( SnmpSyntax &val); + */ + +static void OidTest() +{ + Oid d1; + ACE_ASSERT(d1.valid() == 0); + ACE_ASSERT(d1.length() == 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Oid:d1(\"\") [%s]\n", + d1.to_string())); + + Oid d2("1.2.3"); + ACE_ASSERT(d2.valid() == 1); + ACE_ASSERT(d2.length() == 3); + ACE_ASSERT(d2[0] == (unsigned long) 1); + ACE_ASSERT(d2[1] == (unsigned long) 2); + ACE_ASSERT(d2[2] == (unsigned long) 3); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Oid:d2(\"1.2.3\") [%s]\n", + d2.to_string())); + + Oid d3(d2); + ACE_ASSERT(d3.valid() == 1); + ACE_ASSERT(d3.length() == 3); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Oid:d3(\"d2\") [%s]\n", + d3.to_string())); + + unsigned long t[3] = {2,3,4}; + Oid d4((unsigned long *)&t, sizeof(t)/sizeof(long)); + ACE_ASSERT(d4.valid() == 1); + ACE_ASSERT(d4.length() == 3); + ACE_ASSERT(d4[0] == (unsigned long) 2); + ACE_ASSERT(d4[1] == (unsigned long) 3); + ACE_ASSERT(d4[2] == (unsigned long) 4); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Oid:d4(\"long(2.3.4)\") [%s]\n", + d4.to_string())); + + // suboid + Oid d5; + ACE_ASSERT(d4.suboid(d5, 1,1) == 0); // 2,3,4, 1,1 == 3 + ACE_ASSERT(d5.length() == 1); + ACE_ASSERT(d5.valid() == 1); + ACE_ASSERT(d5[0] == 3); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Oid:d6::suboid(d5,1,1) [%s]\n", + d5.to_string())); + + // trim + Oid d7(d4); + ACE_ASSERT(d7.valid() == 1); + d7.trim(); + ACE_ASSERT(d7.length() == d4.length() -1); + + // compare methods + ACE_ASSERT(d7.left_comparison( d7.length(), d7) == 0); + ACE_ASSERT(d4.right_comparison( d4.length(), d4) == 0); + + // assignment + d1 = d4; + ACE_ASSERT(d1.valid() == 1); + ACE_ASSERT(d1 == d4); + d2 = "5.6.7"; + ACE_ASSERT(d2.valid() == 1); + ACE_ASSERT(d2[2] == (unsigned long) 7); + d1 = "8.9.10"; + ACE_ASSERT(d1.valid() == 1); + + // concat + unsigned long ll = ULONG_MAX; + d1 = ""; + d1 += (unsigned long)0; + d1 += ll; + d1 += ll; + d1 += "0"; + ACE_ASSERT(d1.valid() == 1); + ACE_ASSERT(d1.length() == 4); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Oid:d1(0,max,max,0) [%s]\n", + d1.to_string())); + ACE_ASSERT(d1[0] == (unsigned long)0); + ACE_ASSERT(d1[1] == ll); + ACE_ASSERT(d1[2] == ll); + ACE_ASSERT(d1[3] == (unsigned long)0); + + d2 += d1; + ACE_ASSERT(d2.valid() == 1); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Oid:(5.6.7.8.9.10) [%s]\n", + d2.to_string())); + + // test out max Oid string... + + // relational operators oid,oid + ACE_ASSERT(d2 == d2); + ACE_ASSERT(!(d2 != d2)); + ACE_ASSERT(!(d2 < d2)); + ACE_ASSERT(!(d2 > d2)); + ACE_ASSERT(d2 >= d2); + ACE_ASSERT(d2 <= d2); + +} + +int +main (int, char *[]) +{ + ACE_START_TEST ("Oid_Test"); + OidTest(); + ACE_END_TEST; + return 0; +} + diff --git a/ASNMP/tests/Target_Test.cpp b/ASNMP/tests/Target_Test.cpp new file mode 100644 index 00000000000..49e7b0fff8b --- /dev/null +++ b/ASNMP/tests/Target_Test.cpp @@ -0,0 +1,151 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Target_Test.cpp +// +// = DESCRIPTION +// Test all the member functions of the Target class. +// Not sure if this object is really required or not in the new framework +// +// = AUTHOR +// Michael R. MacFaden <mrm@cisco.com> +// +// ============================================================================ + +/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Copyright 1997 Cisco Systems, Inc. + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this +copyright and permission notice appear on all copies of the software and +supporting documentation, the name of Cisco Systems, Inc. not be used +in advertising or publicity pertaining to distribution of the +program without specific prior permission, and notice be given +in supporting documentation that modification, copying and distribution is by +permission of Cisco Systems, Inc. + +Cisco Systems, Inc. makes no representations about the suitability of this +software for any purpose. THIS SOFTWARE IS PROVIDED ``AS IS'' +AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT +LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGMENT AND +FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL CISCO SYSTEMS, INC. BE +LIABLE FOR ANY DAMAGES ARISING OUT OF THIS LICENSE OR YOUR USE OF THE +SOFTWARE INCLUDING WITHOUT LIMITATION, DIRECT, INDIRECT OR CONSEQUENTIAL +DAMAGES. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ + + +#include "ace/OS.h" +#include "asnmp/octet.h" +#include "asnmp/target.h" +#include "test_config.h" + +// hack: do this so when linking SUNC 4.x compiler will instantiate template +#include "ace/Containers.h" +ACE_Unbounded_Set<ACE_Log_Msg*> x; + +/* + Percieved Problems with this CTarget aka UdpTarget Interface: + + 1) can't set snmp version during constructor (default value?) + 2) doesn't use ANSI C++ String class (still uses char *) + 3) Makes it easy to mix up read and write comm strs (could be diff types) + 3) so many get/set's, leads one to rethink the design/use of UdpTarget + 4) Use of resolve_to_C smells like a HACK... + 5) No valid() member function returns 1 even if no address given.. + 6) No to_string()?! (Fixed) + 7) can't access retry, timeout parameters... + 8) can't assign or equate two UdpTargets + + UdpTarget( void); + UdpTarget( const Address &address); + UdpTarget( const UdpTarget &target); + UdpTarget( const Address &address, // address + const char *read_community_name, // read community name + const char *write_community_name); // write community name + UdpTarget( const Address &address, // address + const OctetStr &read_community_name, // read community + const OctetStr &write_community_name); // write community + ~UdpTarget(); + + SnmpTarget *clone() const; + void get_readcommunity( OctetStr& read_community_oct); + void set_readcommunity( const OctetStr& read_community); + void get_writecommunity( OctetStr &write_community_oct); + void set_writecommunity( const OctetStr& write_community); + void get_address( UdpAddress & address); + int set_address( Address &address); + snmp_version get_version(); + void set_version( const snmp_version v); + + UdpTarget& operator=( const UdpTarget& target); + friend int operator==( const UdpTarget &lhs, const UdpTarget &rhs); + + */ + +static void TestSnmpTarget() +{ + OctetStr rd("rd_comm"), wr("wr_comm"); + ACE_ASSERT(rd.valid() == 1); + ACE_ASSERT(wr.valid() == 1); + char *crd = "rd_comm", *cwr = "wr_comm"; + + // constructor and get tests + UdpAddress ga; + ACE_ASSERT(ga.valid() == 0); + + UdpTarget c1; + ACE_ASSERT(c1.valid() == 0); + OctetStr a, b("public"), c("private"); + c1.get_read_community(a); + ACE_ASSERT(a == b); + c1.get_write_community(a); + ACE_ASSERT(a == c); + c1.get_address (ga); + ACE_ASSERT(c1.get_version() == version1); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpTarget:c1(\"\") [%s]\n", + c1.to_string())); + + IpAddress ip("127.0.0.1"); + UdpTarget c2(ip); + ACE_ASSERT(c2.valid() == 1); + c2.get_address (ga); + ACE_ASSERT(ga.valid() == 1); + ACE_ASSERT(c2.get_version() == version1); + ACE_ASSERT(ga.valid() == 1); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpTarget:c2(\"\") [%s]\n", + c2.to_string())); + + UdpTarget *c5 = new UdpTarget(c2); + ACE_ASSERT(c5 != 0); + ACE_ASSERT(c5->valid() == 1); + c5->get_address (ga); + ACE_ASSERT(ga.valid() == 1); + ACE_ASSERT(c5->get_version() == version1); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) UdpTarget:c5(\"\") [%s]\n", + c5->to_string())); + delete c5; + +// these are not supported yet +// ACE_ASSERT(c5 == c5); +// c5 = c2; +// ACE_ASSERT(c5 == c2); +} + +int +main (int, char *[]) +{ + ACE_START_TEST ("Target_Test"); + TestSnmpTarget(); + + ACE_END_TEST; + return 0; +} + diff --git a/ASNMP/tests/Varbind_Test.cpp b/ASNMP/tests/Varbind_Test.cpp new file mode 100644 index 00000000000..319b2634c04 --- /dev/null +++ b/ASNMP/tests/Varbind_Test.cpp @@ -0,0 +1,200 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// Varbind_Test.cpp +// +// = DESCRIPTION +// Test all the member functions of the Varbind class. +// A varbind is a list of { oids and associated values } +// +// = AUTHOR +// Michael R. MacFaden <mrm@cisco.com> +// +// ============================================================================ + +/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Copyright 1997 Cisco Systems, Inc. + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this +copyright and permission notice appear on all copies of the software and +supporting documentation, the name of Cisco Systems, Inc. not be used +in advertising or publicity pertaining to distribution of the +program without specific prior permission, and notice be given +in supporting documentation that modification, copying and distribution is by +permission of Cisco Systems, Inc. + +Cisco Systems, Inc. makes no representations about the suitability of this +software for any purpose. THIS SOFTWARE IS PROVIDED ``AS IS'' +AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT +LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGMENT AND +FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL CISCO SYSTEMS, INC. BE +LIABLE FOR ANY DAMAGES ARISING OUT OF THIS LICENSE OR YOUR USE OF THE +SOFTWARE INCLUDING WITHOUT LIMITATION, DIRECT, INDIRECT OR CONSEQUENTIAL +DAMAGES. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ + + +#include "ace/OS.h" +#include "asnmp/oid.h" +#include "asnmp/vb.h" +#include "test_config.h" + + +// hack: do this so when linking SUNC 4.x compiler will instantiate template +#include "ace/Containers.h" +ACE_Unbounded_Set<ACE_Log_Msg*> x; + +/* + Vb( void); + Vb( const Oid &oid); + Vb( const Vb &vb); + Vb( const Oid& vb, const SnmpSyntax &val, const SmiUINT32=SNMP_CLASS_SUCCESS); + ~Vb(); + int valid() const; + Vb& operator=( const Vb &vb); + void set_oid( const Oid& oid); + void get_oid( Oid &oid) const; + void set_null(); + void set_value( const TimeTicks& ticks); + void set_value( const Oid& oid); + void set_value( const Counter32& ctr); + void set_value( const Counter64& ctr); + void set_value( const Gauge32& ctr); + void set_value( const SnmpUInt32& ctr); + void set_value( const SnmpInt32& ctr); + void set_value( const OctetStr& oct_str); + int get_value( TimeTicks& ticks); + int get_value( Oid& oid); + int get_value( Counter32& ctr); + int get_value( Counter64& ctr); + int get_value( Gauge32& ctr); + int get_value( SnmpUInt32& ctr); + int get_value( SnmpInt32& ctr); + int get_value( OctetStr& oct_str); + int get_value( SnmpSyntax &val); + void set_value( const SnmpSyntax &val); + int get_value( const SnmpSyntax &val); + SmiUINT32 get_syntax(); + friend void set_exception_status( Vb *vb, const SmiUINT32 status); + char *to_string(); + char *to_string_value(); + char *to_string_oid(); + */ + +static void VbTest() +{ + Vb v1; + ACE_ASSERT(v1.valid() == 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) VarBinad:v1(\"/\") [%s]\n", + v1.to_string())); + + // purpose of this routine?? + set_exception_status( &v1, 10); + + Vb v2(v1); + ACE_ASSERT(v2.valid() == 0); + Oid o1("1.2.3"), o2; + v2.set_oid(o1); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) VarBinad:v2(\"1.2.3/\") [%s]\n", + v2.to_string())); + + v2.get_oid(o2); + ACE_ASSERT(o2 == o1); + ACE_ASSERT(v2.valid() == 0); + v2.set_null(); + ACE_ASSERT(v2.valid() == 0); + v2.get_oid(o2); + + Vb v3; + TimeTicks t(0), t1; + v3.set_oid(o1); + v3.set_value(t); + ACE_ASSERT(v3.valid() == 1); + v3.get_value(t1); + ACE_ASSERT(t == t1); + + Vb v4; + v4.set_oid(o1); + v4.set_value(o1); + ACE_ASSERT(v4.valid() == 1); + v4.get_value(o2); + ACE_ASSERT(o1 == o2); + + Vb v5; + Counter32 c1(12), c2; + v5.set_oid(o1); + v5.set_value(c1); + ACE_ASSERT(v5.valid() == 1); + v5.get_value(c2); + ACE_ASSERT(c1 == c2); + + Vb v6; + Counter64 c3(12345678901234), c4; + v6.set_oid(o1); + v6.set_value(c3); + ACE_ASSERT(v6.valid() == 1); + v6.get_value(c4); + ACE_ASSERT(c3 == c4); + + Vb v7; + Gauge32 g1(0123456), g2; + v7.set_oid(o1); + v7.set_value(g1); + ACE_ASSERT(v7.valid() == 1); + v7.get_value(g2); + ACE_ASSERT(g1 == g2); + + Vb v8; + SnmpInt32 i1(0123456), i2; + v8.set_oid(o1); + v8.set_value(i1); + ACE_ASSERT(v8.valid() == 1); + v8.get_value(i2); + ACE_ASSERT(i1 == i2); + + Vb v9; + SnmpUInt32 u1(0123456), u2; + v9.set_oid(o1); + v9.set_value(u1); + ACE_ASSERT(v9.valid() == 1); + v9.get_value(u2); + ACE_ASSERT(u1 == u2); + + Vb v10; + OctetStr s1(" abcdefghighlmnopqrstuvwxyz!@#$%^&*()"), s2; + v10.set_oid(o1); + v10.set_value(s1); + ACE_ASSERT(v10.valid() == 1); + v10.get_value(s2); + ACE_ASSERT(s1 == s2); + ACE_ASSERT(s1.length() == s2.length()); + + // test assignment over all datatypes + v10 = v5; + ACE_ASSERT(v10 == v5); + + + Vb v11(o1, s1, SNMP_CLASS_SUCCESS); + ACE_ASSERT(v11.valid() == 1); + v11.get_oid(o2); + ACE_ASSERT(o1 == o2); + v11.get_value(s2); + ACE_ASSERT(s1 == s2); +} + +int +main (int, char *[]) +{ + ACE_START_TEST ("VbTest"); + VbTest(); + ACE_END_TEST; + return 0; +} + diff --git a/ASNMP/tests/run_tests.bat b/ASNMP/tests/run_tests.bat new file mode 100644 index 00000000000..985f88b51db --- /dev/null +++ b/ASNMP/tests/run_tests.bat @@ -0,0 +1,44 @@ +@echo off +rem To use this either give it no arguments to run all the tests or +rem pass it the test name (without the extention) to run only one +rem test + +if not "%1" == "" goto runtest + +call run_tests + +call run_tests Address_Test +call run_tests Counter64_Test +call run_tests Counter_Test +call run_tests Gauge_Test +call run_tests Integer_Test +call run_tests Octet_Test +call run_tests Oid_Test +call run_tests Target_Test +call run_tests Varbind_Test + +goto done + +:runtest + +echo Running %1 +%1.exe +if errorlevel 0 goto fine +echo. +echo %1 has FAILED!!! +echo. +type %temp%\log\%1.log | find /I "assertion failed" +type %temp%\log\%1.log | find /I "not supported" +type %temp%\log\%1.log | find /I "no such file or directory" +type %temp%\log\%1.log | find /I "invalid argument" +type %temp%\log\%1.log | find /I "timeout" +type %temp%\log\%1.log | find /I "bad file number" +echo. + +goto done +:fine + +rem We should check the log files here to make sure the test ended correctly +rem type %temp%\log\%1.log | find "Ending" + +:done diff --git a/ASNMP/tests/run_tests.sh b/ASNMP/tests/run_tests.sh new file mode 100755 index 00000000000..f8ebb06fdd4 --- /dev/null +++ b/ASNMP/tests/run_tests.sh @@ -0,0 +1,60 @@ +#!/bin/sh -f +# This is the UNIX version of the one-button ACE tests. +# Contributed by Michael Rueger <m_rueger@SYSCOMP.DE> +# mrm@cisco.com - Change to for loop script could be more generic if we put +# this in the bin dir and fed it a file to read from + +IFS="|" +tmp=/tmp + +# these patterns should not be included in log file +ERROR_MSGS="assertion failed|not supported|No such file or directory|Invalid argument|timeout|Bad file number" + +# these patterns must be included in log file +SUCCESS_MSGS="starting|Ending" + +run() +{ + echo running $1 + /bin/rm -f core + + ./$1 + status=$? + + if [ $status -ne 0 ]; then + echo \"$1\" FAILED with exit status $status!!!! + fi + + if [ -f core ]; then + echo \"$1\" dumped core!!!! + fi + + for i in $SUCCESS_MSGS; do + grep $i log/$1.log >/dev/null + if [ $? -eq 1 ]; then + echo Error in log file no line with $i + fi + done + + for i in $ERROR_MSGS; do + grep $i log/$1.log + done +} + +echo "Starting tests..." +FILES=`ls *_Test 2>/dev/null` +if [ "$FILES" = "" ]; then + echo "ERROR: no test programs generated matching pattern *_Test." + echo "ERROR: Try compiling the test programs first." + exit 1 +fi + +for i in *_Test +do + run $i +done + +echo "Tests complete..." + + +# EOF diff --git a/ASNMP/tests/test_config.h b/ASNMP/tests/test_config.h new file mode 100644 index 00000000000..cec49951d40 --- /dev/null +++ b/ASNMP/tests/test_config.h @@ -0,0 +1,223 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// = FILENAME +// test_config.h +// +// = AUTHOR +// Prashant Jain <pjain@cs.wustl.edu>, Tim Harrison +// <harrison@cs.wustl.edu>, and David Levine <levine@cs.wustl.edu> +// +// ============================================================================ + +#if !defined (ACE_TEST_CONFIG_H) +#define ACE_TEST_CONFIG_H + +#include <iostream.h> +#include <fstream.h> + +#if !defined (ACE_HAS_TEMPLATE_SPECIALIZATION) +class KEY +// ============================================================================ +// = TITLE +// Define a key for use with the Map_Manager_Test. +// +// = DESCRIPTION +// This class is put into the test_config.h header file to work +// around AIX C++ compiler "features" related to template +// instantiation... It is only used by Map_Manager_Test.cpp +// ============================================================================ +{ +public: + KEY (size_t v = 0): value_ (v) + { } + + size_t hash (void) const { return this->value_; } + operator size_t () const { return this->value_; } + +private: + size_t value_; +}; +#else +typedef size_t KEY; +#endif /* ACE_HAS_TEMPLATE_SPECIALIZATION */ + +#if defined (ACE_WIN32) + +#define ACE_DEFAULT_TEST_FILE_A "C:\\temp\\ace_test_file" +#define ACE_TEMP_FILE_NAME_A "C:\\temp\\ace_temp_file" +#define ACE_LOG_DIRECTORY_A "C:\\temp\\log\\" +#define MAKE_PIPE_NAME_A(X) "\\\\.\\pipe\\"#X + +#define ACE_DEFAULT_TEST_FILE_W L"C:\\temp\\ace_test_file" +#define ACE_TEMP_FILE_NAME_W L"C:\\temp\\ace_temp_file" +#define ACE_LOG_DIRECTORY_W L"C:\\temp\\log\\" +#define MAKE_PIPE_NAME_W(X) L"\\\\.\\pipe\\"#X + +#else + +#define ACE_DEFAULT_TEST_FILE_A "/tmp/ace_test_file" +#define ACE_TEMP_FILE_NAME_A "/tmp/ace_temp_file" +#define ACE_LOG_DIRECTORY_A "log/" +#define MAKE_PIPE_NAME_A(X) X + +#if defined (ACE_HAS_UNICODE) +#define ACE_DEFAULT_TEST_FILE_W L"/tmp/ace_test_file" +#define ACE_TEMP_FILE_NAME_W L"/tmp/ace_temp_file" +#define ACE_LOG_DIRECTORY_W L"log/" +#define MAKE_PIPE_NAME_W(X) L##X +#else +#define ACE_DEFAULT_TEST_FILE_W "/tmp/ace_test_file" +#define ACE_TEMP_FILE_NAME_W "/tmp/ace_temp_file" +#define ACE_LOG_DIRECTORY_W "log/" +#define MAKE_PIPE_NAME_W(X) X +#endif /* ACE_HAS_UNICODE */ + +#endif /* ACE_WIN32 */ + +#if defined (UNICODE) +#define ACE_DEFAULT_TEST_FILE ACE_DEFAULT_TEST_FILE_W +#define ACE_TEMP_FILE_NAME ACE_TEMP_FILE_NAME_W +#define ACE_LOG_DIRECTORY ACE_LOG_DIRECTORY_W +#define MAKE_PIPE_NAME MAKE_PIPE_NAME_W +#else +#define ACE_DEFAULT_TEST_FILE ACE_DEFAULT_TEST_FILE_A +#define ACE_TEMP_FILE_NAME ACE_TEMP_FILE_NAME_A +#define ACE_LOG_DIRECTORY ACE_LOG_DIRECTORY_A +#define MAKE_PIPE_NAME MAKE_PIPE_NAME_A +#endif /* UNICODE */ + +#define ACE_START_TEST(NAME) \ + const char *program = NAME; \ + ACE_LOG_MSG->open (program, ACE_Log_Msg::OSTREAM); \ + if (ace_file_stream.set_output (program) != 0) \ + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "set_output failed"), -1); \ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting %s test at %T\n", program)); + +#define ACE_END_TEST \ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Ending %s test at %T\n", program)); \ + ace_file_stream.close (); + +#define ACE_NEW_THREAD \ +do {\ + ACE_LOG_MSG->msg_ostream (ace_file_stream.output_file ()); \ + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER ); \ + ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); \ +} while (0) + +#define ACE_APPEND_LOG(NAME) \ + const char *program = NAME; \ + ACE_LOG_MSG->open (program, ACE_Log_Msg::OSTREAM); \ + if (ace_file_stream.set_output (program, 1) != 0) \ + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "set_output failed"), -1); \ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Starting %s test at %T\n", program)); + +#define ACE_END_LOG \ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Ending %s test at %T\n\n", program)); \ + ace_file_stream.close (); + +#define ACE_INIT_LOG(NAME) \ + char temp[BUFSIZ]; \ + ACE_OS::sprintf (temp, "%s%s%s", \ + ACE_LOG_DIRECTORY_A, \ + ACE::basename (NAME, ACE_DIRECTORY_SEPARATOR_CHAR_A), \ + ".log"); \ + ACE_DEBUG ((LM_DEBUG, "Deleting old log file %s (if any)\n\n", temp)); \ + ACE_OS::unlink (temp); + + +const int ACE_NS_MAX_ENTRIES = 1000; +const int ACE_MAX_TIMERS = 4; +const int ACE_MAX_THREADS = 4; +const int ACE_MAX_DELAY = 10; +const int ACE_MAX_INTERVAL = 0; +const int ACE_MAX_ITERATIONS = 10; +const int ACE_MAX_PROCESSES = 10; + +char ACE_ALPHABET[] = "abcdefghijklmnopqrstuvwxyz"; + +class ACE_Test_Output +{ +public: + ACE_Test_Output (void); + ~ACE_Test_Output (void); + int set_output (const char *filename, int append = 0); + ofstream *output_file (void); + void close (void); + +private: + ofstream output_file_; +}; + +static ACE_Test_Output ace_file_stream; + +ACE_Test_Output::ACE_Test_Output (void) +{ +} + +ACE_Test_Output::~ACE_Test_Output (void) +{ +} + +int +ACE_Test_Output::set_output (const char *filename, int append) +{ + char temp[BUFSIZ]; + // Ignore the error value since the directory may already exist. + ACE_OS::mkdir (ACE_LOG_DIRECTORY_A); + ACE_OS::sprintf (temp, "%s%s%s", + ACE_LOG_DIRECTORY_A, + ACE::basename (filename, ACE_DIRECTORY_SEPARATOR_CHAR_A), + ".log"); + + int flags = ios::out; + if (append) + flags |= ios::app; + + this->output_file_.open (temp, flags); + if (this->output_file_.bad ()) + return -1; + + ACE_LOG_MSG->msg_ostream (ace_file_stream.output_file ()); + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER ); + ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); + + return 0; +} + +ofstream * +ACE_Test_Output::output_file (void) +{ + return &this->output_file_; +} + +void +ACE_Test_Output::close (void) +{ + this->output_file_.flush (); + this->output_file_.close (); +} + +void +randomize (int array[], size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) + array [i] = i; + + ACE_OS::srand (ACE_OS::time (0L)); + + // Generate an array of random numbers from 0 .. size - 1. + + for (i = 0; i < size; i++) + { + int index = ACE_OS::rand() % size--; + int temp = array [index]; + array [index] = array [size]; + array [size] = temp; + } +} + +#endif /* ACE_TEST_CONFIG_H */ |