diff options
Diffstat (limited to 'ACE/ASNMP')
88 files changed, 21228 insertions, 0 deletions
diff --git a/ACE/ASNMP/COPYRIGHT b/ACE/ASNMP/COPYRIGHT new file mode 100644 index 00000000000..ad880b9cf90 --- /dev/null +++ b/ACE/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/ACE/ASNMP/ChangeLog b/ACE/ASNMP/ChangeLog new file mode 100644 index 00000000000..a2fc9832377 --- /dev/null +++ b/ACE/ASNMP/ChangeLog @@ -0,0 +1,538 @@ +Wed Mar 8 10:46:12 UTC 2006 Johnny Willemsen <jwillemsen@remedy.nl> + + * asnmp/*.h: + Converted to doxygen style of documentation + +Wed Jan 4 22:47:13 UTC 2006 J.T. Conklin <jtc@acorntoolworks.com> + + * ChangeLog: + + Untabify. + Delete-trailing-whitespace. + + Added "Local Variables" section defining "add-log-time-format" + to a really ugly lambda expression that formats changelog + timestamps in UTC and works with both GNU Emacs and XEmacs. + +Fri Dec 30 11:11:12 UTC 2005 Johnny Willemsen <jwillemsen@remedy.nl> + + * asnmp/transaction.cpp: + Updated because the ACE_Time_Value constructors are now explicit + +Fri Dec 23 09:56:12 UTC 2005 Johnny Willemsen <jwillemsen@remedy.nl> + + * asnmp/address.{h,cpp}: + Added LEN as postfix for HASH0, HASH1 and HASH2. VxWorks 6.1 PPC + defines HASH1 and HASH2 + +Wed Oct 5 10:23:12 UTC 2005 Johnny Willemsen <jwillemsen@remedy.nl> + + * asnmp/asn1.cpp: + * asnmp/pdu.cpp: + Fixed might be used uninitialized warnings in MinGW build + +Fri Jul 15 10:12:19 2005 Douglas C. Schmidt <schmidt@cs.wustl.edu> + + * Removed the asnmp.mwc file so that it can be regenerated by MPC + automatically. Thanks to Sam Mesh <sam.mesh@gmail.com> for + reporting this. This fixes bugid 2190. + +Sun Oct 3 20:12:43 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu> + + * asnmp/oid.cpp: + + Fixed a double deletion problem reported by Shlomi Yaakobovich. + +Thu Sep 30 10:54:39 2004 Steve Huston <shuston@riverace.com> + + * examples/get/get.cpp: + * examples/get/get_async.cpp: + * examples/next/next.cpp: + * examples/set/set.cpp: + * examples/trap/trap.cpp: + * examples/walk/walk.cpp: Added #include "ace/Argv_Type_Converter.h". + +Wed Sep 29 15:33:29 2004 Steve Huston <shuston@riverace.com> + + * asnmp/sagent.cpp: + * agent/snmp_agent.cpp: + * examples/get/get.cpp: + * examples/get/get_async.cpp: + * examples/next/next.cpp: + * examples/set/set.cpp: + * examples/trap/trap.cpp: + * examples/walk/walk.cpp: + * tests/test_config.h: + * tests/Address_Test.cpp: + * tests/Counter64_Test.cpp: + * tests/Counter_Test.cpp: + * tests/Gauge_Test.cpp: + * tests/Integer_Test.cpp: + * tests/Octet_Test.cpp: + * tests/Oid_Test.cpp: + * tests/Target_Test.cpp: + * tests/Varbind_Test.cpp: Adjustments to build with wide-char. + +Fri Aug 6 08:14:12 2004 Douglas C. Schmidt <schmidt@cs.wustl.edu> + + * asnmp/transaction.{h,cpp}: Added a get_handle() call to + session. Thanks to Geo Sebastian <geosebastian@onmobile.com> + for this fix. + +Fri May 7 14:42:22 2004 Ossama Othman <ossama@dre.vanderbilt.edu> + + * tests/Counter_Test.cpp (TestCounter): + * tests/Gauge_Test.cpp (TestGuage): + * tests/Integer_Test.cpp (TestUnsignedInteger32): + + More "comparison between signed and unsigned integer" + warning fixes. + +Thu May 6 11:03:26 2004 Ossama Othman <ossama@dre.vanderbilt.edu> + + * tests/Counter_Test.cpp (TestCounter): + * tests/Counter64_Test.cpp (TestCounter64): + * tests/Gauge_Test.cpp (TestGuage): + * tests/Integer_Test.cpp (TestUnsignedInteger32): + + Fixed "comparison between signed and unsigned integer" + warnings. + +Mon Apr 26 18:37:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * examples/get/get.cpp: + * examples/get/get_async.cpp: + * examples/next/next.cpp: + * examples/set/set.cpp: + * examples/trap/trap.cpp: + * examples/walk/walk.cpp: + Don't use deprecated methods of ACE_Get_Opt and ACE_Reactor + +Mon Apr 26 15:14:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * examples/trap/purify4.1.txt: + Removed this file, it contains purify results and shouldn't + belong in the repo. + +Thu Apr 22 20:45:27 2004 Ossama Othman <ossama@dre.vanderbilt.edu> + + * tests/Octet_Test.cpp: + * tests/Oid_Test.cpp: + + Changed all return types for equality, relational and logical + operators to "bool", as is the norm for modern C++. + +Fri Apr 16 16:53:20 2004 Ossama Othman <ossama@dre.vanderbilt.edu> + + * tests/Gauge_Test.cpp (TestGuage): + * tests/Integer_Test.cpp (TestInteger32, TestUnsignedInteger32): + + Fixed some "comparison between signed and unsigned integer" + warnings. + +Mon Mar 29 06:56:11 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tests/Integer_Test.cpp: + Fixed a warning in Win32 builds. + +Fri Mar 26 09:49:10 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu> + + * tests/Integer_Test.cpp: + + Fixed a warning in Win32 builds. + +Fri Aug 29 07:56:19 2003 Ossama Othman <ossama@dre.vanderbilt.edu> + + * tests/Octet_Test.cpp (TestOctet): + + Fixed "string literal converted to char *" warning. String + literals are now considered "const" by standard C++. + +Sun Nov 24 17:04:33 2002 Douglas C. Schmidt <schmidt@tango.doc.wustl.edu> + + * agent/main.cpp (main): Added ACE::init() to the beginning of + main() to prevent crashes on Windows. Thanks to Huseyin Calgin + <calgin@yahoo.com> for reporting this. + +Fri Feb 8 04:42:21 2002 Douglas C. Schmidt <schmidt@tango.doc.wustl.edu> + + * asnmp/transaction.cpp (run): Changed the code to use ACE_Reactor::instance () + rather than a local ACE_Reactor on the stack. Thanks to Paresh + Raote <p_raote@yahoo.com> for reporting this. + +Thu Jan 25 12:48:33 2001 Craig Rodrigues <crodrigu@bbn.com> + + * agent/Makefile.orig + asnmp/address.h.orig + examples/next/next.cpp + examples/trap/trap.cpp + examples/walk/walk.cpp + tests/test_config.h + tests/Varbind_Test.cpp + tests/Counter64_Test.cpp + tests/run_tests.sh + + New agent Makefile, and compilation fixes. + +Sun Jun 4 14:51:33 2000 Darrell Brunsch <brunsch@uci.edu> + + * asnmp-overview.html: + + Added missing CVS Id string. + +Tue Dec 21 16:22:21 1999 David L. Levine <levine@cs.wustl.edu> + + * tests/*.cpp: removed the unnecessary explicit template + instantiation. Other instantiations were necessary + with it, and it seemed to serve no useful purpose: + there was no use of an ACE_Unbounded_Set<Log_Msg *>. + Thanks to Jose Rubio <jrubio@tr.comm.mot.com> for + reporting link failures with Sun CC 5.0, with explicit + template instantiation enabled. + + * tests/test_config.h: added #include of "ace/ACE.h", + because the file uses it later. g++ 2.91.66 on Linux + needed it. + +Wed Jul 14 08:26:42 1999 Brian Raven <brianr@liffe.com> + + * asnmp/snmp.{h,cpp},wpdu.cpp: + SYNOPSIS: + 1) The agent IP address in traps originating from logical + domains on an Enterprise 10000 is that of the physical domain. + + 2) The code that gets the IP address uses gethostbyname + which is unsafe in a MT environment (according to the man page). + + DESCRIPTION: + 1) The problem seems to be caused by hostname only returning + the physical domain name. + + SAMPLE FIX/WORKAROUND: + 1) To get around this problem I added the capability to + override the local host name. + + 2) I would suggest using the GenAddress class to obtain the + IP address. + +Tue Jun 22 13:34:54 1999 David L. Levine <levine@cs.wustl.edu> + + * agent/Makefile: replaced rm -f with $(RM). + +Thu Apr 29 06:46:46 1999 David L. Levine <levine@cs.wustl.edu> + + * tests/Makefile: changed SRC to PSRC (for make depend). + Thanks to Sandeep Goyal <sagoyal@hss.hns.com> for reporting + that the Makefile was broken. + +Mon Dec 28 22:03:57 1998 David L. Levine <levine@cs.wustl.edu> + + * agent/main.cpp: added #include "ace/inc_user_config.h", for + ACE_RCSID definition. Thanks to wym <wym@dekang.com> for + reporting that it won't compile without it. + +Tue Oct 27 08:52:05 1998 David L. Levine <levine@cs.wustl.edu> + + * asnmp/Makefile,tests/Makefile: added SRC definition for make depend, and updated dependencies. + +Mon Aug 3 17:50:08 1998 Gonzalo Diethelm <gonzo@tango.cs.wustl.edu> + + * examples/get/get_async.cpp: + * examples/get/get.cpp: + Added ACE_RCSID to these files. + +Fri Jul 31 19:26:07 1998 Gonzalo Diethelm <gonzo@tango.cs.wustl.edu> + + * examples/Makefile: + It had a missing info subdirectory. + + * agent/agent_impl.cpp: + * agent/main.cpp: + * agent/snmp_agent.cpp: + * asnmp/address.cpp: + * asnmp/asn1.cpp: + * asnmp/counter.cpp: + * asnmp/ctr64.cpp: + * asnmp/gauge.cpp: + * asnmp/integer.cpp: + * asnmp/octet.cpp: + * asnmp/oid.cpp: + * asnmp/pdu.cpp: + * asnmp/sagent.cpp: + * asnmp/snmp.cpp: + * asnmp/target.cpp: + * asnmp/timetick.cpp: + * asnmp/transaction.cpp: + * asnmp/vb.cpp: + * asnmp/wpdu.cpp: + * examples/get/get.cpp: + * examples/next/next.cpp: + * examples/set/set.cpp: + * examples/trap/trap.cpp: + * examples/walk/walk.cpp: + * tests/Address_Test.cpp: + * tests/Counter64_Test.cpp: + * tests/Counter_Test.cpp: + * tests/Gauge_Test.cpp: + * tests/Integer_Test.cpp: + * tests/Octet_Test.cpp: + * tests/Oid_Test.cpp: + * tests/Target_Test.cpp: + * tests/Varbind_Test.cpp: + Added ACE_RCSID to these files. + +Wed Jul 15 20:34:55 CDT 1998 + * general fixes for SNMPv1 trap generation code reported by + Hien Nguyen <hnguyen@adcapex.com> and Jeff Hall <jeff@liffe.com> + Added Hien's fixes, plus fixed -c option + in examples/trap to properly set community string. + * release 2.0 + +Fri Jan 30 15:29:42 CST 1998 + * fix vb.cpp to handle Gauge/uInt the same way. While retrieving + ifTable found the bug. + +Wed Dec 10 12:09:36 CST 1997 + * sagent.cpp, Eric Newton fix. result not checked. v1.8 + +Mon Dec 8 14:33:59 CST 1997 + * Thanks to Eric Newton's <ecn@smart.net> continued patches + Version 1.7 has fixes for: agent, base library + Fix to the response type fixes the interoperability with CMU snmp on + linux. (and SNMP Research as well) + + Initialize member of Pdu: output_ + Send responses as response messages + Deallocate and reset the io_vec + + The transaction object didn't initialize the io_vec used to receive + a packet when it was used for an agent transaction. + + Cleans up a warning about using a const object from a previous + patch. + + Removes the transaction object from the Reactor. + + +Sun Nov 30 17:49:12 CST 1997 Mike MacFaden <mrm@tango.cs.wustl.edu> + * Thanks to Eric Newton's <ecn@smart.net> apply patches: + Removed G++ warnings: + Removed unused variables + Cleaned up unused args to functions + Initialized variables + Inserted casts in *printf* functions + Added int return types to function definitions + Converted some variables from int to size_t to cut down on + sign comparison warnings + Reordered constructor initializer lists + Added return statements to functions returning int + + Modified for G++ language differences: + Modified for loops for ANSI scoping rules + + Fixed Bugs: + Deleted incorrect (cut-n-pasted) header to transaction.h + Removed "assignment in if condition" error + Added missing "break;" in switch statement in wpdu + + Features: + Added async interface. + + Noise: + Modified makefiles for g++ on Linux RedHat 4.1 + + * The new async interface has a test example in examples/get/get_async.cpp + that is useful if you are extending the get application. + + * Fixed makefile to include -lasnmp when building tests/examples + + * Compile and test with ACE 4.4 on Solaris 2.5.1 using Sun CC 4.2 + no warnings/errors. get_async will sigbus however in destructors. + +Thu Sep 4 18:56:12 1997 Mike MacFaden <mrm@tango.cs.wustl.edu> + + * commit agent/ mibs/ and update asnmp/ with sagent.h, cpp + to implement a trivial SNMPv1 agent that hard codes support + for mib II system group only. + +Fri Aug 22 23:43:20 1997 Mike MacFaden <mrm@tango.cs.wustl.edu> + + * clean up two memory leaks in octet class and one umr + +Thu Aug 21 20:59:23 1997 Mike MacFaden <mrm@tango.cs.wustl.edu> + + * Added Netbios address support to GenAddress + and added DecNetAddress, AppleTalkAddress classes per CISCO-TC.my + (ftp://ftp.cisco.com/pub/mibs) + +Tue Aug 19 20:19:32 1997 Michael R. MacFaden <mrm@mrm-ss20.cisco.com (Michael R. MacFaden)> + * change IpAddress::is_arpa() to is_private() and update the comments + per RFC 1597. Add new test routine to verify this function in + tests/Address_Test.cpp + + * add IpAddress::to_octet(OctetStr& val) which is useful when having to + send a network address as an Octet String as in CISCO-PING-MIB.my + +Tue Aug 5 12:12:39 1997 Mike MacFaden (mrm@mrm-ss20) + * Thanks to Amos Shapira <amos@gezernet.co.il> apply patches + to support IRIX 6.3. Stated request for: + I think it would make things "righter" to make the code use C++ + strings (and maybe vectors?). + + * Begin testing on HP-UX 10.01 (missing ucontext.h) + +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. + +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 + +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 + +Local Variables: +mode: change-log +add-log-time-format: (lambda () (progn (setq tz (getenv "TZ")) (set-time-zone-rule "UTC") (setq time (format-time-string "%a %b %e %H:%M:%S %Z %Y" (current-time))) (set-time-zone-rule tz) time)) +indent-tabs-mode: nil +End: diff --git a/ACE/ASNMP/Makefile.am b/ACE/ASNMP/Makefile.am new file mode 100644 index 00000000000..7ff1160c8a3 --- /dev/null +++ b/ACE/ASNMP/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +SUBDIRS = \ + asnmp \ + agent \ + examples \ + tests + diff --git a/ACE/ASNMP/README b/ACE/ASNMP/README new file mode 100644 index 00000000000..f07563c61a5 --- /dev/null +++ b/ACE/ASNMP/README @@ -0,0 +1,177 @@ +Fri Dec 18 09:43:35 CST 1998 +==================================================================== +ASNMP = ACE+SNMP++ Version 2.1 +By Michael R. MacFaden mrm@acm.org, mrm@yagosys.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 is Simple Network Management Protocol(SNMP)? + See the FAQ: + http://www.snmp.com/FAQs/snmp-faq-part1.txt + http://www.snmp.com/FAQs/snmp-faq-part2.txt + + +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,4.2 compiler. Linux/GCC + fixes are now in as well. + +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. + + An agent inteface has been added (asnmp/sagent.h) so both agents + and managers can use this class library. A trivial agent + exists in ASNMP/agent/ + + 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. + + The async interface does not match the HP implementation. + +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 about SNMP Version 3? + It is looking good for V3, but so far, we're just watching. + http://www.ietf.org/html.charters/snmpv3-charter.html + A C implemenation is now available from UC Davis. + +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/...). + +How does one Extend an SNMP Agent? + Extending an agent typically means updating the agent source or + using a dynamic link style API. RFC 2257 (AgentX) is the current design + for doing this in a standard way. This hasn't been well formalized yet + so extending an existing agent is still a vendor API thing. + + The agent provided here is a template. A mib compiler and agent + library typically provide better agent support. See the UC-Davis + SNMP software for an example Agent that is portable and can report + on many flavors of UNIX and Windows. + +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 a related cousin of general distributed programming. + + +Regards, +Michael R. MacFaden +Member of the Technical Staff +Cabletron Systems, Inc. +215 Moffet Park Drive +Sunnyvale, CA 94089 +mrm@yagosys.com +http://www.yagosys.com + +==================================================================== +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/ACE/ASNMP/TO-DO b/ACE/ASNMP/TO-DO new file mode 100644 index 00000000000..a05b7106f58 --- /dev/null +++ b/ACE/ASNMP/TO-DO @@ -0,0 +1,3 @@ +TODO: + - Attempt to make all subroutines thread safe + - work on test suite - validate basic stuff doesn't leak diff --git a/ACE/ASNMP/agent/Makefile.am b/ACE/ASNMP/agent/Makefile.am new file mode 100644 index 00000000000..afb76da40ed --- /dev/null +++ b/ACE/ASNMP/agent/Makefile.am @@ -0,0 +1,45 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.asnmp_agent.am + +if !BUILD_USES_WCHAR + +noinst_PROGRAMS = agent + +agent_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +agent_SOURCES = \ + agent_impl.cpp \ + main.cpp \ + snmp_agent.cpp \ + agent_impl.h \ + snmp_agent.h + +agent_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_USES_WCHAR + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/ASNMP/agent/agent.mpc b/ACE/ASNMP/agent/agent.mpc new file mode 100644 index 00000000000..4579c29d458 --- /dev/null +++ b/ACE/ASNMP/agent/agent.mpc @@ -0,0 +1,14 @@ +// $Id$ + +project (asnmp_agent) : aceexe { + exename = agent + after += asnmp_lib + libs += asnmp + avoids += uses_wchar + includes += $(ACE_ROOT)/ASNMP + source_files { + agent_impl.cpp + main.cpp + snmp_agent.cpp + } +} diff --git a/ACE/ASNMP/agent/agent_impl.cpp b/ACE/ASNMP/agent/agent_impl.cpp new file mode 100644 index 00000000000..b0183a964a4 --- /dev/null +++ b/ACE/ASNMP/agent/agent_impl.cpp @@ -0,0 +1,158 @@ +// $Id$ + +// implement a prototype SNMP Agent using ASNMP and ACE + +#include <ace/Reactor.h> +#include <ace/SOCK_Dgram.h> +#include <ace/INET_Addr.h> +#include <ace/Signal.h> + +#include "agent_impl.h" + +ACE_RCSID(agent, agent_impl, "$Id$") + +agent_impl::agent_impl(unsigned short port, const char *rd, const char *wr) : +sagent(port) +{ + ACE_TRACE("agent_impl::agent_impl"); + tgt_.set_read_community(rd); + tgt_.set_write_community(wr); + agent_clock_.start(); +} + +agent_impl::~agent_impl() +{ + ACE_TRACE("agent_impl::~agent_impl"); +} + +// callback : have received a Pdu from the target host with given read comm str +// this is really simplistic, but gives the general idea +int agent_impl::handle_get( Pdu &pdu, UdpTarget &target) +{ + ACE_TRACE("agent_impl::handle_get"); + OctetStr mgr_rd_str, agent_rd_str; + target.get_read_community(mgr_rd_str); // requster's read community string + tgt_.get_read_community(agent_rd_str); // this agent's read community string + + // 1. verify we have a valid read string else drop pdu (no response to caller) + if (mgr_rd_str != agent_rd_str) { + ACE_DEBUG((LM_DEBUG, "agent_impl::handle_get: invalid read community recvd\n")); + return 0; + } + + // 2. iterate over each varbind in the pdu, filling providing responses + int fdone = 0; + for (int i = 0; (i < pdu.get_vb_count()) && !fdone; i++) { + Vb vb; + pdu.get_vb(vb, i); + if (get_response(vb)) { // set a value for the oid if we can else + set_error_status(&pdu, SNMP_ERROR_NO_SUCH_NAME); // these ought to be member + set_error_index(&pdu, i); // functions but are not yet... + fdone++; // trigger flag to exit loop early + } + else // failed, return noSuch error + pdu.set_vb(vb, i); + } + + // 3. lastly, return the pkt to the caller + return respond(pdu, target); +} + +// this routine makes up the brains of the agent +// it knows only the MIB II system group set of variables for a get operation +int agent_impl::get_response(Vb& vb) +{ + // these objects represent the MIB II system group per RFC 1213 + static Oid sysDescr("1.3.6.1.2.1.1.1.0"), + sysObjectID("1.3.6.1.2.1.1.2.0"), sysUpTime("1.3.6.1.2.1.1.3.0"), + sysContact("1.3.6.1.2.1.1.4.0"), sysName("1.3.6.1.2.1.1.5.0"), + sysLocation("1.3.6.1.2.1.1.6.0"), sysServices("1.3.6.1.2.1.1.7.0"); + + Oid oid; + vb.get_oid(oid); + if (oid == sysDescr) { + OctetStr desc("ASNMP Prototype Agent 1.0"); + vb.set_value(desc); + } + else if (oid == sysObjectID) { // the IANA gives assigns Enterprise Numbers + // see ftp://ftp.isi.edu/in-notes/iana/assignments/enterprise-numbers + // for the official list of enterprise numbers. Then under this tree + // assign a unique subtree to identify this agent + Oid id("1.3.6.1.4.1.2533.9.1"); + vb.set_value(id); + } + else if (oid == sysUpTime) { + ACE_Time_Value tv; + agent_clock_.elapsed_time (tv); + TimeTicks tt(tv.msec()); + vb.set_value(tt); + } + else if (oid == sysContact) { + OctetStr contact("mrm@acm.org"); + vb.set_value(contact); + } + else if (oid == sysName) { + OctetStr fqdn("foo.org"); // extract this from the gethostbyname() TODO + vb.set_value(fqdn); + } + else if (oid == sysLocation) { + OctetStr loc(""); + vb.set_value(loc); + } + else if (oid == sysServices) { + SnmpInt32 svcs(72); + vb.set_value(svcs); + } + else + return 1; // noSuchName + + return 0; +} + +int agent_impl::handle_get_next( Pdu &, UdpTarget &) +{ + ACE_TRACE("agent_impl::handle_get_next -NI"); + return 0; +} + +int agent_impl::handle_set( Pdu &, UdpTarget &) +{ + ACE_TRACE("agent_impl::handle_set -NI"); + return 0; +} + +// stuff used by process_requests + +// called when SIGINT +static sig_atomic_t finished = 0; + +extern "C" void +sig_handler (int) +{ + ACE_TRACE("::sig_handler"); + finished = 1; +} + +int agent_impl::process_requests() +{ + ACE_TRACE("agent_impl::process_requests"); + ACE_Reactor reactor; + + ACE_Sig_Action sa ((ACE_SignalHandler) sig_handler, SIGINT); + ACE_UNUSED_ARG (sa); + + // Read data from other side. + if (reactor.register_handler (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_Reactor::register_handler"), -1); + + // TODO: register signal handler to shut down gracefully here + + while (!finished) + { + reactor.handle_events (); + ACE_DEBUG ((LM_DEBUG, "return from handle events\n")); + } + + ACE_DEBUG ((LM_DEBUG, "return from handle events - normal shut down\n")); + return 0; +} diff --git a/ACE/ASNMP/agent/agent_impl.h b/ACE/ASNMP/agent/agent_impl.h new file mode 100644 index 00000000000..60ee90034a2 --- /dev/null +++ b/ACE/ASNMP/agent/agent_impl.h @@ -0,0 +1,52 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ASNMP +// +// = FILENAME +// agent_impl.h +// +// = AUTHOR +// Michael R. MacFaden +// +// ============================================================================ + +#ifndef AGENT_IMPL_H +#define AGENT_IMPL_H + +#include <ace/Event_Handler.h> +#include <ace/SOCK_Dgram.h> +#include <ace/INET_Addr.h> +#include <ace/High_Res_Timer.h> +#include <asnmp/sagent.h> +#include <asnmp/vb.h> + +class agent_impl : public sagent +{ +public: + agent_impl(unsigned short port, const char *rd, const char *wr); + virtual ~agent_impl(); + + virtual int handle_get( Pdu &pdu, UdpTarget &target); + // retrieve data from a peer agent for a given list of oid values + + virtual int handle_get_next( Pdu &pdu, UdpTarget &target); + // retrieve data lexically adjacent to the oids specified in the pdu + // from the peer agent + + virtual int handle_set( Pdu &pdu, UdpTarget &target); + // set data in the agent from the list of oids in the pdu + + int process_requests(); + // main loop here using a reactor object + +private: + UdpTarget tgt_; // this agent's read, write community strings + int get_response(Vb& vb); // set values for a "get" cmd + ACE_High_Res_Timer agent_clock_; // agent "uptime" ticks reported in 1/100 second +}; + +#endif /* AGENT_IMPL_H */ diff --git a/ACE/ASNMP/agent/main.cpp b/ACE/ASNMP/agent/main.cpp new file mode 100644 index 00000000000..ff0c9431518 --- /dev/null +++ b/ACE/ASNMP/agent/main.cpp @@ -0,0 +1,28 @@ +// $Id$ + +// This server daemon processes SNMP Version 1 get, get-next, and set +// commands. over the MIB II "System" group only. + +#include "ace/config-all.h" +#include "snmp_agent.h" +#include "ace/ACE.h" + +ACE_RCSID(agent, main, "$Id$") + +int +main (int argc, char *argv[]) +{ + ACE::init (); + snmp_agent the_agent; + + if (the_agent.set_args(argc, argv)) + return 1; + + if (!the_agent.valid()) { + return 1; + } + + the_agent.run(); // main loop + + return 0; +} diff --git a/ACE/ASNMP/agent/snmp_agent.cpp b/ACE/ASNMP/agent/snmp_agent.cpp new file mode 100644 index 00000000000..520c58eaccf --- /dev/null +++ b/ACE/ASNMP/agent/snmp_agent.cpp @@ -0,0 +1,104 @@ +// $Id$ + +// This server daemon processes SNMPv1 requests over MIB II System group + +#include "snmp_agent.h" +#include "agent_impl.h" // actual implementation +#include "ace/Argv_Type_Converter.h" +#include "ace/Get_Opt.h" +#include "ace/Reactor.h" + +ACE_RCSID(agent, snmp_agent, "$Id$") + +// module globals +#define SNMP_AGENT_PORT (161) +#define WR_COM ACE_TEXT ("private") +#define RD_COM ACE_TEXT ("public") + +snmp_agent::snmp_agent() : agent_(0) +{ + ACE_TRACE("snmp_agent::snmp_agent"); +} + +snmp_agent::~snmp_agent() +{ + ACE_TRACE("snmp_agent::~snmp_agent"); + delete agent_; +} + + +int snmp_agent::valid() const +{ + ACE_TRACE("snmp_agent::valid"); + return (agent_ != 0); +} + +int snmp_agent::set_args(int argc, char *argv[]) +{ + ACE_TRACE("snmp_agent::set_args"); + unsigned short port = SNMP_AGENT_PORT; + const ACE_TCHAR *rd = RD_COM; + const ACE_TCHAR *wr = WR_COM; + ACE_Argv_Type_Converter to_tchar (argc, argv); + + ACE_Get_Opt get_opt + (argc, to_tchar.get_TCHAR_argv (), ACE_TEXT ("p:w:r:hv")); + for (int c; (c = get_opt ()) != -1; ) { + switch (c) + { + case 'p': + port = (ACE_OS::atoi (get_opt.optarg)); + break; + case 'w': // write community string + wr = get_opt.optarg; + break; + case 'r': // read community string + rd = get_opt.optarg; + break; + + case 'h': // help & version info + case 'v': + ACE_DEBUG + ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Example SNMP Version 1 Agent - ASNMP/ACE\n"))); + return -1; + break; + + default: + return -1; // invalid arg + } + } + + + agent_ = new agent_impl(port, + ACE_TEXT_ALWAYS_CHAR (rd), + ACE_TEXT_ALWAYS_CHAR (wr)); // opens OS IO port + return 0; +} + +int snmp_agent::run() +{ + ACE_TRACE("snmp_agent::run"); + ACE_ASSERT(agent_); + + // open service port +#if 0 + if (agent_->open_port()) { + ACE_DEBUG((LM_DEBUG, "(%P|%t) open port %d failed\n", agent_->get_port())); + return -1; + } +#endif + + // Run forever, processing SNMP requests. + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) starting up snmp agent (server) daemon\n"))); + + agent_->process_requests(); + + ACE_DEBUG + ((LM_DEBUG, + ACE_TEXT ("(%P|%t) shutting down snmp agent (server) daemon\n"))); + return 0; +} + diff --git a/ACE/ASNMP/agent/snmp_agent.h b/ACE/ASNMP/agent/snmp_agent.h new file mode 100644 index 00000000000..a7fc4c42de8 --- /dev/null +++ b/ACE/ASNMP/agent/snmp_agent.h @@ -0,0 +1,48 @@ +// $Id$ + +/* -*-C++-*- */ + +#ifndef SNMP_AGENT_ +#define SNMP_AGENT_ +// ============================================================================ +// +// = LIBRARY +// ASNMP +// +// = FILENAME +// snmp_agent.h +// +// = AUTHOR +// Michael R. MacFaden (mrm@cisco.com) +// +// ============================================================================ + +class agent_impl; + +class snmp_agent { + // = TITLE + // An SNMP v1 agent class + // + // = DESCRIPTION + // Contructs agents that are capable of processing SNMPv1 requests + // over the MIB II System group + + public: + snmp_agent(); // uses port 161, public, private + ~snmp_agent(); + + int valid() const; + // did object construct ok + + int set_args(int argc, char *argv[]); + // runtime arguments such as community strings, port to use + + int run(); + // begin processing requests + + private: + snmp_agent(const snmp_agent&); + agent_impl *agent_; +}; + +#endif // SNMP_AGENT_ diff --git a/ACE/ASNMP/asnmp-overview.html b/ACE/ASNMP/asnmp-overview.html new file mode 100644 index 00000000000..4e336178b0d --- /dev/null +++ b/ACE/ASNMP/asnmp-overview.html @@ -0,0 +1,134 @@ +<html> +<!-- $Id$ --> +<! 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>1213 +<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. + +<p>ASNMP can be used for either manager applications or agent applications. +The <i>Snmp</i> class contains the interface for manager applications. The +<i>sagent</i> class contains the interface for agent applications. A +trivial agent that implements the mib II system group per rfc1213 is +in the agents/ directory. + +<h2>Class Heirarchy</h2> + +<pre> +UdpTarget - Defines a collection of attributes needed to define a + communications session with an SNMP agent + This includes network address, response timeout, etc. + +Snmp - A logical session between NM app and agent. Provides the + commands get, get_next, trap. Manages transactions between app and + server. + +Pdu - A container object that represents an SNMP Protocol Data Unit. + A Pdu contains a command (get,getnext,trap) Varbind List list, + a community string. + +Vb - Aka Varbind or Variable Binding. A pdu can have zero, + one or more of these. A Vb consists of an Oid to identify + the variable and a value corresponding to one of the SMI values. + The oid/value binding is defined in a MIB file (RFC 1155) + Agents hava a MIB file that defines what each variable means. + Most agents implement MIB II as defined in RFC 1156. + +<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> + +<h1>References</h1> +<ul> +<li><a href="http://www.ece.ucdavis.edu/ucd-snmp/">UCD SNMP</a> +<li><a href="news://comp.protocols.snmp">comp.protocols.snmp</a> +<li><a href="http://snmp.cs.utwente.nl">University of Twente</a> +<li><a href="http://www.cis.ohio-state.edu/hypertext/faq/bngusenet/comp/protocols/snmp/top.html">SNMP FAQ</a> +<li><a href="http://www.adventnet.com/">Java based SNMP tools from Ardent</a> +<li><a href="http://misa.zurich.ibm.com/Webbin/">IBM SNMP/CMIP research</a> +</ul> +</html> diff --git a/ACE/ASNMP/asnmp/ASNMP_Export.h b/ACE/ASNMP/asnmp/ASNMP_Export.h new file mode 100644 index 00000000000..e4c9898f3f5 --- /dev/null +++ b/ACE/ASNMP/asnmp/ASNMP_Export.h @@ -0,0 +1,58 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl ASNMP +// ------------------------------ +#ifndef ASNMP_EXPORT_H +#define ASNMP_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (ASNMP_HAS_DLL) +# define ASNMP_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && ! ASNMP_HAS_DLL */ + +#if !defined (ASNMP_HAS_DLL) +# define ASNMP_HAS_DLL 1 +#endif /* ! ASNMP_HAS_DLL */ + +#if defined (ASNMP_HAS_DLL) && (ASNMP_HAS_DLL == 1) +# if defined (ASNMP_BUILD_DLL) +# define ASNMP_Export ACE_Proper_Export_Flag +# define ASNMP_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define ASNMP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* ASNMP_BUILD_DLL */ +# define ASNMP_Export ACE_Proper_Import_Flag +# define ASNMP_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define ASNMP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* ASNMP_BUILD_DLL */ +#else /* ASNMP_HAS_DLL == 1 */ +# define ASNMP_Export +# define ASNMP_SINGLETON_DECLARATION(T) +# define ASNMP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* ASNMP_HAS_DLL == 1 */ + +// Set ASNMP_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (ASNMP_NTRACE) +# if (ACE_NTRACE == 1) +# define ASNMP_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define ASNMP_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !ASNMP_NTRACE */ + +#if (ASNMP_NTRACE == 1) +# define ASNMP_TRACE(X) +#else /* (ASNMP_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define ASNMP_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (ASNMP_NTRACE == 1) */ + +#endif /* ASNMP_EXPORT_H */ + +// End of auto generated file. diff --git a/ACE/ASNMP/asnmp/ChangeLog b/ACE/ASNMP/asnmp/ChangeLog new file mode 100644 index 00000000000..8d82c1aa36c --- /dev/null +++ b/ACE/ASNMP/asnmp/ChangeLog @@ -0,0 +1,227 @@ +Wed Jan 4 22:50:09 UTC 2006 J.T. Conklin <jtc@acorntoolworks.com> + + * ChangeLog: + + Untabify. + Delete-trailing-whitespace. + + Added "Local Variables" section defining "add-log-time-format" + to a really ugly lambda expression that formats changelog + timestamps in UTC and works with both GNU Emacs and XEmacs. + +Fri May 7 11:40:25 2004 Ossama Othman <ossama@dre.vanderbilt.edu> + + * pdu.cpp (agent_error_reason): + + Really fixed mismatched sprintf() format specifiers this time + around. + +Thu May 6 11:13:25 2004 Ossama Othman <ossama@dre.vanderbilt.edu> + + * oid.cpp (operator+=, OidToStr): + * pdu.cpp (agent_error_reason): + + Fixed warnings regarding mismatch format specifiers and + arguments to sprintf(). + +Thu May 6 11:05:01 2004 Ossama Othman <ossama@dre.vanderbilt.edu> + + * gauge.h: + + Nuked trailing white space. + +Fri Apr 23 11:23:21 2004 Ossama Othman <ossama@dre.vanderbilt.edu> + + * oid.cpp: + + Missed some bool return types for equality operators. + +Thu Apr 22 23:03:48 2004 Ossama Othman <ossama@dre.vanderbilt.edu> + + * address.cpp: + * address.h: + * octet.cpp: + * octet.h: + * oid.cpp: + * oid.h: + * target.cpp: + * target.h: + * vb.cpp: + * vb.h: + + Changed all return types for equality, relational and logical + operators to "bool", as is the norm for modern C++. + +Fri Aug 29 07:57:05 2003 Ossama Othman <ossama@dre.vanderbilt.edu> + + * octet.cpp (to_string_hex): + + Fixed "string literal converted to char *" warning. String + literals are now considered "const" by standard C++. + +Tue Mar 16 16:28:14 1999 David L. Levine <levine@cs.wustl.edu> + + * address.cpp, address.h, asn1.cpp, asn1.h, counter.cpp, ctr64.cpp, + gauge.cpp, integer.cpp, octet.cpp, oid.cpp, pdu.cpp, sagent.cpp, + snmp.cpp, target.cpp, timetick.cpp, transaction.cpp, vb.cpp, + wpdu.cpp: + replaced TRUE with 1, and FALSE and NULL with 0. Thanks to + Achint Sandhu <sandhu@nortelnetworks.com> for reporting that + TRUE and FALSE weren't define on his Linux platform. + + * wpdu.cpp (set_trap_info): wrapped condition with () to + avoid g++ warning about using result of an assignment as + the condition. + + * ctr64.cpp: made MAX64 unsigned, to avoid warning about it + being to big to be signed. + +Wed Jul 15 20:27:23 1998 Mike MacFaden <mrm@tango.cs.wustl.edu> + * asn1.cpp - Hien Nguyen <hnguyen@apexgrp.com> fixed these bugs: + + Problem: The V1 trap agent-addr field tag value is OCTET STRING + instead of IPADDRESS, and the time stamp field tag value is INTEGER + instead of TIME TICKS. + + Fix: Change cmu_snmp::build() to pass in the correct type for agent-addr + and time stamp. + + 2. Problem: The V1 trap enterprise OID is corrupted after is was set in + wpdu constructor. + + Fix: In wpdu::set_trap_info(), the raw_pdu enterprise OID pointer was + assigned to the raw data of an enterprise Oid object on the stack. + Changed to perform an ACE_NEW_RETURN on the raw_pdu->enterprise and + perform a memcpy to copy the OID. The allocated memory is freed in + cmu_snmp::free_pdu() as currently implemented. + + 3. The V1 trap agent-addr field is currently initialized to "0.0.0.0". + I changed wpdu::set_trap_info to initialize it to the local host IP + Address. + + 4. I noticed that the memory allocation for OID in asn1.cpp using + ACE_NEW consistently use (OID length * size(oid)) as the size. + Shouldn't it be simply OID length ? Since there are numerous instances + of this usage in asn1.cpp, I have not fixed those. If you can double + check and fix these, I appreciate it. + + +Wed Aug 20 15:11:23 1997 Mike MacFaden <mrm@tango.cs.wustl.edu> + + * rebuilt Makefile using g++dep + + * pdu.h pdu.cpp initialization errors fixed + + * address.h address.cpp IpAddress::to_octet() added + +Fri Aug 1 19:23:52 1997 Mike MacFaden (mrm@mrm-ss20) + + * NOTES: This first version only tested on Solaris 2.5 + + * review classes for thread safety. Current thread design only + allows for one thread to safely access any ASNMP object created. + + * run purify test of get routine no -memory leaks. + + * verify both shared archive/static archive types work with + example programs + + * << Globals Changes >> + + * tested only archiver library version + + * reformat code to use one brace style. + + * changed all manifest constants defined as _XX to XX_ to stay out + of compiler namespace + + * change all OS calls to use ACE_OS:: portability layer, #include + <ace/OS.h> + + * reformat code to use one consistent brace layout and redo + header using ACE + + * remove semicolons on member functions foo{}; - not necessary + + * make get() methods const member functions + + * removed unnecessary casts that looked like this: and revamped + all memory allocations via ACE_NEW macro + + new_oid = (SmiLPUINT32) new unsigned long [ smival.value.oid.len + + To + + ACE_NEW(new_oid, SmiUINT32[ smival.value.oid.len]) + + * Collapsed default constructors with constructors to constructors + with default arguments. + + * removed unused #include <iostream.h> + + * Added ACE_TRACE() to classes + + * change get_printable() to to_string() - there will be more java + programmers in the future so this should be the first step... + + * removed ASYNC interface till it can be rebuilt using ACE patterns + + * Attempt to make interface more type strict but leaving generic + interfaces as escape hatch. Example: CTarget becomes UdpTarget + for UDP/IP based agents. + + * << Class Specific Changes >> + + * Oid class: + - remove char * routines, simplify class + - added suboid method and removed get_printable() overloads + + * CTarget class: + - renamed to UdpTarget. Stay out of Microsoft Namespace per MSJ + Article by Allen Hollub. + + * Varbind class: + - remove generic set_value for char,int, etc. Too easy to get + this wrong. Allow just types defined. + - added overload for equality operator (==) + - added new constructor to allow setting full vb state oid,value, exception + - add to_string() + + * Address class: + - change manifest constants to enums for address lengths, add IP V6 lens + + - add a netbios name class, still pretty worthless since I don't have spec + in front of me yet... + + - rewrite resolver calls to be thread safe and cleaner by moving to two + class (static) member functions: + + // thread safe routine to lookup ip address given hostname + // return <> 0 on error + static int resolve_to_addr(const char *hostname, in_addr& quad_addr); + + // thread safe routine to lookup name given ip address + // return <> 0 on error + static int resolve_to_hostname(const in_addr& quad_addr, char *hostname) + + * added some interrogation routines to class IpAddress: + is_loopback() const; + + * Ctr64 class: + - added constructor using long long datatype (needs to be made + portable to NT + + * Pdu class: add to_string() + + * Classes added wpdu class: + - a new adpater class between CMU and HP pdu, varbind data structures + + * transaction class: + - implement get/getnext timeout and retry logic using ACE + Reactor class, ACE_Time_Value + +Local Variables: +mode: change-log +add-log-time-format: (lambda () (progn (setq tz (getenv "TZ")) (set-time-zone-rule "UTC") (setq time (format-time-string "%a %b %e %H:%M:%S %Z %Y" (current-time))) (set-time-zone-rule tz) time)) +indent-tabs-mode: nil +End: diff --git a/ACE/ASNMP/asnmp/Makefile.am b/ACE/ASNMP/asnmp/Makefile.am new file mode 100644 index 00000000000..7b117dab9f6 --- /dev/null +++ b/ACE/ASNMP/asnmp/Makefile.am @@ -0,0 +1,66 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.asnmp_lib.am + +noinst_LTLIBRARIES = libasnmp.la + +libasnmp_la_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP \ + -DASNMP_BUILD_DLL + +libasnmp_la_SOURCES = \ + address.cpp \ + asn1.cpp \ + counter.cpp \ + ctr64.cpp \ + gauge.cpp \ + integer.cpp \ + octet.cpp \ + oid.cpp \ + pdu.cpp \ + sagent.cpp \ + snmp.cpp \ + target.cpp \ + timetick.cpp \ + transaction.cpp \ + vb.cpp \ + wpdu.cpp + +noinst_HEADERS = \ + address.h \ + asn1.h \ + counter.h \ + ctr64.h \ + gauge.h \ + integer.h \ + octet.h \ + oid.h \ + pdu.h \ + sagent.h \ + snmp.h \ + target.h \ + timetick.h \ + transaction.h \ + vb.h \ + wpdu.h + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/ASNMP/asnmp/TODO b/ACE/ASNMP/asnmp/TODO new file mode 100644 index 00000000000..12beb91406b --- /dev/null +++ b/ACE/ASNMP/asnmp/TODO @@ -0,0 +1,25 @@ +This is the todo list aka wish list: feel free to add/implmement +Fri Aug 1 19:40:55 PDT 1997 + +0) collapse CMU and HP code - make this thing faster since it is really + slow and bulky... + +1) implement response time statistics collection so that timeout can vary based + on empirical response times + +2) Implement pdu fragmentation based on tooBig errors or app directed + Snmp::set_pdu_max_size() command + +3) implement async interface + +4) make templatized version to implement sync/nonsync (thread safe version) + +5) add V2c when a real agent is in the field that supports it + +6) Add DISMAN support when IETF approves the Expression Mib + +7) way too many procedural case stmts in the code... + +8) add compare_right() method to be orthogonal to oid class. + + diff --git a/ACE/ASNMP/asnmp/address.cpp b/ACE/ASNMP/asnmp/address.cpp new file mode 100644 index 00000000000..8231868bd89 --- /dev/null +++ b/ACE/ASNMP/asnmp/address.cpp @@ -0,0 +1,2705 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// address.cpp +// +// = DESCRIPTION +// The Vb class is an encapsulation of the snmp variable binding. +// This module contains the class definition for the variable binding (VB) +// class. The VB class is an encapsulation of a SNMP VB. A VB object is +// composed of one SNMP++ Oid and one SMI value. The Vb class utilizes Oid +// objects and thus requires the Oid class. To use this class, +// set oid, value then call valid() to be sure object was constructed correctly. +// +// = AUTHOR +// Peter E Mellquist +// Michael R MacFaden mrm@cisco.com - rework & ACE port +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. + =====================================================================*/ + +#include "asnmp/address.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_arpa_inet.h" +#include "ace/OS_NS_netdb.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_stdio.h" +#include "ace/os_include/os_ctype.h" +#include "ace/OS_Memory.h" + +ACE_RCSID(asnmp, address, "$Id$") + +//================================================================= +//======== Abstract Address Class Implementation ================== +//================================================================= + +// allow destruction of derived classes +Address::~Address() +{ +} + + +//----------------------------------------------------------------- +// is the address object valid? +int Address::valid() const +{ + return valid_flag; +} + +//------------[ Address::trim_white_space( char * ptr) ]------------ +// destructive trim white space +void Address::trim_white_space( char * ptr) +{ + char *tmp; + + tmp = ptr; + // skip leading white space + while (*tmp==' ')tmp++; + ACE_OS::strcpy(ptr,tmp); + + // find end of string + while ((*tmp!=' ') && (*tmp !=0)) tmp++; + if (*tmp!=0) *tmp=0; +} + +//TM: this is not used nor needed, remove? +//-----[ element access ]---------------------------------------------- +unsigned char& Address::operator[]( const int position) +{ + if ( position < MAX_ADDR_SZ) + return address_buffer[ position]; + else + return address_buffer[0]; +} + + +//----------------------------------------------------------------------- +// overloaded equivlence operator, are two addresses equal? +bool operator==( const Address &lhs, const Address &rhs) +{ + if ( ACE_OS::strcmp( (const char*) lhs, (const char*)rhs)==0) + return true; + else + return false; +} + +//----------------------------------------------------------------------- +// overloaded equivlence operator, are two addresses equal? +bool operator!=( const Address &lhs, const Address &rhs) +{ + return (!( lhs == rhs)); +} + + +//------------------------------------------------------------------ +// overloaded > operator, is a1 > a2 +bool operator>( const Address &lhs, const Address &rhs) +{ + if (ACE_OS::strcmp( (const char*) lhs, (const char*)rhs)>0) + return true; + else + return false; +} + +// overloaded >= operator, is a1 > a2 +bool operator>=( const Address &lhs,const Address &rhs) +{ + if (( lhs > rhs) || ( lhs == rhs)) + return true; + else + return false; +} + +// overloaded < operator, is a1 <= a2 +bool operator<=( const Address &lhs,const Address &rhs) +{ + if (( lhs < rhs) || ( lhs == rhs)) + return true; + else + return false; + +} + + +//----------------------------------------------------------------- +// overloaded < operator, is a1 < a2 +bool operator<( const Address &lhs, const Address &rhs) +{ + if (ACE_OS::strcmp( (const char*) lhs, (const char*)rhs)<0) + return true; + else + return false; +} + +//------------------------------------------------------------------ +// equivlence operator overloaded, are an address and a string equal? +bool operator==( const Address &lhs,const char *rhs) +{ + if (!rhs && !lhs.valid()) + return true; + if (ACE_OS::strcmp( (const char *) lhs, rhs)== 0) + return true; + else + return false; +} + +//------------------------------------------------------------------ +// not equal operator overloaded, are an address and a string not equal? +bool operator!=( const Address &lhs,const char *rhs) +{ + return (!( lhs == rhs)); +} + +//------------------------------------------------------------------ +// overloaded > , is a > inaddr +bool operator>( const Address &lhs,const char *rhs) +{ + if (!rhs) + return lhs.valid(); // if lhs valid then > 0, else invalid !> 0 + if (ACE_OS::strcmp( (const char *) lhs, rhs)> 0) + return true; + else + return false; +} + +//------------------------------------------------------------------ +// overloaded >= , is a >= inaddr +bool operator>=( const Address &lhs,const char *rhs) +{ + if (!rhs) + return true; // always >= 0 + if (ACE_OS::strcmp( (const char *) lhs, rhs)>= 0) + return true; + else + return false; +} + +//----------------------------------------------------------------- +// overloaded < , are an address and a string equal? +bool operator<( const Address &lhs,const char *rhs) +{ + if (!rhs) + return false; // always >= 0 + if (ACE_OS::strcmp( (const char *) lhs, rhs)< 0) + return true; + else + return false; +} + +//----------------------------------------------------------------- +// overloaded <= , is a <= inaddr +bool operator<=( const Address &lhs,const char *rhs) +{ + if (!rhs) + return !lhs.valid(); // invalid == 0, else valid > 0 + if (ACE_OS::strcmp( (const char *) lhs, rhs) <= 0) + return true; + else + return false; +} + + +//===================================================================== +//============ IPAddress Implementation =============================== +//===================================================================== + +//-----------[ syntax type ]---------------------------------------------- +SmiUINT32 IpAddress::get_syntax() +{ + return sNMP_SYNTAX_IPADDR; +} + +//-----[ IP Address copy constructor ]--------------------------------- +IpAddress::IpAddress(const IpAddress &ipaddr) + : Address (ipaddr) +{ + // always initialize what type this object is + smival.syntax = sNMP_SYNTAX_IPADDR; + smival.value.string.len =IPV4LEN; + smival.value.string.ptr = address_buffer; + + iv_friendly_name_[0] = 0; + iv_friendly_name_status_ = 0; + valid_flag = ipaddr.valid_flag; + if (valid_flag) { + ACE_OS::memcpy(address_buffer, ipaddr.address_buffer,IPV4LEN); + ACE_OS::strcpy( iv_friendly_name_, ipaddr.iv_friendly_name_); + } + + IpAddress::format_output(); +} + + +//-------[ default construct, an IP address with a string ]--------------------- +IpAddress::IpAddress( const char *inaddr): Address() +{ + // always initialize what type this object is + smival.syntax = sNMP_SYNTAX_IPADDR; + smival.value.string.len = IPV4LEN; + smival.value.string.ptr = address_buffer; + + if (ACE_OS::strlen(inaddr) == 0) { + + valid_flag = 0; + iv_friendly_name_[0] = 0; + iv_friendly_name_status_ = 0; + IpAddress::format_output(); + return; + } + + // parse_address initializes valid, address_buffer & iv_friendly_name_ + valid_flag = parse_address(inaddr); + IpAddress::format_output(); +} + + +//-----[ construct an IP address with a GenAddress ]--------------------- +IpAddress::IpAddress( const GenAddress &genaddr) +{ + // always initialize what type this object is + smival.syntax = sNMP_SYNTAX_IPADDR; + smival.value.string.len = IPV4LEN; + smival.value.string.ptr = address_buffer; + + valid_flag = 0; + iv_friendly_name_[0] = 0; + iv_friendly_name_status_ = 0; + // allow use of an ip or udp genaddress + if (genaddr.get_type() == type_ip) { + valid_flag = genaddr.valid(); + if ( valid_flag) { + // copy in the IP address data + IpAddress temp_ip( (const char *) genaddr); + *this = temp_ip; + } + } + else + if (genaddr.get_type() == type_udp) { + valid_flag = genaddr.valid(); + if ( valid_flag) { + // copy in the IP address data + UdpAddress temp_udp( (const char *) genaddr); + *this = temp_udp; + } + } + IpAddress::format_output(); +} + +//-----[ destructor ]-------------------------------------------------- +IpAddress::~IpAddress() +{ +} + +// assumes member data is word aligned to avoid sigbus +int IpAddress::is_loopback() const +{ + if (valid()) { + return (*(u_long *)&address_buffer == INADDR_LOOPBACK); + } + return 0; +} + +int IpAddress::is_multicast() const +{ + if (valid()) { + return (IN_MULTICAST(*(u_long *)&address_buffer)); + } + return 0; +} + +// Private addressess not are not assignable in the Internet, they are +// defined in RFC 1597 as: 10, 172.16, and 192.168.0 +// Some companies use them internally and apply NAT to allow translation +// instead of paying for ip networks. +// Cisco IOS devices can provide NAT aka Network Address Translation +// but don't expect SNMP based networks to handle cross-NAT address spaces. +// assumes storage in network byte order mrm@cisco.com 7/28/97 + +int IpAddress::is_private() const +{ + if (valid()) { + if (address_buffer[0] == 10) + return 1; + if (address_buffer[0] == 172 && address_buffer[1] == 16) + return 1; + if (address_buffer[0] == 192 && address_buffer[1] == 168 && + address_buffer[2] == 0) + return 1; + } + return 0; +} + + +// convert address into octet string format in network byte order +void IpAddress::to_octet(OctetStr& octet) const +{ + octet.set_data( smival.value.string.ptr, smival.value.string.len); +} + + +int IpAddress::is_broadcast() const +{ + if (valid()) { + return ( (*(u_long *)&address_buffer) & INADDR_BROADCAST); + } + return 0; +} + +//-----[ IP Address general = operator ]------------------------------- +SnmpSyntax& IpAddress::operator=( SnmpSyntax &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + valid_flag = 0; // will get set 1 if really valid + iv_friendly_name_[0]=0; + + if (val.valid()) { + switch (val.get_syntax()) { + case sNMP_SYNTAX_IPADDR: + case sNMP_SYNTAX_OCTETS: + if (((IpAddress &)val).smival.value.string.len ==IPV4LEN) { + ACE_OS::memcpy(address_buffer, + ((IpAddress &)val).smival.value.string.ptr,IPV4LEN); + valid_flag = 1; + } + break; + + // NOTE: as a value add, other types could have "logical" + // mappings, i.e. integer32 and unsigned32 + } + } + IpAddress::format_output(); + return *this; +} + +//------[ assignment to another ipaddress object overloaded ]----------------- +IpAddress& IpAddress::operator=( const IpAddress &ipaddress) +{ + // protect against assignment from itself + if ( this == &ipaddress ) + return *this; + + valid_flag = ipaddress.valid_flag; + iv_friendly_name_[0]=0; + + if (valid_flag) { + ACE_OS::memcpy(address_buffer, ipaddress.address_buffer, IPV4LEN); + ACE_OS::strcpy(iv_friendly_name_, ipaddress.iv_friendly_name_); + } + IpAddress::format_output(); + return *this; +} + + +//--------[ create a new instance of this Value ]----------------------- +SnmpSyntax *IpAddress::clone() const +{ + return (SnmpSyntax *) new IpAddress(*this); +} + +//-------[ return the Fully Qualified Domain Name ]---------------------- +const char *IpAddress::resolve_hostname(int &status) +{ + if ((iv_friendly_name_[0] == 0) && valid_flag) + addr_to_friendly(); + status = iv_friendly_name_status_; + return iv_friendly_name_; +} + +// parse a dotted string +int IpAddress::parse_dotted_ipstring( const char *inaddr) +{ + char *ip_token; + int token_count=0; + unsigned int value; + int error_status = 0; + char temp[MAXHOSTNAMELEN +1]; // temp buffer for destruction + int z,w; + + // check len, an ip can never be bigger than 15 + // 123456789012345 + // XXX.XXX.XXX.XXX + if ( !inaddr || (ACE_OS::strlen( inaddr) > 30)) + return 0; + ACE_OS::strcpy( temp, inaddr); + trim_white_space( temp); + if ( ACE_OS::strlen( temp) > 15) + return 0; + + // must only have three dots + // strtok will not catch this ! + char *ptr = temp; + int dot_count = 0; + while ( *ptr != 0) { + if ( *ptr == '.') dot_count++; + ptr++; + } + if ( dot_count != 3) + return 0; + + // look for dot token separator + ip_token = ACE_OS::strtok( (char *) temp,"."); + + // while more tokens.. + while ( ip_token != 0) { + // verify that the token is all numerics + w = ACE_OS::strlen( ip_token); + if (w>3) + return 0; + for (z=0;z<w;z++) + if (( ip_token[z] < '0') || ( ip_token[z] > '9')) + return 0; + + value = ( unsigned int) strtod(ip_token,0); + if (( value > 0)&& ( value <=255)) + address_buffer[token_count] = (unsigned char) value; + else + if (ACE_OS::strcmp(ip_token,"0")==0) + address_buffer[token_count]= (unsigned char) 0; + else + error_status = 1; + token_count++; + ip_token = ACE_OS::strtok( 0, "."); + } + + // gota be four in len + if ( token_count != 4) + return 0; + + // any parsing errors? + if ( error_status) + return 0; + + return 1; +} + +//-----[ IP Address parse Address ]--------------------------------- +int IpAddress::parse_address( const char *inaddr) +{ + // parse the input char array + // fill up internal buffer with four ip bytes + // set and return validity flag + + in_addr ipAddr; + char ds[MAXHOSTNAMELEN +1]; + + // intialize the friendly_name member variable + iv_friendly_name_[0] = 0; + iv_friendly_name_status_ = 0; + + // is this a dotted IP notation string or + // a friendly name + if ( parse_dotted_ipstring( inaddr)) { + + // since this is a valid dotted string + // don't do any DNS (Performance!) + return 1; + } + else { + int rc; + if ((rc = resolve_to_address(inaddr, ipAddr)) == 0) { + + // now lets check out the dotted string + ACE_OS::strncpy( ds, ACE_OS::inet_ntoa(ipAddr), MAXHOSTNAMELEN); + + if ( !parse_dotted_ipstring( ds)) + return 0; + + // save the friendly name + ACE_OS::strcpy( iv_friendly_name_, inaddr); + + } // end if lookup result + else { + iv_friendly_name_status_ = rc; + return 0; + } + } // end else not a dotted string + return 1; +} + +// using the currently defined address, do a DNS +// and try to fill up the name +int IpAddress::addr_to_friendly() +{ + in_addr ipAddr; + long result = ACE_OS::inet_addr(to_string()); + if (result == -1) + return -1; // expected a dotted quad! + + ipAddr.s_addr = result; + + // set iv_friendly_name_ from ipAddr + if (resolve_to_hostname(ipAddr, iv_friendly_name_) == 0) { + return 0; + } + else { +#if defined (VXWORKS) + // VxWorks doesn't have h_errno + iv_friendly_name_status_ = errno; +#else + iv_friendly_name_status_ = h_errno; +#endif /* VXWORKS */ + return iv_friendly_name_status_; + } +} + +// static aka class member function (1.2.3.4 -> foo.com) +int IpAddress::resolve_to_hostname(const in_addr& quad_addr, char *hostname) +{ + struct hostent lookupResult; + int loc_errno = 0; + ACE_HOSTENT_DATA buffer; + ACE_OS::memset(&lookupResult, 0, sizeof(struct hostent)); + ACE_OS::memset(&buffer, 0, sizeof(ACE_HOSTENT_DATA)); + + // reverse lookup (requires in-addr.arpa to be setup in DNS + if (ACE_OS::gethostbyaddr_r((const char *)&quad_addr.s_addr, IPV4LEN, + AF_INET, &lookupResult, buffer, &loc_errno)) { + + // verify right type of record + if (lookupResult.h_addrtype == AF_INET && + lookupResult.h_length == IPV4LEN) { + ACE_OS::strcpy( hostname, lookupResult.h_name); + // setup multiple entries + return 0; + } + else { + ACE_ASSERT(0); // todo add trace and debug and dump + return -1; // wrong resource record type + } + } + + return loc_errno; +} + +// static aka class member function (foo.com -> 1.2.3.4) +int IpAddress::resolve_to_address(const char *hostname, in_addr& quad_addr) +{ + struct hostent lookupResult; + ACE_HOSTENT_DATA buffer; + ACE_OS::memset(&buffer, 0, sizeof(ACE_HOSTENT_DATA)); + ACE_OS::memset(&lookupResult, 0, sizeof(struct hostent)); + int loc_errno = 0; + if (ACE_OS::gethostbyname_r( hostname, &lookupResult, buffer, &loc_errno)) { + if (lookupResult.h_length == sizeof(in_addr) && + lookupResult.h_addrtype == AF_INET) { + ACE_OS::memcpy((void *) &quad_addr, + (void *) lookupResult.h_addr_list[0], sizeof(in_addr)); + return 0; + } + else + return -1; // wrong address size + } + return loc_errno; +} + +//----[ IP address char * cast ]-------------------------------------- +IpAddress::operator const char *() const +{ + return (char *)output_buffer; +} + +//----[ IP address get char representation ]-------------------------- +const char * IpAddress::to_string() +{ + return (char *)output_buffer; +} + +//----[ IP address format output ]------------------------------------ +void IpAddress::format_output() +{ + // if valid format else null it + if ( valid_flag) + ACE_OS::sprintf( (char *) output_buffer,"%d.%d.%d.%d",address_buffer[0], + address_buffer[1], address_buffer[2], address_buffer[3]); + else + output_buffer[0] = 0; +} + +//------[ return the type ]---------------------------------- +addr_type IpAddress::get_type() const +{ + return type_ip; +} + +//----------------------------------------------------------------- +// logically and two IPaddresses and +// return the new one +void IpAddress::mask( const IpAddress& ipaddr) +{ + if ( this->valid() && ipaddr.valid()) { + this->address_buffer[0] = this->address_buffer[0] & ipaddr.address_buffer[0]; + this->address_buffer[1] = this->address_buffer[1] & ipaddr.address_buffer[1]; + this->address_buffer[2] = this->address_buffer[2] & ipaddr.address_buffer[2]; + this->address_buffer[3] = this->address_buffer[3] & ipaddr.address_buffer[3]; + format_output(); + } + +} + +//======================================================================= +//========== DNS Iterator Implementation ================================ +//======================================================================= + + +Address_Iter::Address_Iter(const char *hostname): valid_(0), count_(0), + entry_(0) +{ + ACE_OS::memset(&buffer_, 0, sizeof(ACE_HOSTENT_DATA)); + ACE_OS::memset(&lookupResult_, 0, sizeof(struct hostent)); + if (ACE_OS::inet_addr(hostname) == (unsigned long) -1) + valid_ = query_dns(hostname); + else { + ACE_ASSERT(0); // don't support dot-quad lookup yet + } + + // count number of hostnames + int n; + char **pc; + for (n = 0, pc = lookupResult_.h_addr_list; *pc != 0; ++n, ++pc); + count_ = n; // plus first one + entry_ = lookupResult_.h_addr_list; +} + +int Address_Iter::valid() const +{ + return (valid_ == 1); +} + +int Address_Iter::how_many_addresses() +{ + return count_; +} + +// return next entry, rc = 0, if entry is null return 0 +int Address_Iter::next(IpAddress& addr) +{ + if (!entry_ || *entry_ == 0) + return 1; + + IpAddress tmp(*entry_++); // return data + addr = tmp; + if (*entry_ == 0) + return 1; + return 0; +} + +// query DNS here +int Address_Iter::query_dns(const char *hostname) +{ + int loc_errno = 0; + if (ACE_OS::gethostbyname_r( hostname, &lookupResult_, buffer_, + &loc_errno)) { + if (lookupResult_.h_length == sizeof(IPV4LEN) && + lookupResult_.h_addrtype == AF_INET) { + return 0; + } + else + return -1; // wrong address size + } + return loc_errno; +} + +//======================================================================= +//========== Udp Address Implementation ================================= +//======================================================================= + +//-----------[ syntax type ]---------------------------------------------- +SmiUINT32 UdpAddress::get_syntax() +{ + return sNMP_SYNTAX_OCTETS; +} + +//-----------------[ construct an Udp address with another Udp address ]--- +UdpAddress::UdpAddress( const UdpAddress &udpaddr):IpAddress(udpaddr) +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = UDPIPV4LEN; + smival.value.string.ptr = address_buffer; + + // Copy the port value + set_port(udpaddr.get_port()); + format_output(); +} + +// default constructor with a dotted string +UdpAddress::UdpAddress( const char *inaddr):IpAddress() +{ + if (ACE_OS::strlen(inaddr) == 0) { + // Inherits IP Address attributes + // Always initialize (override) what type this object is + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = UDPIPV4LEN; + smival.value.string.ptr = address_buffer; + set_port(0); + format_output(); + return; + } + + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = UDPIPV4LEN; + smival.value.string.ptr = address_buffer; + + valid_flag = parse_address( (char *)inaddr); + format_output(); +} + +//-----------------[ construct a UdpAddress from a GenAddress ]-------------- +UdpAddress::UdpAddress( const GenAddress &genaddr):IpAddress() +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = UDPIPV4LEN; + smival.value.string.ptr = address_buffer; + + unsigned int port = 0; + valid_flag = 0; + + // allow use of an ip or udp genaddress + if (genaddr.get_type() == type_udp) + { + valid_flag = genaddr.valid(); + if ( valid_flag) + { + // copy in the IP address data + UdpAddress temp_udp( (const char *) genaddr); + *this = temp_udp; + + // port info since are making an UpAddress + port = temp_udp.get_port(); + } + } + else + if (genaddr.get_type() == type_ip) + { + valid_flag = genaddr.valid(); + if ( valid_flag) + { + // copy in the IP address data + IpAddress temp_ip( (const char *) genaddr); + *this = temp_ip; + } + } + set_port(port); + format_output(); +} + + +//--------[ construct a udp from an IpAddress ]-------------------------- +UdpAddress::UdpAddress( const IpAddress &ipaddr):IpAddress(ipaddr) +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = UDPIPV4LEN; + smival.value.string.ptr = address_buffer; + + set_port(0); + format_output(); +} + + +//-----[ destructor ]-------------------------------------------------- +UdpAddress::~UdpAddress() +{ +} + + + // copy an instance of this Value +SnmpSyntax& UdpAddress::operator=( SnmpSyntax &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + valid_flag=0; // will get set 1 if really valid + if (val.valid()){ + switch (val.get_syntax()){ + case sNMP_SYNTAX_IPADDR: + { + UdpAddress temp_udp(val.to_string()); + *this = temp_udp; // valid_flag is set by the udp assignment + } + break; + + case sNMP_SYNTAX_OCTETS: + if (((UdpAddress &)val).smival.value.string.len == UDPIPV4LEN){ + ACE_OS::memcpy(address_buffer, + ((UdpAddress &)val).smival.value.string.ptr, UDPIPV4LEN); + iv_friendly_name_[0] = 0; + valid_flag = 1; + } + break; + + // NOTE: as a value add, other types could have "logical" + // mappings, i.e. integer32 and unsigned32 + } + } + format_output(); + return *this; +} + + // assignment to another UdpAddress object overloaded +UdpAddress& UdpAddress::operator=( const UdpAddress &udpaddr) +{ + // protect against assignment from itself + if ( this == &udpaddr ) + return *this; + + (IpAddress &)*this = udpaddr; // use ancestor assignment for ipaddr value + set_port(udpaddr.get_port()); // copy to port value + format_output(); + return *this; +} + + +//-----[ IP Address parse Address ]--------------------------------- +int UdpAddress::parse_address( const char *inaddr) +{ + char buffer[MAXHOSTNAMELEN +1]; + + unsigned short port = 0; + if (inaddr && (ACE_OS::strlen( inaddr)< MAXHOSTNAMELEN +1)) + ACE_OS::strcpy( buffer, inaddr); + else { + valid_flag = 0; + return 0; + } + // look for port info @ the end of the string + // port can be delineated by a ':' or a '/' + // if neither are present then just treat it + // like a normal IpAddress + char *tmp; + tmp = ACE_OS::strstr( buffer,":"); + if (tmp==0) + tmp = ACE_OS::strstr(buffer,"/"); + + if ( tmp != 0) { + *tmp=0; // null terminator + tmp++; + port = ACE_OS::atoi( tmp); + } + + set_port(port); + return IpAddress::parse_address( buffer); +} + + +//----------[ create a new instance of this Value ]------------------------ +SnmpSyntax *UdpAddress::clone() const +{ + return (SnmpSyntax *) new UdpAddress(*this); +} + +//--------[ set the port number ]--------------------------------------- +void UdpAddress::set_port( const unsigned short p) +{ + unsigned short port_nbo = htons(p); + ACE_OS::memcpy(&address_buffer[IPV4LEN], &port_nbo, 2); + format_output(); +} + +//---------[ get the port number ]-------------------------------------- +unsigned short UdpAddress::get_port() const +{ + if (valid_flag) { + unsigned short port_nbo; + ACE_OS::memcpy(&port_nbo, &address_buffer[IPV4LEN], 2); + return ntohs(port_nbo); + } + else + return 0; // don't use uninitialized memory +} + +//------[ return the type ]-------------------------------------------- +addr_type UdpAddress::get_type() const +{ + return type_udp; +} + +//----[ UDP address char * cast ]-------------------------------------- +UdpAddress::operator const char *() const +{ + return (char *)output_buffer; +} + +//----[ UDP address get char representation ]-------------------------- +const char * UdpAddress::to_string() +{ + return (char *)output_buffer; +} + +// make format same as ACE_INET_Addr class (addr:port) +void UdpAddress::format_output() +{ + IpAddress::format_output(); // allow ancestors to format their buffers + + // if valid format else null it + if ( valid_flag) + ACE_OS::sprintf( (char *) output_buffer,"%s:%d", + IpAddress::to_string(), + get_port() ); + else + output_buffer[0] = 0; +} + + +//======================================================================= +//=========== Netbios Address Implementation ============================ +//======================================================================= + +void NetbiosAddress::format_output() +{ + if ( valid_flag) + ACE_OS::memcpy(output_buffer, address_buffer, NETBIOSLEN); + else + output_buffer[0] = 0; +} + +void NetbiosAddress::InitNBAddr(const char *inaddr) +{ + if (ACE_OS::strlen(inaddr) == 0) { + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = NETBIOSLEN; + smival.value.string.ptr = address_buffer; + + valid_flag=0; + NetbiosAddress::format_output(); + return; + } + + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = IPXLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = parse_address( (char *) inaddr); + NetbiosAddress::format_output(); +} + +// TODO: how to handle addresses < 15 chars (zero out or pad with ' ') +NetbiosAddress::NetbiosAddress( const char *inaddr) +{ + InitNBAddr(inaddr); + +} + +NetbiosAddress::NetbiosAddress( const char *inaddr, nb_service svc) +{ + InitNBAddr(inaddr); + address_buffer[15] = svc; +} + +// TODO: go back over ms/ibm specs and verify this +// 16 chars, 15 can be any character, 16th is service number between 0 and 20 +// names beginning with IBM are reserved, and hence invalid +// and doubt IBM would use this class anyway +int NetbiosAddress::parse_address(const char *address) +{ + if (ACE_OS::strlen(address) > NETBIOSLEN) + return 0; // invalid + + if (ACE_OS::strncmp(address, "IBM", 3) == 0) + return 0; // invalid + + // addresses are free form but this check may need to be expose to user + // + //if (address[15] < nb_workstation || address[15] > nb_server) + // return 0; //invalid service type + + ACE_OS::memset(address_buffer, 0, NETBIOSLEN); + ACE_OS::memcpy(address_buffer, address, NETBIOSLEN); + + return 1; // valid +} + +NetbiosAddress::NetbiosAddress( const NetbiosAddress& nbaddr) + : Address (nbaddr) +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = NETBIOSLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = nbaddr.valid_flag; + if (valid_flag) + ACE_OS::memcpy(address_buffer, nbaddr.address_buffer, NETBIOSLEN); + NetbiosAddress::format_output(); +} + +NetbiosAddress::NetbiosAddress( const GenAddress& genaddr) +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = NETBIOSLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = 0; + // allow use of an ipx or ipxsock address + if ( (genaddr.get_type() == type_nb) ) { + valid_flag = genaddr.valid(); + if ( valid_flag) { + // copy in the Ipx address data + NetbiosAddress temp_nb( (const char *) genaddr); + *this = temp_nb; + } + } + NetbiosAddress::format_output(); +} + +NetbiosAddress::~NetbiosAddress() +{ +} + +const char *NetbiosAddress::to_string() +{ + return (char *)output_buffer; +} + +void NetbiosAddress::to_octet(OctetStr& octet) const +{ + octet.set_data( smival.value.string.ptr, smival.value.string.len); +} + +NetbiosAddress& NetbiosAddress::operator=( const NetbiosAddress &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + valid_flag = 0; // will set to 1 if really valid + if (val.valid()) { + switch (((NetbiosAddress *) &val)->get_syntax()) { + case sNMP_SYNTAX_OCTETS: + ACE_OS::memcpy(address_buffer, + ((NetbiosAddress &)val).smival.value.string.ptr, NETBIOSLEN); + valid_flag = 1; + break; + } + } + NetbiosAddress::format_output(); + return *this; +} + +nb_service NetbiosAddress::get_service_type() const +{ + return (nb_service) address_buffer[15]; +} + +void NetbiosAddress::set_service_type(nb_service nbservice) +{ + address_buffer[15] = nbservice; + NetbiosAddress::format_output(); +} + +NetbiosAddress::operator const char *() const +{ + return (char *)output_buffer; +} + +SnmpSyntax& NetbiosAddress::operator=( SnmpSyntax &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + valid_flag = 0; // will set to 1 if really valid + if (val.valid()) { + switch (val.get_syntax()) { + case sNMP_SYNTAX_OCTETS: + if (((NetbiosAddress &)val).smival.value.string.len == NETBIOSLEN) { + ACE_OS::memcpy(address_buffer, + ((NetbiosAddress &)val).smival.value.string.ptr, NETBIOSLEN); + valid_flag=1; + } + break; + } + } + NetbiosAddress::format_output(); + return *this; +} + +SnmpSyntax *NetbiosAddress::clone() const +{ + return (SnmpSyntax *) new NetbiosAddress(*this); +} + +SmiUINT32 NetbiosAddress::get_syntax() +{ + return sNMP_SYNTAX_OCTETS; +} + +addr_type NetbiosAddress::get_type() const +{ + return type_nb; +} + +//======================================================================= +//=========== IPX Address Implementation ================================ +//======================================================================= + +//-----------[ syntax type ]---------------------------------------------- +SmiUINT32 IpxAddress::get_syntax() +{ + return sNMP_SYNTAX_OCTETS; +} + + +//----------[ default constructor with a string arg ]--------------------------- +IpxAddress::IpxAddress( const char *inaddr):Address( ) +{ + if (ACE_OS::strlen(inaddr) == 0) { + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = IPXLEN; + smival.value.string.ptr = address_buffer; + + separator = '\0'; + valid_flag=0; + IpxAddress::format_output(); + return; + } + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = IPXLEN; + smival.value.string.ptr = address_buffer; + + separator = '\0'; + valid_flag = parse_address( (char *) inaddr); + IpxAddress::format_output(); +} + + +//-----[ IPX Address copy constructor ]---------------------------------- +IpxAddress::IpxAddress(const IpxAddress &ipxaddr) + : Address (ipxaddr) +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = IPXLEN; + smival.value.string.ptr = address_buffer; + + separator = '\0'; + valid_flag = ipxaddr.valid_flag; + if (valid_flag) + ACE_OS::memcpy(address_buffer, ipxaddr.address_buffer, IPXLEN); + IpxAddress::format_output(); +} + + +//----[ construct an IpxAddress from a GenAddress ]--------------------------- +IpxAddress::IpxAddress( const GenAddress &genaddr) +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = IPXLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = 0; + // allow use of an ipx or ipxsock address + if ( (genaddr.get_type() == type_ipx) ) { + valid_flag = genaddr.valid(); + if ( valid_flag) { + // copy in the Ipx address data + IpxAddress temp_ipx( (const char *) genaddr); + *this = temp_ipx; + } + } + else + if ( (genaddr.get_type() == type_ipxsock) ) { + valid_flag = genaddr.valid(); + if ( valid_flag) { + // copy in the Ipx address data + IpxSockAddress temp_ipxsock( (const char *) genaddr); + *this = temp_ipxsock; + } + } + IpxAddress::format_output(); +} + + +//-----[ destructor ]-------------------------------------------------- +IpxAddress::~IpxAddress() +{ +} + + +//-----[ IPX Address general = operator ]------------------------------- +SnmpSyntax& IpxAddress::operator=( SnmpSyntax &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + valid_flag=0; // will set to 1 if really valid + if (val.valid()){ + switch (val.get_syntax()){ + case sNMP_SYNTAX_OCTETS: + if (((IpxAddress &)val).smival.value.string.len == IPXLEN){ + ACE_OS::memcpy(address_buffer, ((IpxAddress &)val).smival.value.string.ptr, IPXLEN); + valid_flag=1; + } + break; + } + } + IpxAddress::format_output(); + return *this; +} + +//--------[ assignment to another IpAddress object overloaded ]---------- +IpxAddress& IpxAddress::operator=( const IpxAddress &ipxaddress) +{ + // protect against assignment from itself + if ( this == &ipxaddress ) + return *this; + + valid_flag = ipxaddress.valid_flag; + if (valid_flag) + ACE_OS::memcpy(address_buffer, ipxaddress.address_buffer, IPXLEN); + IpxAddress::format_output(); + return *this; +} + + +// create a new instance of this Value +SnmpSyntax *IpxAddress::clone() const +{ + return (SnmpSyntax *) new IpxAddress(*this); +} + +//-----[ IPX Address parse Address ]----------------------------------- +// Convert a string to a ten byte ipx address +// On success sets validity 1 or 0 +// +// IPX address format +// +// NETWORK ID| MAC ADDRESS +// 01 02 03 04|05 06 07 08 09 10 +// XX XX XX XX|XX XX XX XX XX XX +// +// Valid input format +// +// XXXXXXXX.XXXXXXXXXXXX +// Total length must be 21 +// Must have a separator in it +// First string length must be 8 +// Second string length must be 12 +// Each char must take on value 0-F +// +// +// Input formats recognized +// +// XXXXXXXX.XXXXXXXXXXXX +// XXXXXXXX:XXXXXXXXXXXX +// XXXXXXXX-XXXXXXXXXXXX +// XXXXXXXX.XXXXXX-XXXXXX +// XXXXXXXX:XXXXXX-XXXXXX +// XXXXXXXX-XXXXXX-XXXXXX +int IpxAddress::parse_address( const char *inaddr) +{ + char unsigned *str1,*str2; + char temp[30]; // don't destroy original + char unsigned *tmp; + size_t z, tmplen; + + + // save the orginal source + if (!inaddr || (ACE_OS::strlen( inaddr) >(sizeof(temp)-1))) return 0; + ACE_OS::strcpy( temp, inaddr); + trim_white_space( temp); + tmplen = ACE_OS::strlen(temp); + + // bad total length check + // 123456789012345678901 + // XXXXXXXX-XXXXXXXXXXXX 21 len + // + // XXXXXXXX-XXXXXX-XXXXXX 22 len + // need at least 21 chars and no more than 22 + if ( (tmplen <21) || (tmplen >22)) + return 0; + + // convert the string to all lower case + // this allows hex values to be in upper or lower + for (z=0;z< tmplen;z++) + temp[z] = tolower(temp[z]); + + // check for separated nodeid + // if found remove it + if (temp[15] == '-') + { + for(z=16;z<tmplen;z++) + temp[z-1] = temp[z]; + temp[tmplen-1] = 0; + } + + // no dot or colon separator check + separator = temp[8]; + if (( separator != ':') && + ( separator != '.') && + ( separator != '-') && + ( separator != ' ')) + return 0; + + // separate the strings + str1 = ( unsigned char *) temp; + while( *str1 != separator) str1++; + str2 = str1 + 1; + *str1 = 0; + str1= ( unsigned char *) temp; + + // check len of the network portion + if ( ACE_OS::strlen((char *) str1) != 8) + return 0; + + // check len of mac portion + if ( ACE_OS::strlen( (char *) str2) != 12) + return 0; + + // ok we like then lens, make sure that all chars are 0-f + // check out the net id + tmp = str1; + while( *tmp != 0) + if (((*tmp >= '0') && (*tmp <= '9'))|| // good 0-9 + ((*tmp >= 'a') && (*tmp <= 'f'))) // or a-f + tmp++; + else + return 0; + + // check out the MAC address + tmp = str2; + while( *tmp != 0) + if (((*tmp >= '0') && (*tmp <= '9'))|| // good 0-9 + ((*tmp >= 'a') && (*tmp <= 'f'))) // or a-f + tmp++; + else + return 0; + + // convert to target string + tmp = str1; + while ( *tmp != 0) + { + if (( *tmp >= '0') && ( *tmp <= '9')) + *tmp = *tmp - (char unsigned )'0'; + else + *tmp = *tmp - (char unsigned) 'a' + (char unsigned) 10; + tmp++; + } + + // network id portion + address_buffer[0] = (str1[0]*16) + str1[1]; + address_buffer[1] = (str1[2]*16) + str1[3]; + address_buffer[2] = (str1[4]*16) + str1[5]; + address_buffer[3] = (str1[6]*16) + str1[7]; + + tmp = str2; + while ( *tmp != 0) + { + if (( *tmp >= '0') && ( *tmp <= '9')) + *tmp = *tmp - (char unsigned) '0'; + else + *tmp = *tmp - (char unsigned) 'a'+ (char unsigned) 10; + tmp++; + } + + address_buffer[4] = (str2[0]*16) + str2[1]; + address_buffer[5] = (str2[2]*16) + str2[3]; + address_buffer[6] = (str2[4]*16) + str2[5]; + address_buffer[7] = (str2[6]*16) + str2[7]; + address_buffer[8] = (str2[8]*16) + str2[9]; + address_buffer[9] = (str2[10]*16) + str2[11]; + + return 1; +} + +//----[ IPX address char * cast ]-------------------------------------- +IpxAddress::operator const char *() const +{ + return (char *)output_buffer; +} + +//----[ IPX address get char representation ]-------------------------- +const char * IpxAddress::to_string() +{ + return (char *)output_buffer; +} + + +//----[ IPX address format output ]------------------------------------- +void IpxAddress::format_output() +{ + if ( valid_flag) + ACE_OS::sprintf((char *) output_buffer, + "%02x%02x%02x%02x%c%02x%02x%02x%02x%02x%02x", + address_buffer[0],address_buffer[1], + address_buffer[2],address_buffer[3],'-', + address_buffer[4],address_buffer[5], + address_buffer[6],address_buffer[7], + address_buffer[8],address_buffer[9]); + else + output_buffer[0] = 0; +} + + +// get the host id portion of an ipx address +int IpxAddress::get_hostid( MacAddress& mac) +{ + if ( valid_flag) + { + char buffer[18]; + ACE_OS::sprintf( buffer,"%02x:%02x:%02x:%02x:%02x:%02x", + address_buffer[4], + address_buffer[5], address_buffer[6], address_buffer[7], + address_buffer[8], address_buffer[9]); + MacAddress temp( buffer); + // mac = (SnmpSyntax&) temp; + mac = temp; + if ( mac.valid()) + return 1; + else + return 0; + } + else + return 0; +} + + +//------[ return the type ]---------------------------------- +addr_type IpxAddress::get_type() const +{ + return type_ipx; +} + +void IpxAddress::to_octet(OctetStr& octet) const +{ + octet.set_data( smival.value.string.ptr, smival.value.string.len); +} + + +//======================================================================== +//======== IpxSockAddress Implementation ================================= +//======================================================================== + +//-----------[ syntax type ]---------------------------------------------- +SmiUINT32 IpxSockAddress::get_syntax() +{ + return sNMP_SYNTAX_OCTETS; +} + +//-----------[ construct an IpxSockAddress with another IpxSockAddress]---- +IpxSockAddress::IpxSockAddress( const IpxSockAddress &ipxaddr):IpxAddress(ipxaddr) +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = IPXSOCKLEN; + smival.value.string.ptr = address_buffer; + + // copy the socket value + set_socket(ipxaddr.get_socket()); + format_output(); +} + + +//---------------[ default construct a IpxSockAddress ]-------------- +IpxSockAddress::IpxSockAddress( const char *inaddr):IpxAddress() +{ + if (ACE_OS::strlen(inaddr) == 0) { + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = IPXSOCKLEN; + smival.value.string.ptr = address_buffer; + + set_socket(0); + format_output(); + return; + } + + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = IPXSOCKLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = parse_address( (char *) inaddr); + format_output(); +} + + +//---------------[ construct a IpxSockAddress from a GenAddress ]---------- +IpxSockAddress::IpxSockAddress( const GenAddress &genaddr):IpxAddress() +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = IPXSOCKLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = 0; + unsigned short socketid = 0; + // allow use of an ipx or ipxsock address + if ( (genaddr.get_type() == type_ipx) ) + { + valid_flag = genaddr.valid(); + if ( valid_flag) + { + // copy in the Ipx address data + IpxAddress temp_ipx( (const char *) genaddr); + *this = temp_ipx; + } + } + else + if ( (genaddr.get_type() == type_ipxsock) ) + { + valid_flag = genaddr.valid(); + if ( valid_flag) + { + // copy in the Ipx address data + IpxSockAddress temp_ipxsock( (const char *) genaddr); + *this = temp_ipxsock; + // socketid info since are making an IpxSockAddress + socketid = temp_ipxsock.get_socket(); + } + } + set_socket(socketid); + format_output(); +} + + +//------------[ construct an IpxSockAddress from a IpxAddress ]-------------- +IpxSockAddress::IpxSockAddress( const IpxAddress &ipxaddr):IpxAddress(ipxaddr) +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = IPXSOCKLEN; + smival.value.string.ptr = address_buffer; + + set_socket(0); + format_output(); +} + +//-----[ destructor ]-------------------------------------------------- +IpxSockAddress::~IpxSockAddress() +{ +} + +// copy an instance of this Value +SnmpSyntax& IpxSockAddress::operator=( SnmpSyntax &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + valid_flag=0; // will set to 1 if really valid + if (val.valid()){ + switch (val.get_syntax()){ + case sNMP_SYNTAX_OCTETS: + { + // See if it is of the Ipx address family + // This handles IpxSockAddress == IpxAddress + IpxSockAddress temp_ipx(val.to_string()); + if (temp_ipx.valid()){ + *this = temp_ipx; // ipxsock = ipxsock + } + // See if it is an OctetStr of appropriate length + else if (((IpxSockAddress &)val).smival.value.string.len == IPXSOCKLEN){ + ACE_OS::memcpy(address_buffer, + ((IpxSockAddress &)val).smival.value.string.ptr, + IPXSOCKLEN); + valid_flag=1; + } + } + break; + } + } + format_output(); + return *this; +} + +// assignment to another IpAddress object overloaded +IpxSockAddress& IpxSockAddress::operator=( const IpxSockAddress &ipxaddr) +{ + // protect against assignment from itself + if ( this == &ipxaddr ) + return *this; + + (IpxAddress&)*this = ipxaddr; // use ancestor assignment for ipx addr + set_socket(ipxaddr.get_socket()); // copy socket value + format_output(); + return *this; +} + + +//----------[ create a new instance of this Value ]------------------------ +SnmpSyntax *IpxSockAddress::clone() const +{ + return (SnmpSyntax *) new IpxSockAddress(*this); +} + +//----[ IPXSock address char * cast ]-------------------------------------- +IpxSockAddress::operator const char *() const +{ + return (char *)output_buffer; +} + +//----[ IPXSock address get char representation ]-------------------------- +const char * IpxSockAddress::to_string() +{ + return (char *)output_buffer; +} + +//----[ IPX address format output ]------------------------------------- +void IpxSockAddress::format_output() +{ + IpxAddress::format_output(); // allow ancestors to format their buffers + + if ( valid_flag) + ACE_OS::sprintf((char *) output_buffer,"%s/%d", + IpxAddress::to_string(), get_socket()); + else + output_buffer[0] = 0; +} + +//-----[ IP Address parse Address ]--------------------------------- +int IpxSockAddress::parse_address( const char *inaddr) +{ + char buffer[MAXHOSTNAMELEN +1]; + unsigned short socketid=0; + + if (inaddr && (ACE_OS::strlen( inaddr)< MAXHOSTNAMELEN)) + ACE_OS::strcpy( buffer, inaddr); + else + { + valid_flag = 0; + return 0; + } + // look for port info @ the end of the string + // port can be delineated by a ':' or a '/' + // if neither are present then just treat it + // like a normal IpAddress + char *tmp; + tmp = ACE_OS::strstr( buffer,"/"); + + if (tmp != 0) + { + *tmp=0; // null terminator + tmp++; + socketid = ACE_OS::atoi( tmp); + } + set_socket(socketid); + return IpxAddress::parse_address( buffer); +} + + + +//-------------[ set the socket number ]---------------------------------- +void IpxSockAddress::set_socket( const unsigned short s) +{ + unsigned short sock_nbo = htons(s); + ACE_OS::memcpy(&address_buffer[IPXLEN], &sock_nbo, 2); +} + +//--------------[ get the socket number ]--------------------------------- +unsigned short IpxSockAddress::get_socket() const +{ + if (valid_flag) + { + unsigned short sock_nbo; + ACE_OS::memcpy(&sock_nbo, &address_buffer[IPXLEN], 2); + return ntohs(sock_nbo); + } + else + return 0; // don't use uninitialized memory +} + +//------[ return the type ]---------------------------------------------- +addr_type IpxSockAddress::get_type() const +{ + return type_ipxsock; +} + + +//======================================================================== +//======== MACAddress Implementation ===================================== +//======================================================================== + +//-----------[ syntax type ]---------------------------------------------- +SmiUINT32 MacAddress::get_syntax() +{ + return sNMP_SYNTAX_OCTETS; +} + +//-----[ MAC Address copy constructor ]--------------------------------- +MacAddress::MacAddress(const MacAddress &macaddr) + : Address (macaddr) +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = MACLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = macaddr.valid_flag; + if (valid_flag) + ACE_OS::memcpy(address_buffer, macaddr.address_buffer, MACLEN); + format_output(); +} + +//---------[ constructor with a string argument ]------------------------- +MacAddress::MacAddress( const char *inaddr):Address( ) +{ + if (ACE_OS::strlen(inaddr) == 0) { + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = MACLEN; + smival.value.string.ptr = address_buffer; + + valid_flag=0; + format_output(); + return; + } + + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = MACLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = parse_address( (char *) inaddr); + format_output(); +} + +//-----[ construct a MacAddress from a GenAddress ]------------------------ +MacAddress::MacAddress( const GenAddress &genaddr) +{ + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = MACLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = 0; + // allow use of mac address + if (genaddr.get_type() == type_mac) + { + valid_flag = genaddr.valid(); + if ( valid_flag) + { + // copy in the Mac address data + MacAddress temp_mac( (const char *) genaddr); + *this = temp_mac; + } + } + format_output(); +} + +//-----[ destructor ]-------------------------------------------------- +MacAddress::~MacAddress() +{ +} + +//---------[ MacAddress clone ]------------------------------------------- +SnmpSyntax *MacAddress::clone() const +{ + return (SnmpSyntax *) new MacAddress(*this); +} + +//------[ assignment to another ipaddress object overloaded ]-------------- +MacAddress& MacAddress::operator=( const MacAddress &macaddress) +{ + // protect against assignment from itself + if ( this == &macaddress ) + return *this; + + valid_flag = macaddress.valid_flag; + if (valid_flag) + ACE_OS::memcpy(address_buffer, macaddress.address_buffer, MACLEN); + format_output(); + return *this; +} + + + +//-----[ MAC Address general = operator ]--------------------------------- +SnmpSyntax& MacAddress::operator=( SnmpSyntax &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + valid_flag=0; // will set to 1 if really valid + if (val.valid()){ + switch (val.get_syntax()){ + case sNMP_SYNTAX_OCTETS: + if (((MacAddress &)val).smival.value.string.len == MACLEN){ + ACE_OS::memcpy(address_buffer, + ((MacAddress &)val).smival.value.string.ptr, MACLEN); + valid_flag=1; + } + break; + } + } + format_output(); + return *this; +} + +//-----[ MAC Address parse Address ]-------------------------------------- +// Convert a string to a six byte MAC address +// On success sets validity 1 or 0 +// +// MAC address format +// +// MAC ADDRESS +// 01 02 03 04 05 06 +// XX:XX:XX:XX:XX:XX +// Valid input format +// +// XXXXXXXXXXXX +// Total length must be 17 +// Each char must take on value 0-F +// +// +int MacAddress::parse_address( const char *inaddr) +{ + char temp[MAXHOSTNAMELEN +1]; // don't destroy original + char unsigned *tmp; + size_t z; + + + // save the orginal source + if ( !inaddr || (ACE_OS::strlen( inaddr) > 30)) return 0; + ACE_OS::strcpy( temp, inaddr); + trim_white_space( temp); + + // bad total length check + if ( ACE_OS::strlen(temp) != 17) + return 0; + + // check for colons + if ((temp[2] != ':')||(temp[5] != ':')||(temp[8]!=':')||(temp[11]!=':') + ||(temp[14] !=':')) + return 0; + + // strip off the colons + tmp = ( unsigned char *) temp; + int i = 0; + while ( *tmp != 0) + { + if (*tmp != ':') + { + temp[i] = *tmp; + i++; + } + tmp++; + } + temp[i] = 0; + + // convert to lower + for(z=0;z<ACE_OS::strlen(temp);z++) + temp[z] = tolower( temp[z]); + + + // check out the MAC address + tmp = ( unsigned char *) temp; + while( *tmp != 0) + if (((*tmp >= '0') && (*tmp <= '9'))|| // good 0-9 + ((*tmp >= 'a') && (*tmp <= 'f'))) // or a-f + tmp++; + else + return 0; + + // convert to target string + tmp = (unsigned char *) temp; + while ( *tmp != 0) + { + if (( *tmp >= '0') && ( *tmp <= '9')) + *tmp = *tmp - (char unsigned )'0'; + else + *tmp = *tmp - (char unsigned) 'a' + (char unsigned) 10; + tmp++; + } + + address_buffer[0] = (temp[0]*16) + temp[1]; + address_buffer[1] = (temp[2]*16) + temp[3]; + address_buffer[2] = (temp[4]*16) + temp[5]; + address_buffer[3] = (temp[6]*16) + temp[7]; + address_buffer[4] = (temp[8]*16) + temp[9]; + address_buffer[5] = (temp[10]*16) + temp[11]; + + return 1; +} + +//----[ MAC address char * cast ]-------------------------------------- +MacAddress::operator const char *() const +{ + return (char *)output_buffer; +} +//----[ MAC address get char representation ]-------------------------- +const char * MacAddress::to_string() +{ + return (char *)output_buffer; +} + +//----[ MAC address format output ]--------------------------------- +void MacAddress::format_output() +{ + if ( valid_flag) + sprintf(output_buffer,"%02x:%02x:%02x:%02x:%02x:%02x",address_buffer[0], + address_buffer[1],address_buffer[2],address_buffer[3], + address_buffer[4],address_buffer[5]); + else + output_buffer[0] = 0; +} + +//------[ return the type ]---------------------------------- +addr_type MacAddress::get_type() const +{ + return type_mac; +} + + +unsigned int MacAddress::hashFunction() const +{ + return ((((address_buffer[0] << 8) + address_buffer[1]) * HASH0LEN) + + (((address_buffer[2] << 8) + address_buffer[3]) * HASH1LEN) + + (((address_buffer[4] << 8) + address_buffer[5]) * HASH2LEN)); +} + +void MacAddress::to_octet(OctetStr& octet) const +{ + octet.set_data( smival.value.string.ptr, smival.value.string.len); +} + +//======================================================================== +//========== Generic Address Implementation ============================== +//======================================================================== + +//-----------[ get the syntax]---------------------------------------------- +SmiUINT32 GenAddress::get_syntax() +{ + if (address != 0) + return address->get_syntax(); + + return sNMP_SYNTAX_NULL; +} + +void GenAddress::init_smi() +{ + smival.syntax = sNMP_SYNTAX_NULL; // to be overridden + smival.value.string.len = 0; // to be overridden + smival.value.string.ptr = address_buffer; // constant +} + +//-----------[ constructor with a string argument ]---------------------- +GenAddress::GenAddress( const char *addr): address(0) +{ + valid_flag = 0; + // initialize SMI info + // BOK: smival is generally not used for GenAddress, but + // we need this to be a replica of the real address' + // smival info so that <class>::operator=SnmpSyntax + // will work. + init_smi(); + + if (addr && ACE_OS::strlen(addr) == 0) { + format_output(); + return; + } + + parse_address(addr); + + // Copy real address smival info into GenAddr smival + // BOK: smival is generally not used for GenAddress, but + // we need this to be a replica of the real address' + // smival info so that <class>::operator=SnmpSyntax + // will work. + if ( valid_flag ) { + smival.syntax = ((GenAddress *)address)->smival.syntax; + smival.value.string.len = + ((GenAddress *)address)->smival.value.string.len; + ACE_OS::memcpy(smival.value.string.ptr, + ((GenAddress *)address)->smival.value.string.ptr, + (size_t)smival.value.string.len); + } +} + +//-----------[ constructor with an Address argument ]-------------------- +GenAddress::GenAddress( const Address &addr): address(0) +{ + valid_flag = 0; + + // initialize SMI info + // BOK: this is generally not used for GenAddress, + // but we need this to be a replica of the real address' + // smival info so that operator=SnmpSyntax will work. + init_smi(); + // make sure that the object is valid + if (!addr.valid()) { + format_output(); + return; + } + + address = (Address*)addr.clone(); + if (address) + valid_flag = address->valid(); + + // Copy real address smival info into GenAddr smival + // BOK: smival is generally not used for GenAddress, but + // we need this to be a replica of the real address' + // smival info so that <class>::operator=SnmpSyntax + // will work. + if ( valid_flag ) { + smival.syntax = address->get_syntax(); + smival.value.string.len = + ((GenAddress *)address)->smival.value.string.len; + ACE_OS::memcpy(smival.value.string.ptr, + ((GenAddress *)address)->smival.value.string.ptr, + (size_t)smival.value.string.len); + } + + format_output(); +} + +//-----------------[ constructor with another GenAddress object ]------------- +GenAddress::GenAddress( const GenAddress &addr) + : Address (addr), + address(0) +{ + valid_flag = 0; + + // initialize SMI info + // BOK: this is generally not used for GenAddress, + // but we need this to be a replica of the real address' + // smival info so that operator=SnmpSyntax will work. + init_smi(); + + // make sure that the object is valid + if (!addr.valid_flag) { + format_output(); + return; + } + + address = (Address *)addr.address->clone(); + if (address) + valid_flag = address->valid(); + + // Copy real address smival info into GenAddr smival + // BOK: smival is generally not used for GenAddress, but + // we need this to be a replica of the real address' + // smival info so that <class>::operator=SnmpSyntax + // will work. + if ( valid_flag ) { + smival.syntax = ((GenAddress *)address)->smival.syntax; + smival.value.string.len = + ((GenAddress *)address)->smival.value.string.len; + ACE_OS::memcpy(smival.value.string.ptr, + ((GenAddress *)address)->smival.value.string.ptr, + (size_t)smival.value.string.len); + } + + format_output(); +} + +//----------[ destructor ] ------------------------------------------------ +GenAddress::~GenAddress() +{ + if ( address != 0) + delete address; +} + +//----------[ create a new instance of this Value ]------------------------ +SnmpSyntax *GenAddress::clone() const +{ + return (SnmpSyntax *) new GenAddress(*this); +} + +//------[ assignment GenAddress = GenAddress ]----------------------------- +GenAddress& GenAddress::operator=( const GenAddress &addr) +{ + // protect against assignment from itself + if ( this == &addr ) + return *this; + + valid_flag = 0; + if (address) { + delete address; + address = 0; + } + + if (addr.address) + address = (Address *)(addr.address)->clone(); + + if (address) + valid_flag = address->valid(); + + // Copy real address smival info into GenAddr smival + // BOK: smival is generally not used for GenAddress, but + // we need this to be a replica of the real address' + // smival info so that <class>::operator=SnmpSyntax + // will work. + if ( valid_flag ) { + smival.syntax = ((GenAddress *)address)->smival.syntax; + smival.value.string.len = + ((GenAddress *)address)->smival.value.string.len; + ACE_OS::memcpy(smival.value.string.ptr, + ((GenAddress *)address)->smival.value.string.ptr, + (size_t)smival.value.string.len); + } + + format_output(); + return *this; +} + + +//------[ assignment GenAddress = any SnmpSyntax ]----------------------- +SnmpSyntax& GenAddress::operator=( SnmpSyntax &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + valid_flag = 0; // will get set to 1 if really valid + if ( address != 0) { + delete address; + address = 0; + } + + if (val.valid()) { + switch ( val.get_syntax() ) { + //-----[ ip address case ]------------- + // BOK: this case shouldn't be needed since there is an explicit + // GenAddr=Address assignment that will override this assignment. + // Left here for posterity. + case sNMP_SYNTAX_IPADDR: + { + address = (Address *)val.clone(); + if (address) + valid_flag = address->valid(); + } + break; + + //-----[ udp address case ]------------ + //-----[ ipx address case ]------------ + //-----[ mac address case ]------------ + // BOK: This is here only to support GenAddr = primitive OctetStr. + // The explicit GenAddr=Address assignment will handle the cases + // GenAddr = [UdpAdd|IpxAddr|IpxSock|MacAddr|DecNetAddr|NetbiosAddr|AppleTlk]. + // Note, using the heuristic of octet str len to determine type of + // address to create is not accurate when address lengths are equal + // (e.g., UDPIPV4LEN == MACLEN). It gets worse if we add AppleTalk or + // OSI which use variable length addresses! assume AppleTalk as used in IOS Mibs + // is defined in CISCO-TC.my as fixed length of 3 octets + + case sNMP_SYNTAX_OCTETS: + { + unsigned long val_len; + val_len = ((GenAddress &)val).smival.value.string.len; + + if (val_len == UDPIPV4LEN) { + ACE_NEW_RETURN(address, UdpAddress, *this); + } + else if (val_len ==IPV4LEN) { + ACE_NEW_RETURN(address, IpAddress, *this); + } + else if (val_len == IPXLEN) { + ACE_NEW_RETURN(address, IpxAddress, *this); + } + else if (val_len == IPXSOCKLEN) { + ACE_NEW_RETURN(address, IpxSockAddress, *this); + } + else if (val_len == MACLEN) { + ACE_NEW_RETURN(address, MacAddress, *this); + } + else if (val_len == APPLETKLEN) { + ACE_NEW_RETURN(address, AppleTalkAddress, *this); + } + else if (val_len == DECNETLEN) { + ACE_NEW_RETURN(address, DecNetAddress, *this); + } + else if (val_len == NETBIOSLEN) { + ACE_NEW_RETURN(address, DecNetAddress, *this); + } + + if (address) { + *address = val; + valid_flag = address->valid(); + } + } + break; + } // end switch + } + + // Copy real address smival info into GenAddr smival + // BOK: smival is generally not used for GenAddress, but + // we need this to be a replica of the real address' + // smival info so that <class>::operator=SnmpSyntax + // will work. + if ( valid_flag ) { + smival.syntax = ((GenAddress *)address)->smival.syntax; + smival.value.string.len = + ((GenAddress *)address)->smival.value.string.len; + ACE_OS::memcpy(smival.value.string.ptr, + ((GenAddress *)address)->smival.value.string.ptr, + (size_t)smival.value.string.len); + } + + format_output(); + return *this; +} + + +// redefined parse address for macs +// TODO: Add netbios, appletalk, and decnet addresses here +int GenAddress::parse_address( const char *addr) +{ + if ( address != 0) + delete address; + + // try to create each of the addresses until the correct one + // is found + +//BOK: Need to try IPX Sock and IPX before UDP since on Win32, +// gethostbyname() seems to think the ipx network number +// portion is a valid ipaddress string... stupid WinSOCK! + + // ipxsock address + ACE_NEW_RETURN(address, IpxSockAddress( addr), -1); + valid_flag = address->valid(); + if ( valid_flag && ((IpxSockAddress*)address)->get_socket()) { + format_output(); + return 1; // ok its an ipxsock address + } + // otherwise delete it and try another + delete address; + + // ipx address + ACE_NEW_RETURN(address, IpxAddress( addr), -1); + valid_flag = address->valid(); + if ( valid_flag) { + format_output(); + return 1; // ok its an ipx address + } + // otherwise delete it and try another + delete address; + +//TM: Must try the derived classes first...one pitfall of the +//following solution is if someone creates with a port/socket of 0 the +//class will get demoted to ip/ipx. The only proper way to do this is +//to parse the strings ourselves. + + // udp address + ACE_NEW_RETURN(address, UdpAddress( addr), -1); + valid_flag = address->valid(); + if ( valid_flag && ((UdpAddress*)address)->get_port()) { + format_output(); + return 1; // ok its a udp address + } + + // otherwise delete it and try another + delete address; + + // ip address + ACE_NEW_RETURN(address, IpAddress( addr), -1); + valid_flag = address->valid(); + if ( valid_flag) + { + format_output(); + return 1; // ok its an ip address + } + // otherwise delete it and try another + delete address; + + // mac address + ACE_NEW_RETURN(address, MacAddress( addr), -1); + valid_flag = address->valid(); + if ( valid_flag) { + format_output(); + return 1; // ok, its a mac + } + + // guess by length of argument the type of address + switch (ACE_OS::strlen(addr)) { + case NETBIOSLEN: + ACE_NEW_RETURN(address, NetbiosAddress( addr), -1); + valid_flag = address->valid(); + if ( valid_flag) { + format_output(); + return 1; // ok, its a mac + } + break; + + case APPLETKLEN: + ACE_NEW_RETURN(address, AppleTalkAddress( addr), -1); + valid_flag = address->valid(); + if ( valid_flag) { + format_output(); + return 1; // ok, its a mac + } + break; + + case DECNETLEN: + ACE_NEW_RETURN(address, DecNetAddress( addr), -1); + valid_flag = address->valid(); + if ( valid_flag) { + format_output(); + return 1; // ok, its a mac + } + break; + + } + // otherwise its invalid + delete address; + address = 0; + format_output(); + return 0; +} + +GenAddress::operator const char *() const +{ + if ( address != 0) + return (const char *)*address; // pass thru + else + return (char *)output_buffer; +} + +// to_string form of the contained address +const char * GenAddress::to_string() +{ + if ( address != 0) + return address->to_string(); // pass thru + else + return (char *)output_buffer; +} + +// format output +void GenAddress::format_output() +{ + output_buffer[0] = '\0'; +} + +//------[ return the type ]---------------------------------- +addr_type GenAddress::get_type() const +{ + if (!valid()) + return type_invalid; + else + return address->get_type(); +} + +// call the particular type class here +void GenAddress::to_octet(OctetStr& octet) const +{ + if (!valid()) + return; + + address->to_octet(octet); +} + +//------------------------------------------------------------------------ +//---------[ DecNet Address Class ]--------------------------------------- +//------------------------------------------------------------------------ + +DecNetAddress::DecNetAddress( const char *inaddr): Address() +{ + if (ACE_OS::strlen(inaddr) == 0) { + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = DECNETLEN; + smival.value.string.ptr = address_buffer; + + valid_flag=0; + DecNetAddress::format_output(); + return; + } + + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = DECNETLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = parse_address( (char *) inaddr); + DecNetAddress::format_output(); +} + +DecNetAddress::DecNetAddress( const DecNetAddress& addr) + : Address (addr) +{ +} + +DecNetAddress::DecNetAddress( const GenAddress& genaddr) +{ + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = DECNETLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = 0; + // allow use of an ipx or ipxsock address + if ( (genaddr.get_type() == type_decnet) ) { + valid_flag = genaddr.valid(); + if ( valid_flag) { + // copy in the Ipx address data + DecNetAddress temp_ipx( (const char *) genaddr); + *this = temp_ipx; + } + } + DecNetAddress::format_output(); +} + +DecNetAddress::~DecNetAddress() +{ +} + +const char *DecNetAddress::to_string() +{ + return (char *)output_buffer; +} + +DecNetAddress& DecNetAddress::operator=( const DecNetAddress &decaddr) +{ + // protect against assignment from itself + if ( this == &decaddr ) + return *this; + valid_flag = decaddr.valid_flag; + if (valid_flag) + ACE_OS::memcpy(address_buffer, decaddr.address_buffer, DECNETLEN); + format_output(); + return *this; +} + +void DecNetAddress::to_octet(OctetStr& octet) const +{ + octet.set_data( smival.value.string.ptr, smival.value.string.len); +} + +DecNetAddress::operator const char *() const +{ + return (char *)output_buffer; +} + +SmiUINT32 DecNetAddress::get_syntax() +{ + return sNMP_SYNTAX_OCTETS; +} + +SnmpSyntax& DecNetAddress::operator=( SnmpSyntax &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + valid_flag = 0; // will get set 1 if really valid + + if (val.valid()) { + if (((DecNetAddress &)val).smival.value.string.len ==DECNETLEN) { + ACE_OS::memcpy(address_buffer, + ((DecNetAddress &)val).smival.value.string.ptr, DECNETLEN); + valid_flag = 1; + } + } + DecNetAddress::format_output(); + return *this; +} + +SnmpSyntax *DecNetAddress::clone() const +{ + return (SnmpSyntax *) new DecNetAddress(*this); +} + +addr_type DecNetAddress::get_type() const +{ + return type_decnet; +} + +void DecNetAddress::format_output() +{ + // if valid format else null it + if ( valid_flag) + ACE_OS::sprintf( (char *) output_buffer,"%d.%d",address_buffer[0], + address_buffer[1]); + else + output_buffer[0] = 0; +} + +int DecNetAddress::parse_address( const char *address) +{ + if (ACE_OS::strlen(address) > DECNETLEN) + return 0; // invalid + + ACE_OS::memset(address_buffer, 0, DECNETLEN); + ACE_OS::memcpy(address_buffer, address, DECNETLEN); + + return 1; // valid +} + + +//------------------------------------------------------------------------ +//---------[ AppleTalk Address Class ]------------------------------------ +//------------------------------------------------------------------------ + +AppleTalkAddress::AppleTalkAddress( const char *inaddr): Address() +{ + if (ACE_OS::strlen(inaddr) == 0) { + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = APPLETKLEN; + smival.value.string.ptr = address_buffer; + + valid_flag=0; + AppleTalkAddress::format_output(); + return; + } + + // always initialize SMI info + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = APPLETKLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = parse_address( (char *) inaddr); + AppleTalkAddress::format_output(); +} +AppleTalkAddress::AppleTalkAddress( const AppleTalkAddress& addr) + : Address (addr) +{ +} + +AppleTalkAddress::AppleTalkAddress( const GenAddress& genaddr) +{ + smival.syntax = sNMP_SYNTAX_OCTETS; + smival.value.string.len = APPLETKLEN; + smival.value.string.ptr = address_buffer; + + valid_flag = 0; + // allow use of an ipx or ipxsock address + if ( (genaddr.get_type() == type_atk) ) { + valid_flag = genaddr.valid(); + if ( valid_flag) { + // copy in the Ipx address data + AppleTalkAddress temp_ipx( (const char *) genaddr); + *this = temp_ipx; + } + } + AppleTalkAddress::format_output(); +} + +AppleTalkAddress::~AppleTalkAddress() +{ +} + +const char *AppleTalkAddress::to_string() +{ + return (char *)output_buffer; +} + +AppleTalkAddress& AppleTalkAddress::operator=( const AppleTalkAddress &ataddr) +{ + // protect against assignment from itself + if ( this == &ataddr ) + return *this; + valid_flag = ataddr.valid_flag; + if (valid_flag) + ACE_OS::memcpy(address_buffer, ataddr.address_buffer, APPLETKLEN); + format_output(); + return *this; +} + +void AppleTalkAddress::to_octet(OctetStr& octet) const +{ + octet.set_data( smival.value.string.ptr, smival.value.string.len); +} + +AppleTalkAddress::operator const char *() const +{ + return (char *)output_buffer; +} + +SmiUINT32 AppleTalkAddress::get_syntax() +{ + return sNMP_SYNTAX_OCTETS; +} + +SnmpSyntax& AppleTalkAddress::operator=( SnmpSyntax &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + valid_flag = 0; // will get set 1 if really valid + + if (val.valid()) { + if (((AppleTalkAddress &)val).smival.value.string.len ==APPLETKLEN) { + ACE_OS::memcpy(address_buffer, + ((AppleTalkAddress &)val).smival.value.string.ptr,APPLETKLEN); + valid_flag = 1; + } + } + AppleTalkAddress::format_output(); + return *this; +} + +SnmpSyntax *AppleTalkAddress::clone() const +{ + return (SnmpSyntax *) new AppleTalkAddress(*this); +} + +addr_type AppleTalkAddress::get_type() const +{ + return type_atk; +} + +void AppleTalkAddress::format_output() +{ + // if valid format else null it + if ( valid_flag) + ACE_OS::sprintf( (char *) output_buffer,"%d.%d.%d", address_buffer[0], + address_buffer[1], address_buffer[3]); + else + output_buffer[0] = 0; +} + +int AppleTalkAddress::parse_address( const char *address) +{ + if (ACE_OS::strlen(address) > APPLETKLEN) + return 0; // invalid + + ACE_OS::memset(address_buffer, 0, APPLETKLEN); + ACE_OS::memcpy(address_buffer, address, APPLETKLEN); + + return 1; // valid +} + +char AppleTalkAddress::get_host_address() const +{ + return address_buffer[2]; +} + +void AppleTalkAddress::set_host_address(const char host) +{ + address_buffer[2] = host; +} + +short AppleTalkAddress::get_net_address() const +{ + short net; + ACE_OS::memcpy(&net, address_buffer, APPLETKLEN - 1); + return net; +} + +void AppleTalkAddress::set_net_address(const short atknet) +{ + ACE_OS::memcpy(address_buffer, &atknet, APPLETKLEN -1); +} diff --git a/ACE/ASNMP/asnmp/address.h b/ACE/ASNMP/asnmp/address.h new file mode 100644 index 00000000000..f8131c19485 --- /dev/null +++ b/ACE/ASNMP/asnmp/address.h @@ -0,0 +1,845 @@ + + +#ifndef ADDRESS_ +#define ADDRESS_ +//============================================================================= +/** + * @file address.h + * + * $Id$ + * + * Address class definition. Encapsulates various network + * addresses into easy to use, safe and portable classes. + * + * + * @author Peter E Mellquist + */ +//============================================================================= + + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +//----[ includes ]----------------------------------------------------- +// ACE OS Adaption layer +#include "ace/os_include/netinet/os_in.h" +#include "ace/os_include/os_netdb.h" +#include "ace/Log_Msg.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "asnmp/smival.h" +#include "asnmp/octet.h" + +//----[ enumerated types ] -------------------------------- +enum address_lengths { + IPV4LEN=4, + UDPIPV4LEN=6, + IPV6LEN=16, + UDPIPV6LEN=18, + IPXLEN=10, + IPXSOCKLEN=12, + NETBIOSLEN=16, + APPLETKLEN=3, + DECNETLEN=2, + MACLEN=6, + HASH0LEN=19, + HASH1LEN=13, + HASH2LEN=7, + MAX_ADDR_SZ=20, + MAX_DISPLAY_SZ=MAXHOSTNAMELEN+1 +}; + +enum addr_type { + type_ip, + type_ipx, + type_udp, + type_ipxsock, + type_mac, + type_nb, + type_atk, + type_decnet, + type_e164, + type_sip, // IPv6 + type_invalid +}; + +// TODO: get rest of nb service types added here +enum nb_service { + nb_workstation = 0x0, nb_server = 0x20 +}; + +//---[ forward declarations ]----------------------------------------- +class GenAddress; +class UdpAddress; +class IpxSockAddress; +class NetbiosAddress; +class SIPAddress; // aka ipv6 + +// TODO: +// class AtmE164Address; + + +//-------------------------------------------------------------------- +//----[ Address class ]----------------------------------------------- +//-------------------------------------------------------------------- +/** + * @class + * + * @brief Defines the member functions for the abstract base class + * Address. An Address is a unique network endpoint. + */ +class ASNMP_Export Address: public SnmpSyntax +{ + +public: + /// allow destruction of derived classes + virtual ~Address(); + + /// overloaded equivlence operator, are two addresses equal? + friend ASNMP_Export bool operator==( const Address &lhs,const Address &rhs); + + /// overloaded not equivlence operator, are two addresses not equal? + friend ASNMP_Export bool operator!=( const Address &lhs,const Address &rhs); + + /// overloaded > operator, is a1 > a2 + friend ASNMP_Export bool operator>( const Address &lhs,const Address &rhs); + + /// overloaded >= operator, is a1 >= a2 + friend ASNMP_Export bool operator>=( const Address &lhs,const Address &rhs); + + /// overloaded < operator, is a1 < a2 + friend ASNMP_Export bool operator<( const Address &lhs,const Address &rhs); + + /// overloaded <= operator, is a1 <= a2 + friend ASNMP_Export bool operator<=( const Address &lhs,const Address &rhs); + + /// equivlence operator overloaded, are an address and a string equal? + friend ASNMP_Export bool operator==( const Address &lhs,const char *rhs); + + /// overloaded not equivlence operator, are an address and string not equal? + friend ASNMP_Export bool operator!=( const Address &lhs,const char *rhs); + + /// overloaded < , is an address greater than a string? + friend ASNMP_Export bool operator>( const Address &lhs,const char *rhs); + + /// overloaded >=, is an address greater than or equal to a string? + friend ASNMP_Export bool operator>=( const Address &lhs,const char *rhs); + + /// overloaded < , is an address less than a string? + friend ASNMP_Export bool operator<( const Address &lhs,const char *rhs); + + /// overloaded <=, is an address less than or equal to a string? + friend ASNMP_Export bool operator<=( const Address &lhs,const char *rhs); + + /// overloaded const char * cast + virtual operator const char *() const = 0; + + /// verify the is the address object constructed ok + virtual int valid() const; + + /// return a suitable buffer to contain the address + virtual void to_octet(OctetStr& octet) const = 0; + + /// (pure virtual) syntax type + virtual SmiUINT32 get_syntax() = 0; + + /// for non const [], allows reading and writing + unsigned char& operator[]( const int position); + + /// get a printable ASCII value + virtual const char *to_string() = 0; + + /// create a new instance of this Value + virtual SnmpSyntax *clone() const = 0; + + /// return the type of address + virtual addr_type get_type() const = 0; + + /// overloaded assignment operator + virtual SnmpSyntax& operator=( SnmpSyntax &val) = 0; + + /// return a hash key + virtual unsigned int hashFunction() const { return 0;}; + + +protected: + /// state of constructed object (1/0) + /// addr internal representation + int valid_flag; + unsigned char address_buffer[MAX_ADDR_SZ]; + + /// parse the address string + /// redefined for each specific address subclass + virtual int parse_address( const char * inaddr) =0; + + /// format the output + /// redefined for each specific address subclass + virtual void format_output() =0; + + /// a reused trimm white space method + void trim_white_space( char * ptr); +}; + + +//----------------------------------------------------------------------- +//---------[ IPv4 Address Class ]---------------------------------------- +//----------------------------------------------------------------------- +/** + * @class IpAddress + * + * @brief Defines the member functions for the concrete class IpAddress + * An IP Version 4 Address is 4 bytes long and consists of a + * Network, Sub Network, and host component. + */ +class ASNMP_Export IpAddress : public Address +{ +public: + /// default construct an IP address with a string + IpAddress( const char *inaddr = ""); + + /// construct an IP address with another IP address + IpAddress( const IpAddress &ipaddr); + + /// construct an IP address with a GenAddress + IpAddress( const GenAddress &genaddr); + + /// destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden) + ~IpAddress(); + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// assignment to another IpAddress object overloaded + IpAddress& operator=( const IpAddress &ipaddress); + + // TODO: add ability to set addr given long + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// return the DNS Fully Qualified Domain Name (host.domain) + /// on failure returns dotted_quad string + const char *resolve_hostname(int& was_found); + + /// return string representation of object (dotted quad returned) + virtual const char *to_string() ; + + /// const char * operator overloaded for streaming output + virtual operator const char *() const; + + /// logically AND two IPaddresses and + /// return the new one + void mask( const IpAddress& ipaddr); + + /// return the type + virtual addr_type get_type() const; + + /// syntax type + virtual SmiUINT32 get_syntax(); + + /// is this the loopback address? 127.0.0.1/loopback/1.0.0.127.in-addr.arpa + int is_loopback() const; + + /// determine if this is a multicast address + int is_multicast() const; + + /// determine if this a broadcast address + int is_broadcast() const; + + /// per RFC 1597, private addresses are:: 10, 172.16, and 192.168.0 + int is_private() const; + + /// convert address into octet string format in network byte order + virtual void to_octet(OctetStr& octet) const; + +protected: + char output_buffer[MAX_DISPLAY_SZ]; // output buffer + + /// friendly name storage + char iv_friendly_name_[MAX_DISPLAY_SZ]; + + /// did resolver call work? some addrs won't resolve + int iv_friendly_name_status_; + + /// redefined parse address + /// specific to IP addresses + virtual int parse_address( const char *inaddr); + + /// redefined format output + /// specific to IP addresses + virtual void format_output(); + + /// parse a dotted string + int parse_dotted_ipstring( const char *inaddr); + + /// using the currently defined address, do a gethostbyname() + /// and try to fill up the name + int addr_to_friendly(); + + /// thread safe routine to lookup ip address given hostname + /// return <> 0 on error + static int resolve_to_address(const char *hostname, in_addr& quad_addr); + + /// thread safe routine to lookup name given ip address + /// return <> 0 on error + static int resolve_to_hostname(const in_addr& quad_addr, char *hostname); + +}; + +//------------------------------------------------------------------------ +//--------------[ DNS Iterator Class ]------------------------------------ +//------------------------------------------------------------------------ + +/** + * @class Address_Iter + * + * @brief Defines routines to obtain information on a hostname/FQDN + * such as multiple addresses + */ +class ASNMP_Export Address_Iter +{ +public: + Address_Iter(const char *hostname); // fully qualified domain name, hostname + + /// did hostname resolve via DNS? + int valid() const; + + /// how many addresses associated with this hostname + int how_many_addresses(); + + /// return next address + int next(IpAddress& addr); + +private: + Address_Iter(const Address_Iter&); + int valid_; // ctor status + int count_; // number of addresses + char **entry_; // ptr to current address + struct hostent lookupResult_; + ACE_HOSTENT_DATA buffer_; + int query_dns(const char *hostname); +}; + +//------------------------------------------------------------------------ +//---------[ UDP/IPv4 Address Class ]------------------------------------- +//------------------------------------------------------------------------ +/** + * @class + * + * @brief Defines the member functions for the concrete class UdpAddress + * A Udp Address consists of an IP Version 4 Address (IpAddress) + * and a 2 byte unsigned port number. (see /etc/services file) + * User Datagram Protocol (UDP) is a best effort transport + */ +class ASNMP_Export UdpAddress : public IpAddress +{ +public: + /// default constructor with a dotted string in the form of addr:port + UdpAddress( const char *inaddr = ""); + + /// construct an Udp address with another Udp address + UdpAddress( const UdpAddress &udpaddr); + + /// construct a Udp address with a GenAddress + UdpAddress( const GenAddress &genaddr); + + /// construct a Udp address with an IpAddress + /// default port # to zero + UdpAddress( const IpAddress &ipaddr); + + /// destructor + ~UdpAddress(); + + /// syntax type + SmiUINT32 get_syntax(); + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// assignment to another IpAddress object overloaded + UdpAddress& operator=( const UdpAddress &udpaddr); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// output in the form of address:port + virtual const char *to_string() ; + + /// const char * operator overloaded for streaming output + virtual operator const char *() const; + + /// set the port number + void set_port( const unsigned short p); + + /// get the port number + unsigned short get_port() const; + + /// return the type + virtual addr_type get_type() const; + +protected: + /// output buffer + char output_buffer[MAX_DISPLAY_SZ]; + + /// redefined parse address + /// specific to IP addresses + virtual int parse_address( const char *inaddr); + + /// redefined format output + /// specific to IP addresses + virtual void format_output(); +}; + + +//------------------------------------------------------------------------- +//---------[ 802.3 MAC Address Class ]------------------------------------- +//------------------------------------------------------------------------- +/** + * @class + * + * @brief Defines the member functions for the concrete class MacAddress. + * A Media Access Control Address consists of 48 bits as defined + * in IEEE 802.3 specifications. + */ +class ASNMP_Export MacAddress : public Address +{ +public: + /// constructor with a string argument + MacAddress( const char *inaddr = ""); + + /// constructor with another MAC object + MacAddress( const MacAddress &macaddr); + + /// construct a MacAddress with a GenAddress + MacAddress( const GenAddress &genaddr); + + /// destructor + ~MacAddress(); + + /// syntax type + SmiUINT32 get_syntax(); + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// assignment to another IpAddress object overloaded + MacAddress& operator=( const MacAddress &macaddress); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// create a string to internal class storage representing object + virtual const char *to_string(); + + /// const char * operator overloaded for streaming output + virtual operator const char *() const; + + /// return the type + virtual addr_type get_type() const; + + /// return a hash key + unsigned int hashFunction() const; + + /// return byte array of the mac address + virtual void to_octet(OctetStr& octet) const; + +protected: + /// output buffer containing string representation of object + char output_buffer[MAX_DISPLAY_SZ]; + + /// redefined parse address for macs + virtual int parse_address( const char *inaddr); + + /// redefined format output for MACs + virtual void format_output(); +}; + +//------------------------------------------------------------------------ +//---------[ Netbios Address Class ]-------------------------------------- +//------------------------------------------------------------------------ +/** + * @class + * + * @brief Defines the member functions for the concrete class NetbiosAddress. + * The IBM/Microsoft address for NETBIOS, NETBEUI protocol transport. + */ +class ASNMP_Export NetbiosAddress : public Address +{ +public: + + /// default constructor with string arg + NetbiosAddress( const char *inaddr = ""); + + /// set name and service type + NetbiosAddress( const char *inaddr, nb_service svc); + + /// copy constructor + NetbiosAddress( const NetbiosAddress& nbaddr); + + /// construct with a GenAddress + NetbiosAddress( const GenAddress& genaddr); + + ~NetbiosAddress(); + + virtual const char *to_string(); + + NetbiosAddress& operator=( const NetbiosAddress &nbaddr); + + /// retrieve the network service type + nb_service get_service_type() const; + + /// set the service type (workstation, server, etc) + void set_service_type(nb_service nbservice); + + /// const char * operator overloaded for streaming output + virtual operator const char *() const; + + /// syntax type + virtual SmiUINT32 get_syntax(); + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// output byte buffer containing netbios name + virtual void to_octet(OctetStr& octet) const; + +protected: + void InitNBAddr(const char *inaddr); + char output_buffer[MAX_DISPLAY_SZ]; + + /// output buffer to hold string representation + virtual void format_output(); + virtual int parse_address( const char *inaddr); + virtual addr_type get_type() const; +}; + +//------------------------------------------------------------------------ +//---------[ DecNet Address Class ]--------------------------------------- +//------------------------------------------------------------------------ +/** + * @class + * + * @brief Defines the member functions for the concrete class DecNetAddress. + * DecNet Phase ? address consists of two octets (CISCO-TC.my) + */ +class ASNMP_Export DecNetAddress : public Address +{ + public: + /// default constructor with string arg + DecNetAddress( const char *inaddr = ""); + + /// copy constructor + DecNetAddress( const DecNetAddress& decaddr); + + /// construct with a GenAddress + DecNetAddress( const GenAddress& genaddr); + + ~DecNetAddress(); + + virtual const char *to_string(); + + DecNetAddress& operator=( const DecNetAddress &decaddr); + + /// convert address into octet string format 2 bytes of decnet address + virtual void to_octet(OctetStr& octet) const; + + /// const char * operator overloaded for streaming output + virtual operator const char *() const; + + /// syntax type + virtual SmiUINT32 get_syntax(); + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + protected: + virtual int parse_address( const char *inaddr); + virtual addr_type get_type() const; + virtual void format_output(); + char output_buffer[MAX_DISPLAY_SZ]; +}; + +//------------------------------------------------------------------------ +//---------[ AppleTalk Address Class ]------------------------------------ +//------------------------------------------------------------------------ +/** + * @class + * + * @brief Defines the member functions for the concrete class DecNetAddress. + * DecNet Phase ? address consists of two octets (CISCO-TC.my) + */ +class ASNMP_Export AppleTalkAddress : public Address +{ + public: + /// default constructor with string arg + AppleTalkAddress( const char *inaddr = ""); + + /// copy constructor + AppleTalkAddress( const AppleTalkAddress& atkaddr); + + /// construct with a GenAddress + AppleTalkAddress( const GenAddress& genaddr); + + ~AppleTalkAddress(); + + virtual const char *to_string(); + + AppleTalkAddress& operator=( const AppleTalkAddress &atkaddr); + + /// convert address into octet string format 3 bytes of atk address + virtual void to_octet(OctetStr& octet) const; + + /// get the host part of the address + char get_host_address() const; + + /// set the host part of the address + void set_host_address(const char); + + /// get the 2 byte atk network address + short get_net_address() const; + + /// set the host 2 byte atk network address + void set_net_address(const short atknet); + + /// const char * operator overloaded for streaming output + virtual operator const char *() const; + + /// syntax type + virtual SmiUINT32 get_syntax(); + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + private: + virtual int parse_address( const char *inaddr); + virtual addr_type get_type() const; + virtual void format_output(); + char output_buffer[MAX_DISPLAY_SZ]; +}; + +//------------------------------------------------------------------------ +//---------[ IPX Address Class ]------------------------------------------ +//------------------------------------------------------------------------ +/** + * @class IpxAddress + * + * @brief Defines the member functions for the concrete class IpxAddress. + * Novell's IPX (version ?) network protocol endpoint + */ +class ASNMP_Export IpxAddress : public Address +{ +public: + /// default constructor with a string arg + IpxAddress( const char *inaddr = ""); + + /// constructor with another ipx object + IpxAddress( const IpxAddress &ipxaddr); + + /// construct with a GenAddress + IpxAddress( const GenAddress &genaddr); + + /// destructor + ~IpxAddress(); + + /// syntax type + virtual SmiUINT32 get_syntax(); + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// assignment to another IpxAddress object overloaded + IpxAddress& operator=( const IpxAddress &ipxaddress); + + /// get the host id portion of an ipx address + int get_hostid( MacAddress& mac); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// create string represtation of object value + virtual const char *to_string(); + + /// const char * operator overloaded for streaming output + virtual operator const char *() const; + + /// return the type + virtual addr_type get_type() const; + + /// return byte sequence containing ipx address + virtual void to_octet(OctetStr& octet) const; + +protected: + /// ipx format separator {:,/} + char separator; + + /// output buffer to hold string representation + char output_buffer[MAX_DISPLAY_SZ]; + + /// redefined parse address for ipx strings + virtual int parse_address( const char *inaddr); + + /// redefined format output for ipx strings + /// uses same separator as when constructed + virtual void format_output(); +}; + + + +//------------------------------------------------------------------------ +//---------[ IpxSock Address Class ]-------------------------------------- +//------------------------------------------------------------------------ +/** + * @class IpxSockAddress + * + * @brief Defines the member functions for the concrete class IpxAddress. + * Novell's IPX (version ?) network protocol endpoint + */ +class ASNMP_Export IpxSockAddress : public IpxAddress +{ +public: + /// constructor with a dotted string + IpxSockAddress( const char *inaddr = ""); + + /// construct an Udp address with another Udp address + IpxSockAddress( const IpxSockAddress &ipxaddr); + + ///constructor with a GenAddress + IpxSockAddress( const GenAddress &genaddr); + + ///constructor with a IpxAddress + /// default socket # is 0 + IpxSockAddress( const IpxAddress &ipxaddr); + + /// destructor + ~IpxSockAddress(); + + /// syntax type + virtual SmiUINT32 get_syntax(); + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// assignment to another IpxAddress object overloaded + IpxSockAddress& operator=( const IpxSockAddress &ipxaddr); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// set the socket number + void set_socket( const unsigned short s); + + /// get the socket number + unsigned short get_socket() const; + + /// create string representation of object value + virtual const char *to_string(); + + /// const char * operator overloaded for streaming output + virtual operator const char *() const; + + /// return the type + virtual addr_type get_type() const; + +protected: + /// output buffer to hold string representation of object + char output_buffer[MAX_DISPLAY_SZ]; + + /// redefined parse address for ipx strings + virtual int parse_address( const char *inaddr); + + /// redefined format output + /// specific to IP addresses + virtual void format_output(); +}; + +//------------------------------------------------------------------------- +//--------[ Generic Address ]---------------------------------------------- +//------------------------------------------------------------------------- +/** + * @class GenAddress + * + * @brief Defines the member functions for the concrete class GenAddress. + * This class attempts to determine an address type given a char string. + */ +class ASNMP_Export GenAddress : public Address +{ +public: + /// constructor with a string argument + GenAddress( const char *addr = ""); + + /// constructor with an Address + GenAddress( const Address &addr); + + /// constructor with another GenAddress + GenAddress( const GenAddress &addr); + + /// destructor + ~GenAddress(); + + /// get the snmp syntax of the contained address + SmiUINT32 get_syntax(); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// assignment of a GenAddress + GenAddress& operator=( const GenAddress &addr); + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// string representation of object value + virtual const char *to_string(); + + /// const char * operator overloaded for streaming output + virtual operator const char *() const; + + /// return the type + virtual addr_type get_type() const; + + /// return the address as a octet sequence + virtual void to_octet(OctetStr& octet) const; + +protected: + /// pointer to a a concrete address + Address *address; + + /// output buffer of objects value + char output_buffer[MAX_DISPLAY_SZ]; + + /// redefined parse address for macs + virtual int parse_address( const char *addr); + + /// format output for a generic address + virtual void format_output(); + + /// initialize smi data structure + void init_smi(); +}; + +#endif //_ADDRESS diff --git a/ACE/ASNMP/asnmp/asn1.cpp b/ACE/ASNMP/asnmp/asn1.cpp new file mode 100644 index 00000000000..8a3b6f9c088 --- /dev/null +++ b/ACE/ASNMP/asnmp/asn1.cpp @@ -0,0 +1,1729 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// asn1.cpp +// +// = DESCRIPTION +// The Vb class is an encapsulation of the snmp variable binding. +// This module contains the class definition for the variable binding (VB) +// class. The VB class is an encapsulation of a SNMP VB. A VB object is +// composed of one SNMP++ Oid and one SMI value. The Vb class utilizes Oid +// objects and thus requires the Oid class. To use this class, +// set oid, value then call valid() to be sure object was constructed correctly. +// +// = AUTHOR +// S. Waldbusser (assumed) +// Michael R MacFaden mrm@cisco.com - rework & ACE port +// ============================================================================ +/********************************************************************** +// * + * Abstract Syntax Notation One, ASN.1 + * As defined in ISO/IS 8824 and ISO/IS 8825 + * This implements a subset of the above International Standards that + * is sufficient to implement SNMP. + * + * Encodes abstract data types into a machine independent stream of bytes. + * + Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University + + All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the name of CMU not be + used in advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. + ******************************************************************/ + +#include "asnmp/asn1.h" +#include "asnmp/snmp.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID(asnmp, asn1, "$Id$") + +/* + * parse_int - pulls a long out of an ASN int type. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the end of this object. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char * asn1::parse_int( u_char *data, + int *datalength, + u_char *type, + long int *intp, + int intsize) +{ + ACE_TRACE("asn1::parse_int"); + /* + * ASN.1 integer ::= 0x02 asnlength byte {byte}* + */ + u_char *bufp = data; + u_long asn_length; + long value = 0; + + if (intsize != sizeof (long)){ + ASNERROR("not long"); + return 0; + } + *type = *bufp++; + bufp =asn1::parse_length(bufp, &asn_length); + if (bufp == 0){ + ASNERROR("bad length"); + return 0; + } + if ((int)(asn_length + (bufp - data)) > *datalength){ + ASNERROR("overflow of message"); + return 0; + } + if ((int)asn_length > intsize){ + ASNERROR("I don't support such large integers"); + return 0; + } + *datalength -= (int)asn_length + (bufp - data); + if (*bufp & 0x80) + value = -1; /* integer is negative */ + while(asn_length--) + value = (value << 8) | *bufp++; + *intp = value; + return bufp; +} + + +/* + * parse_unsigned_int - pulls an u_long out of an ASN int type. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the end of this object. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char * asn1::parse_unsigned_int( u_char *data, + int *datalength, + u_char *type, + u_long *intp, + int intsize) +{ + ACE_TRACE("asn1::parse_unsigned_int"); + /* + * ASN.1 integer ::= 0x02 asnlength byte {byte}* + */ + u_char *bufp = data; + u_long asn_length; + u_long value = 0; + + if (intsize != sizeof (long)){ + ASNERROR("not long"); + return 0; + } + *type = *bufp++; + bufp = asn1::parse_length(bufp, &asn_length); + if (bufp == 0){ + ASNERROR("bad length"); + return 0; + } + if ((int)(asn_length + (bufp - data)) > *datalength){ + ASNERROR("overflow of message"); + return 0; + } + if (((int)asn_length > (intsize + 1)) || + (((int)asn_length == intsize + 1) && *bufp != 0x00)){ + ASNERROR("I don't support such large integers"); + return 0; + } + *datalength -= (int)asn_length + (bufp - data); + if (*bufp & 0x80) + value = (u_long) -1; + while(asn_length--) + value = (value << 8) | *bufp++; + *intp = value; + return bufp; +} + + +/* + * build_int - builds an ASN object containing an integer. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the end of this object. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char * asn1::build_int( u_char *data, + int *datalength, + u_char type, + long *intp, + int intsize) +{ + ACE_TRACE("asn1::build_int"); + /* + * ASN.1 integer ::= 0x02 asnlength byte {byte}* + */ + + long integer; + u_long mask; + + if (intsize != sizeof (long)) + return 0; + integer = *intp; + /* + * Truncate "unnecessary" bytes off of the most significant end of this + * 2's complement integer. There should be no sequence of 9 + * consecutive 1's or 0's at the most significant end of the + * integer. + */ + mask = u_long (0x1FF) << ((8 * (sizeof(u_long) - 1)) - 1); + /* mask is 0xFF800000 on a big-endian machine */ + while((((integer & mask) == 0) || ((integer & mask) == mask)) + && intsize > 1){ + intsize--; + integer <<= 8; + } + data = asn1::build_header(data, datalength, type, intsize); + if (data == 0) + return 0; + if (*datalength < intsize) + return 0; + *datalength -= intsize; + mask = u_long (0xFF) << (8 * (sizeof(u_long) - 1)); + /* mask is 0xFF000000 on a big-endian machine */ + while(intsize--){ + *data++ = (u_char)((integer & mask) >> (8 * (sizeof(long) - 1))); + integer <<= 8; + } + return data; +} + + +/* + * build_unsigned_int - builds an ASN object containing an integer. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the end of this object. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char * asn1::build_unsigned_int( u_char *data, + int *datalength, + u_char type, + u_long *intp, + int intsize) +{ + ACE_TRACE("asn1::build_unsigned_int"); + /* + * ASN.1 integer ::= 0x02 asnlength byte {byte}* + */ + + u_long integer; + u_long mask; + int add_null_byte = 0; + + if (intsize != sizeof (long)) + return 0; + integer = *intp; + mask = u_long (0xFF) << (8 * (sizeof(u_long) - 1)); + /* mask is 0xFF000000 on a big-endian machine */ + if ((u_char)((integer & mask) >> (8 * (sizeof(long) - 1))) & 0x80){ + /* if MSB is set */ + add_null_byte = 1; + intsize++; + } + /* + * Truncate "unnecessary" bytes off of the most significant end of this 2's complement integer. + * There should be no sequence of 9 consecutive 1's or 0's at the most significant end of the + * integer. + */ + mask = u_long (0x1FF) << ((8 * (sizeof(u_long) - 1)) - 1); + /* mask is 0xFF800000 on a big-endian machine */ + while((((integer & mask) == 0) || ((integer & mask) == mask)) && intsize > 1){ + intsize--; + integer <<= 8; + } + data = asn1::build_header(data, datalength, type, intsize); + if (data == 0) + return 0; + if (*datalength < intsize) + return 0; + *datalength -= intsize; + if (add_null_byte == 1){ + *data++ = '\0'; + intsize--; + } + mask = u_long (0xFF) << (8 * (sizeof(u_long) - 1)); + /* mask is 0xFF000000 on a big-endian machine */ + while(intsize--){ + *data++ = (u_char)((integer & mask) >> (8 * (sizeof(long) - 1))); + integer <<= 8; + } + return data; +} + + +/* + * parse_string - pulls an octet string out of an ASN octet string type. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the beginning of the next object. + * + * "string" is filled with the octet string. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char * asn1::parse_string( u_char *data, + int *datalength, + u_char *type, + u_char *string, + int *strlength) +{ + ACE_TRACE("asn1::parse_string"); + /* + * ASN.1 octet string ::= primstring | cmpdstring + * primstring ::= 0x04 asnlength byte {byte}* + * cmpdstring ::= 0x24 asnlength string {string}* + */ + u_char *bufp = data; + u_long asn_length; + + *type = *bufp++; + bufp = asn1::parse_length(bufp, &asn_length); + if (bufp == 0) + return 0; + if ((int)(asn_length + (bufp - data)) > *datalength){ + ASNERROR("overflow of message"); + return 0; + } + if ((int)asn_length > *strlength){ + ASNERROR("I don't support such long strings"); + return 0; + } + // fixed + ACE_OS::memcpy((char *)string, (char *)bufp, (int)asn_length); + *strlength = (int)asn_length; + *datalength -= (int)asn_length + (bufp - data); + return bufp + asn_length; +} + + +/* + * build_string - Builds an ASN octet string object containing the input string. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the beginning of the next object. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char * asn1::build_string( u_char *data, + int *datalength, + u_char type, + u_char *string, + int strlength) +{ + ACE_TRACE("asn1::build_string"); + /* + * ASN.1 octet string ::= primstring | cmpdstring + * primstring ::= 0x04 asnlength byte {byte}* + * cmpdstring ::= 0x24 asnlength string {string}* + * This code will never send a compound string. + */ + data = asn1::build_header(data, datalength, type, strlength); + if (data == 0) + return 0; + if (*datalength < strlength) + return 0; + // fixed + ACE_OS::memcpy((u_char *)data,(u_char *)string, strlength); + *datalength -= strlength; + return data + strlength; +} + + +/* + * parse_header - interprets the ID and length of the current object. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * in this object following the id and length. + * + * Returns a pointer to the first byte of the contents of this object. + * Returns 0 on any error. + */ +u_char *asn1::parse_header( u_char *data, + int *datalength, + u_char *type) +{ + ACE_TRACE("asn1::parse_header"); + u_char *bufp = data; + register int header_len; + u_long asn_length; + + /* this only works on data types < 30, i.e. no extension octets */ + if (IS_EXTENSION_ID(*bufp)){ + ASNERROR("can't process ID >= 30"); + return 0; + } + *type = *bufp; + bufp = asn1::parse_length(bufp + 1, &asn_length); + if (bufp == 0) + return 0; + header_len = bufp - data; + if ((int)(header_len + asn_length) > *datalength){ + ASNERROR("asn length too long"); + return 0; + } + *datalength = (int)asn_length; + return bufp; +} + +/* + * asn1::build_header - builds an ASN header for an object with the ID and + * length specified. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * in this object following the id and length. + * + * This only works on data types < 30, i.e. no extension octets. + * The maximum length is 0xFFFF; + * + * Returns a pointer to the first byte of the contents of this object. + * Returns 0 on any error. + */ +u_char * asn1::build_header( u_char *data, + int *datalength, + u_char type, + int length) +{ + ACE_TRACE("asn1::build_header"); + if (*datalength < 1) + return 0; + *data++ = type; + (*datalength)--; + return asn1::build_length(data, datalength, length); + +} + +/* + * asn_build_sequence - builds an ASN header for a sequence with the ID and + * length specified. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * in this object following the id and length. + * + * This only works on data types < 30, i.e. no extension octets. + * The maximum length is 0xFFFF; + * + * Returns a pointer to the first byte of the contents of this object. + * Returns 0 on any error. + */ +u_char * asn1::build_sequence( u_char *data, + int *datalength, + u_char type, + int length) +{ + ACE_TRACE("asn1::build_sequence"); + *datalength -= 4; + if (*datalength < 0){ + *datalength += 4; /* fix up before punting */ + return 0; + } + *data++ = type; + *data++ = (u_char)(0x02 | ASN_LONG_LEN); + *data++ = (u_char)((length >> 8) & 0xFF); + *data++ = (u_char)(length & 0xFF); + return data; +} + +/* + * parse_length - interprets the length of the current object. + * On exit, length contains the value of this length field. + * + * Returns a pointer to the first byte after this length + * field (aka: the start of the data field). + * Returns 0 on any error. + */ +u_char * asn1::parse_length( u_char *data, + u_long *length) +{ + ACE_TRACE("asn1::parse_length"); + u_char lengthbyte = *data; + + if (lengthbyte & ASN_LONG_LEN){ + lengthbyte &= ~ASN_LONG_LEN; /* turn MSb off */ + if (lengthbyte == 0){ + ASNERROR("We don't support indefinite lengths"); + return 0; + } + if (lengthbyte > sizeof(long)){ + ASNERROR("we can't support data lengths that long"); + return 0; + } + // fixed + ACE_OS::memcpy((char *)length, (char *)data + 1, (int)lengthbyte); + *length = ntohl(*length); + *length >>= (8 * ((sizeof *length) - lengthbyte)); + return data + lengthbyte + 1; + } else { /* short asnlength */ + *length = (long)lengthbyte; + return data + 1; + } +} + +u_char *asn1::build_length( u_char *data, + int *datalength, + int length) +{ + ACE_TRACE("asn1::build_length"); + u_char *start_data = data; + + /* no indefinite lengths sent */ + if (length < 0x80){ + if (*datalength < 1){ + ASNERROR("build_length"); + return 0; + } + *data++ = (u_char)length; + } else if (length <= 0xFF){ + if (*datalength < 2){ + ASNERROR("build_length"); + return 0; + } + *data++ = (u_char)(0x01 | ASN_LONG_LEN); + *data++ = (u_char)length; + } else { /* 0xFF < length <= 0xFFFF */ + if (*datalength < 3){ + ASNERROR("build_length"); + return 0; + } + *data++ = (u_char)(0x02 | ASN_LONG_LEN); + *data++ = (u_char)((length >> 8) & 0xFF); + *data++ = (u_char)(length & 0xFF); + } + *datalength -= (data - start_data); + return data; + +} + +/* + * parse_objid - pulls an object indentifier out of an ASN object identifier type. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the beginning of the next object. + * + * "objid" is filled with the object identifier. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char *asn1::parse_objid( u_char *data, + int *datalength, + u_char *type, + oid *objid, + int *objidlength) +{ + ACE_TRACE("asn1::parse_objid"); + /* + * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}* + * subidentifier ::= {leadingbyte}* lastbyte + * leadingbyte ::= 1 7bitvalue + * lastbyte ::= 0 7bitvalue + */ + u_char *bufp = data; + oid *oidp = objid + 1; + u_long subidentifier; + long length; + u_long asn_length; + + *type = *bufp++; + bufp = asn1::parse_length(bufp, &asn_length); + if (bufp == 0) + return 0; + if ((int)asn_length + (bufp - data) > *datalength){ + ASNERROR("overflow of message"); + return 0; + } + *datalength -= (int)asn_length + (bufp - data); + + /* Handle invalid object identifier encodings of the form 06 00 robustly */ + if (asn_length == 0) + objid[0] = objid[1] = 0; + + length = asn_length; + (*objidlength)--; /* account for expansion of first byte */ + while (length > 0 && (*objidlength)-- > 0){ + subidentifier = 0; + do { /* shift and add in low order 7 bits */ + subidentifier = (subidentifier << 7) + (*(u_char *)bufp & ~ASN_BIT8); + length--; + } while (*(u_char *)bufp++ & ASN_BIT8); /* last byte has high bit clear */ + if (subidentifier > (u_long)MAX_SUBID){ + ASNERROR("subidentifier too long"); + return 0; + } + *oidp++ = (oid)subidentifier; + } + + /* + * The first two subidentifiers are encoded into the first component + * with the value (X * 40) + Y, where: + * X is the value of the first subidentifier. + * Y is the value of the second subidentifier. + */ + subidentifier = (u_long)objid[1]; + if (subidentifier == 0x2B){ + objid[0] = 1; + objid[1] = 3; + } else { + objid[1] = (u_char)(subidentifier % 40); + objid[0] = (u_char)((subidentifier - objid[1]) / 40); + } + + *objidlength = (int)(oidp - objid); + return bufp; +} + +/* + * build_objid - Builds an ASN object identifier object containing the + * input string. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the beginning of the next object. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char *asn1::build_objid( u_char *data, + int *datalength, + u_char type, + oid *objid, + int objidlength) +{ + ACE_TRACE("asn1::build_objid"); + /* + * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}* + * subidentifier ::= {leadingbyte}* lastbyte + * leadingbyte ::= 1 7bitvalue + * lastbyte ::= 0 7bitvalue + */ + u_char buf[MAX_OID_LEN]; + u_char *bp = buf; + oid *op = objid; + int asnlength; + u_long subid, mask, testmask; + int bits, testbits; + + if (objidlength < 2){ + *bp++ = 0; + objidlength = 0; + } else { + *bp++ = (u_char) (op[1] + (op[0] * 40)); + objidlength -= 2; + op += 2; + } + + while(objidlength-- > 0){ + subid = *op++; + if (subid < 127){ /* off by one? */ + *bp++ = (u_char )subid; + } else { + mask = 0x7F; /* handle subid == 0 case */ + bits = 0; + /* testmask *MUST* !!!! be of an u_type */ + for(testmask = 0x7F, testbits = 0; testmask != 0; + testmask <<= 7, testbits += 7){ + if (subid & testmask){ /* if any bits set */ + mask = testmask; + bits = testbits; + } + } + /* mask can't be zero here */ + for(;mask != 0x7F; mask >>= 7, bits -= 7){ + /* fix a mask that got truncated above */ + if (mask == 0x1E00000) + mask = 0xFE00000; + *bp++ = (u_char)(((subid & mask) >> bits) | ASN_BIT8); + } + *bp++ = (u_char)(subid & mask); + } + } + asnlength = bp - buf; + data = asn1::build_header(data, datalength, type, asnlength); + if (data == 0) + return 0; + if (*datalength < asnlength) + return 0; + // fixed + ACE_OS::memcpy((char *)data, (char *)buf, asnlength); + *datalength -= asnlength; + return data + asnlength; +} + +/* + * parse_null - Interprets an ASN null type. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the beginning of the next object. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char *asn1::parse_null(u_char *data, + int *datalength, + u_char *type) +{ + ACE_TRACE("asn1::parse_null"); + /* + * ASN.1 null ::= 0x05 0x00 + */ + u_char *bufp = data; + u_long asn_length; + + *type = *bufp++; + bufp = asn1::parse_length(bufp, &asn_length); + if (bufp == 0) + return 0; + if (asn_length != 0){ + ASNERROR("Malformed 0"); + return 0; + } + *datalength -= (bufp - data); + return bufp + asn_length; +} + + +/* + * build_null - Builds an ASN null object. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the beginning of the next object. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char *asn1::build_null( u_char *data, + int *datalength, + u_char type) +{ + ACE_TRACE("asn1::build_null"); + /* + * ASN.1 null ::= 0x05 0x00 + */ + return asn1::build_header(data, datalength, type, 0); +} + +/* + * parse_bitstring - pulls a bitstring out of an ASN bitstring type. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the beginning of the next object. + * + * "string" is filled with the bit string. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char *asn1::parse_bitstring( u_char *data, + int *datalength, + u_char *type, + u_char *string, + int *strlength) +{ + ACE_TRACE("asn1::parse_bitstring"); + /* + * bitstring ::= 0x03 asnlength unused {byte}* + */ + u_char *bufp = data; + u_long asn_length; + + *type = *bufp++; + bufp = asn1::parse_length(bufp, &asn_length); + if (bufp == 0) + return 0; + if ((int)(asn_length + (bufp - data)) > *datalength){ + ASNERROR("overflow of message"); + return 0; + } + if ((int) asn_length > *strlength){ + ASNERROR("I don't support such long bitstrings"); + return 0; + } + if (asn_length < 1){ + ASNERROR("Invalid bitstring"); + return 0; + } + if (*bufp > 7){ + ASNERROR("Invalid bitstring"); + return 0; + } + // fixed + ACE_OS::memcpy((char *)string,(char *)bufp, (int)asn_length); + *strlength = (int)asn_length; + *datalength -= (int)asn_length + (bufp - data); + return bufp + asn_length; +} + + +/* + * build_bitstring - Builds an ASN bit string object containing the + * input string. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the beginning of the next object. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char *asn1::build_bitstring( u_char *data, + int *datalength, + u_char type, + u_char *string, + int strlength) +{ + ACE_TRACE("asn1::build_bitstring"); + /* + * ASN.1 bit string ::= 0x03 asnlength unused {byte}* + */ + if (strlength < 1 || *string || *string > 7){ + ASNERROR("Building invalid bitstring"); + return 0; + } + data = asn1::build_header(data, datalength, type, strlength); + if (data == 0) + return 0; + if (*datalength < strlength) + return 0; + // fixed + ACE_OS::memcpy((char *)data,(char *)string, strlength); + *datalength -= strlength; + return data + strlength; +} + + +/* + * parse_unsigned_int64 - pulls a 64 bit u_long out of an ASN int + * type. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the end of this object. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char * asn1::parse_unsigned_int64(u_char *data, + int *datalength, + u_char *type, + struct counter64 *cp, + int countersize) +{ + ACE_TRACE("asn1::parse_unsigned_int64"); + /* + * ASN.1 integer ::= 0x02 asnlength byte {byte}* + */ + u_char *bufp = data; + u_long asn_length; + u_long low = 0, high = 0; + int intsize = 4; + + if (countersize != sizeof(struct counter64)){ + ASNERROR("not right size"); + return 0; + } + *type = *bufp++; + bufp = asn1::parse_length(bufp, &asn_length); + if (bufp == 0){ + ASNERROR("bad length"); + return 0; + } + if ((int)(asn_length + (bufp - data)) > *datalength){ + ASNERROR("overflow of message"); + return 0; + } + if (((int)asn_length > (intsize * 2 + 1)) || + (((int)asn_length == (intsize * 2) + 1) && *bufp != 0x00)){ + ASNERROR("I don't support such large integers"); + return 0; + } + *datalength -= (int)asn_length + (bufp - data); + if (*bufp & 0x80){ + low = (u_long) -1; // integer is negative + high = (u_long) -1; + } + while(asn_length--){ + high = (high << 8) | ((low & 0xFF000000) >> 24); + low = (low << 8) | *bufp++; + } + cp->low = low; + cp->high = high; + return bufp; +} + + +/* + * build_unsigned_int64 - builds an ASN object containing a 64 bit integer. + * On entry, datalength is input as the number of valid bytes following + * "data". On exit, it is returned as the number of valid bytes + * following the end of this object. + * + * Returns a pointer to the first byte past the end + * of this object (i.e. the start of the next object). + * Returns 0 on any error. + */ +u_char * asn1::build_unsigned_int64( u_char *data, + int *datalength, + u_char type, + struct counter64 *cp, + int countersize) +{ + ACE_TRACE("asn1::build_unsigned_int64"); + /* + * ASN.1 integer ::= 0x02 asnlength byte {byte}* + */ + + u_long low, high; + u_long mask, mask2; + int add_null_byte = 0; + int intsize; + + if (countersize != sizeof (struct counter64)) + return 0; + intsize = 8; + low = cp->low; + high = cp->high; + mask = u_long (0xFF) << (8 * (sizeof(u_long) - 1)); + /* mask is 0xFF000000 on a big-endian machine */ + if ((u_char)((high & mask) >> (8 * (sizeof(long) - 1))) & 0x80){ + /* if MSB is set */ + add_null_byte = 1; + intsize++; + } + /* + * Truncate "unnecessary" bytes off of the most significant end of this 2's + * complement integer. + * There should be no sequence of 9 consecutive 1's or 0's at the most + * significant end of the integer. + */ + mask2 = u_long (0x1FF) << ((8 * (sizeof(u_long) - 1)) - 1); + /* mask2 is 0xFF800000 on a big-endian machine */ + while((((high & mask2) == 0) || ((high & mask2) == mask2)) + && intsize > 1){ + intsize--; + high = (high << 8) + | ((low & mask) >> (8 * (sizeof(long) - 1))); + low <<= 8; + } + data = asn1::build_header(data, datalength, type, intsize); + if (data == 0) + return 0; + if (*datalength < intsize) + return 0; + *datalength -= intsize; + if (add_null_byte == 1){ + *data++ = '\0'; + intsize--; + } + while(intsize--){ + *data++ = (u_char)((high & mask) >> (8 * (sizeof(long) - 1))); + high = (high << 8) + | ((low & mask) >> (8 * (sizeof(long) - 1))); + low <<= 8; + + } + return data; +} + + +// create a pdu +struct snmp_pdu * cmu_snmp::pdu_create( int command) +{ + ACE_TRACE("cmu_snmp::snmp_pdu_create"); + struct snmp_pdu *pdu; + + ACE_NEW_RETURN(pdu, snmp_pdu, 0); + ACE_OS::memset((char *)pdu, 0,sizeof(struct snmp_pdu)); + pdu->command = command; + pdu->errstat = 0; + pdu->errindex = 0; + pdu->enterprise = 0; + pdu->enterprise_length = 0; + pdu->variables = 0; + return pdu; +} + +// release a pdu from memory +void cmu_snmp::free_pdu( struct snmp_pdu *pdu) +{ + ACE_TRACE("cmu_snmp::free_pdu"); + struct variable_list *vp, *ovp; + + vp = pdu->variables; + while(vp){ + // release the oid part + if (vp->name) + delete [] vp->name; + // if deep data, then release as well + if (vp->val.string) + delete [] vp->val.string; + ovp = vp; + // go to the next one + vp = vp->next_variable; + // release up vb itself + delete ovp; + } + // if enterprise release it up + if (pdu->enterprise) + delete [] pdu->enterprise; + // release up pdu itself + delete pdu; +} + + +// add a null var to a pdu +void cmu_snmp::add_var(struct snmp_pdu *pdu, + oid *name, + int name_length, + SmiVALUE *smival) +{ + ACE_TRACE("cmu_snmp::add_var"); + + struct variable_list *vars = 0; + + // if we don't have a vb list ,create one + if (pdu->variables == 0) { + ACE_NEW(pdu->variables, variable_list); + vars = pdu->variables; + } + else + { // we have one, find the end + for(vars = pdu->variables; vars->next_variable; vars = vars->next_variable); + // create one + ACE_NEW(vars->next_variable, variable_list); + // bump ptr + vars = vars->next_variable; + } + + // add the oid with no data + vars->next_variable = 0; + + // hook in the Oid portion + ACE_NEW(vars->name, oid[(name_length)]); + + // fixed + ACE_OS::memcpy((char *)vars->name,(char *)name, name_length * sizeof(oid)); + vars->name_length = name_length; + + // hook in the SMI value + switch( smival->syntax) + { + // null , do nothing + case sNMP_SYNTAX_NULL: + case sNMP_SYNTAX_NOSUCHOBJECT: + case sNMP_SYNTAX_NOSUCHINSTANCE: + case sNMP_SYNTAX_ENDOFMIBVIEW: + { + vars->type = (u_char) smival->syntax; + vars->val.string = 0; + vars->val_len = 0; + } + break; + + // octects + case sNMP_SYNTAX_OCTETS: + case sNMP_SYNTAX_OPAQUE: + case sNMP_SYNTAX_IPADDR: + { + vars->type = (u_char) smival->syntax; + ACE_NEW(vars->val.string, + u_char[(unsigned)smival->value.string.len]); + vars->val_len = (int) smival->value.string.len; + ACE_OS::memcpy( (u_char *) vars->val.string, + (u_char *) smival->value.string.ptr, + (unsigned) smival->value.string.len); + } + break; + + // oid + case sNMP_SYNTAX_OID: + { + vars->type = (u_char) smival->syntax; + vars->val_len = (int) smival->value.oid.len * sizeof(oid); + ACE_NEW(vars->val.objid, oid[(unsigned)vars->val_len]); + ACE_OS::memcpy((u_long *)vars->val.objid, + (u_long *)smival->value.oid.ptr, + (unsigned) vars->val_len); + } + break; + + + + case sNMP_SYNTAX_TIMETICKS: + case sNMP_SYNTAX_CNTR32: + case sNMP_SYNTAX_GAUGE32: + case sNMP_SYNTAX_UINT32: + { + long templong; + vars->type = (u_char) smival->syntax; + ACE_NEW(vars->val.integer, long); + vars->val_len = sizeof(long); + templong = (long) smival->value.uNumber; + ACE_OS::memcpy( (long*) vars->val.integer, + (long*) &templong, + sizeof(long)); + } + break; + + case sNMP_SYNTAX_INT32: + { + long templong; + vars->type = (u_char) smival->syntax; + ACE_NEW(vars->val.integer, long); + vars->val_len = sizeof(long); + templong = (long) smival->value.sNumber; + ACE_OS::memcpy( (long*) vars->val.integer, + (long*) &templong, + sizeof(long)); + } + break; + + // 64 bit counter + case sNMP_SYNTAX_CNTR64: + { + vars->type = ( u_char) smival->syntax; + ACE_NEW(vars->val.counter64, counter64); + vars->val_len = sizeof(struct counter64); + ACE_OS::memcpy( (struct counter64*) vars->val.counter64, + (SmiLPCNTR64) &(smival->value.hNumber), + sizeof( SmiCNTR64)); + } + break; + + } // end switch + +} + +// build the authentication +// works for v1 or v2c +u_char *cmu_snmp::auth_build( u_char *data, + int *length, + long int version, + u_char *community, + int community_len, + int messagelen) +{ + ACE_TRACE("cmu_snmp::auth_build"); + u_char *params; + int plen; + + params = community; + plen = community_len; + + data = asn1::build_sequence(data, + length, + (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), + messagelen + plen + 5); + if (data == 0){ + ASNERROR("buildheader"); + return 0; + } + data = asn1::build_int(data, + length, + (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), + (long *)&version, + sizeof(version)); + if (data == 0){ + ASNERROR("buildint"); + return 0; + } + + data = asn1::build_string(data, + length, + (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR), + params, + plen ); + if (data == 0){ + ASNERROR("buildstring"); + return 0; + } + + return (u_char *)data; +} + + +// build a variable binding +u_char * cmu_snmp::build_var_op(u_char *data, oid * var_name, + int *var_name_len, + u_char var_val_type, + int var_val_len, u_char *var_val, + int *listlength) + +{ + ACE_TRACE("cmu_snmp::build_var_op"); + int dummyLen, headerLen; + u_char *dataPtr; + + dummyLen = *listlength; + dataPtr = data; + + data += 4; + dummyLen -=4; + if (dummyLen < 0) + return 0; + + headerLen = data - dataPtr; + *listlength -= headerLen; + data = asn1::build_objid( data, listlength, + (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID), + var_name, *var_name_len); + if (data == 0) { + ASNERROR(""); + return 0; + } + + // based on the type... + switch(var_val_type) { + case ASN_INTEGER: + data = asn1::build_int( data, listlength, var_val_type, (long *)var_val, + var_val_len); + break; + + case SMI_GAUGE: + case SMI_COUNTER: + case SMI_TIMETICKS: + case SMI_UINTEGER: + data = asn1::build_unsigned_int( data, + listlength, + var_val_type, + (u_long *)var_val, + var_val_len); + break; + + case SMI_COUNTER64: + data = asn1::build_unsigned_int64(data, + listlength, + var_val_type, + (struct counter64 *)var_val, + var_val_len); + break; + + case ASN_OCTET_STR: + case SMI_IPADDRESS: + case SMI_OPAQUE: + case SMI_NSAP: + data = asn1::build_string(data, listlength, var_val_type, + var_val, var_val_len); + break; + + case ASN_OBJECT_ID: + data = asn1::build_objid(data, listlength, var_val_type, + (oid *)var_val, var_val_len / sizeof(oid)); + break; + + case ASN_NULL: + data = asn1::build_null(data, listlength, var_val_type); + break; + + case ASN_BIT_STR: + data = asn1::build_bitstring(data, listlength, var_val_type, + var_val, var_val_len); + break; + + case SNMP_NOSUCHOBJECT: + case SNMP_NOSUCHINSTANCE: + case SNMP_ENDOFMIBVIEW: + data = asn1::build_null(data, listlength, var_val_type); + break; + + default: + ASNERROR("wrong type"); + return 0; + } + if (data == 0) { + ASNERROR(""); + return 0; + } + dummyLen = (data - dataPtr) - headerLen; + + asn1::build_sequence(dataPtr, &dummyLen, + (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), + dummyLen); + return data; +} + + +// serialize the pdu +int cmu_snmp::build( struct snmp_pdu *pdu, u_char *packet, + int *out_length, long version, + u_char* community, int community_len) +{ + ACE_TRACE("cmu_snmp::build"); + u_char buf[SNMP_MSG_LENGTH]; + u_char *cp; + struct variable_list *vp; + int length; + int totallength; + + length = *out_length; + cp = packet; + for(vp = pdu->variables; vp; vp = vp->next_variable) { + cp = cmu_snmp::build_var_op( cp, vp->name, + &vp->name_length, vp->type, + vp->val_len, (u_char *)vp->val.string, + &length); + if (cp == 0) + return -1; + } + totallength = cp - packet; + + length = SNMP_MSG_LENGTH; + + // encode the total len + cp = asn1::build_header( buf, &length, + (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), + totallength); + if (cp == 0) + return -1; + ACE_OS::memcpy( (char *)cp, (char *)packet,totallength); + totallength += cp - buf; + + length = *out_length; + if (pdu->command != TRP_REQ_MSG) { + + // request id + cp = asn1::build_int( packet, + &length, + (u_char )(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), + (long *)&pdu->reqid, + sizeof(pdu->reqid)); + if (cp == 0) + return -1; + + // error status + cp = asn1::build_int(cp, + &length, + (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), + (long *)&pdu->errstat, sizeof(pdu->errstat)); + if (cp == 0) + return -1; + + // error index + cp = asn1::build_int(cp, + &length, + (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), + (long *)&pdu->errindex, sizeof(pdu->errindex)); + if (cp == 0) + return -1; + } + else { // this is a trap message + + // enterprise + cp = asn1::build_objid( packet, + &length, + (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID), + (oid *)pdu->enterprise, + pdu->enterprise_length); + if (cp == 0) + return -1; + + // agent-addr + cp = asn1::build_string(cp, + &length, + // HDN Fixed to use correct tag + (u_char)SMI_IPADDRESS, + //(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR), + (u_char *)&pdu->agent_addr.sin_addr.s_addr, + sizeof(pdu->agent_addr.sin_addr.s_addr)); + if (cp == 0) + return -1; + + // generic trap + cp = asn1::build_int(cp, + &length, + (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), + (long *)&pdu->trap_type, + sizeof(pdu->trap_type)); + if (cp == 0) + return -1; + + // specific trap + cp = asn1::build_int( cp, + &length, + (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), + (long *)&pdu->specific_type, + sizeof(pdu->specific_type)); + if (cp == 0) + return -1; + + // timestamp + cp = asn1::build_int(cp, + &length, + // HDN Fixed to use correct tag + (u_char)SMI_TIMETICKS, + //(u_char )(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), + (long *)&pdu->time, + sizeof(pdu->time)); + if (cp == 0) + return -1; + } + + if (length < totallength) + return -1; + // fixed + ACE_OS::memcpy((char *)cp, (char *)buf, totallength); + totallength += cp - packet; + + length = SNMP_MSG_LENGTH; + cp = asn1::build_header(buf, + &length, + (u_char)pdu->command, + totallength); + if (cp == 0) + return -1; + if (length < totallength) + return -1; + // fixed + ACE_OS::memcpy((char *)cp, (char *)packet, totallength); + totallength += cp - buf; + + length = *out_length; + + cp = cmu_snmp::auth_build( packet, + &length, + version, + community, + community_len, + totallength ); + if (cp == 0) + return -1; + if ((*out_length - (cp - packet)) < totallength) + return -1; + // fixed + ACE_OS::memcpy((char *)cp, (char *)buf, totallength); + totallength += cp - packet; + *out_length = totallength; + + return 0; +} + +// parse the authentication header +u_char *cmu_snmp::auth_parse(u_char *data, + int *length, u_char *sid, + int *slen, long *version) +{ + ACE_TRACE("cmu_snmp::auth_parse"); + u_char type; + + // get the type + data = asn1::parse_header( data, length, &type); + if (data == 0){ + ASNERROR("bad header"); + return 0; + } + + if (type != (ASN_SEQUENCE | ASN_CONSTRUCTOR)) { + ASNERROR("wrong auth header type"); + return 0; + } + + // get the version + data = asn1::parse_int(data, length, &type, version, sizeof(*version)); + if (data == 0) { + ASNERROR("bad parse of version"); + return 0; + } + + // get the community name + data = asn1::parse_string(data, length, &type, sid, slen); + if (data == 0) { + ASNERROR("bad parse of community"); + return 0; + } + + return (u_char *)data; +} + +/* u_char *data, // IN - pointer to the start of object + oid *var_name, // OUT - object id of variable + int *var_name_len, // IN/OUT - length of variable name + u_char *var_val_type, // OUT - type of variable + (int or octet string) (one byte) + int *var_val_len, // OUT - length of variable + u_char **var_val, // OUT - pointer to ASN1 encoded value of variable +*/ + +u_char * +cmu_snmp::parse_var_op( u_char *data, oid *var_name, + int *var_name_len, u_char *var_val_type, + int *var_val_len, u_char **var_val, + int *listlength) +{ + ACE_TRACE("cmu_snmp::parse_var_op"); + u_char var_op_type; + int var_op_len = *listlength; + u_char *var_op_start = data; + + data = asn1::parse_header(data, &var_op_len, &var_op_type); + if (data == 0){ + ASNERROR(""); + return 0; + } + if (var_op_type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)) + return 0; + data = asn1::parse_objid(data, &var_op_len, &var_op_type, var_name, var_name_len); + if (data == 0) { + ASNERROR(""); + return 0; + } + if (var_op_type != (u_char) + (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID)) + return 0; + *var_val = data; /* save pointer to this object */ + /* find out what type of object this is */ + data = asn1::parse_header(data, &var_op_len, var_val_type); + if (data == 0) { + ASNERROR(""); + return 0; + } + *var_val_len = var_op_len; + data += var_op_len; + *listlength -= (int)(data - var_op_start); + return data; +} + + + +// build a pdu from a data and length +int cmu_snmp::parse( struct snmp_pdu *pdu, + u_char *data, + u_char *community_name, + u_long &community_len, + snmp_version &spp_version, + int length) +{ + ACE_TRACE("cmu_snmp::parse"); + u_char msg_type; + u_char type; + u_char *var_val; + long version; + int len, four; + u_char community[256]; + int community_length = 256; + struct variable_list *vp = 0; + oid objid[MAX_NAME_LEN], *op; + + // authenticates message and returns length if valid + data = cmu_snmp::auth_parse(data, + &length, + community, + &community_length, + &version); + if (data == 0) + return -1; + + // copy the returned community name + ACE_OS::memcpy( (u_char *) community_name, + (u_char *) community, + community_length); + community_len = (long) community_length; + + if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C ) { + ASNERROR("Wrong version"); + return -1; + } + + spp_version = (snmp_version) version; + + data = asn1::parse_header(data, + &length, + &msg_type); + if (data == 0) + return -1; + pdu->command = msg_type; + + if (pdu->command != TRP_REQ_MSG){ + // get the rid + data = asn1::parse_int(data, + &length, &type, + (long *)&pdu->reqid, + sizeof(pdu->reqid)); + if (data == 0) + return -1; + // get the error status + data = asn1::parse_int(data, + &length, + &type, + (long *)&pdu->errstat, + sizeof(pdu->errstat)); + if (data == 0) + return -1; + // get the error index + data = asn1::parse_int(data, + &length, + &type, + (long *)&pdu->errindex, + sizeof(pdu->errindex)); + if (data == 0) + return -1; + } + else { // is a trap + + // get the enterprise + pdu->enterprise_length = MAX_NAME_LEN; + data = asn1::parse_objid(data, + &length, + &type, + objid, + &pdu->enterprise_length); + if (data == 0) + return -1; + + ACE_NEW_RETURN(pdu->enterprise, + oid[pdu->enterprise_length*sizeof(oid)],-1); + + // fixed + ACE_OS::memcpy((char *)pdu->enterprise,(char *)objid, + pdu->enterprise_length * sizeof(oid)); + + // get source address + four = 4; + data = asn1::parse_string(data, &length, &type, + (u_char *)&pdu->agent_addr.sin_addr.s_addr, + &four); + if (data == 0) + return -1; + + // get trap type + data = asn1::parse_int(data, &length, &type, (long *)&pdu->trap_type, + sizeof(pdu->trap_type)); + if (data == 0) + return -1; + + // trap type + data = asn1::parse_int(data, &length, &type, (long *)&pdu->specific_type, + sizeof(pdu->specific_type)); + if (data == 0) + return -1; + + // timestamp + data = asn1::parse_int(data, &length, &type, (long *)&pdu->time, + sizeof(pdu->time)); + if (data == 0) + return -1; + } + + // get the vb list + data = asn1::parse_header(data, &length, &type); + if (data == 0) + return -1; + + if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)) + return -1; + + while((int)length > 0) { + if (pdu->variables == 0) { + ACE_NEW_RETURN(pdu->variables, variable_list, -1); + vp = pdu->variables; + } else { + ACE_NEW_RETURN(vp->next_variable, variable_list, -1); + vp = vp->next_variable; + } + vp->next_variable = 0; + vp->val.string = 0; + vp->name = 0; + vp->name_length = MAX_NAME_LEN; + data = cmu_snmp::parse_var_op( data, objid, + &vp->name_length, &vp->type, + &vp->val_len, &var_val, + (int *)&length); + if (data == 0) + return -1; + + ACE_NEW_RETURN(op, oid[(unsigned)vp->name_length * sizeof(oid)], -1); + + // fixed + ACE_OS::memcpy((char *)op, (char *)objid, vp->name_length * sizeof(oid)); + vp->name = op; + + len = SNMP_MSG_LENGTH; + switch((short)vp->type) { + case ASN_INTEGER: + case SMI_COUNTER: + case SMI_GAUGE: + case SMI_TIMETICKS: + case SMI_UINTEGER: + ACE_NEW_RETURN(vp->val.integer,long, -1); + vp->val_len = sizeof(long); + asn1::parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer)); + break; + case SMI_COUNTER64: + ACE_NEW_RETURN(vp->val.counter64, counter64, -1); + vp->val_len = sizeof(struct counter64); + asn1::parse_unsigned_int64(var_val, &len, &vp->type, + (struct counter64 *)vp->val.counter64, + sizeof(*vp->val.counter64)); + break; + + case ASN_OCTET_STR: + case SMI_IPADDRESS: + case SMI_OPAQUE: + case SMI_NSAP: + ACE_NEW_RETURN(vp->val.string, u_char[(unsigned)vp->val_len + 1], -1); + asn1::parse_string(var_val, &len, &vp->type, vp->val.string, + &vp->val_len); + break; + + case ASN_OBJECT_ID: + vp->val_len = MAX_NAME_LEN; + asn1::parse_objid(var_val, &len, &vp->type, objid, &vp->val_len); + //vp->val_len *= sizeof(oid); + + ACE_NEW_RETURN(vp->val.objid, oid[(unsigned)vp->val_len*sizeof(oid)], -1); + + // fixed + ACE_OS::memcpy((char *)vp->val.objid, + (char *)objid, + vp->val_len * sizeof(oid)); + break; + + case SNMP_NOSUCHOBJECT: + case SNMP_NOSUCHINSTANCE: + case SNMP_ENDOFMIBVIEW: + case ASN_NULL: + break; + default: + ASNERROR("bad type returned "); + break; + } + } + return 0; +} diff --git a/ACE/ASNMP/asnmp/asn1.h b/ACE/ASNMP/asnmp/asn1.h new file mode 100644 index 00000000000..3be7e3925ef --- /dev/null +++ b/ACE/ASNMP/asnmp/asn1.h @@ -0,0 +1,345 @@ +/* -*-C++-*- */ +#ifndef ASN1 +#define ASN1 +//============================================================================= +/** + * @file asn1.h + * + * $Id$ + * + * Abstract Syntax Notation One, ASN.1 + * As defined in ISO/IS 8824 and ISO/IS 8825 + * This implements a subset of the above International Standards that + * is sufficient to implement SNMP. + * + * + * @author Steve Waldbusser/CMU ? + */ +//============================================================================= + + +/********************************************************************** + Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of CMU not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. +******************************************************************/ + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "asnmp/snmp.h" + +// CMU code to define "oid" typedef (old C style) +#ifndef EIGHTBIT_SUBIDS +typedef unsigned long oid; +#define MAX_SUBID 0xFFFFFFFF +#else +typedef unsigned char oid; +#define MAX_SUBID 0xFF +#endif + +#define MAX_OID_LEN 64 /* max subid's in an oid */ + + +// asn.1 values +#define ASN_BOOLEAN (0x01) +#define ASN_INTEGER (0x02) +#define ASN_BIT_STR (0x03) +#define ASN_OCTET_STR (0x04) +#define ASN_NULL (0x05) +#define ASN_OBJECT_ID (0x06) +#define ASN_SEQUENCE (0x10) +#define ASN_SET (0x11) +#define ASN_UNIVERSAL (0x00) +#define ASN_APPLICATION (0x40) +#define ASN_CONTEXT (0x80) +#define ASN_PRIVATE (0xC0) +#define ASN_PRIMITIVE (0x00) +#define ASN_CONSTRUCTOR (0x20) +#define ASN_LONG_LEN (0x80) +#define ASN_EXTENSION_ID (0x1F) +#define ASN_BIT8 (0x80) + +#define IS_CONSTRUCTOR(byte) ((byte) & ASN_CONSTRUCTOR) +#define IS_EXTENSION_ID(byte) (((byte) & ASN_EXTENSION_ID) == ASN_EXTENSION_ID) + +#define ASNERROR( string) +#define MAX_NAME_LEN 64 +#define SNMP_VERSION_1 0 +#define SNMP_VERSION_2C 1 + + +// defined types (from the SMI, RFC 1065) +#define SMI_IPADDRESS (ASN_APPLICATION | 0) +#define SMI_COUNTER (ASN_APPLICATION | 1) +#define SMI_GAUGE (ASN_APPLICATION | 2) +#define SMI_TIMETICKS (ASN_APPLICATION | 3) +#define SMI_OPAQUE (ASN_APPLICATION | 4) +#define SMI_NSAP (ASN_APPLICATION | 5) +#define SMI_COUNTER64 (ASN_APPLICATION | 6) +#define SMI_UINTEGER (ASN_APPLICATION | 7) + +#define GET_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x0) +#define GETNEXT_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x1) +#define GET_RSP_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x2) +#define SET_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x3) +#define TRP_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x4) + +#define GETBULK_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x5) +#define INFORM_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x6) +#define TRP2_REQ_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x7) +#define REPORT_MSG (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x8) + +#define SNMP_NOSUCHOBJECT (ASN_CONTEXT | ASN_PRIMITIVE | 0x0) +#define SNMP_NOSUCHINSTANCE (ASN_CONTEXT | ASN_PRIMITIVE | 0x1) +#define SNMP_ENDOFMIBVIEW (ASN_CONTEXT | ASN_PRIMITIVE | 0x2) + +#define SNMP_MSG_LENGTH 1500 + +typedef struct sockaddr_in ipaddr; + +// pdu +struct snmp_pdu { + int command; // pdu type + unsigned long reqid; // Request id + unsigned long errstat; // Error status + unsigned long errindex; // Error index + + // Trap information + oid *enterprise; // System OID + int enterprise_length; + ipaddr agent_addr; // address of object generating trap + int trap_type; // trap type + int specific_type; // specific type + unsigned long time; // Uptime + + // vb list + struct variable_list *variables; +}; + +// vb list +struct variable_list { + struct variable_list *next_variable; // 0 for last variable + oid *name; // Object identifier of variable + int name_length; // number of subid's in name + unsigned char type; // ASN type of variable + union { // value of variable + long *integer; + unsigned char *string; + oid *objid; + unsigned char *bitstring; + struct counter64 *counter64; + } val; + int val_len; +}; + +struct counter64 { + unsigned long high; + unsigned long low; +}; + +// CMU Interface class for ASN.1 routines +/** + * @class asn1 + * + * @brief Defines the member functions for the asn1 concrete interface class + * CMU routines for performing ASN.1 data marshalling / representation + */ +class ASNMP_Export asn1 + +{ +public: +static unsigned char *parse_int( unsigned char *data, + int *datalength, + unsigned char *type, + long int *intp, + int intsize); +static unsigned char *parse_unsigned_int( unsigned char *data, + int *datalength, + unsigned char *type, + unsigned long *intp, + int intsize); +static unsigned char *build_int( unsigned char *data, + int *datalength, + unsigned char type, + long *intp, + int intsize); + +static unsigned char *build_unsigned_int( unsigned char *data, + int *datalength, + unsigned char type, + unsigned long *intp, + int intsize); + +static unsigned char *parse_string( unsigned char *data, + int *datalength, + unsigned char *type, + unsigned char *string, + int *strlength); + +static unsigned char *build_string( unsigned char *data, + int *datalength, + unsigned char type, + unsigned char *string, + int strlength); + +static unsigned char *parse_header( unsigned char *data, + int *datalength, + unsigned char *type); + +static unsigned char * build_header( unsigned char *data, + int *datalength, + unsigned char type, + int length); + +static unsigned char * build_sequence( unsigned char *data, + int *datalength, + unsigned char type, + int length); + +static unsigned char * parse_length( unsigned char *data, + unsigned long *length); + +static unsigned char *build_length( unsigned char *data, + int *datalength, + int length); + +static unsigned char *build_objid( unsigned char *data, + int *datalength, + unsigned char type, + oid *objid, + int objidlength); + +static unsigned char *parse_objid( unsigned char *data, + int *datalength, + unsigned char *type, + oid *objid, + int *objidlength); + +static unsigned char *parse_null(unsigned char *data, + int *datalength, unsigned + char *type); + +static unsigned char *build_null( unsigned char *data, + int *datalength, + unsigned char type); + +static unsigned char *parse_bitstring( unsigned char *data, + int *datalength, + unsigned char *type, + unsigned char *string, + int *strlength); + +static unsigned char *build_bitstring( unsigned char *data, + int *datalength, + unsigned char type, + unsigned char *string, + int strlength); + +static unsigned char * parse_unsigned_int64(unsigned char *data, + int *datalength, + unsigned char *type, + struct counter64 *cp, + int countersize); + +static unsigned char * build_unsigned_int64( unsigned char *data, + int *datalength, + unsigned char type, + struct counter64 *cp, + int countersize); + +}; + + +// CMU Interface class for SNMPv1, SNMPv2c routines +/** + * @class cmu_snmp + * + * @brief Defines the static functions for the cmu_snmp concrete class. + * These routine create cmu pdu's that can be sent/received on/from agents + */ +class ASNMP_Export cmu_snmp +{ + public: + static struct snmp_pdu *pdu_create( int command); + static void free_pdu( struct snmp_pdu *pdu); + static int build( struct snmp_pdu *pdu, + unsigned char *packet, + int *out_length, + long version, + unsigned char* community, + int community_len); + + static void add_var(struct snmp_pdu *pdu, + oid *name, + int name_length, + SmiVALUE *smival); + + static int parse( struct snmp_pdu *pdu, + unsigned char *data, + unsigned char *community_name, + unsigned long &community_len, + snmp_version &version, + int length); + static unsigned char *auth_build( unsigned char *data, + int *length, + long int version, + unsigned char *community, + int community_len, + int messagelen); + + static unsigned char *build_var_op(unsigned char *data, + oid * var_name, + int *var_name_len, + unsigned char var_val_type, + int var_val_len, + unsigned char *var_val, + int *listlength); + + +static unsigned char *auth_parse(unsigned char *data, + int *length, + unsigned char *sid, + int *slen, + long *version); + +/* + @params data, IN - pointer to the start of object + var_name OUT - object id of variable + var_name_len IN/OUT - length of variable name + var_val_type OUT - type of variable (int or octet string) (one byte) + var_val_len OUT - length of variable + var_val, OUT - pointer to ASN1 encoded value of variable + listlength IN/OUT - number of valid bytes left in var_op_list +*/ +static unsigned char *parse_var_op( unsigned char *data, + oid *var_name, + int *var_name_len, + unsigned char *var_val_type, + int *var_val_len, + unsigned char **var_val, + int *listlength); + +}; + +#endif // ASN1 + diff --git a/ACE/ASNMP/asnmp/asnmp.mpc b/ACE/ASNMP/asnmp/asnmp.mpc new file mode 100644 index 00000000000..40063285e2b --- /dev/null +++ b/ACE/ASNMP/asnmp/asnmp.mpc @@ -0,0 +1,26 @@ +// $Id$ + +project (asnmp_lib) : acelib { + sharedname = asnmp + dynamicflags = ASNMP_BUILD_DLL + includes += $(ACE_ROOT)/ASNMP + + source_files { + address.cpp + asn1.cpp + counter.cpp + ctr64.cpp + gauge.cpp + integer.cpp + octet.cpp + oid.cpp + pdu.cpp + snmp.cpp + target.cpp + timetick.cpp + transaction.cpp + vb.cpp + wpdu.cpp + sagent.cpp + } +} diff --git a/ACE/ASNMP/asnmp/counter.cpp b/ACE/ASNMP/asnmp/counter.cpp new file mode 100644 index 00000000000..c62b1d0a20a --- /dev/null +++ b/ACE/ASNMP/asnmp/counter.cpp @@ -0,0 +1,107 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// counter.cpp +// +// = DESCRIPTION +// Class implementation for SMI Counter32 class. +// +// = AUTHOR +// Peter E Mellquist +// Michael R MacFaden mrm@cisco.com - rework & ACE port +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/counter.h" + +ACE_RCSID(asnmp, counter, "$Id$") + +// constructor with a value +Counter32::Counter32( const unsigned long i):SnmpUInt32(i) +{ + smival.syntax = sNMP_SYNTAX_CNTR32; +} + +// copy constructor +Counter32::Counter32( const Counter32 &c) + : SnmpUInt32 (c) +{ + this->smival.value.uNumber = c.smival.value.uNumber; + smival.syntax = sNMP_SYNTAX_CNTR32; + valid_flag = 1; +} + +// syntax type +SmiUINT32 Counter32::get_syntax() +{ + return sNMP_SYNTAX_CNTR32; +} + +// general assignment from any Value +SnmpSyntax& Counter32::operator=( SnmpSyntax &in_val){ + if ( this == &in_val ) // handle assignement from itself + return *this; + + valid_flag = 0; // will get set true if really valid + if (in_val.valid()) + { + switch (in_val.get_syntax()) + { + case sNMP_SYNTAX_UINT32: + // case sNMP_SYNTAX_GAUGE32: .. indistinquishable from UINT32 + case sNMP_SYNTAX_CNTR32: + case sNMP_SYNTAX_TIMETICKS: + case sNMP_SYNTAX_INT32: // implied cast int -> uint + this->smival.value.uNumber = + ((Counter32 &)in_val).smival.value.uNumber; + valid_flag = 1; + break; + } + } + return *this; +} + +// overloaded assignment +Counter32& Counter32::operator=( const unsigned long int i) +{ + this->smival.value.uNumber=i; + return *this; +} + +// overloaded assignment +Counter32& Counter32::operator=( const Counter32 &uli) +{ + this->smival.value.uNumber = uli.smival.value.uNumber; + return *this; +} + +// otherwise, behave like an unsigned long int +Counter32::operator unsigned long() +{ + return this->smival.value.uNumber; +} + +// clone +SnmpSyntax * Counter32::clone() const +{ + return ( SnmpSyntax *) new Counter32(*this); +} diff --git a/ACE/ASNMP/asnmp/counter.h b/ACE/ASNMP/asnmp/counter.h new file mode 100644 index 00000000000..36fda2f84ce --- /dev/null +++ b/ACE/ASNMP/asnmp/counter.h @@ -0,0 +1,79 @@ +/* -*-C++-*- */ +#ifndef COUNTER_ +#define COUNTER_ +//============================================================================= +/** + * @file counter.h + * + * $Id$ + * + * Class definition for SMI Counter32 class. + * + * + * @author Peter E Mellquist + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/smival.h" +#include "asnmp/integer.h" + +//------------[ Counter32 Class ]------------------------------------------ +// The counter class allows all the functionality of unsigned +// 32 bit integers but is recognized as a distinct SMI type. Counter32 +// class objects may be set or get into Vb objects. +// +// This class does not behave as defined by the abstract model +// in RFC 1155 section 3.2.3.3 + +/** + * @class Counter32 + * + * @brief Defines the member functions for the Counter32 concrete class + * This class implements RFC 1155 Counter Object and is named + * Counter32 after the RFC1902 redefinition of V1 SMI datatypes + */ +class ASNMP_Export Counter32 : public SnmpUInt32 +{ + public: + /// constructor with a value + Counter32( const unsigned long i = 0); + + /// copy constructor + Counter32( const Counter32 &c); + + /// syntax type + SmiUINT32 get_syntax(); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// overloaded assignment + Counter32& operator=( const Counter32 &uli); + + /// overloaded assignment + Counter32& operator=( const unsigned long i); + + /// otherwise, behave like an unsigned long int + operator unsigned long(); +}; + +#endif // COUNTER_ diff --git a/ACE/ASNMP/asnmp/ctr64.cpp b/ACE/ASNMP/asnmp/ctr64.cpp new file mode 100644 index 00000000000..df3468a1475 --- /dev/null +++ b/ACE/ASNMP/asnmp/ctr64.cpp @@ -0,0 +1,213 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// ctr64.cpp +// +// = DESCRIPTION +// Implementation for Counter64 ( 64 bit counter class). +// +// = AUTHOR +// Peter E Mellquist +// Michael R MacFaden mrm@cisco.com - rework & ACE port +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/ctr64.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID(asnmp, ctr64, "$Id$") + +#define MAX32 4294967295u + +//-----------[ syntax type ]---------------------------------------------- +SmiUINT32 Counter64::get_syntax() +{ + return sNMP_SYNTAX_CNTR64; +} + +//------------------[ constructor with values ]-------------------------- +Counter64::Counter64( unsigned long hiparm, unsigned long loparm) +{ + smival.syntax = sNMP_SYNTAX_CNTR64; + smival.value.hNumber.hipart = hiparm; + smival.value.hNumber.lopart = loparm; +} + +//------------------[ constructor with low value only ]------------------ +Counter64::Counter64( ACE_UINT64 llw ) +{ + smival.syntax = sNMP_SYNTAX_CNTR64; + smival.value.hNumber.hipart = (unsigned long) (llw >> 32); + smival.value.hNumber.lopart = (unsigned long) llw & 0xffffffff; +} + +//------------------[ copy constructor ]--------------------------------- +Counter64::Counter64( const Counter64 &ctr64 ) + : SnmpSyntax (ctr64) +{ + smival.syntax = sNMP_SYNTAX_CNTR64; + smival.value.hNumber.hipart = ctr64.high(); + smival.value.hNumber.lopart = ctr64.low(); +} + +//------------------[ destructor ]--------------------------------- +Counter64::~Counter64() +{ +} + + +//------------------[ Counter64::high() ]------------------------------ +// return the high part +unsigned long Counter64::high() const +{ + return smival.value.hNumber.hipart; +} + + +//------------------[ Counter64::low() ]------------------------------- +// return the low part +unsigned long Counter64::low() const +{ + return smival.value.hNumber.lopart; +} + +//------------------[ set_high( const unsigned long h) ]----------- +// set the high part +void Counter64::set_high( const unsigned long h) +{ + smival.value.hNumber.hipart = h; +} + +//------------------[ set_low( const unsigned long l) ]------------ +// set the low part +void Counter64::set_low( const unsigned long l) +{ + smival.value.hNumber.lopart = l; +} + + +//-----------[ to_long_double( Counter64 c64) ]----------------------------- +// convert a Counter 64 to a long double +long double Counter64::to_long_double() const +{ + long double ld = this->high(); + ld *= MAX32; + ld += this->low(); + return ld; +} + + +//-----------[ ld_to_c64( long double ld) ]---------------------------- +// convert a long double to a Counter64 +// semantics changed from prior version +Counter64& Counter64::assign( long double ld) +{ + smival.syntax = sNMP_SYNTAX_CNTR64; + unsigned long h = smival.value.hNumber.hipart = (unsigned long)(ld / MAX32); + smival.value.hNumber.lopart = (unsigned long)(ld - h); + return *this; +} + +//----------------[ general Value = operator ]--------------------- +SnmpSyntax& Counter64::operator=( SnmpSyntax &val) +{ + // protect against assignment from itself + if ( this == &val ) + return *this; + + smival.value.hNumber.lopart = 0; // pessimsitic - assume no mapping + smival.value.hNumber.hipart = 0; + + // try to make assignment valid + if (val.valid()){ + switch (val.get_syntax()){ + case sNMP_SYNTAX_CNTR64: + smival.value.hNumber.hipart = + ((Counter64 &)val).smival.value.hNumber.hipart; + smival.value.hNumber.lopart = + ((Counter64 &)val).smival.value.hNumber.lopart; + break; + + case sNMP_SYNTAX_CNTR32: + case sNMP_SYNTAX_TIMETICKS: + case sNMP_SYNTAX_GAUGE32: + // case sNMP_SYNTAX_UINT32: .. indistinguishable from GAUGE32 + case sNMP_SYNTAX_INT32: + // take advantage of union... + smival.value.hNumber.lopart = ((Counter64 &)val).smival.value.uNumber; + smival.value.hNumber.hipart = 0; + break; + } + } + return *this; +} + +// overloaded assignment +Counter64& Counter64::operator=( const ACE_UINT64 rhs) +{ + smival.value.hNumber.hipart = (unsigned long) (rhs >> 32); + smival.value.hNumber.lopart = (unsigned long) rhs; + return *this; +} + +// overloaded assignment +Counter64& Counter64::operator=( const Counter64 &rhs) +{ + smival.value.hNumber.hipart = rhs.high(); + smival.value.hNumber.lopart = rhs.low(); + return *this; +} + +// otherwise, behave like an unsigned long int +Counter64::operator ACE_UINT64() +{ + ACE_UINT64 val = smival.value.hNumber.hipart; + val = val << 32; // shift right 4 bytes + val |= smival.value.hNumber.lopart; + return val; +} + +//----------------[ Counter64::clone() ]----------------------------------- +// create a new instance of this Value +SnmpSyntax* Counter64::clone() const +{ + return ( SnmpSyntax *) new Counter64(*this); +} + +//----------------[ Counter64::valid() ]------------------------------------- +int Counter64::valid() const +{ + return 1; +} + +//----------[ return ASCII format ]------------------------- +// TODO: Fix up to do real 64bit decimal value printing... +// For now, print > 32-bit values in hex +const char * Counter64::to_string() +{ + if ( high() != 0 ) + sprintf(output_buffer, "0x%X%08X", + (unsigned int)high(), (unsigned int)low()); + else + sprintf(output_buffer, "%d", (int) low()); + return output_buffer; +} diff --git a/ACE/ASNMP/asnmp/ctr64.h b/ACE/ASNMP/asnmp/ctr64.h new file mode 100644 index 00000000000..6b97b9966f2 --- /dev/null +++ b/ACE/ASNMP/asnmp/ctr64.h @@ -0,0 +1,111 @@ +/* -*-C++-*- */ +#ifndef CTR64_ +#define CTR64_ +//============================================================================= +/** + * @file ctr64.h + * + * $Id$ + * + * SNMP Counter64 class definition. + * + * + * @author Peter E Mellquist + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/smival.h" +#include "ace/Basic_Types.h" + +#define CTR64OUTBUF 30 // maximum ascii string for a 64-bit ctr + + +//---------[ 64 bit Counter Class ]-------------------------------- +// Counter64 Class encapsulates two unsigned integers into a +// a single entity. This type has is available in SNMPv2 but +// may be used anywhere where needed. +// +/** + * @class Counter64 + * + * @brief Defines the member functions for the Counter64 concrete class + * This class implements RFC 1902 64 bit Counter Object. + */ +class ASNMP_Export Counter64 : public SnmpSyntax +{ +public: + /// default constructor + Counter64( ACE_UINT64 llw = 0); + + /// constructor with values + Counter64( unsigned long hiparm, unsigned long loparm); + + /// copy constructor + Counter64( const Counter64 &ctr64); + + /// destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden) + ~Counter64(); + + /// syntax type + SmiUINT32 get_syntax(); + + /// return a long double representation + long double to_long_double() const; + + /// assign a long double to a counter64 + Counter64& assign( long double ld); + + /// return the high part + unsigned long high() const; + + /// return the low part + unsigned long low() const; + + /// set the high part + void set_high( const unsigned long h); + + /// set the low part + void set_low( const unsigned long l); + + /// overloaded assignment + Counter64& operator=( const ACE_UINT64 rhs); + + /// overloaded assignment + Counter64& operator=( const Counter64 &rhs); + + /// get a printable ASCII representation + const char *to_string(); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// general validity test, always true + int valid() const; + + /// otherwise, behave like an ACE_UINT64 + operator ACE_UINT64(); + +protected: + char output_buffer[CTR64OUTBUF]; +}; + +#endif // CTR64_ diff --git a/ACE/ASNMP/asnmp/enttraps.h b/ACE/ASNMP/asnmp/enttraps.h new file mode 100644 index 00000000000..433538eb258 --- /dev/null +++ b/ACE/ASNMP/asnmp/enttraps.h @@ -0,0 +1,147 @@ +/* -*-C++-*- */ +#ifndef ENTTRAPS_ +#define ENTTRAPS_ +//============================================================================= +/** + * @file enttraps.h + * + * $Id$ + * + * constants for Enterprise Traps + * + * + * @author Peter E MellquistMichael R MacFaden mrm@cisco.com - rework & ACE port + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/asn1.h" // ASN.1 header file + +//--------------[ well known trap ids ]----------------------------------- +/** + * @class snmpTrapsOid + * + * @brief Defines the member functions for the snmpTrapsOid base class + * to implement the traps defined in RFC 1215 + */ +class ASNMP_Export snmpTrapsOid : public Oid +{ + public: + snmpTrapsOid (void):Oid("1.3.6.1.6.3.1.1.5"){} + SnmpSyntax& operator=( SnmpSyntax &val){ return Oid::operator=(val); } +}; + +/** + * @class snmpTrapEnterpriseOid + * + * @brief Defines the default Enterprise Oid for this software package + */ +class ASNMP_Export snmpTrapEnterpriseOid : public Oid +{ + public: + snmpTrapEnterpriseOid(void): Oid("1.3.6.1.6.3.1.1.4.3.0") { } + SnmpSyntax& operator=( SnmpSyntax &val){ return Oid::operator=(val); } +}; + +/** + * @class coldStartOid + * + * @brief Defines the RFC 1215 agent cold start generic trap (system reboot) + */ +class ASNMP_Export coldStartOid : public snmpTrapsOid +{ + public: + coldStartOid( void){*this+=".1";} + SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); } +}; + +/** + * @class warmStartOid + * + * @brief Defines the RFC 1215 agent warm start generic trap (agent reboot) + */ +class ASNMP_Export warmStartOid : public snmpTrapsOid +{ + public: + warmStartOid( void){*this+=".2";} + SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); } +}; + +/** + * @class linkDownOid + * + * @brief Defines the RFC 1215 interface (link) down trap + */ +class ASNMP_Export linkDownOid : public snmpTrapsOid +{ + public: + linkDownOid( void){*this+=".3";} + SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); } +}; + + +// SMI LinkUp Oid +/** + * @class linkUpOid + * + * @brief Defines the RFC 1215 interface (link) up trap + */ +class ASNMP_Export linkUpOid : public snmpTrapsOid +{ + public: + linkUpOid( void){*this+=".4";} + SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); } +}; + +/** + * @class authenticationFailureOid + * + * @brief Defines the RFC 1215 device/agent invalid access trap + */ +class ASNMP_Export authenticationFailureOid : public snmpTrapsOid +{ + public: + authenticationFailureOid( void){*this+=".5";} + SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); } +}; + +/** + * @class egpNeighborLossOid + * + * @brief Defines the RFC 1215 Exterior Gateway Protocol neighbor loss trap + */ +class ASNMP_Export egpNeighborLossOid : public snmpTrapsOid +{ + public: + egpNeighborLossOid( void){*this+=".6";} + SnmpSyntax& operator=( SnmpSyntax &val){ return snmpTrapsOid::operator=(val); } +}; + +#ifdef DEFINE_TRAP_CONSTANTS_ + +const coldStartOid coldStart; +const warmStartOid warmStart; +const linkDownOid linkDown; +const linkUpOid linkUp; +const authenticationFailureOid authenticationFailure; +const egpNeighborLossOid egpNeighborLoss; +const snmpTrapEnterpriseOid snmpTrapEnterprise; + +#endif + +#endif // ENTTRAPS_ diff --git a/ACE/ASNMP/asnmp/gauge.cpp b/ACE/ASNMP/asnmp/gauge.cpp new file mode 100644 index 00000000000..9051e2f83fb --- /dev/null +++ b/ACE/ASNMP/asnmp/gauge.cpp @@ -0,0 +1,114 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// gauge.cpp +// +// = DESCRIPTION +// Class implemtation for SMI Gauge32 class. +// NOTES: This does not behave exactly as a Gauge described in RFC 1155 +// +// = AUTHOR +// Peter E Mellquist +// Michael R MacFaden mrm@cisco.com - rework & ACE port +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/gauge.h" // header file for gauge class + +ACE_RCSID(asnmp, gauge, "$Id$") + +// constructor with a value +Gauge32::Gauge32( const unsigned long i):SnmpUInt32(i) +{ + smival.syntax = sNMP_SYNTAX_GAUGE32; +} + +// copy constructor +Gauge32::Gauge32 ( const Gauge32 &g) + : SnmpUInt32 (g) +{ this->smival.value.uNumber = g.smival.value.uNumber; + smival.syntax = sNMP_SYNTAX_GAUGE32; + valid_flag = 1; +} + +// destructor +Gauge32::~Gauge32() +{ +} + +// syntax type +SmiUINT32 Gauge32::get_syntax() +{ + return sNMP_SYNTAX_GAUGE32; +} + +// overloaded assignment +Gauge32& Gauge32::operator=( const Gauge32 &uli) +{ + this->smival.value.uNumber = uli.smival.value.uNumber; + return *this; +} + +// overloaded assignment +Gauge32& Gauge32::operator=( const unsigned long int i) +{ + smival.value.uNumber=i; return *this; +} + +// general assignment from any Value +// TODO: this is broken if not inherited from UInt32 (see UInt32 code). +SnmpSyntax& Gauge32::operator=( SnmpSyntax &in_val) +{ + + if ( this == &in_val ) // handle assignement from itself + return *this; + + valid_flag = 0; // will get set true if really valid + if (in_val.valid()) + { + switch (in_val.get_syntax()) + { + case sNMP_SYNTAX_UINT32: + case sNMP_SYNTAX_GAUGE32: + case sNMP_SYNTAX_CNTR32: + case sNMP_SYNTAX_TIMETICKS: + case sNMP_SYNTAX_INT32: // implied cast int -> uint + this->smival.value.uNumber = + ((Gauge32 &)in_val).smival.value.uNumber; + valid_flag = 1; + break; + } + } + return *this; +} + +// otherwise, act as unsigned long +Gauge32::operator unsigned long() +{ + return smival.value.uNumber; +} + +// clone - create a new instance of this Value +SnmpSyntax* Gauge32::clone() const +{ + return ( SnmpSyntax *) new Gauge32(*this); +} diff --git a/ACE/ASNMP/asnmp/gauge.h b/ACE/ASNMP/asnmp/gauge.h new file mode 100644 index 00000000000..202edaf98bf --- /dev/null +++ b/ACE/ASNMP/asnmp/gauge.h @@ -0,0 +1,79 @@ +/* -*-C++-*- */ +#ifndef GAUGE_ +#define GAUGE_ +//============================================================================= +/** + * @file gauge.h + * + * $Id$ + * + * Class definition for SMI Gauge32 class. + * This class currently does not behave as defined by the abstract model + * in RFC 1155 section 3.2.3.4 (ie the value doesn't latch on the max value) + * + * + * @author Peter E Mellquist + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/integer.h" + +//------------[ Gauge32 Class ]------------------------------------------ +// The gauge class allows all the functionality of unsigned +// integers but is recognized as a distinct SMI type. Gauge32 +// objects may be set or get into Vb objects. +// + +/** + * @class Gauge32: + * + * @brief Define RFC1902 Gauge datatype from RFC 1155 section 3.2.3.4 + * Note that this datatype does not behave exactly (acts like a long) + */ +class ASNMP_Export Gauge32: public SnmpUInt32 +{ + public: + /// constructor with a value + Gauge32( const unsigned long i = 0); + + /// copy constructor + Gauge32 ( const Gauge32 &g); + + /// destructor for a Gauge32 (ensure that Value::~Value() is overridden) + ~Gauge32(); + + /// syntax type + SmiUINT32 get_syntax(); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// overloaded assignment + Gauge32& operator=( const Gauge32 &uli); + + /// overloaded assignment + Gauge32& operator=( const unsigned long i); + + /// otherwise, behave like an unsigned int + operator unsigned long(); + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); +}; +#endif //GAUGE_ diff --git a/ACE/ASNMP/asnmp/integer.cpp b/ACE/ASNMP/asnmp/integer.cpp new file mode 100644 index 00000000000..d732e0f3ff9 --- /dev/null +++ b/ACE/ASNMP/asnmp/integer.cpp @@ -0,0 +1,230 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// integer.cpp +// +// = DESCRIPTION +// Class implemtation for SMI Integer classes. +// +// = AUTHOR +// Jeff Meyer +// Michael R MacFaden mrm@cisco.com - rework & ACE port +// ============================================================================ +/*=================================================================== + + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/integer.h" // header file for gauge class +#include "ace/OS_NS_stdio.h" + +ACE_RCSID(asnmp, integer, "$Id$") + +// constructor with value +SnmpUInt32::SnmpUInt32 (const unsigned long i) +{ + smival.value.uNumber=i; + smival.syntax = sNMP_SYNTAX_UINT32; + valid_flag = 1; +} + +// copy constructor +SnmpUInt32::SnmpUInt32( const SnmpUInt32 &c) + : SnmpSyntax (c) +{ + smival.value.uNumber=c.smival.value.uNumber; + smival.syntax = sNMP_SYNTAX_UINT32; + valid_flag = 1; +} + +// destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden) +SnmpUInt32::~SnmpUInt32() +{ +} + +// syntax type +SmiUINT32 SnmpUInt32::get_syntax() +{ + return sNMP_SYNTAX_UINT32; +} + +// object validity +int SnmpUInt32::valid( void) const +{ + return valid_flag; +} + +// overloaded assignment +SnmpUInt32& SnmpUInt32::operator=( const unsigned long int i) +{ + smival.value.uNumber=i; + valid_flag = 1; + return *this; +} + +// general assignment from any Value +SnmpSyntax& SnmpUInt32::operator=( SnmpSyntax &in_val) +{ + if ( this == &in_val ) // handle assignement from itself + return *this; + + valid_flag = 0; // will get set true if really valid + if (in_val.valid()) + { + switch (in_val.get_syntax()) + { + case sNMP_SYNTAX_UINT32: + // case sNMP_SYNTAX_GAUGE32: .. indistinquishable from UINT32 + case sNMP_SYNTAX_CNTR32: + case sNMP_SYNTAX_TIMETICKS: + case sNMP_SYNTAX_INT32: // implied cast int -> uint + this->smival.value.uNumber = + ((SnmpUInt32 &)in_val).smival.value.uNumber; + valid_flag = 1; + break; + } + } + return *this; +} + +// overloaded assignment +SnmpUInt32& SnmpUInt32::operator=( const SnmpUInt32 &uli) +{ + this->smival.value.uNumber = uli.smival.value.uNumber; return *this; +} + +// otherwise, behave like an unsigned long int +SnmpUInt32::operator unsigned long() +{ + return smival.value.uNumber; +} + +// create a new instance of this Value +SnmpSyntax* SnmpUInt32::clone() const +{ + return (SnmpSyntax *) new SnmpUInt32(*this); +} + +// ASCII format return +const char * SnmpUInt32::to_string() +{ + sprintf(output_buffer, "%d", (int) (this->smival.value.uNumber)); + return output_buffer; +} + + +//==================================================================== +// INT 32 Implementation +//==================================================================== + +// default constructor +SnmpInt32::SnmpInt32 (const long i) +{ + smival.value.sNumber=i; + smival.syntax = sNMP_SYNTAX_INT32; + valid_flag = 1; +} + +// constructor with value +SnmpInt32::SnmpInt32 (const SnmpInt32 &c) + : SnmpSyntax (c) +{ + smival.value.sNumber=c.smival.value.sNumber; + smival.syntax = sNMP_SYNTAX_INT32; + valid_flag = 1; +} + +// destructor +SnmpInt32::~SnmpInt32() +{ +} + +// syntax type +SmiUINT32 SnmpInt32::get_syntax() +{ + return sNMP_SYNTAX_INT32; +} + +// object validity +int SnmpInt32::valid( void) const +{ + return valid_flag; +} + +// overloaded assignment +SnmpInt32& SnmpInt32::operator=( const long i) +{ + this->smival.value.sNumber = (unsigned long) i; + valid_flag = 1; + return *this; +} + +// overloaded assignment +SnmpInt32& SnmpInt32::operator=( const SnmpInt32 &uli) +{ + this->smival.value.sNumber = uli.smival.value.sNumber; + valid_flag = 1; + return *this; +} + +// general assignment from any Value +SnmpSyntax& SnmpInt32::operator=( SnmpSyntax &in_val) +{ + if ( this == &in_val ) // handle assignement from itself + return *this; + + valid_flag = 0; // will get set true if really valid + if (in_val.valid()) + { + switch (in_val.get_syntax()) + { + case sNMP_SYNTAX_INT32: + case sNMP_SYNTAX_UINT32: // implied cast uint -> int + // case sNMP_SYNTAX_GAUGE32: .. indistinquishable from UINT32 + case sNMP_SYNTAX_CNTR32: // implied cast uint -> int + case sNMP_SYNTAX_TIMETICKS: // implied cast uint -> int + this->smival.value.sNumber = + ((SnmpInt32 &)in_val).smival.value.sNumber; + valid_flag = 1; + break; + } + } + return *this; +} + +// otherwise, behave like a long int +SnmpInt32::operator long() +{ + return (long) smival.value.sNumber; +} + +// clone - create a new instance of this Value +SnmpSyntax* SnmpInt32::clone() const +{ + return ( SnmpSyntax *) new SnmpInt32(*this); +} + +// ASCII format return + +const char *SnmpInt32::to_string() +{ + sprintf(output_buffer, "%d", (int) (long) this->smival.value.sNumber); + return output_buffer; +} diff --git a/ACE/ASNMP/asnmp/integer.h b/ACE/ASNMP/asnmp/integer.h new file mode 100644 index 00000000000..d120684c095 --- /dev/null +++ b/ACE/ASNMP/asnmp/integer.h @@ -0,0 +1,142 @@ +/* -*-C++-*- */ +#ifndef SNMPINTEGER_ +#define SNMPINTEGER_ +//============================================================================= +/** + * @file integer.h + * + * $Id$ + * + * Class definition for Integer classes convertable to SMI. + * + * + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/smival.h" + +// TODO get rid of this constant +#define INTOUTBUF 15 // largest ASCII formatted integer + +//------------[ Integer Classes ]------------------------------------------ +// The integer class allows all the functionality of the various +// integers but is contained in a Value object for consistency +// among the various types. +// class objects may be set or get into Vb objects. +// + +// 32 bit unsigned integer class +/** + * @class SnmpUInt32 + * + * @brief Implement RFC 1920 Unsigned Integer SMI datatype + */ +class ASNMP_Export SnmpUInt32 : public SnmpSyntax +{ + + public: + /// default constructor + SnmpUInt32 (const unsigned long i = 0); + + /// copy constructor + SnmpUInt32( const SnmpUInt32 &c); + + /// destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden) + virtual ~SnmpUInt32(); + + /// syntax type + virtual SmiUINT32 get_syntax(); + + /// overloaded assignment + SnmpUInt32& operator=( const unsigned long i); + + /// overloaded assignment + SnmpUInt32& operator=( const SnmpUInt32 &uli); + + /// otherwise, behave like an unsigned long int + operator unsigned long(); + + /// get a printable ASCII value + virtual const char *to_string(); + + /// create a new instance of this Value + virtual SnmpSyntax *clone() const; + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// did object construct properly + int valid() const; + + protected: + /// contain string representation of object + int valid_flag; + char output_buffer[INTOUTBUF]; +}; + + +// 32 bit signed integer class + /** + * @class SnmpInt32 + * + * @brief Implement RFC 1902 32 bit Integer SMI data object + */ +class ASNMP_Export SnmpInt32 : public SnmpSyntax +{ + public: + /// constructor with value + SnmpInt32 (const long i = 0); + + /// constructor with value + SnmpInt32 (const SnmpInt32 &c); + + /// destructor (ensure that SnmpSyntax::~SnmpSyntax() is overridden) + virtual ~SnmpInt32(); + + /// syntax type + virtual SmiUINT32 get_syntax(); + + /// overloaded assignment + SnmpInt32& operator=( const long i); + + /// overloaded assignment + SnmpInt32& operator=( const SnmpInt32 &li); + + /// otherwise, behave like a long int + operator long(); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + + /// get a printable ASCII value + const char *to_string(); + + /// logical state of object + int valid() const; + + protected: + /// contain string representation of object + int valid_flag; + char output_buffer[INTOUTBUF]; +}; + +#endif diff --git a/ACE/ASNMP/asnmp/octet.cpp b/ACE/ASNMP/asnmp/octet.cpp new file mode 100644 index 00000000000..885197919c4 --- /dev/null +++ b/ACE/ASNMP/asnmp/octet.cpp @@ -0,0 +1,594 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// octet.cpp +// +// = DESCRIPTION +// Implements the SMI Octet datatype (RFC 1155) +// This class is fully contained and does not rely on or any other +// SNMP libraries. Ported to ACE by Michael MacFaden mrm@cisco.com +// +// = AUTHOR +// Peter E Mellquist +// +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/octet.h" // include definition for octet class +#include "ace/OS_Memory.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_ctype.h" +#include "ace/os_include/os_ctype.h" + +ACE_RCSID(asnmp, octet, "$Id$") + +//============[ syntax type ]========================================= +SmiUINT32 OctetStr::get_syntax() +{ + return sNMP_SYNTAX_OCTETS; +} + +inline +void init_octet_smi(SmiVALUE& smi) +{ + smi.syntax = sNMP_SYNTAX_OCTETS; + smi.value.string.ptr = 0; + smi.value.string.len = 0; +} + +inline +void reset_octet_smi(SmiVALUE& smi) +{ + delete [] smi.value.string.ptr; + smi.value.string.ptr = 0; + smi.value.string.len = 0; +} + +inline +int copy_octet_smi(SmiVALUE& smi, int size, const char *src, int& valid_flag) +{ + valid_flag = 0; + + if (smi.value.string.ptr) + delete [] smi.value.string.ptr; + + ACE_NEW_RETURN(smi.value.string.ptr, SmiBYTE[size], 1); + ACE_OS::memcpy( smi.value.string.ptr, src, size); + smi.value.string.len = size; + valid_flag = 1; + return 0; +} + +//============[ default constructor ]========================= +OctetStr::OctetStr( const char * string, long size): + output_buffer(0), validity(0) +{ + + init_octet_smi(smival); + + // check for null string + if ( !string) + return; + + if (size == -1) // calc if no length given - assume c style string + size = ACE_OS::strlen( string); + + copy_octet_smi(smival, size, string, validity); +} + + +//============[ set the data on an already constructed Octet ]============ +// TODO: should return status since it can fail in so many places +void OctetStr::set_data( const SmiBYTE* string, long size) +{ + // invalid args, set octetStr to not valid + if ( !string || !size) { + validity = 0; + return; + } + + // assume non-zero terminated string + if (size == -1) // calc if no length given - assume c style string + size = ACE_OS::strlen( (char *)string); + + // free up already used space + if ( smival.value.string.ptr ) { + reset_octet_smi(smival); + } + smival.value.string.len = 0; + + + copy_octet_smi(smival, size, (const char *)string, validity); +} + +//============[ constructor using another octet object ]============== +OctetStr::OctetStr ( const OctetStr &octet): + SnmpSyntax (octet), output_buffer(0), validity(1) +{ + init_octet_smi(smival); + // check for zero len case + if ( octet.smival.value.string.len == 0) { + return; + } + + // must be a valid object + if ( octet.validity == 0) { + validity = 0; + return; + } + + // get the mem needed + copy_octet_smi(smival, octet.smival.value.string.len, + (const char *)octet.smival.value.string.ptr, validity); +} + +//=============[ destructor ]========================================= +OctetStr::~OctetStr() +{ + reset_octet_smi(smival); + delete [] output_buffer; +} + + +//=============[ assignment to a string operator overloaded ]========= +OctetStr& OctetStr::operator=( const char *string) +{ + // get the string size + size_t nz; + + // free up previous memory if needed + if ( smival.value.string.ptr ) { + reset_octet_smi(smival); + } + + // if empty then we are done + if (!string || !(nz = ACE_OS::strlen( string))) { + validity = 1; + return *this; + } + + // get memory needed + copy_octet_smi(smival, nz, string, validity); + return *this; +} + +//=============[ assignment to another oid object overloaded ]======== +OctetStr& OctetStr::operator=( const OctetStr &octet) +{ + // protect against assignment from self + if ( this == &octet ) + return *this; + + // don't assign from invalid objs + if (!octet.validity) { + return *this; + } + + // free up previous memory if needed + if ( smival.value.string.len ) { + reset_octet_smi(smival); + } + + if (!octet.smival.value.string.len) { + validity = 1; + return *this; + } + + // get some memory + copy_octet_smi(smival, octet.smival.value.string.len, + (const char*) octet.smival.value.string.ptr, validity); + return *this; // return self reference +} + +//==============[ equivlence operator overloaded ]==================== +bool operator==( const OctetStr &lhs, const OctetStr &rhs) +{ + if( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0) + return true; + else + return false; +} + +//==============[ not equivlence operator overloaded ]================ +bool operator!=( const OctetStr &lhs, const OctetStr &rhs) +{ + if( lhs.left_comparison( rhs.smival.value.string.len, rhs)!=0) + return true; + else + return false; +} + +//==============[ less than < overloaded ]============================ +bool operator<( const OctetStr &lhs, const OctetStr &rhs) +{ + if( lhs.left_comparison( rhs.smival.value.string.len, rhs)<0) + return true; + else + return false; +} + +//==============[ less than <= overloaded ]=========================== +bool operator<=( const OctetStr &lhs, const OctetStr &rhs) +{ + if(( lhs.left_comparison( rhs.smival.value.string.len, rhs)<0) || + ( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0)) + return true; + else + return false; +} + +//===============[ greater than > overloaded ]======================== +bool operator>( const OctetStr &lhs, const OctetStr &rhs) +{ + if( lhs.left_comparison( rhs.smival.value.string.len, rhs)>0) + return true; + else + return false; +} + +//===============[ greater than >= overloaded ]======================= +bool operator>=( const OctetStr &lhs, const OctetStr &rhs) +{ + if(( lhs.left_comparison( rhs.smival.value.string.len, rhs)>0) || + ( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0)) + return true; + else + return false; +} + +//===============[ equivlence operator overloaded ]=================== +bool operator==( const OctetStr &lhs,const char *rhs) +{ + OctetStr to( rhs); + if( lhs.left_comparison( to.smival.value.string.len,to)==0) + return true; + else + return false; +} + +//===============[ not equivlence operator overloaded ]=============== +bool operator!=( const OctetStr &lhs,const char *rhs) +{ + OctetStr to( rhs); + if ( lhs.left_comparison( to.smival.value.string.len,to)!=0) + return true; + else + return false; +} + +//===============[ less than < operator overloaded ]================== +bool operator<( const OctetStr &lhs,const char *rhs) +{ + OctetStr to( rhs); + if ( lhs.left_comparison( to.smival.value.string.len,to)<0) + return true; + else + return false; +} + +//===============[ less than <= operator overloaded ]================= +bool operator<=( const OctetStr &lhs,char *rhs) +{ + OctetStr to( rhs); + if (( lhs.left_comparison( to.smival.value.string.len,to)<0) || + ( lhs.left_comparison( to.smival.value.string.len,to)==0)) + return true; + else + return false; +} + +//===============[ greater than > operator overloaded ]=============== +bool operator>( const OctetStr &lhs,const char *rhs) +{ + OctetStr to( rhs); + if ( lhs.left_comparison( to.smival.value.string.len,to)>0) + return true; + else + return false; +} + +//===============[ greater than >= operator overloaded ]============== +bool operator>=( const OctetStr &lhs,const char *rhs) +{ + OctetStr to( rhs); + if (( lhs.left_comparison( to.smival.value.string.len,to)>0) || + ( lhs.left_comparison( to.smival.value.string.len,to)==0)) + return true; + else + return false; +} + +//===============[ append operator, appends a string ]================ +OctetStr& OctetStr::operator+=( const char *a) +{ + SmiBYTE *tmp; // temp pointer + size_t slen,nlen; + + // get len of string + if ( !a || ((slen = ACE_OS::strlen( a)) == 0)) + return *this; + + // total len of octet + nlen = slen + (size_t) smival.value.string.len; + ACE_NEW_RETURN(tmp, SmiBYTE [ nlen], *this); + ACE_OS::memcpy ( tmp, smival.value.string.ptr, + (size_t) smival.value.string.len); + ACE_OS::memcpy( tmp + smival.value.string.len, a, (size_t) slen); + // delete the original + if ( smival.value.string.ptr ) + reset_octet_smi(smival); + smival.value.string.ptr = tmp; + smival.value.string.len = nlen; + return *this; +} + +//================[ append one OctetStr to another ]================== +OctetStr& OctetStr::operator+=( const OctetStr& octetstr) +{ + SmiBYTE *tmp; // temp pointer + size_t slen,nlen; + + if (!octetstr.validity || + !(slen = (size_t)octetstr.length())) + return *this; + + // total len of octet + nlen = slen + (size_t) smival.value.string.len; + // get mem needed + ACE_NEW_RETURN(tmp, SmiBYTE[ nlen], *this); + ACE_OS::memcpy ( tmp, smival.value.string.ptr, + (size_t) smival.value.string.len); + ACE_OS::memcpy( tmp + smival.value.string.len, octetstr.data(), + (size_t) slen); + if ( smival.value.string.ptr ) + reset_octet_smi(smival); + smival.value.string.ptr = tmp; + smival.value.string.len = nlen; + return *this; +} + +//================[ appends an int ]================================== +OctetStr& OctetStr::operator+=( const char c) +{ + SmiBYTE *tmp; + // get the memory needed plus one extra byte + ACE_NEW_RETURN(tmp, SmiBYTE[ smival.value.string.len + 1], *this); + ACE_OS::memcpy ( tmp, smival.value.string.ptr, + (size_t) smival.value.string.len); // len of original + tmp[ smival.value.string.len ] = c; // assign in byte + if ( smival.value.string.ptr ) // delete the original + reset_octet_smi(smival); + + smival.value.string.ptr = tmp; // point to one + smival.value.string.len++; // up the len + return *this; +} + + +//================[ compare n elements of an Octet ]================== +int OctetStr::left_comparison( const long n, const OctetStr &o) const +{ + long z, w; + + // both are empty, they are equal + if (( smival.value.string.len == 0) && + ( o.smival.value.string.len == 0)) + return 0; // equal + + // self is empty and param has something + if (( smival.value.string.len == 0) && + ( o.smival.value.string.len >0) && + (n>0)) + return -1; + + // self has something and param has nothing + if (( smival.value.string.len > 0) && + ( o.smival.value.string.len ==0) && + (n>0)) + return 1; + + // special case + if (( smival.value.string.len == 0) && + ( o.smival.value.string.len > 0) && + ( n == 0)) + return 0; + + // pick the Min of n, this and the param len + // this is the maximum # to iterate a search + w = smival.value.string.len < o.smival.value.string.len + ? smival.value.string.len : o.smival.value.string.len; + if (n<w) w=n; + + z = 0; + while( z < w) { + if ( smival.value.string.ptr[z] < o.smival.value.string.ptr[z]) + return -1; // less than + if ( smival.value.string.ptr[z] > o.smival.value.string.ptr[z]) + return 1; // greater than + z++; + } + + if (( z == 0) && + ( smival.value.string.len == 0) && + ( o.smival.value.string.len > 0)) + return -1; + + if (( z == 0) && + ( o.smival.value.string.len == 0) && + ( smival.value.string.len > 0)) + return 1; + + return 0; +} + +//================[ return the length of the oid ]======================= +size_t OctetStr::length() const +{ + return (size_t) smival.value.string.len; +} + +//================[ operator[]: access as if array ]================== +SmiBYTE& OctetStr::operator[]( int position) +{ + return smival.value.string.ptr[position]; +} + +//===============[ reuturns pointer to internal data ]=============== +SmiBYTE * OctetStr::data() const +{ + return smival.value.string.ptr; +} + +//================[ returns validity ]================================ +int OctetStr::valid() const +{ + return validity; +} + +//================[ clone() ]========================================= +SnmpSyntax * OctetStr::clone() const +{ + OctetStr *tmp = new OctetStr(*this); + return ( SnmpSyntax *) tmp; +} + +//================[ ASCII format return ]============================= +const char * OctetStr::to_string() +{ + for ( unsigned long i=0; i < smival.value.string.len; i++) { + if (( smival.value.string.ptr[i] != '\r')&& + ( smival.value.string.ptr[i] != '\n')&& + (ACE_OS::ace_isprint((int) (smival.value.string.ptr[i]))==0)) + return(to_string_hex()); + } + + if ( output_buffer != 0) + delete [] output_buffer; + + ACE_NEW_RETURN(output_buffer, char[smival.value.string.len + 1], ""); + if (smival.value.string.len) + ACE_OS::memcpy(output_buffer, smival.value.string.ptr, + (int) smival.value.string.len); + output_buffer[smival.value.string.len] = '\0'; + return output_buffer; +} + + +//================[ general Value = operator ]======================== +SnmpSyntax& OctetStr::operator=( SnmpSyntax &val) +{ + // protect against assignment from self + if ( this == &val ) + return *this; + + // blow away the old value + validity=0; + if (smival.value.string.ptr) { + reset_octet_smi(smival); + } + smival.value.string.len = 0; + if (val.valid()){ + switch (val.get_syntax()) { + case sNMP_SYNTAX_OCTETS: + case sNMP_SYNTAX_IPADDR: + set_data( ((OctetStr &)val).smival.value.string.ptr, + ((OctetStr &)val).smival.value.string.len); + break; + } + } + return *this; +} + +//================[ format the output into hex ]======================== +const char *OctetStr::to_string_hex() +{ + int cnt; + char char_buf[80]; // holds ASCII representation of data + char *buf_ptr; // pointer into ASCII listing + char *line_ptr; // pointer into Hex listing + int storageNeeded; // how much space do we need ? + int local_len = (int) smival.value.string.len; + SmiBYTE *bytes = smival.value.string.ptr; + + + storageNeeded = (int) ((smival.value.string.len/16)+1) * 72 + 1; + + if ( output_buffer != 0) + delete [] output_buffer; + + ACE_NEW_RETURN(output_buffer, char[storageNeeded], ""); + + line_ptr = output_buffer; + + /*----------------------------------------*/ + /* processing loop for entire data buffer */ + /*----------------------------------------*/ + while (local_len > 0) { + cnt = 16; /* print 16 bytes per line */ + buf_ptr = char_buf; + sprintf(line_ptr, " "); + line_ptr += 2; /* indent */ + + /*-----------------------*/ + /* process a single line */ + /*-----------------------*/ + while (cnt-- > 0 && local_len-- > 0) { + sprintf(line_ptr, "%2.2X ", *bytes); + + line_ptr +=3; /* the display of a byte always 3 chars long */ + if (isprint(*bytes)) + sprintf(buf_ptr, "%c", *bytes); + else + sprintf(buf_ptr, "."); + bytes++; + buf_ptr++; + } + cnt++; + + /*----------------------------------------------------------*/ + /* this is to make sure that the ASCII displays line up for */ + /* incomplete lines of hex */ + /*----------------------------------------------------------*/ + while (cnt-- > 0) { + sprintf(line_ptr," "); + line_ptr += 3; + } + + /*------------------------------------------*/ + /* append the ASCII display to the Hex line */ + /*------------------------------------------*/ + +// TODO: verify ACE_OS:: on NT works like this or not + +#if defined(_WIN32) + const char *fmt = " %s\r\n"; +#else + const char *fmt = " %s\n"; +#endif // _WIN32 + + ACE_OS::sprintf(line_ptr, fmt, char_buf); + line_ptr += 3 + ACE_OS::strlen(char_buf); + } + + return output_buffer; +} diff --git a/ACE/ASNMP/asnmp/octet.h b/ACE/ASNMP/asnmp/octet.h new file mode 100644 index 00000000000..5e8c8d63d98 --- /dev/null +++ b/ACE/ASNMP/asnmp/octet.h @@ -0,0 +1,152 @@ + + +#ifndef OCTET_CLS_ +#define OCTET_CLS_ +//============================================================================= +/** + * @file octet.h + * + * $Id$ + * + * This class is fully contained and does not rely on or any other + * SNMP libraries. This class is portable across any platform + * which supports C++. + * + * + * @author Peter E Mellquist / design/original code Michael R. MacFaden / modified for ACE + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +//------------------------------------------------------------------------ +#include "asnmp/smival.h" + +/** + * @class OctetStr + * + * @brief Implement RFC1155 Octet SMI data object + */ +class ASNMP_Export OctetStr : public SnmpSyntax + +{ +public: + /// construct octet from byte buffer, assume c style string if size == -1 + OctetStr( const char *string = "", long size = -1); + + /// constructor using another octet object + OctetStr ( const OctetStr &octet); + + /// destructor + ~OctetStr(); + + /// syntax type + SmiUINT32 get_syntax(); + + /// set octet from byte buffer, assume c style string if size == -1 + void set_data( const SmiBYTE* string, long int size = -1); + + /// assignment to a string operator overloaded + OctetStr& operator=( const char *string); + + /// assignment to another oid object overloaded + OctetStr& operator=( const OctetStr &octet); + + /// equivlence operator overloaded + friend ASNMP_Export bool operator==( const OctetStr &lhs, const OctetStr &rhs); + + /// not equivlence operator overloaded + friend ASNMP_Export bool operator!=( const OctetStr &lhs, const OctetStr &rhs); + + /// less than < overloaded + friend ASNMP_Export bool operator<( const OctetStr &lhs, const OctetStr &rhs); + + /// less than <= overloaded + friend ASNMP_Export bool operator<=( const OctetStr &lhs,const OctetStr &rhs); + + /// greater than > overloaded + friend ASNMP_Export bool operator>( const OctetStr &lhs, const OctetStr &rhs); + + /// greater than >= overloaded + friend ASNMP_Export bool operator>=( const OctetStr &lhs, const OctetStr &rhs); + + /// equivlence operator overloaded + friend ASNMP_Export bool operator==( const OctetStr &lhs,const char *rhs); + + /// not equivlence operator overloaded + friend ASNMP_Export bool operator!=( const OctetStr &lhs,const char *rhs); + + /// less than < operator overloaded + friend ASNMP_Export bool operator<( const OctetStr &lhs,const char *rhs); + + /// less than <= operator overloaded + friend ASNMP_Export bool operator<=( const OctetStr &lhs,char *rhs); + + /// greater than > operator overloaded + friend ASNMP_Export bool operator>( const OctetStr &lhs,const char *rhs); + + /// greater than >= operator overloaded + friend ASNMP_Export bool operator>=( const OctetStr &lhs,const char *rhs); + + /// append operator, appends a string + OctetStr& operator+=( const char *a); + + /// appends an int + OctetStr& operator+=( const char c); + + /// append one octetStr to another + OctetStr& operator+=( const OctetStr& octetstr); + + /// for non const [], allows reading and writing + SmiBYTE& operator[]( int position); + + /** + * compare the n leftmost bytes (left-to-right) + * returns 0, equal + * returns -1, < + * returns 1 , > + */ + int left_comparison( const long n, const OctetStr &o) const; + + /// return the len of the oid + size_t length() const ; + + /// returns validity + int valid() const; + + /// returns pointer to internal data + SmiBYTE *data() const; + + /// get a printable ASCII value + const char *to_string(); + + /// get an ASCII formattted hex dump of the contents + const char *to_string_hex(); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + +protected: + //----[ instance variables ] + char *output_buffer; // formatted Octet value + int validity; // validity boolean +}; + +#endif // OCTET_CLS_ diff --git a/ACE/ASNMP/asnmp/oid.cpp b/ACE/ASNMP/asnmp/oid.cpp new file mode 100644 index 00000000000..b5999a1fcbd --- /dev/null +++ b/ACE/ASNMP/asnmp/oid.cpp @@ -0,0 +1,803 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// oid.cpp +// +// = DESCRIPTION +// This module contains the implementation of the oid class. This +// includes all protected and public member functions. The oid class +// may be compiled stand alone without the use of any other library. +// +// = AUTHOR +// Peter E Mellquist +// Michael R MacFaden mrm@cisco.com - rework & ACE port +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS" without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +//---------[ external C libaries used ]-------------------------------- + +#include "asnmp/oid.h" // include def for oid class +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_Memory.h" +#include "ace/os_include/os_ctype.h" + +ACE_RCSID(asnmp, oid, "$Id$") + +enum Defs {SNMPBUFFSIZE=300, + SNMPCHARSIZE=15}; // max oid value (4294967295UL) + +#define NO_MEM_STR "ERROR: Oid::to_string: memory allocation failure" + +//=============[Oid::get_syntax(void)]==================================== +SmiUINT32 Oid::get_syntax() +{ + return sNMP_SYNTAX_OID; +} + + +//=============[Oid::Oid( const char *dotted_string ]===================== +// constructor using a dotted string +// +// do a string to oid using the string passed in +Oid::Oid( const char * dotted_oid_string, size_t size) +{ + // can't init enum SmiValue so just memset it clean + set_null(); + + size_t z; + if ((z = ACE_OS::strlen(dotted_oid_string)) == 0) { + set_invalid(); + return; + } + + if (size == (unsigned int)-1) + size = z; + if (size > z) + size = z; + + char *ptr = (char *)dotted_oid_string;; + if (size < z) { + // create new buffer if needed + ACE_NEW(ptr, char [size]); + + // sz should be in StrToOid? + ACE_OS::memcpy( (void *)ptr, dotted_oid_string, size); + } + + size_t byte_counter; + if (StrToOid( (char *) ptr, &smival.value.oid, byte_counter) < 0) + set_invalid(); + if (ptr != dotted_oid_string) + delete [] ptr; +} + + +//=============[Oid::Oid( const Oid &oid) ]================================ +// constructor using another oid object +// +// do an oid copy using the oid object passed in +Oid::Oid ( const Oid &oid) + : SnmpSyntax (oid) +{ + set_null(); + + // allocate some memory for the oid + // in this case the size to allocate is the same + // size as the source oid + if (oid.smival.value.oid.len) { + ACE_NEW(smival.value.oid.ptr, SmiUINT32[ oid.smival.value.oid.len]); + size_t byte_counter; + OidCopy( (SmiLPOID) &(oid.smival.value.oid),(SmiLPOID) + &smival.value.oid, byte_counter); + } +} + + +//=============[Oid::Oid( const unsigned long *raw_oid, int oid_len) ]==== +// constructor using raw numeric form +// +// copy the integer values into the private member +Oid::Oid(const unsigned long *raw_oid, size_t oid_len) +{ + set_null(); + + smival.syntax = sNMP_SYNTAX_OID; + set_invalid(); + + if (raw_oid && oid_len > 0) { + ACE_NEW(smival.value.oid.ptr, SmiUINT32[ oid_len]); + smival.value.oid.len = oid_len; + for (size_t i=0; i < oid_len; i++) + smival.value.oid.ptr[i] = raw_oid[i]; + } +} + +//=============[Oid::~Oid]============================================== +// destructor +// +// free up the descriptor space +Oid::~Oid() +{ + // free up the octet deep memory + if ( smival.value.oid.ptr ) { + set_invalid(); + } + + // free up the output string + if ( iv_str != 0) + delete [] iv_str; +} + + +//=============[Oid::operator = const char * dotted_string ]============== +// assignment to a string operator overloaded +// +// free the existing oid +// create the new oid from the string +// return this object +void Oid::set_data( const char *dotted_oid_string) +{ + // delete the old value + if ( smival.value.oid.ptr ) { + set_invalid(); + } + + // assign the new value + size_t byte_counter; + if (StrToOid( (char *) dotted_oid_string, &smival.value.oid, byte_counter) <0) + set_invalid(); +} + + +//=============[Oid:: operator = const Oid &oid ]========================== +// assignment to another oid object overloaded +// +// free the existing oid +// create a new one from the object passed in +// TODO: measure perf vs memory of no realloc in case where len >= oid.len +Oid& Oid::operator=( const Oid &oid) +{ + // protect against assignment from self + if ( this == &oid) + return *this; + + set_invalid(); + + // check for zero len on source + if ( oid.smival.value.oid.len == 0) + return *this; + + const SmiLPOID srcOid = (SmiLPOID) &(oid.smival.value.oid); + init_value(srcOid, oid.smival.value.oid.len); + return *this; +} + +// assign this object the oid, set to invalid if copy fails +void Oid::init_value(const SmiLPOID srcOid, size_t len) +{ + // allocate some memory for the oid + ACE_NEW(smival.value.oid.ptr, SmiUINT32[ len]); + size_t byte_counter; + OidCopy( srcOid, (SmiLPOID) &smival.value.oid, byte_counter); +} + +void Oid::init_value(const unsigned long *raw_oid, size_t oid_len) +{ + if (smival.value.oid.ptr) + delete [] smival.value.oid.ptr; + + ACE_NEW(smival.value.oid.ptr, SmiUINT32[ oid_len]); + ACE_OS::memcpy((SmiLPBYTE) smival.value.oid.ptr, + (SmiLPBYTE) raw_oid, + (size_t) (oid_len * sizeof(SmiUINT32))); + smival.value.oid.len = oid_len; +} + +//==============[Oid:: operator += const char *a ]========================= +// append operator, appends a string +// +// allocate some space for a max oid string +// extract current string into space +// concat new string +// free up existing oid +// make a new oid from string +// delete allocated space +Oid& Oid::operator+=( const char *a) +{ + unsigned long n; + + if (!a) + return *this; + + if ( *a=='.') + a++; + size_t sz = ACE_OS::strlen(a); + + if (valid()) { + n = (smival.value.oid.len *SNMPCHARSIZE) + smival.value.oid.len + 1 + sz; + char *ptr; + ACE_NEW_RETURN(ptr, char[ n], *this); + size_t byte_counter; + if (OidToStr(&smival.value.oid, n,ptr, byte_counter) > 0) { + delete [] ptr; + set_invalid(); + return *this; + } + + if (ACE_OS::strlen(ptr)) + ACE_OS::strcat(ptr,"."); + ACE_OS::strcat(ptr,a); + if ( smival.value.oid.len !=0) { + set_invalid(); + } + + if (StrToOid( (char *) ptr, &smival.value.oid, byte_counter) < 0) { + set_invalid(); + } + delete [] ptr; + } + else { + size_t byte_counter; + if (StrToOid( (char *) a, &smival.value.oid, byte_counter) < 0) { + set_invalid(); + } + } + + return *this; +} + +//=============[ bool operator == oid,oid ]================================= +// equivlence operator overloaded +bool operator==( const Oid &lhs, const Oid &rhs) +{ + // ensure same len, then use left_comparison + if (rhs.length() != lhs.length()) + return false; + if( lhs.left_comparison( rhs.length(), rhs) == 0) + return true; + else + return false; +} + +//==============[ bool operator!=( Oid &x,Oid &y) ]======================= +//not equivlence operator overloaded +bool operator!=( const Oid &lhs,const Oid &rhs) +{ + return (!(lhs == rhs)); +} + +//==============[ bool operator<( Oid &x,Oid &y) ]======================== +// less than < overloaded +bool operator<( const Oid &lhs,const Oid &rhs) +{ + int result; + + // call left_comparison with the current + // Oidx, Oidy and len of Oidx + if ((result = lhs.left_comparison( rhs.length(), rhs)) < 0) + return true; + else if (result > 0) + return false; + + else{ + // if here, equivalent substrings, call the shorter one < + if (lhs.length() < rhs.length()) + return true; + else + return false; + } +} + +//==============[ bool operator<=( Oid &x,Oid &y) ]======================= +// less than <= overloaded +bool operator<=( const Oid &x,const Oid &y) +{ + if ( (x < y) || (x == y) ) + return true; + else + return false; +} + +//==============[ bool operator>( Oid &x,Oid &y) ]======================== +// greater than > overloaded +bool operator>( const Oid &x,const Oid &y) +{ + // just invert existing <= + if (!(x<=y)) + return true; + else + return false; +} + +//==============[ bool operator>=( Oid &x,Oid &y) ]======================= +// greater than >= overloaded +bool operator>=( const Oid &x,const Oid &y) +{ + // just invert existing < + if (!(x<y)) + return true; + else + return false; +} + +//===============[Oid::oidval ]============================================= +// return the WinSnmp oid part +SmiLPOID Oid::oidval() +{ + return (SmiLPOID) &smival.value.oid; +} + +//===============[Oid::set_data ]==---===================================== +// copy data from raw form... +void Oid::set_data( const unsigned long *raw_oid, const size_t oid_len) +{ + if (smival.value.oid.len < oid_len) { + if ( smival.value.oid.ptr) { + set_invalid(); + } + } + init_value(raw_oid, oid_len); +} + + +//===============[Oid::len ]================================================ +// return the len of the oid +size_t Oid::length() const +{ + return smival.value.oid.len; +} + +//===============[Oid::trim( unsigned int) ]============================ +// trim off the n leftmost values of an oid +// Note!, does not adjust actual space for +// speed +void Oid::trim( const size_t n) +{ + // verify that n is legal + if ((n<=smival.value.oid.len)&&(n>0)) { + smival.value.oid.len -= n; + + if (smival.value.oid.len == 0) { + set_invalid(); + } + } +} + +//===============[Oid::set_invalid() ]==================== +// make this object invalid by resetting all values +void Oid::set_invalid() { + delete [] smival.value.oid.ptr; + smival.value.oid.ptr = 0; + smival.value.oid.len = 0; + delete [] iv_str; + iv_str = 0; +} + +//===============[Oid::set_null() ]==================== +void Oid::set_null() { + smival.syntax = sNMP_SYNTAX_OID; + smival.value.oid.ptr = 0; + smival.value.oid.len = 0; + iv_str = 0; +} + +//===============[Oid::operator += const unsigned int) ]==================== +// append operator, appends an int +// +// allocate some space for a max oid string +// extract current string into space +// concat new string +// free up existing oid +// make a new oid from string +// delete allocated space +Oid& Oid::operator+=( const unsigned long i) +{ + unsigned long n = (smival.value.oid.len * SNMPCHARSIZE) + + ( smival.value.oid.len -1) + 1 + 4; + char buffer[SNMPBUFFSIZE]; + + // two cases: null oid, existing oid + if (valid()) { + // allocate some temporary space + char *ptr; + ACE_NEW_RETURN(ptr, char[ n], *this); + size_t byte_counter; + if (OidToStr(&smival.value.oid, n, ptr, byte_counter) < 0) { + set_invalid(); + delete [] ptr; + return *this; + } + + if (ACE_OS::strlen(ptr)) + ACE_OS::strcat(ptr,"."); + + if (ACE_OS::sprintf( buffer,"%lu",i) != -1) { + ACE_OS::strcat(ptr, buffer); + if ( smival.value.oid.ptr ) { + set_invalid(); + } + if (StrToOid( (char *) ptr, &smival.value.oid, byte_counter) < 0) { + set_invalid(); + } + delete [] ptr; + } + } + else { + init_value((const unsigned long *)&i, (size_t)1); + } + + return *this; +} + +//===============[Oid::operator += const Oid) ]======================== +// append operator, appends an Oid +// +// allocate some space for a max oid string +// extract current string into space +// concat new string +// free up existing oid +// make a new oid from string +// delete allocated space +Oid& Oid::operator+=( const Oid &o) +{ + SmiLPUINT32 new_oid; + + if (o.smival.value.oid.len == 0) + return *this; + + ACE_NEW_RETURN(new_oid, + SmiUINT32[ smival.value.oid.len + o.smival.value.oid.len], *this); + if (smival.value.oid.ptr) { + ACE_OS::memcpy((SmiLPBYTE) new_oid, + (SmiLPBYTE) smival.value.oid.ptr, + (size_t) (smival.value.oid.len*sizeof(SmiUINT32))); + + delete [] smival.value.oid.ptr; + } + + // out with the old, in with the new... + smival.value.oid.ptr = new_oid; + + ACE_OS::memcpy((SmiLPBYTE) &new_oid[smival.value.oid.len], + (SmiLPBYTE) o.smival.value.oid.ptr, + (size_t) (o.smival.value.oid.len*sizeof(SmiUINT32))); + + smival.value.oid.len += o.smival.value.oid.len; + return *this; +} + +// return string portion of the oid +// +const char * Oid::to_string() +{ + unsigned long n; + if (!valid()) + return ""; // be consistent with other classes + + // the worst case char len of an oid can be.. + // oid.len*3 + dots in between if each oid is XXXX + // so.. size = (len*4) + (len-1) + 1 , extra for a null + + n = (smival.value.oid.len *SNMPCHARSIZE) + ( smival.value.oid.len -1) + 1 ; + if (n == 0) + n = 1; // need at least 1 byte for a null string + + // adjust the len of output array in case size was adjusted + if ( iv_str != 0) + delete [] iv_str; + // allocate some space for the output string + ACE_NEW_RETURN(iv_str, char[ n], ""); + + // convert to an output string + size_t how_many; + if ( valid() && iv_str != 0) + if (OidToStr(&smival.value.oid,n,iv_str, how_many) < 0) + return "ERROR: Oid::OidToStr failed"; + return iv_str; +} + +//==============[Oid::suboid( unsigned int start, n) ]============= +int Oid::suboid(Oid& new_oid, size_t start, size_t how_many) +{ + if (how_many == 0) + return 0; + else + if (how_many == (size_t)-1) + how_many = length(); + else + if (how_many > length()) + how_many = length(); + + // reset new_oid + new_oid.set_invalid(); + + size_t new_size = how_many - start; + if (new_size == 0) + new_size++; + new_oid.smival.value.oid.len = new_size; + ACE_NEW_RETURN(new_oid.smival.value.oid.ptr, + SmiUINT32 [ new_oid.smival.value.oid.len], -1); + // copy source to destination + ACE_OS::memcpy( (SmiLPBYTE) new_oid.smival.value.oid.ptr, + (SmiLPBYTE) (smival.value.oid.ptr + start), + new_size * sizeof(SmiLPBYTE)); + return 0; +} + + +//=============[Oid::StrToOid( char *string, SmiLPOID dst) ]============== +// convert a string to an oid +int Oid::StrToOid( const char *string, SmiLPOID dstOid, size_t& how_many) +{ + size_t index = 0; + size_t number = 0; + + // make a temp buffer to copy the data into first + SmiLPUINT32 temp; + unsigned long nz; + + if (string && *string) { + nz = ACE_OS::strlen( string); + } + else { + dstOid->len = 0; + dstOid->ptr = 0; + return -1; + } + + ACE_NEW_RETURN(temp, SmiUINT32[ nz], -1); + while (*string!=0 && index<nz) { + // init the number for each token + number = 0; + // skip over the dot + if (*string=='.') + string++; + + // grab a digit token and convert it to a long int + while (isdigit(*string)) + number=number*10 + *(string++)-'0'; + + // check for invalid chars + if (*string!=0 && *string!='.') { + // Error: Invalid character in string + delete [] temp; + return -1; + } + + // stuff the value into the array + temp[index] = number; + index++; // bump the counter + } + + + // get some space for the real oid + ACE_NEW_RETURN(dstOid->ptr, SmiUINT32[ index], -1); + // TODO: make tmp autoptr type delete [] temp to prevent leak + + // copy in the temp data + ACE_OS::memcpy((SmiLPBYTE) dstOid->ptr, (SmiLPBYTE) temp, + (size_t) (index*sizeof(SmiUINT32))); + + // set the len of the oid + dstOid->len = index; + + // free up temp data + delete [] temp; + + how_many = index; + return 0; +} + + +//===============[Oid::OidCopy( source, destination) ]==================== +// Copy an oid, return bytes copied +int Oid::OidCopy( SmiLPOID srcOid, SmiLPOID dstOid, size_t& how_many_bytes) +{ + // check source len ! zero + if (srcOid->len == 0) + return -1; + + // copy source to destination + ACE_OS::memcpy((SmiLPBYTE) dstOid->ptr, + (SmiLPBYTE) srcOid->ptr, + (size_t) (srcOid->len * sizeof(SmiUINT32))); + + //set the new len + dstOid->len = srcOid->len; + how_many_bytes = srcOid->len; + + return 0; +} + + +//===============[Oid::left_comparison( n, Oid) ]================================= +// compare the n leftmost values of two oids ( left-to_right ) +// +// self == Oid then return 0, they are equal +// self < Oid then return -1, < +// self > Oid then return 1, > +int Oid::left_comparison( const unsigned long n, const Oid &o) const +{ + unsigned long z; + unsigned long len = n; + int reduced_len = 0; + + // 1st case they both are null + if (( len==0)&&( this->smival.value.oid.len==0)) + return 0; // equal + + // verify that n is valid, must be >= 0 + if ( len <=0) + return 1; // ! equal + + // only compare for the minimal length + if (len > this->smival.value.oid.len) { + len = this->smival.value.oid.len; + reduced_len = 1; + } + if (len > o.smival.value.oid.len) { + len = o.smival.value.oid.len; + reduced_len = 1; + } + + z = 0; + while(z < len) { + if ( this->smival.value.oid.ptr[z] < o.smival.value.oid.ptr[z]) + return -1; // less than + if ( this->smival.value.oid.ptr[z] > o.smival.value.oid.ptr[z]) + return 1; // greater than + z++; + } + + // if we truncated the len then these may not be equal + if (reduced_len) { + if (this->smival.value.oid.len < o.smival.value.oid.len) + return -1; + if (this->smival.value.oid.len > o.smival.value.oid.len) + return 1; + } + return 0; // equal + +} + + +//===============[Oid::left_comparison( n, Oid) ]================================= +// compare the n rightmost bytes (right-to-left) +// returns 0, equal +// returns -1, < +// returns 1 , > +int Oid::right_comparison( const unsigned long n, const Oid &o) const +{ + // oid to compare must have at least the same number + // of sub-ids to comparison else the argument Oid is + // less than THIS + if ( o.length() < n) + return -1; + + // also can't compare argument oid for sub-ids which + // THIS does not have + if ( this->length() < n) + return -1; + + int start = (int) this->length(); + int end = (int) start - (int) n; + for ( int z=start;z< end;z--) + { + if ( o.smival.value.oid.ptr[z] < this->smival.value.oid.ptr[z]) + return -1; + if ( o.smival.value.oid.ptr[z] > this->smival.value.oid.ptr[z]) + return 1; + } + + return 0; // they are equal + +} + + +//================[ Oid::valid() ]======================================== +// is the Oid object valid +// returns validity +int Oid::valid() const +{ + return ( smival.value.oid.ptr ? 1 : 0 ); +} + +//================[Oid::OidToStr ]========================================= +// convert an oid to a string +int Oid::OidToStr( SmiLPOID srcOid, unsigned long size, + char *string, size_t& how_many_bytes) +{ + unsigned long index = 0; + unsigned totLen = 0; + char szNumber[SNMPBUFFSIZE]; + + // init the string + string[totLen] = 0; + + // verify there is something to copy + if (srcOid->len == 0) + return -1; + + // loop through and build up a string + for (index=0; index < srcOid->len; index++) { + + // convert data element to a string + if (ACE_OS::sprintf( szNumber,"%lu", srcOid->ptr[index]) == -1) + return -1; + + // verify len is not over + if (totLen + ACE_OS::strlen(szNumber) + 1 >= size) + return -2; + + // if not at end, pad with a dot + if (totLen!=0) + string[totLen++] = '.'; + + // copy the string token into the main string + ACE_OS::strcpy(string + totLen, szNumber); + + // adjust the total len + totLen += ACE_OS::strlen(szNumber); + } + + how_many_bytes = totLen + 1; + return 0; +} + + +//================[ general Value = operator ]======================== +SnmpSyntax& Oid::operator=( SnmpSyntax &val) +{ + // protect against assignment from self + if ( this == &val ) + return *this; + + // blow away old value + smival.value.oid.len = 0; + if (smival.value.oid.ptr) { + set_invalid(); + } + + // assign new value + if (val.valid()) { + switch (val.get_syntax()) { + case sNMP_SYNTAX_OID: + set_data( ((Oid &)val).smival.value.oid.ptr, + (unsigned int)((Oid &)val).smival.value.oid.len); + break; + } + } + return *this; +} + +//================[ [] operator ]===================================== +unsigned long& Oid::operator[](size_t position) +{ + return smival.value.oid.ptr[position]; +} + +//================[ clone ]=========================================== +SnmpSyntax *Oid::clone() const +{ + return (SnmpSyntax *) new Oid(*this); +} diff --git a/ACE/ASNMP/asnmp/oid.h b/ACE/ASNMP/asnmp/oid.h new file mode 100644 index 00000000000..77118b518f0 --- /dev/null +++ b/ACE/ASNMP/asnmp/oid.h @@ -0,0 +1,175 @@ + + +#ifndef OID_CLS_ +#define OID_CLS_ +//============================================================================= +/** + * @file oid.h + * + * $Id$ + * + * This class is fully contained and does not rely on or any other + * SNMP libraries. This class is portable across any platform + * which supports C++. Ported to ACE by Mike MacFaden mrm@cisco.com + * and modified for MT. Some API cleanup: collapse constructors, + * add suboid() method remove unnecessary overload, and update a few + * names and types to improve clarity. + * + * + * @author Peter E Mellquist + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +//----------[ extern C libraries Needed ]--------------------------------- +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "asnmp/smival.h" // derived class for all values + +/** + * @class Oid + * + * @brief Implement RFC 1155 Object Identifier (OID) datatype + */ +class ASNMP_Export Oid : public SnmpSyntax +{ +public: + /// constructor using a dotted string + Oid( const char * dotted_oid_string = "", size_t size = unsigned(-1) ); + + /// constructor using another oid object + Oid ( const Oid &oid); + + /// constructor from raw form + Oid(const unsigned long *raw_oid, size_t oid_len); + + /// destructor + ~Oid(); + + /// syntax type + SmiUINT32 get_syntax(); + + /// assignment to another oid object overloaded + Oid& operator=( const Oid &oid); + + /// equal operator overloaded + friend ASNMP_Export bool operator==( const Oid &lhs,const Oid &rhs); + + /// not equal operator overloaded + friend ASNMP_Export bool operator!=( const Oid &lhs,const Oid &rhs); + + /// less than < overloaded + friend ASNMP_Export bool operator<( const Oid &lhs,const Oid &rhs); + + /// less than <= overloaded + friend ASNMP_Export bool operator<=( const Oid &lhs,const Oid &rhs); + + /// greater than > overloaded + friend ASNMP_Export bool operator>( const Oid &lhs,const Oid &rhs); + + /// greater than >= overloaded + friend ASNMP_Export bool operator>=( const Oid &lhs,const Oid &rhs); + + /// append operator, appends a string + Oid& operator+=( const char *a); + + /// appends an int + Oid& operator+=( const unsigned long i); + + /// appends an Oid + Oid& operator+=( const Oid &o); + + /// allows element access + unsigned long & operator[]( size_t position); + + /// return the WinSnmp oid part + SmiLPOID oidval(); + + /// reset the data from raw 1 byte format + void set_data( const char *dotted_oid_string); + + /// reset the data from raw 4byte integer format + void set_data( const unsigned long *raw_oid, const size_t oid_len); + + /// return the len of the oid + size_t length() const; + + /// trim off the n rightmost values of an oid + void trim( const size_t how_many = 1); + + /// the equivalent of a substr(new_str, 0, 1) + int suboid(Oid& oid, size_t start = 0, size_t how_many = size_t (-1)); + + /** + * compare the n leftmost bytes (left-to-right) + * returns 0, equal + * returns -1, < + * returns 1 , > + */ + int left_comparison( const unsigned long n, const Oid &o) const; + + + /** + * compare the n rightmost bytes (right-to-left) + * returns 0, equal + * returns -1, < + * returns 1 , > + */ + int right_comparison( const unsigned long n, const Oid &o) const; + + /// is the Oid object valid + int valid() const; + + /// return dotted string value from the right + /// where the user specifies how many positions to print + const char *to_string(); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// copy an instance of this Value + SnmpSyntax& operator=( SnmpSyntax &val); + +protected: + /// used for returning oid string + char *iv_str; + + /// convert a string to an smi oid + int StrToOid( const char *string, SmiLPOID dstOid, size_t& how_many_bytes); + + /// clone an smi oid + int OidCopy( SmiLPOID srcOid, SmiLPOID dstOid, size_t& how_many_bytes); + + /// convert an smi oid to its string representation + int OidToStr(SmiLPOID srcOid, SmiUINT32 size, char *string, size_t& how_many_bytes); + + private: + /// release memory, re-init data members + void set_invalid(); + + /// initialize object data members + void set_null(); + void init_value( const SmiLPOID srcOid, size_t len); + void init_value(const unsigned long *raw_oid, size_t oid_len); +}; + +#endif //OID_CLS_ diff --git a/ACE/ASNMP/asnmp/oid_def.h b/ACE/ASNMP/asnmp/oid_def.h new file mode 100644 index 00000000000..31ccbfa3e4a --- /dev/null +++ b/ACE/ASNMP/asnmp/oid_def.h @@ -0,0 +1,84 @@ +/* -*-C++-*- */ +#ifndef OID_DEF +#define OID_DEF +//============================================================================= +/** + * @file oid_def.h + * + * $Id$ + * + * Well known Oids defined in RFC 1215 + * + * + * @author Peter E Mellquist + */ +//============================================================================= + +/*=================================================================== + + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +// SMI trap oid def +class snmpTrapsOid: public Oid { + public: + snmpTrapsOid (void):Oid("1.3.6.1.6.3.1.1.5"){}; +}; + +// SMI Enterprose Oid +class snmpTrapEnterpriseOid: public Oid { + public: + snmpTrapEnterpriseOid(void):Oid("1.3.6.1.6.3.1.1.4.3.0"){}; +}; + +// SMI Cold Start Oid +class coldStartOid: public snmpTrapsOid { + public: + coldStartOid( void){*this+=".1";}; +}; + +// SMI WarmStart Oid +class warmStartOid: public snmpTrapsOid { + public: + warmStartOid( void){*this+=".2";}; +}; + +// SMI LinkDown Oid +class linkDownOid: public snmpTrapsOid { + public: + linkDownOid( void){*this+=".3";}; +}; + + +// SMI LinkUp Oid +class linkUpOid: public snmpTrapsOid { + public: + linkUpOid( void){*this+=".4";}; +}; + +// SMI Authentication Failure Oid +class authenticationFailureOid: public snmpTrapsOid { + public: + authenticationFailureOid( void){*this+=".5";}; +}; + +// SMI egpneighborloss Oid +class egpNeighborLossOid: public snmpTrapsOid { + public: + egpNeighborLossOid( void){*this+=".6";}; +}; + + +#endif // OID_DEF diff --git a/ACE/ASNMP/asnmp/pdu.cpp b/ACE/ASNMP/asnmp/pdu.cpp new file mode 100644 index 00000000000..cbe67dcbbab --- /dev/null +++ b/ACE/ASNMP/asnmp/pdu.cpp @@ -0,0 +1,499 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// pdu.cpp +// +// = DESCRIPTION +// Pdu class implementation. Encapsulation of an SMI Protocol +// Data Unit (PDU) in C++. +// +// = AUTHOR +// Peter E Mellquist +// Michael R MacFaden mrm@cisco.com - rework & ACE port +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/snmp.h" +#include "asnmp/pdu.h" // include Pdu class definition +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID(asnmp, pdu, "$Id$") + +//=====================[ constructor no args ]========================= +Pdu::Pdu( void): vb_count_(0), error_status_(0), error_index_(0), +validity_(0), request_id_(0), pdu_type_(0), notify_timestamp_(0), +output_(0) +{ +} + +//=====================[ constructor with vbs_ and count ]============== +Pdu::Pdu( Vb* pvbs, const int pvb_count): vb_count_(0), error_index_(0), +validity_(0), request_id_(0), pdu_type_(0), notify_timestamp_(0), +output_(0) +{ + int z = 0; // looping variable + + // zero is ok + if ( pvb_count == 0) { + validity_ = 1; + return; + } + + // check for over then max + if ( pvb_count > MAX_VBS) { + validity_ = 0; + return; + } + + // loop through and assign internal vbs_ + for (z = 0;z < pvb_count; z++) { + validity_ = 0; + ACE_NEW(vbs_[z], Vb( pvbs[z])); + validity_ = 1; + } + + // assign the vb count + vb_count_ = pvb_count; + + validity_ = 1; +} + +//=====================[ constructor with another Pdu instance ]======== +Pdu::Pdu( const Pdu &pdu): vb_count_(0), +error_index_(0), validity_(0), request_id_(0), pdu_type_(0), +notify_timestamp_(0), output_(0) +{ + *this = pdu; + return; +} + +//=====================[ destructor ]==================================== +Pdu::~Pdu() +{ + delete_all_vbs(); + delete [] output_; +} + + +//=====================[ assignment to another Pdu object overloaded ]=== +Pdu& Pdu::operator=( const Pdu &pdu) +{ + int z; // looping variable + + // Initialize all mv's + error_status_ = pdu.error_status_; + error_index_ = pdu.error_index_; + request_id_ = pdu.request_id_; + pdu_type_ = pdu.pdu_type_; + notify_id_ = pdu.notify_id_; + notify_timestamp_ = pdu.notify_timestamp_; + notify_enterprise_ = pdu.notify_enterprise_; + validity_ = 1; + + // free up old vbs_ + for ( z = 0;z < vb_count_; z++) + delete vbs_[z]; + vb_count_ = 0; + + // check for zero case + if ( pdu.vb_count_ == 0) { + return *this; + } + + // loop through and fill em up + for (z = 0; z < pdu.vb_count_; z++) { + validity_ = 0; + ACE_NEW_RETURN(vbs_[z], Vb ( *(pdu.vbs_[z])), *this); + validity_ = 1; + } + + vb_count_ = pdu.vb_count_; + return *this; +} + +// append operator, appends a string +Pdu& Pdu::operator+=( Vb &vb) +{ + + // do we have room? + if ( vb_count_ + 1 > MAX_VBS) + return *this; + + // add the new one + validity_ = 0; + ACE_NEW_RETURN(vbs_[vb_count_], Vb (vb), *this); + // set up validity_ + validity_ = 1; + + // up the vb count + vb_count_++; + + // return self reference + return *this; + +} + +// return fomatted version of this object +const char * Pdu::to_string() +{ + // determine how big a buffer and allocate it + const int HEADER_STR = 100; + unsigned size = HEADER_STR; // header takes up this much room + int z; + + for ( z = 0; z < vb_count_; z++) + size += ACE_OS::strlen(vbs_[z]->to_string()); + + ACE_NEW_RETURN(output_, char[size], ""); + + // print pdu header info + sprintf(output_, "pdu: valid: %d type:%d, req:%d, cnt: %d, err stat: %d \ + err idx: %d\n", validity_, pdu_type_, (int) request_id_, + vb_count_, error_status_, error_index_ ); + + // now append vb pairs in this object + for ( z = 0; z < vb_count_; z++) { + ACE_OS::strcat(output_, vbs_[z]->to_string()); + ACE_OS::strcat(output_, "\n\t"); + } + + return output_; +} + + +//=====================[ extract Vbs from Pdu ]========================== +// how do you know that the caler has enough memory??? +// should I self allocate this in here and require the +// caller then to free it up at soem later time +int Pdu::get_vblist( Vb* pvbs, const int pvb_count) +{ + if ((!pvbs) || ( pvb_count < 0) || ( pvb_count > vb_count_)) + return 0; + + // loop through all vbs_ and assign to params + int z; + for (z = 0; z < pvb_count; z++) + pvbs[z] = *vbs_[z]; + + return 1; + +} + +//=====================[ deposit Vbs ]=================================== +int Pdu::set_vblist( Vb* pvbs, const int pvb_count) +{ + + // if invalid then don't destroy + if ((!pvbs) || ( pvb_count < 0) || ( pvb_count > MAX_VBS)) + return 0; + + // free up current vbs_ + int z; + for ( z = 0; z < vb_count_; z++) + delete vbs_[z]; + vb_count_ = 0; + + // check for zero case + if ( pvb_count == 0) { + validity_ = 1; + error_status_ = 0; + error_index_ = 0; + request_id_ = 0; + return 0; + } + + + // loop through all vbs_ and reassign them + for ( z = 0; z < pvb_count; z++) { + validity_ = 0; + ACE_NEW_RETURN(vbs_[z], Vb (pvbs[z]), 0); + validity_ = 1; + } + + vb_count_ = pvb_count; + + // clear error status and index since no longer valid + // request id may still apply so don't reassign it + error_status_ = 0; + error_index_ = 0; + validity_ = 1; + + return 1; +} + +//===================[ get a particular vb ]============================= +// here the caller has already instantiated a vb object +// index is zero based +int Pdu::get_vb( Vb &vb, const int index) const +{ + // can't have an index less than 0 + if ( index < 0) + return 0; + + // can't ask for something not there + if ( index > (vb_count_ - 1)) + return 0; + + // asssign it + vb = *vbs_[index]; + + return 1; +} + +//===================[ set a particular vb ]============================= +int Pdu::set_vb( Vb &vb, const int index) +{ + // can't set a vb at index less than 0 + if ( index < 0) + return 0; + + // can't ask for something not there + if ( index > (vb_count_ - 1)) + return 0; + + // delete what is there + delete vbs_[index]; + + // assign it + validity_ = 0; + ACE_NEW_RETURN(vbs_[index], Vb (vb), 0); + validity_ = 1; + + return 1; + +} + +//=====================[ return number of vbs_ ]========================== +int Pdu::get_vb_count() const +{ + return vb_count_; +} + +//=====================[ return the error status ]======================= +int Pdu::get_error_status() const +{ + return error_status_; +} + +const char *Pdu::agent_error_reason() +{ + int pdu_err = get_error_status(); + if (pdu_err == 0) // any real error? + return "not in error state"; + + int n_vbs = get_vb_count(); + Vb bad; + get_vb(bad, get_error_index() -1); // not zero based?? + const char *pmsg = Snmp::error_string(get_error_status()); + const char *id = bad.to_string_oid(); + const char *val = bad.to_string_value(); + const int HDR_SZ = 100; + + if (!output_) { + int size = ACE_OS::strlen(pmsg) + ACE_OS::strlen(id) + + ACE_OS::strlen(val); + ACE_NEW_RETURN(output_, char[size + HDR_SZ], ""); + } + + ACE_OS::sprintf(output_, + "FAIL PDU REPORT: pdu id: %lu vb cnt: %d vb idx: %d\n" + " msg: %s vb oid: %s value: %s\n", + get_request_id(), n_vbs, get_error_index(), + pmsg, id, val); + + return output_; +} + +//=====================[ set the error status ]========================== +// friend +void set_error_status( Pdu *pdu, const int status) +{ + if (pdu) + pdu->error_status_ = status; +} + +//=====================[ return the error index ]======================== +int Pdu::get_error_index() const +{ + return error_index_; +} + +//=====================[ set the error index ]=========================== +// friend +void set_error_index( Pdu *pdu, const int index) +{ + if (pdu) + pdu->error_index_ = index; +} + +//=====================[ clear error status ]============================= +void clear_error_status( Pdu *pdu) +{ + if (pdu) + pdu->error_status_ = 0; +} + +//=====================[ clear error index ]============================== +void clear_error_index( Pdu *pdu) +{ + if (pdu) + pdu->error_index_ = 0; +} + +//=====================[ return the request id ]========================== +unsigned long Pdu::get_request_id() const +{ + return request_id_; +} + +//=====================[ set the request id ]============================= +// friend function +void set_request_id( Pdu *pdu, const unsigned long rid) +{ + if (pdu) + pdu->request_id_ = rid; +} + +//=====================[ returns validity_ of Pdu instance ]=============== +int Pdu::valid() const +{ + return validity_; +} + +//=====================[ get the pdu type ]=============================== +unsigned short Pdu::get_type()const +{ + return pdu_type_; +} + +// set the pdu type +void Pdu::set_type( unsigned short type) +{ + pdu_type_ = type; +} + + +// trim off the last vb +int Pdu::trim(const int p) +{ + int lp = p; + + // verify that lp is legal + if ( lp < 0 || lp > vb_count_) + return 0; + + while ( lp != 0) { + if ( vb_count_ > 0) { + delete vbs_[vb_count_ - 1]; + vb_count_--; + } + lp--; + } + return 1; +} + + + +// delete a Vb anywhere within the Pdu +int Pdu::delete_vb( const int p) +{ + // position has to be in range + if (( p < 0) || ( p > (vb_count_ - 1))) + return 0; + + // safe to remove it + delete vbs_[ p]; + + for ( int z=p;z < (vb_count_-1);z++) { + vbs_[z] = vbs_[z+1]; + } + vb_count_--; + + return 1; +} + +void Pdu::delete_all_vbs() +{ + for ( int z = 0; z < vb_count_; z++) + delete vbs_[z]; + vb_count_ = 0; +} + + +// set notify timestamp +void Pdu::set_notify_timestamp( const TimeTicks & timestamp) +{ + notify_timestamp_ = timestamp; +} + + +// get notify timestamp +void Pdu::get_notify_timestamp( TimeTicks & timestamp) const +{ + timestamp = notify_timestamp_; +} + +// set the notify id +void Pdu::set_notify_id( const Oid id) +{ + notify_id_ = id; +} + +// get the notify id +void Pdu::get_notify_id( Oid &id) const +{ + id = notify_id_; +} + +// set the notify enterprise +void Pdu::set_notify_enterprise( const Oid &enterprise) +{ + notify_enterprise_ = enterprise; +} + +// get the notify enterprise +void Pdu::get_notify_enterprise( Oid & enterprise) const +{ + enterprise = notify_enterprise_; +} + +// ------ class VbIter ------------------- +VbIter::VbIter(Pdu& pdu): idx_(-1), pdu_(&pdu) +{ +} + +// returns 1 if ok, else 0 if none left +int VbIter::next(Vb& vb) +{ + if (idx_ == -1) { + idx_ = 0; + pdu_->get_vb(vb, idx_++); + return 1; + } + else + if (idx_ < pdu_->get_vb_count()) { + pdu_->get_vb(vb, idx_++); + return 1; + } + return 0; // non left +} diff --git a/ACE/ASNMP/asnmp/pdu.h b/ACE/ASNMP/asnmp/pdu.h new file mode 100644 index 00000000000..a2d84388da0 --- /dev/null +++ b/ACE/ASNMP/asnmp/pdu.h @@ -0,0 +1,219 @@ +/* -*-C++-*- */ +#ifndef PDU_CLS_ +#define PDU_CLS_ +//============================================================================= +/** + * @file pdu.h + * + * $Id$ + * + * Pdu class definition. Encapsulation of an SMI Protocol + * Data Unit (PDU) aka Packet in C++. + * + * + * @author Peter E Mellquist original code Michael MacFaden mrm@cisco.com ACE port + * @author add iterator class for pdus + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +// TODO: this needs to be moved into the CLASS and modifyable at runtime +// TODO: define an iterator object to traverse the vbs in a pdu + +#define MAX_VBS 25 +#include "asnmp/vb.h" // include Vb class definition + +/** + * @class Pdu + * + * @brief Protocol Data Unit (PDU) concrete class. An abstraction of the + * data packet used to by two SNMP sessions to communicate. + */ +class ASNMP_Export Pdu +{ +public: + /// constructor no args + Pdu( void); + + /// constructor with vbs and count + Pdu( Vb* pvbs, const int pvb_count); + + /// constructor with another Pdu instance + Pdu( const Pdu &pdu); + + /// destructor + ~Pdu(); + + /// assignment to another Pdu object overloaded + Pdu& operator=( const Pdu &pdu); + + /// append a vb to the pdu + Pdu& operator+=( Vb &vb); + + // TODO: add Pdu& operator-=(const Vb &vb); + + /// extract all Vbs from Pdu + int get_vblist( Vb* pvbs, const int pvb_count); + + /// deposit all Vbs to Pdu + int set_vblist( Vb* pvbs, const int pvb_count); + + /// get a particular vb + /// where 0 is the first vb + int get_vb( Vb &vb, const int index = 0) const; + + /// set a particular vb + /// where 0 is the first vb + int set_vb( Vb &vb, const int index); + + /// return number of vbs + int get_vb_count() const; + + /// return the error status + int get_error_status() const; + + /// return the complete error info from this pdu + const char *agent_error_reason(); + + /// set the error status + friend ASNMP_Export void set_error_status( Pdu *pdu, const int status); + + /// return the error index + int get_error_index() const; + + /// set the error index + friend ASNMP_Export void set_error_index( Pdu *pdu, const int index); + + /// clear error status + friend ASNMP_Export void clear_error_status( Pdu *pdu); + + /// clear error index + friend ASNMP_Export void clear_error_index( Pdu *pdu); + + /// return the request id + unsigned long get_request_id() const; + + /// set the request id + friend void set_request_id( Pdu *pdu, const unsigned long rid); + + /// get the pdu type + unsigned short get_type() const; + + /// set the pdu type + void set_type( unsigned short type); + + /// returns validity of Pdu instance + int valid() const; + + /// trim off count vbs from the end of the vb list + int trim(const int count=1); + + /// delete a Vb anywhere within the Pdu + int delete_vb( const int position); + + /// delete_all vbs in pdu + void delete_all_vbs(); + + /// set notify timestamp + void set_notify_timestamp( const TimeTicks & timestamp); + + /// get notify timestamp + void get_notify_timestamp( TimeTicks & timestamp) const; + + /// set the notify id + void set_notify_id( const Oid id); + + /// get the notify id + void get_notify_id( Oid &id) const; + + /// set the notify enterprise + void set_notify_enterprise( const Oid &enterprise); + + /// get the notify enterprise + void get_notify_enterprise( Oid & enterprise) const; + + /// return fomatted version of this object + const char *to_string(); + + + protected: + /// pointer to array of Vbs + Vb *vbs_[MAX_VBS]; + + /// count of Vbs + int vb_count_; + + /// SMI error status + int error_status_; + + /// SMI error index + int error_index_; + + /// valid boolean status of object construction + /// SMI request id + int validity_; + unsigned long request_id_; + + /// derived at run time based on request type + unsigned short pdu_type_; + + /** + * a timestamp associated with an infor + * for notify Pdu objects only + * traps & notifies + */ + TimeTicks notify_timestamp_; + + /// an id + Oid notify_id_; + + Oid notify_enterprise_; + + private: + /// buffer for to_string() + char *output_; +}; + + +/** + * @class VbIter + * + * @brief Utility class to iterate once through a PDU varbind list + */ +class ASNMP_Export VbIter +{ + public: + /// default constructor + VbIter(Pdu& pdu); + + /// returns 1 if ok, else 0 if none left + int next(Vb& vb); + + private: + /// disallow copy constructor use + VbIter(const VbIter&); + + /// current object in list + int idx_; + + /// ptr to pdu being interated over + Pdu *pdu_; +}; + +#endif //PDU_CLS_ + diff --git a/ACE/ASNMP/asnmp/sagent.cpp b/ACE/ASNMP/asnmp/sagent.cpp new file mode 100644 index 00000000000..8ee2fdb5b8d --- /dev/null +++ b/ACE/ASNMP/asnmp/sagent.cpp @@ -0,0 +1,97 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// sagent.cpp +// +// = DESCRIPTION +// SNMP agent class definition. The sagent class provides an object oriented +// approach for creating SNMP Agents. The sagent class is an encapsulation +// of SNMP sessions, gets, sets, etc. +// +// = AUTHOR +// Michael R. MacFaden +// +// ============================================================================ +#include "ace/Reactor.h" +#include "ace/SOCK_Dgram.h" + +#include "asnmp/oid.h" // snmp++ oid class +#include "asnmp/vb.h" // snbmp++ vb class +#include "asnmp/target.h" // snmp++ target class +#include "asnmp/pdu.h" // snmp++ pdu class +#include "asnmp/snmperrs.h" // error macros and strings +#include "asnmp/address.h" // snmp++ address class defs +#include "asnmp/snmp.h" // manager snmp interface +#include "asnmp/sagent.h" // agent interface +#include "asnmp/transaction.h" // convert from wire to API + +ACE_RCSID(asnmp, sagent, "$Id$") + +sagent::sagent(unsigned short port): Snmp(port) +{ + ACE_TRACE("sagent::sagent(short)"); +} + +sagent::~sagent() +{ + ACE_TRACE("sagent::~sagent"); +} + +int sagent::handle_input(ACE_HANDLE fd) +{ + ACE_TRACE("sagent::handle_input"); + + transaction tr(iv_snmp_session_); // this section needs a better design + tr.handle_input(fd); + char rcv_com_str[MAX_COMM_STR_LEN]; + if (tr.result(pdu_, rcv_com_str) < 0) + return 0; + OctetStr community(rcv_com_str); + const ACE_INET_Addr &ta = tr.get_from_addr(); + ACE_TCHAR buf_tmp[MAXHOSTNAMELEN + 1]; + ta.addr_to_string (buf_tmp, MAXHOSTNAMELEN); + UdpAddress ra (ACE_TEXT_ALWAYS_CHAR (buf_tmp)); + tgt_.set_address(ra); + + + // process msg here by calling subclass's implementation + switch (pdu_.get_type()){ + case sNMP_PDU_GET: + tgt_.set_read_community(community); + this->handle_get(pdu_, tgt_); + break; + + case sNMP_PDU_GETNEXT: + tgt_.set_read_community(community); + this->handle_get_next(pdu_, tgt_); + break; + + case sNMP_PDU_SET: + tgt_.set_write_community(community); + this->handle_set(pdu_, tgt_); + break; + + default: + ACE_ASSERT(0); + } + return 0; +} + +ACE_HANDLE sagent::get_handle() const +{ + ACE_TRACE("sagent::get_handle"); + return iv_snmp_session_.get_handle(); +} + +int sagent::respond(Pdu& pdu,UdpTarget& tgt) +{ + pdu.set_type(sNMP_PDU_RESPONSE); + transaction tr(pdu, tgt, iv_snmp_session_); + tr.send(); + return 0; +} diff --git a/ACE/ASNMP/asnmp/sagent.h b/ACE/ASNMP/asnmp/sagent.h new file mode 100644 index 00000000000..d220c3ed459 --- /dev/null +++ b/ACE/ASNMP/asnmp/sagent.h @@ -0,0 +1,82 @@ +/* -*-C++-*- */ +#ifndef SAGENT_CLS_ +#define SAGENT_CLS_ +//============================================================================= +/** + * @file sagent.h + * + * $Id$ + * + * SNMP agent class defintion. The sagent class provides an object oriented + * approach for creating SNMP Agents. The sagent class is an encapsulation of SNMP + * sessions, gets, sets, etc. + * + * @author Michael R. MacFaden + */ +//============================================================================= + +#include "ace/Reactor.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SOCK_Dgram.h" + +#include "asnmp/oid.h" // snmp++ oid class +#include "asnmp/vb.h" // snbmp++ vb class +#include "asnmp/target.h" // snmp++ target class +#include "asnmp/pdu.h" // snmp++ pdu class +#include "asnmp/snmperrs.h" // error macros and strings +#include "asnmp/address.h" // snmp++ address class defs +#include "asnmp/snmp.h" // snmp interface + +// sagent - supports Version 1 operations in blocking mode + +#define DEF_AGENT_PORT (161) + +/** + * @class sagent + * + * @brief Concrete class sagent defines the session and interface to + * communicate with another SNMP Version 1 manager + */ +class ASNMP_Export sagent : public ACE_Event_Handler, private Snmp +{ + public: + + + // override the next three methods (callbacks) to implment your agent + // + + /// retrieve data from a peer agent for a given list of oid values + virtual int handle_get( Pdu &pdu, UdpTarget &target) = 0; + + /// retrieve data lexically adjacent to the oids specified in the pdu + /// from the peer agent + virtual int handle_get_next( Pdu &pdu, UdpTarget &target) = 0; + + /// set data in the agent from the list of oids in the pdu + virtual int handle_set( Pdu &pdu, UdpTarget &target) = 0; + + /// new pdu received from mgr (reactor calls this) + virtual int handle_input(ACE_HANDLE); + + /// retrieve io descriptor (reactor uses this) + virtual ACE_HANDLE get_handle() const; + + /// send a response pdu to the mgr + int respond(Pdu& pdu, UdpTarget& tgt); + + protected: + sagent(unsigned short port = DEF_AGENT_PORT); + virtual ~sagent(); + +private: + sagent(const sagent&); + Pdu pdu_; // current input pdu + UdpTarget tgt_; // addr & com strs +}; + +#endif //SAGENT_CLS_ + diff --git a/ACE/ASNMP/asnmp/smi.h b/ACE/ASNMP/asnmp/smi.h new file mode 100644 index 00000000000..3e505c64cb8 --- /dev/null +++ b/ACE/ASNMP/asnmp/smi.h @@ -0,0 +1,147 @@ +/* -*-C++-*- */ +#ifndef SMIDEF_ +#define SMIDEF_ +//============================================================================= +/** + * @file smi.h + * + * $Id$ + * + * Address class definition. Encapsulates various network + * addresses into easy to use, safe and portable classes. + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. + +=====================================================================*/ + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +//----------[ ASN/BER Base Types ]----------------------------------------- +// Basic Encoding Rules (BER) +// (used in forming SYNTAXes and certain SNMP types/values) +#define aSN_UNIVERSAL (0x00) +#define aSN_APPLICATION (0x40) +#define aSN_CONTEXT (0x80) +#define aSN_PRIVATE (0xC0) +#define aSN_PRIMITIVE (0x00) +#define aSN_CONSTRUCTOR (0x20) + +//------[ SNMP ObjectSyntax Values ]--------------------------------------- +#define sNMP_SYNTAX_SEQUENCE (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x10) + + +//------------------------------------------------------------------------- +// These values are used in the "syntax" member +// of the smiVALUE structure which follows. +// Note: UInt32 is indistinguishable from Gauge32 per SNMPv2 Draft Standard +// NsapAddr is obsoleted as unique SMI type per SNMPv2 Draft Standard +#define sNMP_SYNTAX_INT (aSN_UNIVERSAL | aSN_PRIMITIVE | 0x02) +#define sNMP_SYNTAX_BITS (aSN_UNIVERSAL | aSN_PRIMITIVE | 0x03) +#define sNMP_SYNTAX_OCTETS (aSN_UNIVERSAL | aSN_PRIMITIVE | 0x04) +#define sNMP_SYNTAX_NULL (aSN_UNIVERSAL | aSN_PRIMITIVE | 0x05) +#define sNMP_SYNTAX_OID (aSN_UNIVERSAL | aSN_PRIMITIVE | 0x06) +#define sNMP_SYNTAX_INT32 sNMP_SYNTAX_INT +#define sNMP_SYNTAX_IPADDR (aSN_APPLICATION | aSN_PRIMITIVE | 0x00) +#define sNMP_SYNTAX_CNTR32 (aSN_APPLICATION | aSN_PRIMITIVE | 0x01) +#define sNMP_SYNTAX_GAUGE32 (aSN_APPLICATION | aSN_PRIMITIVE | 0x02) +#define sNMP_SYNTAX_TIMETICKS (aSN_APPLICATION | aSN_PRIMITIVE | 0x03) +#define sNMP_SYNTAX_OPAQUE (aSN_APPLICATION | aSN_PRIMITIVE | 0x04) +#define sNMP_SYNTAX_CNTR64 (aSN_APPLICATION | aSN_PRIMITIVE | 0x06) +#define sNMP_SYNTAX_UINT32 (aSN_APPLICATION | aSN_PRIMITIVE | 0x07) + +//------------------------------------------------------------------------- + +//---------------[ Exception conditions for SNMPv2 ]----------------------- +// support SNMP v2 +#define sNMP_SYNTAX_NOSUCHOBJECT (aSN_CONTEXT | aSN_PRIMITIVE | 0x00) +#define sNMP_SYNTAX_NOSUCHINSTANCE (aSN_CONTEXT | aSN_PRIMITIVE | 0x01) +#define sNMP_SYNTAX_ENDOFMIBVIEW (aSN_CONTEXT | aSN_PRIMITIVE | 0x02) + + +//--------------[ different types of PDU's ]------------------------------- +#define sNMP_PDU_GET (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x0) +#define sNMP_PDU_GETNEXT (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x1) +#define sNMP_PDU_RESPONSE (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x2) +#define sNMP_PDU_SET (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x3) +#define sNMP_PDU_V1TRAP (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x4) +#define sNMP_PDU_GETBULK (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x5) +#define sNMP_PDU_INFORM (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x6) +#define sNMP_PDU_TRAP (aSN_CONTEXT | aSN_CONSTRUCTOR | 0x7) + + +//------[ smi typedefs ]--------------------------------------------------- +// SNMP-related types from RFC1442 (SMI) + +typedef unsigned char SmiBYTE, *SmiLPBYTE; + +//------------------------------------------------------------------------- +// SNMP-related types from RFC1442 (SMI) + +// int +typedef long SmiINT, *SmiLPINT; + +// int 32 +typedef SmiINT SmiINT32, *SmiLPINT32; + +// unit32 +typedef unsigned long SmiUINT32, *SmiLPUINT32; + +// octet struct +typedef struct { + SmiUINT32 len; + SmiLPBYTE ptr;} SmiOCTETS, *SmiLPOCTETS; + +// bits +typedef SmiOCTETS SmiBITS, *SmiLPBITS; + +// SMI oid struct +typedef struct { + SmiUINT32 len; + SmiLPUINT32 ptr;} SmiOID, *SmiLPOID; + +// ipaddr +typedef SmiOCTETS SmiIPADDR, *SmiLPIPADDR; + +// 32bit counter +typedef SmiUINT32 SmiCNTR32, *SmiLPCNTR32; + +// gauge +typedef SmiUINT32 SmiGAUGE32, *SmiLPGAUGE32; + +// timeticks +typedef SmiUINT32 SmiTIMETICKS, *SmiLPTIMETICKS; + +// opaque +typedef SmiOCTETS SmiOPAQUE, *SmiLPOPAQUE; + +// nsapaddr +typedef SmiOCTETS SmiNSAPADDR, *SmiLPNSAPADDR; + +// 64 bit counter +typedef struct { + SmiUINT32 hipart; + SmiUINT32 lopart; +} SmiCNTR64, *SmiLPCNTR64; + +#endif // SMIDEF_ + + diff --git a/ACE/ASNMP/asnmp/smival.h b/ACE/ASNMP/asnmp/smival.h new file mode 100644 index 00000000000..e754206f506 --- /dev/null +++ b/ACE/ASNMP/asnmp/smival.h @@ -0,0 +1,102 @@ +/* -*-C++-*- */ +#ifndef SMIVALUE_ +#define SMIVALUE_ +//============================================================================= +/** + * @file smival.h + * + * $Id$ + * + * SMIValue class definition. Superclass for the various types + * of SNMP values (Address, Oid, Octet, etc.). Provides + * only a few functions, most info is in subclass. + * + * + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +//----[ includes ]----------------------------------------------------- +#include "asnmp/smi.h" +#include "asnmp/ASNMP_Export.h" +#include "ace/os_include/os_stddef.h" + +//----[ macros ]------------------------------------------------------- + +//====================================================================== +// SMI value structure conforming with SMI RFC +// +typedef struct { /* smiVALUE portion of VarBind */ + SmiUINT32 syntax; /* Insert SNMP_SYNTAX_<type> */ + union { + SmiINT sNumber; /* SNMP_SYNTAX_INT + SNMP_SYNTAX_INT32 */ + SmiUINT32 uNumber; /* SNMP_SYNTAX_UINT32 + SNMP_SYNTAX_CNTR32 + SNMP_SYNTAX_GAUGE32 + SNMP_SYNTAX_TIMETICKS */ + SmiCNTR64 hNumber; /* SNMP_SYNTAX_CNTR64 */ + SmiOCTETS string; /* SNMP_SYNTAX_OCTETS + SNMP_SYNTAX_BITS + SNMP_SYNTAX_OPAQUE + SNMP_SYNTAX_IPADDR + SNMP_SYNTAX_NSAPADDR */ + SmiOID oid; /* SNMP_SYNTAX_OID */ + SmiBYTE empty; /* SNMP_SYNTAX_NULL + SNMP_SYNTAX_NOSUCHOBJECT + SNMP_SYNTAX_NOSUCHINSTANCE + SNMP_SYNTAX_ENDOFMIBVIEW */ + } value; +} SmiVALUE, *SmiLPVALUE; + +// An "abstract" (pure virtual) class that serves as the base class +// for all specific SNMP syntax types. +// +class ASNMP_Export SnmpSyntax { + +public: + virtual const char * to_string() = 0; + // virtual function for getting a printable ASCII value for any SNMP Value + + virtual SmiUINT32 get_syntax() = 0; + // return the current syntax + + virtual SnmpSyntax * clone() const = 0; + // virtual clone operation for creating a new Value from an existing + // value. The caller MUST use the delete operation on the return + // value when done. + + virtual ~SnmpSyntax() {}; + // virtual destructor to ensure deletion of derived classes... + + virtual SnmpSyntax& operator=(SnmpSyntax &/*val*/) + { + return *this; + } + // overloaded assignment operator + // This should be pure virtual, but WinNT compiler + // complains about unresolved reference at link time. + + virtual int valid() const = 0; + // return validity of value object. + +protected: + SmiVALUE smival; +}; + +#endif // SMIVALUE_ diff --git a/ACE/ASNMP/asnmp/snmp.cpp b/ACE/ASNMP/asnmp/snmp.cpp new file mode 100644 index 00000000000..cc2e1dd4179 --- /dev/null +++ b/ACE/ASNMP/asnmp/snmp.cpp @@ -0,0 +1,286 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// snmp.cpp +// +// = DESCRIPTION +// The basic SNMPv1 API - blocking version using UDP/IPv4 transport +// and addressing. +// +// = AUTHOR +// Peter E Mellquist class design/orig code +// Michael R MacFaden mrm@cisco.com / rework API, use ACE facilities +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + + +#define INCLUDE_SNMP_ERR_STRINGS_ + +//----[ snmp++ includes ]---------------------------------------------- +#include "asnmp/snmp.h" // class def for this module +#include "asnmp/oid.h" // class def for oids +#include "asnmp/enttraps.h" // class def for well known trap oids +#include "asnmp/vb.h" // class def for vbs +#include "asnmp/address.h" // class def for addresses +#include "asnmp/wpdu.h" // adapter to cmu_library / wire protocol +#include "asnmp/transaction.h" // synchronous transaction processor +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_time.h" + +ACE_RCSID(asnmp, snmp, "$Id$") + +const coldStartOid coldStart; +const warmStartOid warmStart; +const linkDownOid linkDown; +const linkUpOid linkUp; +const authenticationFailureOid authenticationFailure; +const egpNeighborLossOid egpNeighborLoss; +const snmpTrapEnterpriseOid snmpTrapEnterprise; + +char Snmp::host_name_[MAXHOSTNAMELEN] = ""; + +Snmp::Snmp(unsigned short port): result_(0), construct_status_(SNMP_CLASS_ERROR), last_transaction_status_(0) +{ + ACE_TRACE("Snmp::Snmp"); + + ACE_INET_Addr addr(port); // any port,address is ok + if (iv_snmp_session_.open(addr) < 0) { + last_transaction_status_ = errno; // open udp/ipv4 socket + ACE_DEBUG((LM_DEBUG, "Snmp::snmp::open port %d failed", port)); + return; + } + + // initial request id randomly generated then monotonically incremented + req_id_ = (unsigned) ACE_OS::time(0); + + construct_status_ = SNMP_CLASS_SUCCESS; + return; +} + +Snmp::~Snmp() +{ + ACE_TRACE("Snmp::~Snmp"); + iv_snmp_session_.close(); +} + +int Snmp::valid() const +{ + return construct_status_; +} + +// given error code, return string definition +// class version +// static +const char * Snmp::error_string(int last_transaction_status_) +{ + ACE_TRACE("Snmp::error_string"); + + return ((last_transaction_status_ < 0) ? + ((last_transaction_status_ < MAX_NEG_ERROR)? + nErrs[ abs(MAX_NEG_ERROR) + 1] : nErrs[abs(last_transaction_status_)]): + ((last_transaction_status_ > MAX_POS_ERROR)? + pErrs[MAX_POS_ERROR+1] : pErrs[last_transaction_status_])); +} + +// instance version +const char * Snmp::error_string() +{ + return Snmp::error_string(last_transaction_status_); +} + +void Snmp::check_default_port(UdpTarget& target, unsigned short port) +{ + UdpAddress tmp; + target.get_address(tmp); + if (tmp.get_port() == 0) { + tmp.set_port(port); + target.set_address(tmp); + } +} + +int Snmp::run_transaction(Pdu& pdu, UdpTarget& target) +{ + int rc, done = 0; + + // 1. set unique id to match this packet on return + size_t hold_req_id = req_id_++; + set_request_id(&pdu, hold_req_id); + + // 2. write request to agent + transaction trans(pdu, target, iv_snmp_session_); + + // this call blocks while it attempts to retrieve agent response + while (!done) { + if ((rc = trans.run()) < 0) { + last_transaction_status_ = rc; + return rc; + } + else { + trans.result(pdu); + // verify this is the pdu we are after + if (pdu.get_request_id() == hold_req_id) + done = 1 ; + } + } + return 0; +} + +int Snmp::run_transaction(Pdu& pdu, UdpTarget& target, Snmp_Result * cb) +{ + if (!cb) + return run_transaction(pdu, target); + + // 1. set unique id to match this packet on return + hold_req_id_ = req_id_++; + set_request_id(&pdu, hold_req_id_); + pdu_ = &pdu; + result_ = cb; + + // 2. write request to agent + transaction * trans = new transaction(pdu, target, iv_snmp_session_); + return trans->run(this); +} + +void Snmp::result(transaction *t, int rc) +{ + t->result(*pdu_); + // verify this is the pdu we are after + if (pdu_->get_request_id() == hold_req_id_) + { + last_transaction_status_ = rc; + delete t; + result_->result(this, rc); + } + else + { + rc = t->run(this); + if (rc < 0) + { + delete t; + result_->result(this, rc); + } + } +} + +int Snmp::validate_args(const Pdu& pdu, const UdpTarget& target) const +{ + // 0. check object status + if (construct_status_ != SNMP_CLASS_SUCCESS) + return construct_status_; + + // 1. check args passed + if ( !pdu.valid() || !target.valid() ) + return SNMP_INVALID_ARGS; + return 0; +} + +// SYNC API: write request to wire then wait for reply or timeout +int Snmp::get( Pdu &pdu, UdpTarget &target, Snmp_Result * cb) +{ + ACE_TRACE("Snmp::get"); + int rc; + if ((rc = validate_args(pdu, target)) != 0) + return rc; + + pdu.set_type( sNMP_PDU_GET); + check_default_port(target); + return run_transaction(pdu, target, cb); +} + +int Snmp::get_next( Pdu &pdu, UdpTarget &target, Snmp_Result * cb) +{ + ACE_TRACE("Snmp::get_next"); + int rc; + if ((rc = validate_args(pdu, target)) != 0) + return rc; + + pdu.set_type( sNMP_PDU_GETNEXT); + check_default_port(target); + return run_transaction(pdu, target, cb); +} + +int Snmp::set( Pdu &pdu, UdpTarget &target, Snmp_Result * cb) +{ + ACE_TRACE("Snmp::set"); + int rc; + if ((rc = validate_args(pdu, target)) != 0) + return rc; + + pdu.set_type( sNMP_PDU_SET); + check_default_port(target); + return run_transaction(pdu, target, cb); +} + +// one way, best of luck, non-confirmed alert +int Snmp::trap( Pdu &pdu, UdpTarget &target) +{ + ACE_TRACE("Snmp::trap"); + int rc; + if ((rc = validate_args(pdu, target)) != 0) + return rc; + + pdu.set_type( sNMP_PDU_V1TRAP); + check_default_port(target, DEF_TRAP_PORT); + + // 2. write request to agent + transaction trans(pdu, target, iv_snmp_session_); + if (trans.send() > 0) // expect number of bytes sent on + return 0; + + last_transaction_status_ = SNMP_CLASS_INTERNAL_ERROR; + return -1; +} + +// Allow host name to be overriden. Supplying a null pointer or zero +// length string removes the override. +void Snmp::override_host_name(const char* name) +{ + if (name) + { + ACE_OS::strncpy(host_name_, name, MAXHOSTNAMELEN); + host_name_[MAXHOSTNAMELEN-1] = 0; + } + else { + host_name_[0] = 0; + } +} + +// Returns the current host name in the supplied string. +void Snmp::get_host_name(char* name, int len) +{ + if (name) + { + if (ACE_OS::strlen(host_name_) > 0) + { + ACE_OS::strncpy(name, host_name_, len); + name[len-1] = 0; + } + else + { + if (ACE_OS::hostname(name, len-1) == -1) + name[0] = 0; + } + } +} + +Snmp_Result::~Snmp_Result() {} diff --git a/ACE/ASNMP/asnmp/snmp.h b/ACE/ASNMP/asnmp/snmp.h new file mode 100644 index 00000000000..5bae232baa0 --- /dev/null +++ b/ACE/ASNMP/asnmp/snmp.h @@ -0,0 +1,137 @@ +/* -*-C++-*- */ +#ifndef SNMP_CLS_ +#define SNMP_CLS_ +//============================================================================= +/** + * @file snmp.h + * + * $Id$ + * + * SNMP class defintion. The Snmp class provides an object oriented + * approach to SNMP. The SNMP class is an encapsulation of SNMP + * sessions, gets, sets, etc. The class manages all SNMP + * resources and provides complete retry and timeout capability. + * + * + * @author Peter E Mellquist design + * @author first implementation Michael R. MacFaden port to ACE / use Reactor pattern + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "ace/Reactor.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SOCK_Dgram.h" + +#include "asnmp/oid.h" // snmp++ oid class +#include "asnmp/vb.h" // snbmp++ vb class +#include "asnmp/target.h" // snmp++ target class +#include "asnmp/pdu.h" // snmp++ pdu class +#include "asnmp/snmperrs.h" // error macros and strings +#include "asnmp/address.h" // snmp++ address class defs +#include "asnmp/transaction_result.h" +#include "asnmp/ASNMP_Export.h" + +class Snmp; +class ASNMP_Export Snmp_Result +{ + public: + virtual ~Snmp_Result(); + virtual void result(Snmp *snmp, int result) = 0; +}; + +// Snmp session class - supports Version 1 operations in blocking mode +/** + * @class Snmp + * + * @brief Concrete class Snmp defined the session and interface to + * communicate with another SNMP Version 1 agent + */ +class ASNMP_Export Snmp : public transaction_result +{ + Snmp_Result * result_; + Pdu * pdu_; + unsigned hold_req_id_; +public: + Snmp(unsigned short port = INADDR_ANY); + virtual ~Snmp(); + + /// retrieve data from a peer agent for a given list of oid values + /// default port 161 + int get( Pdu &pdu, UdpTarget &target, Snmp_Result * cb = 0); + + /** + * retrieve data lexically adjacent to the oids specified in the pdu + * from the peer agent + * default port 161 + */ + int get_next( Pdu &pdu, UdpTarget &target, Snmp_Result * cb = 0); + + /// set data in the agent from the list of oids in the pdu + /// default port 161 + int set( Pdu &pdu, UdpTarget &target, Snmp_Result * cb = 0); + + /// send an SNMPv1 trap (unreliable) to a remote system (def port 162) + int trap( Pdu &pdu, UdpTarget &target); + + /// status of object after construction + int valid() const; + + /// given error code, return string reason + static const char * error_string(int code); + + /// retrieve a reason string if any of the above commands fail + const char * error_string(); + + /// for async transaction results + void result(transaction * t, int rc); + + /// allow the host name to be overriden + static void override_host_name(const char* name); + + /// returns the overriden host name + static void get_host_name(char* name, int len); + +protected: + void check_default_port(UdpTarget& target,unsigned short port=DEF_AGENT_PORT); + int run_transaction(Pdu& pdu, UdpTarget& target); + int run_transaction(Pdu& pdu, UdpTarget& target, Snmp_Result * cb); + int validate_args(const Pdu& pdu, const UdpTarget& target) const; + + Snmp(const Snmp&); + + /// io object + ACE_SOCK_Dgram iv_snmp_session_; + + /// status of construction + int construct_status_; + + /// result code from last transaction + int last_transaction_status_; + + /// transaction request id + unsigned req_id_; + + static char host_name_[MAXHOSTNAMELEN]; +}; + +#endif //SNMP_CLS_ diff --git a/ACE/ASNMP/asnmp/snmperrs.h b/ACE/ASNMP/asnmp/snmperrs.h new file mode 100644 index 00000000000..7aafdc0619a --- /dev/null +++ b/ACE/ASNMP/asnmp/snmperrs.h @@ -0,0 +1,210 @@ +/* -*-C++-*- */ +#ifndef SNMPERRS_H_ +#define SNMPERRS_H_ +//============================================================================= +/** + * @file snmperrs.h + * + * $Id$ + * + * Definition of error macros and error strings + * + * + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +============================================================================*/ + + +//-------[ Positive ASNMP Error Return Codes ]------------------------------ +// These values are error status values from RFC 1905 +// +// The values can be returned via Pdu::get_error_status() +// +#define SNMP_ERROR_SUCCESS 0 // Success Status +#define SNMP_ERROR_TOO_BIG 1 // Pdu encoding too big +#define SNMP_ERROR_NO_SUCH_NAME 2 // No such VB name, see error index +#define SNMP_ERROR_BAD_VALUE 3 // Bad Vb +#define SNMP_ERROR_READ_ONLY 4 // VB is read only, see error index +#define SNMP_ERROR_GENERAL_VB_ERR 5 // General VB error, see error index +#define SNMP_ERROR_NO_ACCESS 6 // No access to MIBs data +#define SNMP_ERROR_WRONG_TYPE 7 // Requested type was incorrect +#define SNMP_ERROR_WRONG_LENGTH 8 // Request Pdu has inccorect length +#define SNMP_ERROR_WRONG_ENCODING 9 // Request Pdu has wrong encoding +#define SNMP_ERROR_WRONG_VALUE 10 // Request Pdu has wrong value +#define SNMP_ERROR_NO_CREATION 11 // Unable to create object specified +#define SNMP_ERROR_INCONSIST_VAL 12 // Inconsistent value in request +#define SNMP_ERROR_RESOURCE_UNAVAIL 13 // Resources unavailable +#define SNMP_ERROR_COMITFAIL 14 // Unable to comit +#define SNMP_ERROR_UNDO_FAIL 15 // Unable to undo +#define SNMP_ERROR_AUTH_ERR 16 // Authentication failure +#define SNMP_ERROR_NOT_WRITEABLE 17 // Mib Object not writeable +#define SNMP_ERROR_INCONSIS_NAME 18 // Inconsistent naming used + + +//-------[ Negative ASNMP Result/Error Return Codes ]------------------- + +// General +#define SNMP_CLASS_SUCCESS 0 // success +#define SNMP_CLASS_ERROR -1 // general error +#define SNMP_CLASS_RESOURCE_UNAVAIL -2 // e.g., malloc failed +#define SNMP_CLASS_INTERNAL_ERROR -3 // unexpected / internal error +#define SNMP_CLASS_UNSUPPORTED -4 // unsupported function + +// Callback reasons: +#define SNMP_CLASS_TIMEOUT -5 // outstanding request timed out +#define SNMP_CLASS_ASYNC_RESPONSE -6 // received response for outstd request +#define SNMP_CLASS_NOTIFICATION -7 // received notification (trap/inform) +#define SNMP_CLASS_SESSION_DESTROYED -8 // snmp::destroyed with oustanding reqs pending + +// Snmp Class: +#define SNMP_CLASS_INVALID -10 // snmp::mf called on invalid instance +#define SNMP_CLASS_INVALID_PDU -11 // invalid pdu passed to mf +#define SNMP_CLASS_INVALID_TARGET -12 // invalid target passed to mf +#define SNMP_CLASS_INVALID_CALLBACK -13 // invalid callback to mf +#define SNMP_CLASS_INVALID_REQID -14 // invalid request id to cancel +#define SNMP_CLASS_INVALID_NOTIFYID -15 // missing trap/inform oid +#define SNMP_CLASS_INVALID_OPERATION -16 // snmp operation not allowed for specified target +#define SNMP_CLASS_INVALID_OID -17 // invalid oid passed to mf +#define SNMP_CLASS_INVALID_ADDRESS -18 // invalid address passed to mf +#define SNMP_CLASS_ERR_STATUS_SET -19 // agent returned response pdu with error_status set + +// Transport Errors: +#define SNMP_CLASS_TL_UNSUPPORTED -20 // transport unsupported +#define SNMP_CLASS_TL_IN_USE -21 // transport in use +#define SNMP_CLASS_TL_FAILED -22 // transport operation failed + +// extras +#define SNMP_CLASS_SHUTDOWN -23 // used for back door shutdown +#define SNMP_INVALID_ARGS -24 // invalid args passed + +#ifdef INCLUDE_SNMP_ERR_STRINGS_ + +// ASCII strings returned through Snmp::error() function. NOTE: altering +// the strings in this header file will not affect the return values of +// Snmp::error(), unless you rebuild the ASNMP library from source. + +#define MAX_POS_ERROR SNMP_ERROR_INCONSIS_NAME +#define MAX_NEG_ERROR SNMP_CLASS_SHUTDOWN + +static const char * pErrs[] = { + "Success", // 0 + "SNMP: Response PDU Too Big", // 1 + "SNMP: Variable does not exist", // 2 + "SNMP: Cannot modify variable: Bad Value", // 3 + "SNMP: Cannot modify object, Read Only", // 4 + "SNMP: Cannot perform operation, General Error", // 5 + "SNMP: Cannot access variable, No Access", // 6 + "SNMP: Cannot create/modify variable, Wrong Type", // 7 + "SNMP: Cannot create/set variable, Wrong Length", // 8 + "SNMP: Cannot create/set variable, Wrong Encoding", // 9 + "SNMP: Cannot create/set variable, Wrong Value", // 10 + "SNMP: Cannot create variable, Creation Not Allowed", // 11 + "SNMP: Cannot create/set variable, Inconsistent Value", // 12 + "SNMP: Cannot create/set variable, Resource Unavailable", // 13 + "SNMP: Cannot create/set variable, Commit Failed", // 14 + "SNMP: Cannot create/set variable, Undo Failed", // 15 + "SNMP: Cannot perform operation, Authorization Error", // 16 + "SNMP: Cannot create/set variable, Not Writable", // 17 + "SNMP: Cannot create variable, Inconsistent Name", // 18 +}; + + +static const char * nErrs[] = { + // General: + // 0 SNMP_CLASS_SUCCESS + "ASNMP: Success", + + // 1 SNMP_CLASS_ERROR + "ASNMP: Operation failed", + + // 2 SNMP_CLASS_RESOURCE_UNAVAIL + "ASNMP: Resource unavailable", + + // 3 SNMP_CLASS_INTERNAL_ERROR + "ASNMP: Internal error", + + // 4 SNMP_CLASS_UNSUPPORTED + "ASNMP: Unsupported function", + + // Callback reasons: + // 5 SNMP_CLASS_TIMEOUT + "ASNMP: SNMP request timed out", + + // 6 SNMP_CLASS_ASYNC_RESPONSE + "ASNMP: Received SNMP Response", + + // 7 SNMP_CLASS_NOTIFICATION + "ASNMP: Received SNMP Notification (trap or inform)", + + // 8 SNMP_CLASS_SESSION_DESTROYED + "ASNMP: Closing session with outstanding requests", + + // 9 reserved for future + "Unknown error code", + + // Snmp Class errors: + // 10 SNMP_CLASS_INVALID + "ASNMP: Class not valid", + + // 11 SNMP_CLASS_INVALID_PDU + "ASNMP: Invalid Pdu", + + // 12 SNMP_CLASS_INVALID_TARGET + "ASNMP: Invalid Target", + + // 13 SNMP_CLASS_INVALID_CALLBACK + "ASNMP: Invalid (null) Callback Function", + + // 14 SNMP_CLASS_INVALID_REQID + "ASNMP: Invalid Request Id", + + // 15 SNMP_CLASS_INVALID_NOTIFYID + "ASNMP: Invalid Notification Id", + + // 16 SNMP_CLASS_INVALID_OPERATION + "ASNMP: SNMP Operation not supported on specified Target", + + // 17 SNMP_CLASS_INVALID_OID + "ASNMP: Invalid Object Identifier", + + // 18 SNMP_CLASS_INVALID_ADDRESS + "ASNMP: Invalid Address", + + // 19 SNMP_CLASS_ERR_STATUS_SET + "ASNMP: Agent indicates error in SNMP request", + + // Transport Errors: + // 20 SNMP_CLASS_TL_UNSUPPORTED + "ASNMP: Transport is not supported", + + // 21 SNMP_CLASS_TL_IN_USE + "ASNMP: Transport is in use", + + // 22 SNMP_CLASS_TL_FAILED + "ASNMP: Transport operation failed", + + // 23 SNMP_CLASS_SHUTDOWN + "ASNMP: Blocked Mode Shutdown", + + // unknown error code + "Unknown error code", +}; + +#endif //INCLUDE_SNMP_ERR_STRINGS_ + +#endif //SNMPERRS_H_ diff --git a/ACE/ASNMP/asnmp/target.cpp b/ACE/ASNMP/asnmp/target.cpp new file mode 100644 index 00000000000..7c93a9275f9 --- /dev/null +++ b/ACE/ASNMP/asnmp/target.cpp @@ -0,0 +1,321 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// target.cpp +// +// = DESCRIPTION +// Target class defines target SNMP agents. +// +// = AUTHOR +// Peter E Mellquist +// Michael R MacFaden mrm@cisco.com - rework & ACE port +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. + =====================================================================*/ + +#include "asnmp/target.h" + +ACE_RCSID(asnmp, target, "$Id$") + +//---------------------------------------------------------------------- +//--------[ Class default values ]---------------------- +//---------------------------------------------------------------------- +u_long SnmpTarget::default_timeout_ = DEF_TIMEOUT; +int SnmpTarget::default_retries_ = DEF_RETRIES; +u_long SnmpTarget::default_max_pdu_size_ = DEF_MAX_SNMP_PACKET; +snmp_version SnmpTarget::default_version_ = version1; + +OctetStr UdpTarget::default_rd_community_(READ_COMM_STR); +OctetStr UdpTarget::default_wr_community_(WRITE_COMM_STR); + +//---------------------------------------------------------------------- +//--------[ Abstract SnmpTarget Member Functions ]---------------------- +//---------------------------------------------------------------------- +SnmpTarget::SnmpTarget(): + validity_(0), timeout_(default_timeout_), retries_(default_retries_), + max_pdu_size_(default_max_pdu_size_), version_(default_version_) +{ +} + +// return validity of target +int SnmpTarget::valid() const +{ + return validity_; +} + +// allow destruction of derived classes +SnmpTarget::~SnmpTarget() +{ +} + +// set the timeout +void SnmpTarget::set_timeout( const u_long t) +{ + timeout_ = t; +} + +// change the default timeout +void SnmpTarget::set_default_timeout( const u_long t) +{ + default_timeout_ = t; +} + +// set the retry value +void SnmpTarget::set_retry( const int r) +{ + retries_ = r; +} + +// change the default retries +void SnmpTarget::set_default_retry( const int r) +{ + default_retries_ = r; +} + +void SnmpTarget:: set_max_pdu_size(const u_long max_pdu_sz) +{ + max_pdu_size_ = max_pdu_sz; +} + + +void SnmpTarget::set_default_max_pdu_size(const u_long max_pdu_sz) +{ + default_max_pdu_size_ = max_pdu_sz; +} + +void SnmpTarget::set_version( const snmp_version v) +{ + version_ = v; +} + +void SnmpTarget::set_default_version( const snmp_version v) +{ + default_version_ = v; +} + +snmp_version SnmpTarget::get_version() const +{ + return version_; +} + +snmp_version SnmpTarget::get_default_version() const +{ + return default_version_; +} + +u_long SnmpTarget::get_max_pdu_size() const +{ + return max_pdu_size_; +} + +// get the retry value +int SnmpTarget::get_retry() const +{ + return retries_; +} + +// get the retry value +int SnmpTarget::get_default_retry() const +{ + return default_retries_; +} + +// get the timeout +u_long SnmpTarget::get_timeout() const +{ + return timeout_; +} + +SnmpTarget& SnmpTarget::operator=(const SnmpTarget& lhs) +{ + if (this == &lhs) + return *this; + + validity_ = lhs.validity_; + timeout_ = lhs.timeout_; + retries_ = lhs.retries_; + max_pdu_size_ =lhs.max_pdu_size_; + version_ = lhs.version_; + return *this; +} + +bool operator==(const SnmpTarget& lhs, const SnmpTarget& rhs) +{ + if (lhs.timeout_ != rhs.timeout_) + return false; + + if (lhs.retries_ != rhs.retries_) + return false; + + if (lhs.max_pdu_size_ != rhs.max_pdu_size_) + return false; + + if (lhs.version_ != rhs.version_) + return false; + + return true; +} + + +//---------------------------------------------------------------------- +//--------[ IpTarget Member Functions ]---------------------------------- +//---------------------------------------------------------------------- + + +//---------[ UdpTarget::UdpTarget( void) ]---------------------------------- + +UdpTarget::UdpTarget() +{ + validity_ = 0; + read_community_ = default_rd_community_; // assign by init fails + write_community_ = default_wr_community_; +} + +UdpTarget::UdpTarget(const UdpAddress& udp) : udp_address_(udp) +{ + if (udp_address_.valid()) + validity_ = 1; + read_community_ = default_rd_community_; + write_community_ = default_wr_community_; +} + +// - copy constructor can be synthesised by compiler + +//-----------[ UdpTarget::~UdpTarget() ]-------------------------------- +UdpTarget::~UdpTarget() +{ +} + +//-----------[ UdpTarget::clone() ]-------------------------------- +SnmpTarget * UdpTarget::clone() const +{ + return (SnmpTarget *) new UdpTarget(*this); +} + + +void UdpTarget::set_default_read_community(const OctetStr& rd_community) +{ + default_rd_community_ = rd_community; +} + +void UdpTarget::set_default_write_community(const OctetStr& wr_community) +{ + default_wr_community_ = wr_community; +} + + +// get the read community name as an u_char and len +void UdpTarget::get_read_community( OctetStr& read_community_oct) const +{ + read_community_oct = read_community_; +} + +//---------[ UdpTarget::set_getcommunity ]--------------------------------- +// set the read community name +void UdpTarget::set_read_community( const OctetStr& new_read_community) +{ + read_community_ = new_read_community; +} + +//---------[ UdpTarget::get_writecommunity ]---------------------------- +// get the write community +void UdpTarget::get_write_community( OctetStr &write_community_oct) const +{ + write_community_oct = write_community_; +} + +//-----------[ UdpTarget::set_writecommunity ]--------------------------- +// set the write community +void UdpTarget::set_write_community( const OctetStr& write_community_oct) +{ + write_community_ = write_community_oct; +} + +//------------[ Address& UdpTarget::get_address() ]--------------------- +// get the address +void UdpTarget::get_address( UdpAddress &address) const +{ + address = udp_address_; + return; +} + +//-------------[ UdpTarget::set_address ]-------------------------------- +// set the address +int UdpTarget::set_address( UdpAddress &udp_address) +{ + udp_address_ = udp_address; + if ( udp_address_.valid()) + validity_ = 1; + else + validity_ = 0; + + return validity_; +} + +// overloaded assignment +UdpTarget& UdpTarget::operator=( const UdpTarget& lhs) +{ + if (this == &lhs) + return *this; + + // assign base part + *((SnmpTarget *) this) = *((SnmpTarget *)&lhs); + + udp_address_ = lhs.udp_address_; + read_community_ = lhs.read_community_; + write_community_ = lhs.write_community_; + validity_ = lhs.validity_; + + return *this; +} + +const char *UdpTarget::to_string() +{ + sprintf(output_buffer_,"UdpTarget: [ valid: %d addr: %s rd: %s wr: %s \ +ver: %d, timeout: %d, retries: %d max_pdu_size: %d]", + valid(), udp_address_.to_string(), read_community_.to_string(), + write_community_.to_string(), version_, (int) timeout_, + retries_, max_pdu_size_); + return output_buffer_; +} + +//=============[ int operator == UdpTarget, UdpTarget ]=============== +// equivlence operator overloaded +bool operator==( const UdpTarget &lhs,const UdpTarget &rhs) +{ + // need to compare all the members of a UdpTarget + if ( lhs.read_community_ != rhs.read_community_) + return false; // != + + if ( lhs.write_community_ != rhs.write_community_) + return false; // != + + if ( lhs.udp_address_ != rhs.udp_address_) + return false; + + if ( lhs.timeout_ != rhs.timeout_) + return false; + + if ( lhs.retries_ != rhs.retries_) + return false; + + return true; // they are equal +} diff --git a/ACE/ASNMP/asnmp/target.h b/ACE/ASNMP/asnmp/target.h new file mode 100644 index 00000000000..084088e5f4f --- /dev/null +++ b/ACE/ASNMP/asnmp/target.h @@ -0,0 +1,260 @@ + + +#ifndef TARGET_ +#define TARGET_ +//============================================================================= +/** + * @file target.h + * + * $Id$ + * + * @brief + * + * @author Peter E Mellquist Michael R. MacFaden (ported to ACE) + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS" without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +//----[ includes ]------------------------------------------------ +#include "ace/INET_Addr.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "asnmp/address.h" +#include "asnmp/oid.h" +#include "asnmp/octet.h" + +//----[ enumerated types for SNMP versions ]------------------------- +enum snmp_version { + version1, // 0 + version2c, // 1 (Cisco IOS does not have IOS v2c agent available yet) + version3 // 2 (IETF working on this version) +}; + +// targets contain the following default properties +enum ASNMP_Defs { + DEF_TIMEOUT = 1, // unit: seconds + DEF_RETRIES = 1, // no retry default + DEF_MAX_SNMP_PACKET = 1430, // maximum pdu len on the wire (eth mtu-ip hdr) + // split bigger pdus (not implemented yet) + DEF_AGENT_PORT = 161, // port # for SNMP agent + DEF_TRAP_PORT = 162, // port # for SNMP trap receiver + DEF_VERSION = version1, // default SNMP version + MAX_COMM_STR_LEN = 255, // max value this impl will accept from client + MAX_TARGET_STRING_REP = 2048 // max value this impl will accept from client +}; + +#define READ_COMM_STR "public" +#define WRITE_COMM_STR "private" + +// Abstract class used to provide a virtual interface into Targets +// +/** + * @class SnmpTarget + * + * @brief Abstract Base class SnmpTarget is used to Collect all transmission + * details to communicate with an SNMP + */ +class ASNMP_Export SnmpTarget +{ + public: + + /// allow destruction of derived classes + virtual ~SnmpTarget(); + + /// return validity of target + int valid() const; + + /// set the retry value + void set_retry( const int r); + + /// set the object's timeout (in seconds) + void set_timeout( const unsigned long t); + + /// set the instance version + void set_version( const snmp_version v); + + /// all classes constructed will have this write community string + void set_max_pdu_size(const unsigned long max_pdu_sz); + + /// change the "class" default default timeout (in seconds) + void set_default_timeout( const unsigned long t); + + /// change the default send retries + void set_default_retry( const int r); + + /// all classes constructed will have this write community string + void set_default_max_pdu_size(const unsigned long max_pdu_sz); + + /// change class default + void set_default_version( const snmp_version v); + + // *** get methods *** + + /// get the retry value + int get_default_retry() const; + + /// get the timeout (seconds) + unsigned long get_timeout() const; + + /// get instance max buffer size + unsigned long get_max_pdu_size() const; + + /// all classes constructed will have this write community string + void get_default_max_pdu_size(const unsigned long max_pdu_sz); + + /// get the version + snmp_version get_version() const; + + snmp_version get_default_version() const; + + /// return send retry number for this instancd + int get_retry() const; + + /** + * virtual clone operation for creating a new SnmpTarget from an existing + * SnmpTarget. The caller MUST use the delete operation on the return + * value when done. + */ + virtual SnmpTarget *clone() const = 0; + + /// manipulate the base part + friend bool operator==(const SnmpTarget& lhs, const SnmpTarget& rhs); + + SnmpTarget& operator=(const SnmpTarget& lhs); + + protected: + /// SnmpTarget(const SnmpTarget &); + SnmpTarget(); + + /// used by derived class instances + int validity_; + + /// instance value xmit timeout in milli secs + unsigned long timeout_; + + /// instance value number of retries + int retries_; + + /// size of pdu + unsigned max_pdu_size_; + + /// instance value the snmp version + snmp_version version_; + + // class wide default values + /// xmit timeout in secs + static unsigned long default_timeout_; + + /// number of retries + static int default_retries_; + + /// snmp protocol version + static unsigned long default_max_pdu_size_; + static snmp_version default_version_; +}; + +//----[ UdpTarget class ]---------------------------------------------- +// UDP/IP transport using "community string" based agents (targets) +// +/** + * @class UdpTarget + * + * @brief Concrete class UdpTarget contains all Details for communicating + * with a SNMPv1 agent over UDP/IPv4 transport + */ +class ASNMP_Export UdpTarget : public SnmpTarget +{ + public: + UdpTarget(); + + /** + * constructor with only address + * assumes default as public, public + * can be constructed with IP address object + */ + UdpTarget( const UdpAddress& udp); + + /// can be constructed with Udp address object TODO: merge addresses + UdpTarget( ACE_INET_Addr& ace_inet_addr); + + /// destructor + ~UdpTarget(); + + // ** set *** + + /// set the read community using an OctetStr + void set_read_community( const OctetStr& new_read_community); + + /// set the write community using an OctetStr + void set_write_community( const OctetStr& write_community); + + /// set the address + int set_address( UdpAddress &udp_address); + + // ** get *** + + /// get the read community as an Octet Str object + void get_read_community( OctetStr& read_community_oct) const; + + /// get the write community as an OctetStr + void get_write_community( OctetStr &write_community_oct) const; + + /// get the address + void get_address( UdpAddress& address) const; + + /// all classes constructed will have this read community string + void set_default_read_community(const OctetStr& rd_community); + + /// all classes constructed will have this write community string + void set_default_write_community(const OctetStr& wr_community); + + /// all classes constructed will have this read community string + void get_default_read_community(OctetStr& rd_community) const; + + /// all classes constructed will have this write community string + void get_default_write_community(OctetStr& wr_community) const; + + /// overloaded assignment + UdpTarget& operator=( const UdpTarget& target); + + /// compare two C targets + friend bool operator==( const UdpTarget &lhs, const UdpTarget &rhs); + + /// string representation of object + const char *to_string(); + + /// clone from existing UdpTarget + SnmpTarget *clone() const; + + protected: + static OctetStr default_rd_community_; + static OctetStr default_wr_community_; + OctetStr read_community_; + OctetStr write_community_; + UdpAddress udp_address_; + snmp_version version_; + + /// to_string() rep of data + char output_buffer_[MAX_TARGET_STRING_REP]; +}; + + +#endif //TARGET_ diff --git a/ACE/ASNMP/asnmp/timetick.cpp b/ACE/ASNMP/asnmp/timetick.cpp new file mode 100644 index 00000000000..e6b2d0d2231 --- /dev/null +++ b/ACE/ASNMP/asnmp/timetick.cpp @@ -0,0 +1,144 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// timetick.cpp +// +// = DESCRIPTION +// Class implentation for SMI Timeticks class. +// +// = AUTHOR +// Peter E Mellquist +// Michael R MacFaden mrm@cisco.com - rework & ACE port +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/timetick.h" // include header file for timetick class +#include "ace/OS_NS_stdio.h" + +ACE_RCSID(asnmp, timetick, "$Id$") + +// constructor with a value +TimeTicks::TimeTicks( const unsigned long i):SnmpUInt32(i) +{ + smival.syntax = sNMP_SYNTAX_TIMETICKS; +} + +// copy constructor +TimeTicks::TimeTicks( const TimeTicks &t) + : SnmpUInt32 (t) +{ + smival.value.uNumber = t.smival.value.uNumber; + smival.syntax = sNMP_SYNTAX_TIMETICKS; +} + +// destructor +TimeTicks::~TimeTicks() +{ +} + +// syntax type +SmiUINT32 TimeTicks::get_syntax() +{ + return sNMP_SYNTAX_TIMETICKS; +} + +// create a new instance of this Value +SnmpSyntax *TimeTicks::clone() const +{ + return (SnmpSyntax *) new TimeTicks(*this); +} + +// overloaded assignement from ulong +TimeTicks& TimeTicks::operator=( const unsigned long int i) +{ + smival.value.uNumber =i; return *this; +} + +// overloaded assignment from TimeTicks +TimeTicks& TimeTicks::operator=( const TimeTicks &uli) +{ + this->smival.value.uNumber = uli.smival.value.uNumber; return *this; +} + +// general assignment from any Value +SnmpSyntax& TimeTicks::operator=( SnmpSyntax &in_val) +{ + if ( this == &in_val ) // handle assignement from itself + return *this; + + valid_flag = 0; // will get set true if really valid + if (in_val.valid()) { + switch (in_val.get_syntax()) { + case sNMP_SYNTAX_UINT32: + // case sNMP_SYNTAX_GAUGE32: .. indistinquishable from UINT32 + case sNMP_SYNTAX_CNTR32: + case sNMP_SYNTAX_TIMETICKS: + case sNMP_SYNTAX_INT32: // implied cast int -> uint + this->smival.value.uNumber = + ((TimeTicks &)in_val).smival.value.uNumber; + valid_flag = 1; + break; + } + } + return *this; +} + +// otherwise, behave like an unsigned long +TimeTicks::operator unsigned long() +{ + return smival.value.uNumber; +} + + +// ASCII format return +const char * TimeTicks::to_string() + /* Should do something nicer like days:hours:minutes... */ +{ + unsigned long tt, hseconds, seconds, minutes, hours, days; + tt = this->smival.value.uNumber; + + // days + days = tt / 8640000; + tt %= 8640000; + + // hours + hours = tt / 360000; + tt %= 360000; + + // minutes + minutes = tt / 6000; + tt %= 6000; + + seconds = tt / 100; + tt %= 100; + + hseconds = tt; + + if ( days ==0) + sprintf( output_buffer,"%ld:%02ld:%02ld.%02ld", hours, minutes,seconds,hseconds); + else if ( days==1) + sprintf( output_buffer,"1 day %ld:%02ld:%02ld.%02ld", hours, minutes,seconds,hseconds); + else + sprintf( output_buffer,"%ld days, %ld:%02ld:%02ld.%02ld", days,hours, minutes,seconds,hseconds); + + return output_buffer; +} diff --git a/ACE/ASNMP/asnmp/timetick.h b/ACE/ASNMP/asnmp/timetick.h new file mode 100644 index 00000000000..ca52a3e1d9d --- /dev/null +++ b/ACE/ASNMP/asnmp/timetick.h @@ -0,0 +1,85 @@ +/* -*-C++-*- */ +#ifndef TIMETICKS_ +#define TIMETICKS_ +//============================================================================= +/** + * @file timetick.h + * + * $Id$ + * + * Class definition for SMI Timeticks class. + * + * + * @author Michael R. MacFaden <mrm@cisco.com> + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/integer.h" + +#define TICKOUTBUF 30 // max formatted time string + +//------------[ TimeTicks Class ]----------------------------------- +// The timeticks class allows all the functionality of unsigned +// integers but is recognized as a distinct SMI type. TimeTicks +// objects may be get or set into Vb objects. +// +/** + * @class TimeTicks + * + * @brief Define RFC1155 TimeTicks Data object + */ +class ASNMP_Export TimeTicks : public SnmpUInt32 + +{ + + public: + TimeTicks( const unsigned long i = 0); + + /// copy constructor + TimeTicks( const TimeTicks &t); + + /// destructor + ~TimeTicks(); + + /// syntax type + SmiUINT32 get_syntax(); + + /// get a printable ASCII value + const char *to_string(); + + /// create a new instance of this Value + SnmpSyntax *clone() const; + + /// copy an instance of this Value + SnmpSyntax& operator=(SnmpSyntax &val); + + /// overloaded assignment + TimeTicks& operator=( const TimeTicks &uli); + + /// overloaded assignment + TimeTicks& operator=( const unsigned long int i); + + /// otherwise, behave like an unsigned long + operator unsigned long(); + + protected: + /// for storing printed form + char output_buffer[TICKOUTBUF]; +}; +#endif // TIMETICKS_ diff --git a/ACE/ASNMP/asnmp/transaction.cpp b/ACE/ASNMP/asnmp/transaction.cpp new file mode 100644 index 00000000000..2f29cf79544 --- /dev/null +++ b/ACE/ASNMP/asnmp/transaction.cpp @@ -0,0 +1,207 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// transaction.cpp +// +// = DESCRIPTION +// implements blocking SNMPv1 API using a simple state machine +// transactions over UDP/IP networks +// +// = AUTHOR +// Michael R MacFaden mrm@cisco.com - remove v2c, async, rework for ACE +// ============================================================================ + +#include "ace/Reactor.h" +#include "asnmp/transaction.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID(asnmp, transaction, "$Id$") + +// pre: pdu, target report valid() == 1 +// post: pdu sent out over the wire +inline void reset_receive_buffer(iovec& io) +{ + io.iov_base = 0; + io.iov_len = 0; +} + +transaction::transaction(const Pdu& pdu, const UdpTarget& target, + ACE_SOCK_Dgram& io): + result_(0), + wp_(pdu,target), params_(target), session_(io) +{ + // last step, convert address (get ride of this once we have merged address + UdpAddress udp; + target.get_address(udp); + // via string conversion "dotted-quad:port" + ACE_INET_Addr tmp(udp); + addr_ = tmp; + reset_receive_buffer(receive_iovec_); +} + +transaction::~transaction() +{ + ACE_Reactor::instance()->remove_handler(this, READ_MASK | DONT_CALL); + ACE_Reactor::instance()->cancel_timer(this); + + delete [] (char *) receive_iovec_.iov_base; +} + +// implement state machine, send, wait (timeout/results) return +int transaction::run() +{ + int rc, done = 0; + int retry_counter = 0; + ACE_Time_Value to(params_.get_timeout(), 0); // seconds + ACE_Reactor *reactor = ACE_Reactor::instance (); + + // 1. register io port for read access + if (reactor->register_handler(session_.get_handle(), this, + ACE_Event_Handler::READ_MASK) == -1) + return SNMP_CLASS_INTERNAL_ERROR; + + // register a time handler and a socket with this + + while (!done) { + + if ((rc = send()) < 0) // send pkt to agent + return rc; + else { + if (retry_counter++ > params_.get_retry()) + return SNMP_CLASS_TIMEOUT; + } + + // 2. wait for events (timeout, returned msg) + if (( rc = reactor->handle_events (to)) == 1) // one handler registered + return 0; + else { + if (rc == 0) { + to.set(params_.get_timeout(), 0); + } + else + return SNMP_CLASS_INTERNAL_ERROR; + } + } + return SNMP_CLASS_INTERNAL_ERROR; +} + +// implement state machine, send, wait (timeout/results) return +int transaction::run(transaction_result * r) +{ + result_ = r; + int rc; + + // 1. register io port for read access + ACE_Reactor * reactor = ACE_Reactor::instance(); + if (reactor->register_handler(session_.get_handle(), + this, + READ_MASK) == -1) + return SNMP_CLASS_INTERNAL_ERROR; + + retry_counter_ = 0; + + // register a time handler and a socket with this + ACE_Time_Value to (params_.get_timeout()); + if (reactor->schedule_timer(this, 0, to, to) < 0) + return SNMP_CLASS_INTERNAL_ERROR; + + if ((rc = send()) < 0) // send pkt to agent + return rc; + return 0; +} + +// got back response from SNMPv1 agent - process it +int transaction::handle_input (ACE_HANDLE) +{ + // OS allocates iovec_.iov_base ptr and len + delete [] (char*) receive_iovec_.iov_base; + reset_receive_buffer(receive_iovec_); + int rc = session_.recv(&receive_iovec_, receive_addr_, 0); + if (rc == -1) + { + delete [] (char*) receive_iovec_.iov_base; + reset_receive_buffer(receive_iovec_); + if (result_) + result_->result(this, SNMP_CLASS_RESOURCE_UNAVAIL); + return SNMP_CLASS_RESOURCE_UNAVAIL; + } + if (result_) + result_->result(this, rc); + + return 0; +} + +int transaction::handle_timeout(const ACE_Time_Value &, + const void *) +{ + if (send() < 0) // send pkt to agent + result_->result(this, 0); + else + if (retry_counter_++ > params_.get_retry()) + result_->result(this, SNMP_CLASS_TIMEOUT); + + return 0; +} + + +const ACE_INET_Addr& transaction::get_from_addr() const +{ + return receive_addr_; +} + + +// return pdu to caller +int transaction::result(Pdu& pdu, char *comm_str, ACE_INET_Addr *from) +{ + // TODO: check to see the sender matches the receiver address.. + + // remove any vbs existing in this pdu + pdu.delete_all_vbs(); + + // any data to return? + if (receive_iovec_.iov_len == 0) + return -1; + + wpdu tmp(receive_iovec_); + + snmp_version ver; + + // return comm str and from address of incomming pdu if requested + int rc = tmp.get_pdu(pdu, ver); + if (comm_str) + ACE_OS::strcpy(comm_str, (char *)tmp.get_community()); + if (from) + *from = receive_addr_; + return rc; +} + +transaction::transaction(ACE_SOCK_Dgram& io) +: result_(0), session_(io) +{ + reset_receive_buffer(receive_iovec_); +} + + +int transaction::send() +{ + iovec io = wp_.get_buffer(); + if (io.iov_len == 0) { + // NO DATA ? + return -1; + } + ssize_t rc = session_.send (io.iov_base, io.iov_len, addr_ , 0); + return rc; +} + +transaction_result::~transaction_result() {} + +ACE_HANDLE +transaction::get_handle () const +{ + return session_.get_handle (); +} diff --git a/ACE/ASNMP/asnmp/transaction.h b/ACE/ASNMP/asnmp/transaction.h new file mode 100644 index 00000000000..d114bd40d1f --- /dev/null +++ b/ACE/ASNMP/asnmp/transaction.h @@ -0,0 +1,83 @@ +/* -*-C++-*- */ +#ifndef TRANSACTION_ +#define TRANSACTION_ +//============================================================================= +/** + * @file transaction.h + * + * $Id$ + * + * @brief + * + * @author Michael R. MacFaden port to ACE / use Reactor pattern + */ +//============================================================================= + + +#include "ace/Event_Handler.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "asnmp/target.h" +#include "asnmp/pdu.h" +#include "asnmp/transaction_result.h" +#include "asnmp/wpdu.h" // cmu adapter class +#include "ace/SOCK_Dgram.h" + +/** + * @class transaction + * + * @brief Used to manage the details of a particular transaction betwen + * two SNMP agents. Uses SnmpTarget class to implement retry/timeout + */ +class ASNMP_Export transaction : public ACE_Event_Handler + +{ + int retry_counter_; + transaction_result * result_; + +public: + /// constructor + /// destructor + transaction(const Pdu& pdu, const UdpTarget& target, ACE_SOCK_Dgram& io); + transaction(ACE_SOCK_Dgram& io); + ~transaction(); + + /// begin polling for values + int run(); + int run(transaction_result *r); // Async interface, with callback object + + /// return pdu with result from agent after run() is completed rc = 0 + /// optionally get community str + int result(Pdu& pdu, char *comm_str = 0, ACE_INET_Addr *from_addr = 0); + + /// called by reactor when data is ready to be read in from OS memory + /// used for resend in asynchronous run() + virtual int handle_input (ACE_HANDLE fd); + virtual int handle_timeout (const ACE_Time_Value &, const void *); + + /// transmit buffer command to network... + int send(); + + /// pre: handle_input called + /// retrieve the sender's from address from the last pkt + const ACE_INET_Addr& get_from_addr() const; + + /// Return session_ handle. + ACE_HANDLE get_handle () const; + +private: + /// disallow copy construction + transaction(const transaction&); + + wpdu wp_; // wire pdu + UdpTarget params_; // params + ACE_INET_Addr addr_; // to address + ACE_SOCK_Dgram session_; // io object + iovec receive_iovec_; // receive buffer + ACE_INET_Addr receive_addr_; // from address +}; + +#endif // TRANSACTION_ diff --git a/ACE/ASNMP/asnmp/transaction_result.h b/ACE/ASNMP/asnmp/transaction_result.h new file mode 100644 index 00000000000..9ea94c60e8e --- /dev/null +++ b/ACE/ASNMP/asnmp/transaction_result.h @@ -0,0 +1,26 @@ +/* -*-C++-*- */ +#ifndef TRANSACTION_RESULT_H_ +#define TRANSACTION_RESULT_H_ +//============================================================================= +/** + * @file transaction_result.h + * + * $Id$ + * + * An object respresenting a request/reply operation between mgr/agent + * + * + * @author Michael R. MacFaden + */ +//============================================================================= + + +class transaction; +class ASNMP_Export transaction_result +{ + public: + virtual ~transaction_result(); + virtual void result(transaction * trans, int) = 0; +}; + +#endif diff --git a/ACE/ASNMP/asnmp/vb.cpp b/ACE/ASNMP/asnmp/vb.cpp new file mode 100644 index 00000000000..4e94b5e81b9 --- /dev/null +++ b/ACE/ASNMP/asnmp/vb.cpp @@ -0,0 +1,399 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// vb.h +// +// = DESCRIPTION +// The Vb class is an encapsulation of the snmp variable binding. +// This module contains the class definition for the variable binding (VB) +// class. The VB class is an encapsulation of a SNMP VB. A VB object is +// composed of one SNMP++ Oid and one SMI value. The Vb class utilizes Oid +// objects and thus requires the Oid class. To use this class, +// set oid, value then call valid() to be sure object was constructed correctly. +// +// = AUTHOR +// Peter E Mellquist +// Michael R MacFaden mrm@cisco.com - rework & ACE port +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "asnmp/oid.h" // include oid class defs +#include "asnmp/vb.h" // include vb class defs +#include "asnmp/snmperrs.h" // error codes +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_Memory.h" + +ACE_RCSID(asnmp, vb, "$Id$") + +//---------------[ Vb::Vb( void) ]-------------------------------------- +// constructor with no arguments +// makes an vb, unitialized +Vb::Vb( void): output_(0), iv_vb_value_(0), + exception_status_(SNMP_CLASS_SUCCESS) +{ +} + +//---------------[ Vb::Vb( const Oid &oid) ]----------------------------- +// constructor to initialize the oid +// makes a vb with oid portion initialized +Vb::Vb( const Oid &oid): output_(0), iv_vb_oid_(oid), iv_vb_value_(0), + exception_status_(SNMP_CLASS_SUCCESS) +{ +} + +//---------------[ Vb::Vb( const Oid &oid, const SmiSyntax &val) ]------- +Vb::Vb( const Oid &oid, const SnmpSyntax &val, const SmiUINT32 status): + output_(0), iv_vb_oid_(oid), iv_vb_value_(0), exception_status_(status) +{ + // iv_vb_value_ = recast_smi_object(val); // allocate and construct object + iv_vb_value_ = val.clone(); +} + +//---------------[ Vb::Vb( const Vb &vb) ]----------------------------- +// copy constructor +Vb::Vb( const Vb &vb): output_(0), iv_vb_value_(0) +{ + *this = vb; +} + +//---------------[ Vb::~Vb() ]------------------------------------------ +// destructor +// if the vb has a oid or an octect string then +// the associated memory needs to be freed +Vb::~Vb() +{ + free_vb(); + delete [] output_; // formatting buffer if it exists +} + + +//--------------[ Vb::valid() ]----------------------------------------- +// returns validity of a Vb object +// must have a valid oid and value +int Vb::valid() const +{ + if ( iv_vb_oid_.valid() && (iv_vb_value_ && iv_vb_value_->valid()) ) + return 1; + else + return 0; +} + + +//---------------[ Vb& Vb::operator=( const Vb &vb) ]-------------------- +// overloaded assignment allows assigning one Vb to another +// this involves deep memory thus target vb needs to be freed +// before assigning source +Vb& Vb::operator=( const Vb &vb) +{ + free_vb(); // free up target to begin with + + //-----[ reassign the Oid portion 1st ] + vb.get_oid( iv_vb_oid_); + + //-----[ next set the vb value portion ] + if (vb.iv_vb_value_ == 0) { + iv_vb_value_ = 0; + } + else { + iv_vb_value_ = vb.iv_vb_value_->clone(); + } + exception_status_ = vb.exception_status_; + + return *this; // return self reference +} + + // set a Vb null, if its not already +void Vb::set_null() +{ + free_vb(); +} + +//---------------[ Vb::set_oid( const Oid oid ) ]----------------------- +// set value oid only with another oid +void Vb::set_oid( const Oid& oid) +{ + iv_vb_oid_ = oid; +} + +//---------------[ Vb::get_oid( Oid &oid) ]----------------------------- +// get oid portion +void Vb::get_oid( Oid &oid) const +{ + oid = iv_vb_oid_; +} + +//----------------[ void Vb::free_vb() ]-------------------------------- +// protected method to free memory +// this methos is used to free memory when assigning new vbs +// or destructing +// in the case of oids and octets, we need to do a deep free +void Vb::free_vb() +{ + if (iv_vb_value_) + delete iv_vb_value_; + exception_status_ = SNMP_CLASS_SUCCESS; + iv_vb_value_ = 0; +} + +void Vb::set_value( const SnmpInt32& i) +{ + free_vb(); + iv_vb_value_ = (SnmpSyntax *)new SnmpInt32(i); +} + +void Vb::set_value( const SnmpUInt32& u) +{ + free_vb(); + iv_vb_value_ = (SnmpSyntax *)new SnmpUInt32(u); +} + +void Vb::set_value( const Gauge32& g) +{ + free_vb(); + iv_vb_value_ = (SnmpSyntax *)new Gauge32(g); +} + +void Vb::set_value( const Counter32& c) +{ + free_vb(); + iv_vb_value_ = (SnmpSyntax *)new Counter32(c); +} + +void Vb::set_value( const Counter64& c) +{ + free_vb(); + iv_vb_value_ = (SnmpSyntax *)new Counter64(c); +} + +void Vb::set_value( const TimeTicks& t) +{ + free_vb(); + iv_vb_value_ = (SnmpSyntax *)new TimeTicks(t); +} + +void Vb::set_value( const OctetStr& s) +{ + free_vb(); + iv_vb_value_ = (SnmpSyntax *)new OctetStr(s); +} + +void Vb::set_value( const Oid& o) +{ + free_vb(); + iv_vb_value_ = (SnmpSyntax *)new Oid(o); +} + +void Vb::set_value ( const SnmpSyntax &val) +{ + free_vb(); + iv_vb_value_ = val.clone(); +} + +int Vb::get_value( SnmpInt32 &i) +{ + if (iv_vb_value_ && + iv_vb_value_->valid() && + (iv_vb_value_->get_syntax() == sNMP_SYNTAX_INT32 )) { + i = *((SnmpInt32 *) iv_vb_value_); + return SNMP_CLASS_SUCCESS; + } + else + return SNMP_CLASS_INVALID; +} + +int Vb::get_value( SnmpUInt32 &u) +{ + if (iv_vb_value_ && iv_vb_value_->valid()) + { + SmiUINT32 syntax = iv_vb_value_->get_syntax(); + if (syntax == sNMP_SYNTAX_GAUGE32 || + syntax == sNMP_SYNTAX_CNTR32 || + syntax == sNMP_SYNTAX_TIMETICKS || + syntax == sNMP_SYNTAX_UINT32) + { + u = *((SnmpUInt32 *) iv_vb_value_); + return SNMP_CLASS_SUCCESS; + } + } + return SNMP_CLASS_INVALID; +} + +/* return a uint or a gauge. this is casting, but no semantic difference + * at this level + */ +int Vb::get_value( Gauge32 &g) +{ + if (iv_vb_value_ && + iv_vb_value_->valid() && + ((iv_vb_value_->get_syntax() == sNMP_SYNTAX_GAUGE32) || + iv_vb_value_->get_syntax() == sNMP_SYNTAX_UINT32) ) { + g = *((Gauge32 *) iv_vb_value_); + return SNMP_CLASS_SUCCESS; + } + else + return SNMP_CLASS_INVALID; +} + +int Vb::get_value( Counter32 &c) +{ + if (iv_vb_value_ && + iv_vb_value_->valid() && + (iv_vb_value_->get_syntax() == sNMP_SYNTAX_CNTR32 )) { + c = *((Counter32 *) iv_vb_value_); + return SNMP_CLASS_SUCCESS; + } + else + return SNMP_CLASS_INVALID; +} + +int Vb::get_value( Counter64 &c) +{ + if (iv_vb_value_ && + iv_vb_value_->valid() && + (iv_vb_value_->get_syntax() == sNMP_SYNTAX_CNTR64 )) { + c = *((Counter32 *) iv_vb_value_); + return SNMP_CLASS_SUCCESS; + } + else + return SNMP_CLASS_INVALID; +} + +int Vb::get_value( TimeTicks &t) +{ + if (iv_vb_value_ && + iv_vb_value_->valid() && + (iv_vb_value_->get_syntax() == sNMP_SYNTAX_TIMETICKS )) { + t = *((TimeTicks *) iv_vb_value_); + return SNMP_CLASS_SUCCESS; + } + else + return SNMP_CLASS_INVALID; +} + +int Vb::get_value( OctetStr &s) +{ + if (iv_vb_value_ && + iv_vb_value_->valid() && + (iv_vb_value_->get_syntax() == sNMP_SYNTAX_OCTETS )) { + s = *((OctetStr *) iv_vb_value_); + return SNMP_CLASS_SUCCESS; + } + else + return SNMP_CLASS_INVALID; +} + +int Vb::get_value( Oid &s) +{ + if (iv_vb_value_ && + iv_vb_value_->valid() && + (iv_vb_value_->get_syntax() == sNMP_SYNTAX_OID )) { + s = *((Oid *) iv_vb_value_); + return SNMP_CLASS_SUCCESS; + } + else + return SNMP_CLASS_INVALID; +} + + +//---------------[ Vb::get_value( Value &val) ]-------- +int Vb::get_value( SnmpSyntax &val) +{ + if (iv_vb_value_) { + val = *iv_vb_value_; + if (val.valid()) + return SNMP_CLASS_SUCCESS; + else + return SNMP_CLASS_INVALID; + } + else + { +//TM: should set val to be invalid + return SNMP_CLASS_INVALID; + } +} + + + +//-----[ misc]-------------------------------------------------------- + +// return the current syntax +// This method violates Object Orientation but may be useful if +// the caller has a vb object and does not know what it is. +// This would be useful in the implementation of a browser. +SmiUINT32 Vb::get_syntax() +{ + if ( exception_status_ != SNMP_CLASS_SUCCESS) + return exception_status_; + else + return ( iv_vb_value_ ? iv_vb_value_->get_syntax() : sNMP_SYNTAX_NULL); +} + +// return the printabel value +const char *Vb::to_string_value() +{ + if (iv_vb_value_) + return iv_vb_value_->to_string(); + else + return ""; +} + +// return the printable oid +const char *Vb::to_string_oid() +{ + return iv_vb_oid_.to_string(); +} + +// generate string with name/ value format +const char *Vb::to_string() +{ + int len = ACE_OS::strlen(iv_vb_oid_.to_string()); + const char *ptr = iv_vb_value_ ? iv_vb_value_->to_string() : ""; + len += ACE_OS::strlen(ptr) + 3 + 1; // " / " + null + ACE_NEW_RETURN(output_, char[len], ""); + ACE_OS::sprintf(output_, "%s / %s", iv_vb_oid_.to_string(), ptr); + return output_; +} + +// friend function to set exception status +void set_exception_status( Vb *vb, const SmiUINT32 status) +{ + vb->exception_status_ = status; +} + +// equivlence operator overloaded +// hack, by side effect, compare based on string formatting output_ +bool operator==( const Vb &lhs, const Vb &rhs) +{ + if ( lhs.iv_vb_oid_ != rhs.iv_vb_oid_) + return false; + + if (lhs.iv_vb_value_ != 0 && rhs.iv_vb_value_ != 0) + { + const int val = + ACE_OS::strcmp (lhs.iv_vb_value_->to_string(), + rhs.iv_vb_value_->to_string()); + return !val; + } + else + return false; +} diff --git a/ACE/ASNMP/asnmp/vb.h b/ACE/ASNMP/asnmp/vb.h new file mode 100644 index 00000000000..b82adb2bc0e --- /dev/null +++ b/ACE/ASNMP/asnmp/vb.h @@ -0,0 +1,207 @@ + + +#ifndef VB_CLS_ +#define VB_CLS_ +//============================================================================= +/** + * @file vb.h + * + * $Id$ + * + * This module contains the class definition for the variable binding (VB) + * class. The VB class is an encapsulation of a SNMP VB. A VB object is + * composed of one SNMP++ Oid and one SMI value. The Vb class utilizes Oid + * objects and thus requires the Oid class. To use this class, + * set oid, value then call valid() to be sure object was constructed correctly. + * + * + * @author Peter E Mellquist + */ +//============================================================================= + +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +//----[ external calls ]---------------------------------------------- +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "asnmp/smival.h" +#include "asnmp/snmperrs.h" // V2c error def +#include "asnmp/oid.h" // oid class def +#include "asnmp/timetick.h" // time ticks +#include "asnmp/counter.h" // counter +#include "asnmp/gauge.h" // gauge class +#include "asnmp/ctr64.h" // 64 bit counters +#include "asnmp/octet.h" // octet class +#include "asnmp/address.h" // address class def +#include "asnmp/integer.h" // integer class + + +//------------[ VB Class Def ]------------------------------------- +// The Vb class is the encapsulation of the SNMP variable binding. +// Variable binding lists in SNMP++ are represented as arrays of +// Vb objects. Vb objects are passed to and from SNMP objects to +// provide getting or setting MIB values. +// The vb class keeps its own memory for objects and does not +// utilize pointers to external data structures. +// +/** + * @class Vb + * + * @brief Implement the concrete Variable Bindings aka Varbind + * composite type. Varbinds hold 1 Oid and 1 Value (Any SMI value) + */ +class ASNMP_Export Vb +{ +public: + /// constructor with no arguments + /// makes an vb, unitialized (does not make object valid) + Vb( void); + + /// constructor to initialize the oid + /// makes a vb with oid portion initialized (does not make object valid) + Vb( const Oid &oid); + + /// constructor to initialize the oid + /// makes a vb with oid portion and value portion initialized, (valid) + Vb( const Oid& vb, const SnmpSyntax &val, const SmiUINT32=SNMP_CLASS_SUCCESS); + + /// copy constructor + Vb( const Vb &vb); + + /** + * destructor + * if the vb has a oid or an octect string then + * the associated memory needs to be freed + */ + ~Vb(); + + /// return validity of Vb object (both oid and value set return 1 else 0) + int valid() const; + + /// assignment to another Vb object overloaded + Vb& operator=( const Vb &vb); + + /// equivlence operator overloaded + friend ASNMP_Export bool operator==( const Vb &lhs, const Vb &rhs); + + //-----[ set oid / get oid part]------------------------------------------ + + /// set value oid only with another oid + void set_oid( const Oid& oid); + + /// get oid portion + void get_oid( Oid &oid) const; + + //-----[ set value part]-------------------------------------------------- + + /// set a Vb null, if its not already + void set_null(); + + /// returns 0 on success and a value + void set_value( const TimeTicks& ticks); + + /// returns 0 on success and a value + void set_value( const Oid& oid); + + /// returns 0 on success and a value + void set_value( const Counter32& ctr); + + /// returns 0 on success and a value + void set_value( const Counter64& ctr); + + /// returns 0 on success and a value + void set_value( const Gauge32& ctr); + + /// returns 0 on success and a value + void set_value( const SnmpUInt32& ctr); + + /// returns 0 on success and a value + void set_value( const SnmpInt32& ctr); + + /// get an octet string object + void set_value( const OctetStr& oct_str); + + //----[ get value ]------------------------------------------------ + + /// returns 0 on success and a value + int get_value( TimeTicks& ticks); + + /// returns 0 on success and a value + int get_value( Oid& oid); + + /// returns 0 on success and a value + int get_value( Counter32& ctr); + + /// returns 0 on success and a value + int get_value( Counter64& ctr); + + /// returns 0 on success and a value + int get_value( Gauge32& ctr); + + /// returns 0 on success and a value + int get_value( SnmpUInt32& ctr); + + /// returns 0 on success and a value + int get_value( SnmpInt32& ctr); + + /// get an octet string object + int get_value( OctetStr& oct_str); + + // escape hatch + /// for other derived types that can be casted + void set_value( const SnmpSyntax &val); + + /// gets a general value + int get_value( SnmpSyntax &val); + + /// return the current syntax + /// Or.. if a V2 VB exception is present then return the exception value + SmiUINT32 get_syntax(); + + /// set the exception status + friend ASNMP_Export void set_exception_status( Vb *vb, const SmiUINT32 status); + + /// return fomatted version of this object + const char *to_string(); + + /// returns a formatted version of the value + const char *to_string_value(); + + /// returns a formatted version of the value + const char *to_string_oid(); + +protected: + /// display vb as [ oid / value ] + char *output_; + + /// a vb is made up of a oid + Oid iv_vb_oid_; + + /// and a value... + SnmpSyntax *iv_vb_value_; + + /// are there any vb exceptions?? + SmiUINT32 exception_status_; + + void free_vb(); +}; + +#endif // VB_CLS_ diff --git a/ACE/ASNMP/asnmp/wpdu.cpp b/ACE/ASNMP/asnmp/wpdu.cpp new file mode 100644 index 00000000000..d05a750970f --- /dev/null +++ b/ACE/ASNMP/asnmp/wpdu.cpp @@ -0,0 +1,521 @@ +// $Id$ + +// ============================================================================ +// = LIBRARY +// asnmp +// +// = FILENAME +// wpdu.cpp +// +// = DESCRIPTION +// Adapter class. Converts between raw wire format and Pdu objects +// that can be stuffed out a I/O port or reconstructed +// +// = AUTHOR +// Michael R. MacFaden rework the class api and impl using ACE +// Peter E Mellquist implementation/code from snmp++ snmpmsg class +// +// ============================================================================ + +#include "asnmp/wpdu.h" +#include <ace/Log_Msg.h> +#include "ace/OS_NS_string.h" + +#define DEFINE_TRAP_CONSTANTS_ +#include "asnmp/enttraps.h" + +ACE_RCSID(asnmp, wpdu, "$Id$") + +#define MAX_COMM_STR_LEN 255 +#define V1_COLD_START 0 +#define V1_WARM_START 1 +#define V1_LINK_DOWN 2 +#define V1_LINK_UP 3 +#define V1_AUTH_FAILURE 4 +#define V1_EGP_NEIGHBOR_LOSS 5 +#define V1_ENT_SPECIFIC 6 + +inline +void reset_iov(iovec& iov) +{ + iov.iov_base = 0; + iov.iov_len = 0; +} + +wpdu::wpdu(const Pdu& pdu, const UdpTarget& target): + valid_flag_(SNMP_CLASS_INVALID ), comm_len(MAX_COMM_STR_LEN) +{ + reset_iov(iovec_); + version_ = target.get_version(); + int status; + OctetStr comm_str; + + community_name[0] = 0; + + snmp_pdu *raw_pdu; // create a raw pdu + raw_pdu = cmu_snmp::pdu_create( (int) pdu.get_type()); + if (!raw_pdu) { + valid_flag_ = SNMP_CLASS_RESOURCE_UNAVAIL; + return; + } + + raw_pdu->reqid = pdu.get_request_id(); + raw_pdu->errstat= (unsigned long) pdu.get_error_status(); + raw_pdu->errindex= (unsigned long) pdu.get_error_index(); + + switch (raw_pdu->command) { + case sNMP_PDU_GET: + case sNMP_PDU_GETNEXT: + target.get_read_community(comm_str); + break; + + case sNMP_PDU_SET: + target.get_write_community(comm_str); + break; + + case sNMP_PDU_V1TRAP: + target.get_read_community(comm_str); + if (set_trap_info(raw_pdu, pdu)) // will free raw_pdu + return; + break; + case sNMP_PDU_RESPONSE: + break; + + default: + ACE_ASSERT(0); + return; + } + + if (load_vbs(raw_pdu, pdu)) { + cmu_snmp::free_pdu( raw_pdu); + valid_flag_ = SNMP_CLASS_RESOURCE_UNAVAIL; + return; + } + + // TODO: determine how big raw_pdu serializes out to + iovec_.iov_len = target.get_max_pdu_size(); + ACE_NEW(iovec_.iov_base, char [iovec_.iov_len]); + + // create raw byte stream + status = cmu_snmp::build( raw_pdu, + (unsigned char *)iovec_.iov_base, + (int *) &iovec_.iov_len, + target.get_version(), + comm_str.data(), comm_str.length()); + if ( status != 0) { + valid_flag_ = SNMP_ERROR_WRONG_ENCODING; + cmu_snmp::free_pdu( raw_pdu); + return; + } + + cmu_snmp::free_pdu( raw_pdu); + valid_flag_ = SNMP_CLASS_SUCCESS; +} + +int wpdu::set_trap_info(snmp_pdu *raw_pdu, const Pdu& pdu) const +{ + Oid enterprise; + Oid trapid; // validate caller has set this correctly + pdu.get_notify_id( trapid); + if ( !trapid.valid() || trapid.length() < 2 ) { + cmu_snmp::free_pdu( raw_pdu); + return SNMP_CLASS_INVALID_NOTIFYID; + } + + + raw_pdu->specific_type=0; + + // TODO: object should emit numeric instead of this kind of mess... + if ( trapid == coldStart) + raw_pdu->trap_type = V1_COLD_START; // cold start + else if ( trapid == warmStart) + raw_pdu->trap_type = V1_WARM_START; // warm start + else if( trapid == linkDown) + raw_pdu->trap_type = V1_LINK_DOWN; // link down + else if ( trapid == linkUp) + raw_pdu->trap_type = V1_LINK_UP; // link up + else if ( trapid == authenticationFailure ) + raw_pdu->trap_type = V1_AUTH_FAILURE; // authentication failure + else if ( trapid == egpNeighborLoss) + raw_pdu->trap_type = V1_EGP_NEIGHBOR_LOSS; // egp neighbor loss + else { + raw_pdu->trap_type = V1_ENT_SPECIFIC; // enterprise specific + // last oid subid is the specific value + // if 2nd to last subid is "0", remove it + // enterprise is always the notify oid prefix + raw_pdu->specific_type = (int) trapid[(int) (trapid.length() - 1)]; + trapid.trim(1); + if ( trapid[(int)(trapid.length() - 1)] == 0 ) + trapid.trim(1); + enterprise = trapid; + } + + if ( raw_pdu->trap_type != V1_ENT_SPECIFIC) + pdu.get_notify_enterprise( enterprise); + if ( enterprise.length() > 0) { + // note!! To the contrary, enterprise OID val is + // copied here and raw_pdu->enterprise is freed in free_pdu + // as it should be (HDN) + // these are hooks into an SNMP++ oid + // and therefor the raw_pdu enterprise + // should not free them. null them out!! + SmiLPOID rawOid; + rawOid = enterprise.oidval(); + // HDN - enterprise is a local object, cannot simply assign pointer + //raw_pdu->enterprise = rawOid->ptr; + raw_pdu->enterprise_length = (int) rawOid->len; + ACE_NEW_RETURN(raw_pdu->enterprise, + oid[raw_pdu->enterprise_length],-1); + ACE_OS::memcpy((char *)raw_pdu->enterprise,(char *)rawOid->ptr, + raw_pdu->enterprise_length * sizeof(oid)); + } + + TimeTicks timestamp; + pdu.get_notify_timestamp( timestamp); + raw_pdu->time = ( unsigned long) timestamp; + + // HDN - set agent addr using the local hostname if possible + char localHostName[MAXHOSTNAMELEN]; + Snmp::get_host_name(localHostName, MAXHOSTNAMELEN); + if (ACE_OS::strlen(localHostName) > 0) { + GenAddress addr(localHostName); + OctetStr octet; + addr.to_octet(octet); + ACE_OS::memcpy(&(raw_pdu->agent_addr.sin_addr), + octet.data(), + octet.length()); + } + + return 0; +} + +wpdu::wpdu(const iovec& iov): valid_flag_(0),comm_len(MAX_COMM_STR_LEN) +{ + community_name[0] = 0; + reset_iov(iovec_); + version_ = version1; // TODO: figure where this should come from + ACE_NEW(iovec_.iov_base, char[iov.iov_len]); + if (!iovec_.iov_base) { + valid_flag_ = SNMP_CLASS_RESOURCE_UNAVAIL; + return; + } + + copy_iovec(iovec_, iov); + valid_flag_ = SNMP_CLASS_SUCCESS; +} + +wpdu::wpdu(): valid_flag_(0), comm_len(MAX_COMM_STR_LEN) +{ + community_name[0] = 0; + reset_iov(iovec_); + version_ = version1; // TODO: figure where this should come from +} + +int wpdu::valid() const +{ + return (valid_flag_ == SNMP_CLASS_SUCCESS); +} + +int wpdu::load_vbs(snmp_pdu *raw_pdu, const Pdu& pdu) +{ + int status = 0; + + // load up the payload + // for all Vbs in list, add them to the pdu + int vb_count; + Vb tempvb; + Oid tempoid; + SmiLPOID smioid; + SmiVALUE smival; + + vb_count = pdu.get_vb_count(); + + for (int z = 0; z < vb_count; z++) { + pdu.get_vb( tempvb, z); + tempvb.get_oid( tempoid); + smioid = tempoid.oidval(); + // what are we trying to convert here (vb oid part or value part) + status = convert_vb_to_smival( tempvb, &smival ); + if ( status != SNMP_CLASS_SUCCESS) + return status; + + // add the var to the raw pdu + cmu_snmp::add_var(raw_pdu, smioid->ptr, (int) smioid->len, &smival); + free_smival_descriptor( &smival); + } + + return status; +} + +// supports overlapped copies +// static +void wpdu::copy_iovec(iovec& dest, const iovec& src) +{ + if (&dest == &src) + return; + + ACE_OS:: memmove( dest.iov_base, src.iov_base, src.iov_len); + dest.iov_len = src.iov_len; +} + +int wpdu::convert_vb_to_smival( Vb &tempvb, SmiVALUE *smival ) +{ + smival->syntax = tempvb.get_syntax(); + + switch ( smival->syntax ) { + + case sNMP_SYNTAX_NULL: + break; + + // case sNMP_SYNTAX_INT32: + case sNMP_SYNTAX_INT: + { + SnmpInt32 tmp; + tempvb.get_value(tmp); + smival->value.sNumber = tmp; + } + break; + + // case sNMP_SYNTAX_UINT32: + case sNMP_SYNTAX_GAUGE32: + case sNMP_SYNTAX_CNTR32: + case sNMP_SYNTAX_TIMETICKS: + { + SnmpUInt32 tmp; + tempvb.get_value(tmp); + smival->value.uNumber = tmp; + } + break; + + // case Counter64 + case sNMP_SYNTAX_CNTR64: + { + Counter64 c64; + tempvb.get_value(c64); + smival->value.hNumber.hipart = c64.high(); + smival->value.hNumber.lopart = c64.low(); + } + break; + + // OID syntax + case sNMP_SYNTAX_OID: + { + Oid tmpoid; + tmpoid.oidval(); + tempvb.get_value(tmpoid); + SmiLPOID smi = tmpoid.oidval(); + smival->value.oid.len = tmpoid.length(); + ACE_NEW_RETURN(smival->value.oid.ptr, + SmiUINT32 [smival->value.oid.len], 1); + ACE_OS::memcpy(smival->value.oid.ptr, smi->ptr, + smival->value.oid.len *sizeof(SmiUINT32)); + } + break; + + case sNMP_SYNTAX_BITS: + case sNMP_SYNTAX_OCTETS: + case sNMP_SYNTAX_IPADDR: + { + OctetStr os; + tempvb.get_value(os); + smival->value.string.ptr = 0; + smival->value.string.len = os.length(); + if ( smival->value.string.len > 0 ) { + ACE_NEW_RETURN(smival->value.string.ptr, + SmiBYTE [smival->value.string.len], 1); + if ( smival->value.string.ptr ) { + for (int i=0; i<(int) smival->value.string.len ; i++) + smival->value.string.ptr[i] = os[i]; + } + else { + smival->syntax = sNMP_SYNTAX_NULL; // invalidate the smival + return SNMP_CLASS_RESOURCE_UNAVAIL; + } + } + } + break; + + default: + ACE_DEBUG((LM_DEBUG, "wpdu::convert_vb_to_smival did not convert vb\n")); + // ACE_ASSERT(0); + } // switch + + return 0; +} + +// free a SMI value +void wpdu::free_smival_descriptor( SmiVALUE *smival ) +{ + switch ( smival->syntax ) { + case sNMP_SYNTAX_OCTETS: + case sNMP_SYNTAX_OPAQUE: + case sNMP_SYNTAX_IPADDR: + case sNMP_SYNTAX_BITS: // obsoleted in SNMPv2 Draft Std + delete [] smival->value.string.ptr; + break; + + case sNMP_SYNTAX_OID: + delete [] smival->value.oid.ptr; + break; + } + smival->syntax = sNMP_SYNTAX_NULL; +} + + +wpdu::~wpdu() +{ + delete [] (char*) iovec_.iov_base; +} + +const iovec& wpdu::get_buffer() const +{ + return iovec_; +} + +// return a pdu from a buffer +int wpdu::get_pdu(Pdu& pdu, snmp_version& version) +{ + if (iovec_.iov_len == 0) + return -1; // NO DATA + + snmp_pdu *raw_pdu; + raw_pdu = cmu_snmp::pdu_create(0); + if (!raw_pdu) { + return SNMP_CLASS_RESOURCE_UNAVAIL; + } + + // max value a client can send us - TODO: replace this with an + // api to get actual string length + int status = cmu_snmp::parse( raw_pdu, (unsigned char *)iovec_.iov_base, + community_name, comm_len, + version, iovec_.iov_len); + if (status != 0) + return SNMP_CLASS_INTERNAL_ERROR; + + community_name[comm_len] = 0; // set null based on returned length + set_request_id( &pdu, raw_pdu->reqid); + set_error_status( &pdu, (int) raw_pdu->errstat); + set_error_index( &pdu, (int) raw_pdu->errindex); + pdu.set_type( raw_pdu->command); + + if (restore_vbs(pdu, raw_pdu)) { + cmu_snmp::free_pdu(raw_pdu); + return SNMP_CLASS_INTERNAL_ERROR; + } + + cmu_snmp::free_pdu(raw_pdu); + return 0; +} + +int wpdu::restore_vbs(Pdu& pdu, const snmp_pdu *raw_pdu) const +{ + Vb tempvb; + Oid tempoid; + struct variable_list *vp; + + for(vp = raw_pdu->variables; vp; vp = vp->next_variable) { + + // extract the oid portion + tempoid.set_data( (unsigned long *)vp->name, + ( unsigned int) vp->name_length); + tempvb.set_oid( tempoid); + + // extract the value portion + switch(vp->type) { + + // octet string + case sNMP_SYNTAX_OCTETS: + case sNMP_SYNTAX_OPAQUE: + { + OctetStr octets( (char *) vp->val.string, + (long) vp->val_len); + tempvb.set_value( octets); + } + break; + + // object id + case sNMP_SYNTAX_OID: + { + Oid oid( (unsigned long*) vp->val.objid, + (int) vp->val_len); + tempvb.set_value( oid); + } + break; + + // timeticks + case sNMP_SYNTAX_TIMETICKS: + { + TimeTicks timeticks( (unsigned long) *(vp->val.integer)); + tempvb.set_value( timeticks); + } + break; + + // 32 bit counter + case sNMP_SYNTAX_CNTR32: + { + Counter32 counter32( (unsigned long) *(vp->val.integer)); + tempvb.set_value( counter32); + } + break; + + // ip address + case sNMP_SYNTAX_IPADDR: + { + char buffer[20]; + sprintf( buffer,"%d.%d.%d.%d", + vp->val.string[0], + vp->val.string[1], + vp->val.string[2], + vp->val.string[3]); + IpAddress ipaddress( buffer); + tempvb.set_value( ipaddress); + } + break; + + // 32 bit integer + case sNMP_SYNTAX_INT: + { + SnmpInt32 int32( (long) *(vp->val.integer)); + tempvb.set_value( int32); + } + break; + + // 32 bit unsigned integer + case sNMP_SYNTAX_UINT32: + { + SnmpUInt32 uint32( (unsigned long) *(vp->val.integer)); + tempvb.set_value( uint32); + } + break; + + // v2 counter 64's + case sNMP_SYNTAX_CNTR64: + break; + + case sNMP_SYNTAX_NULL: + tempvb.set_null(); + break; + + // v2 vb exceptions + case sNMP_SYNTAX_NOSUCHOBJECT: + case sNMP_SYNTAX_NOSUCHINSTANCE: + case sNMP_SYNTAX_ENDOFMIBVIEW: + set_exception_status( &tempvb, vp->type); + break; + + default: + tempvb.set_null(); + + } // end switch + + // append the vb to the pdu + pdu += tempvb; + } + + return 0; +} + +const unsigned char *wpdu::get_community() const +{ + return community_name; +} diff --git a/ACE/ASNMP/asnmp/wpdu.h b/ACE/ASNMP/asnmp/wpdu.h new file mode 100644 index 00000000000..7feec356bc8 --- /dev/null +++ b/ACE/ASNMP/asnmp/wpdu.h @@ -0,0 +1,84 @@ +/* -*-C++-*- */ +#ifndef WPDU_H_ +#define WPDU_H_ +//============================================================================= +/** + * @file wpdu.h + * + * $Id$ + * + * Adapter class. Converts a Pdu and GenTarget into a format + * that can be stuffed out a I/O port + * + * + * @author Michael R. MacFaden re-worked api + * @author use ACE APIPeter E Mellquist wrote original class snmpmsg + */ +//============================================================================= + + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "asnmp/asn1.h" +#include "asnmp/pdu.h" +#include "asnmp/target.h" + +// this is an adapter class, it peforms the following transformations +// PDU / Target -> iovec buffer +// iovec buffer -> PDU / Target +struct snmp_pdu; +/** + * @class wpdu + * + * @brief Implement an Adapter pattern between CMU SNMP and HP SNMP++ + */ +class ASNMP_Export wpdu +{ +public: + + /// construct CMU data from HP SNMP++ objects + /// construct HP SNMP++ objects from raw buffer via CMU SNMP datatypes + wpdu(const Pdu& pdu, const UdpTarget& target); + wpdu(const iovec& buffer); + wpdu(); // same as using iovec? + + ~wpdu(); + + /// constructor completed ok? rc = 1 else 0 + int valid() const; + + /// return raw data stream via CMU code + const iovec& get_buffer() const; + + /// return HP SNMP++ pdu + int get_pdu(Pdu& pdu, snmp_version& version); + + /// return community strptr + const unsigned char *get_community() const; + +private: + int convert_vb_to_smival( Vb &tempvb, SmiVALUE *smival ); + int load_vbs(snmp_pdu *raw_pdu, const Pdu& pdu); + int restore_vbs(Pdu& pdu, const snmp_pdu *raw_pdu) const; + void free_smival_descriptor( SmiVALUE *smival ); + static void copy_iovec(iovec& dest, const iovec& src); + int set_trap_info(snmp_pdu *raw_pdu, const Pdu& pdu) const; + + /// raw format + iovec iovec_; + + /// object construction state + int valid_flag_; + + /// snmp version + snmp_version version_; + + unsigned char community_name[MAX_COMM_STR_LEN]; + unsigned long comm_len; // = MAX_COMM_STR_LEN; +}; + +#endif // WPDU_H_ diff --git a/ACE/ASNMP/examples/Makefile.am b/ACE/ASNMP/examples/Makefile.am new file mode 100644 index 00000000000..ba48f01c667 --- /dev/null +++ b/ACE/ASNMP/examples/Makefile.am @@ -0,0 +1,17 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +SUBDIRS = \ + get \ + next \ + set \ + trap \ + walk + diff --git a/ACE/ASNMP/examples/get/Makefile.am b/ACE/ASNMP/examples/get/Makefile.am new file mode 100644 index 00000000000..0c3a6e4ea95 --- /dev/null +++ b/ACE/ASNMP/examples/get/Makefile.am @@ -0,0 +1,62 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.asnmp_example_get.am + +if !BUILD_USES_WCHAR + +noinst_PROGRAMS += get + +get_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +get_SOURCES = \ + get.cpp + +get_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_USES_WCHAR + +## Makefile.asnmp_example_get_async.am + +if !BUILD_USES_WCHAR + +noinst_PROGRAMS += get_async + +get_async_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +get_async_SOURCES = \ + get_async.cpp + +get_async_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_USES_WCHAR + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/ASNMP/examples/get/get.cpp b/ACE/ASNMP/examples/get/get.cpp new file mode 100644 index 00000000000..ff6fcb9681f --- /dev/null +++ b/ACE/ASNMP/examples/get/get.cpp @@ -0,0 +1,202 @@ +// $Id$ + +// ============================================================================ +// +// = 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/Argv_Type_Converter.h" +#include "ace/Get_Opt.h" + +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" + +ACE_RCSID(get, get, "$Id$") + +// +// 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; +} + +int 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_Argv_Type_Converter to_tchar (argc, argv); + ACE_Get_Opt get_opt (argc, + to_tchar.get_TCHAR_argv (), + ACE_TEXT ("o:c:r:t:p:")); + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'o': + req = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + if (req.valid() == 0) + cout << "ERROR: oid value: " + << ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()) + << "is not valid. using default.\n"; + break; + + case 'c': + community_ = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + target_.set_read_community(community_); + break; + + case 'r': + target_.set_retry(ACE_OS::atoi (get_opt.opt_arg())); + break; + + case 't': + target_.set_timeout(ACE_OS::atoi (get_opt.opt_arg())); + 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; + const char *name = address_.resolve_hostname(rc); + + cout << "Device: " << address_ << " "; + cout << (rc ? "<< did not resolve via gethostbyname() >>" : 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 { + const char *ptr = snmp_.error_string(); + cout << "ASNMP:ERROR: get command failed reason: " << ptr << endl; + } + + cout << "\nASNMP:INFO: command completed normally.\n"<< endl; + return 0; +} + diff --git a/ACE/ASNMP/examples/get/get.mpc b/ACE/ASNMP/examples/get/get.mpc new file mode 100644 index 00000000000..ffa5a2a5f53 --- /dev/null +++ b/ACE/ASNMP/examples/get/get.mpc @@ -0,0 +1,23 @@ +// $Id$ + +project (asnmp_example_get) : aceexe { + exename = get + after += asnmp_lib + libs += asnmp + avoids += uses_wchar + includes += $(ACE_ROOT)/ASNMP + source_files { + get.cpp + } +} + +project (asnmp_example_get_async) : aceexe { + exename = get_async + after += asnmp_lib + libs += asnmp + avoids += uses_wchar + includes += $(ACE_ROOT)/ASNMP + source_files { + get_async.cpp + } +} diff --git a/ACE/ASNMP/examples/get/get_async.cpp b/ACE/ASNMP/examples/get/get_async.cpp new file mode 100644 index 00000000000..8217ffabac1 --- /dev/null +++ b/ACE/ASNMP/examples/get/get_async.cpp @@ -0,0 +1,211 @@ +// ============================================================================ +// $Id$ +// = 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/Argv_Type_Converter.h" +#include "ace/Get_Opt.h" + +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" + +ACE_RCSID(get, get_async, "$Id$") + +// +// SNMPv1 Get Application +// +class getapp : public Snmp_Result { + 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 + + virtual void result(Snmp * r, int rc); + + 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; +} + +int 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_Argv_Type_Converter to_tchar (argc, argv); + ACE_Get_Opt get_opt (argc, + to_tchar.get_TCHAR_argv (), + ACE_TEXT ("o:c:r:t:p:")); + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'o': + req = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + if (req.valid() == 0) + cout << "ERROR: oid value: " + << ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()) + << "is not valid. using default.\n"; + break; + + case 'c': + community_ = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + target_.set_read_community(community_); + break; + + case 'r': + target_.set_retry(ACE_OS::atoi (get_opt.opt_arg())); + break; + + case 't': + target_.set_timeout(ACE_OS::atoi (get_opt.opt_arg())); + 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; + const char *name = address_.resolve_hostname(rc); + + cout << "Device: " << address_ << " "; + cout << (rc ? "<< did not resolve via gethostbyname() >>" : name) << "\n"; + cout << "[ Retries=" << target_.get_retry() << " \ + Timeout=" << target_.get_timeout() <<" ms " << "Community=" << \ + community_.to_string() << " ]"<< endl; + + if (snmp_.get( pdu_, target_, this) != SNMP_CLASS_SUCCESS) { + const char *ptr = snmp_.error_string(); + cout << "ASNMP:ERROR: get command failed reason: " << ptr << endl; + } else { + ACE_Reactor::instance()->run_reactor_event_loop(); + } + return 0; +} + +void getapp::result(Snmp *, int rc) +{ + Vb vb; + if (rc < 0) + { + const char *ptr = snmp_.error_string(); + cout << "ASNMP:ERROR: get command failed reason: " << ptr << endl; + } else { + // 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"; + } + } + } + cout << "\nASNMP:INFO: command completed normally.\n"<< endl; + ACE_Reactor::instance()->end_reactor_event_loop(); +} diff --git a/ACE/ASNMP/examples/next/Makefile.am b/ACE/ASNMP/examples/next/Makefile.am new file mode 100644 index 00000000000..a7b4c2a1256 --- /dev/null +++ b/ACE/ASNMP/examples/next/Makefile.am @@ -0,0 +1,41 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.asnmp_example_next.am + +if !BUILD_USES_WCHAR + +noinst_PROGRAMS = next + +next_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +next_SOURCES = \ + next.cpp + +next_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_USES_WCHAR + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/ASNMP/examples/next/next.cpp b/ACE/ASNMP/examples/next/next.cpp new file mode 100644 index 00000000000..7a9a2208ca2 --- /dev/null +++ b/ACE/ASNMP/examples/next/next.cpp @@ -0,0 +1,200 @@ +// $Id$ + +// ============================================================================ +// +// = 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/Argv_Type_Converter.h" +#include "ace/Get_Opt.h" + +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" + +ACE_RCSID(next, next, "$Id$") + +// +// 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; +} + +int 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_Argv_Type_Converter to_tchar (argc, argv); + ACE_Get_Opt get_opt (argc, + to_tchar.get_TCHAR_argv (), + ACE_TEXT ("o:c:r:t:")); + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'o': + req = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + if (req.valid() == 0) + cout << "ERROR: oid value: " + << ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()) + << "is not valid. using default.\n"; + break; + + case 'c': + community_ = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + target_.set_read_community(community_); + break; + + case 'r': + target_.set_retry(ACE_OS::atoi (get_opt.opt_arg())); + break; + + case 't': + target_.set_timeout(ACE_OS::atoi (get_opt.opt_arg())); + 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; + const char *name = address_.resolve_hostname(rc); + + cout << "Device: " << address_ << " "; + cout << (rc ? "<< did not resolve via gethostbyname() >>" : 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 { + const 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/ACE/ASNMP/examples/next/next.mpc b/ACE/ASNMP/examples/next/next.mpc new file mode 100644 index 00000000000..f0022cb46a2 --- /dev/null +++ b/ACE/ASNMP/examples/next/next.mpc @@ -0,0 +1,13 @@ +// $Id$ + +project (asnmp_example_next) : aceexe { + exename = next + after += asnmp_lib + libs += asnmp + avoids += uses_wchar + includes += $(ACE_ROOT)/ASNMP + source_files { + next.cpp + } +} + diff --git a/ACE/ASNMP/examples/set/Makefile.am b/ACE/ASNMP/examples/set/Makefile.am new file mode 100644 index 00000000000..94f708ec8e1 --- /dev/null +++ b/ACE/ASNMP/examples/set/Makefile.am @@ -0,0 +1,41 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.asnmp_example_set.am + +if !BUILD_USES_WCHAR + +noinst_PROGRAMS = set + +set_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +set_SOURCES = \ + set.cpp + +set_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_USES_WCHAR + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/ASNMP/examples/set/set.cpp b/ACE/ASNMP/examples/set/set.cpp new file mode 100644 index 00000000000..39eb447f9a7 --- /dev/null +++ b/ACE/ASNMP/examples/set/set.cpp @@ -0,0 +1,271 @@ +// $Id$ + +// ============================================================================ +// +// = 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/Argv_Type_Converter.h" +#include "ace/Get_Opt.h" + +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" + +ACE_RCSID(set, set, "$Id$") + +// +// 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; +} + +int +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_Argv_Type_Converter to_tchar (argc, argv); + ACE_Get_Opt get_opt (argc, + to_tchar.get_TCHAR_argv (), + ACE_TEXT ("o:c:r:t:I:U:C:G:T:O:S:P:")); + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'o': + req = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + if (req.valid() == 0) + cout << "ERROR: oid value: " + << ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()) + << "is not valid. using default.\n"; + break; + + case 'c': + community_ = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + target_.set_write_community(community_); + break; + + case 'r': + target_.set_retry(ACE_OS::atoi (get_opt.opt_arg())); + break; + + case 't': + target_.set_timeout(ACE_OS::atoi (get_opt.opt_arg())); + break; + + case 'I': // Integer32 + { + SnmpInt32 o(ACE_OS::atoi(get_opt.opt_arg())); + vb.set_value(o); + pdu_ += vb; + } + break; + + case 'U': // Unsigned32 + { + SnmpUInt32 o(ACE_OS::atoi(get_opt.opt_arg())); + vb.set_value(o); + pdu_ += vb; + } + break; + + case 'C': // Counter32 + { + Counter32 o(ACE_OS::atoi(get_opt.opt_arg())); + vb.set_value(o); + pdu_ += vb; + } + break; + + case 'G': // Gauge32 + { + Gauge32 o(ACE_OS::atoi(get_opt.opt_arg())); + vb.set_value(o); + pdu_ += vb; + } + break; + + case 'T': // TimeTicks + { + TimeTicks o(ACE_OS::atoi(get_opt.opt_arg())); + vb.set_value(o); + pdu_ += vb; + } + break; + + case 'O': // Oid as a variable identifier + { + oid_ = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + vb.set_oid(oid_); // when value is set, pdu updated + } + break; + + case 'S': // Octet String + { + OctetStr o(ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg())); + vb.set_value(o); // set the Oid portion of the Vb + pdu_ += vb; + } + break; + + case 'P': // Oid String as a value + { + Oid o(ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg())); + 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; + const char *name = address_.resolve_hostname(rc); + + cout << "Device: " << address_ << " "; + cout << (rc ? "<< did not resolve via gethostbyname() >>" : 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 { + const 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/ACE/ASNMP/examples/set/set.mpc b/ACE/ASNMP/examples/set/set.mpc new file mode 100644 index 00000000000..bb40f93e6df --- /dev/null +++ b/ACE/ASNMP/examples/set/set.mpc @@ -0,0 +1,13 @@ +// $Id$ + +project (asnmp_example_set) : aceexe { + exename = set + after += asnmp_lib + libs += asnmp + avoids += uses_wchar + includes += $(ACE_ROOT)/ASNMP + source_files { + set.cpp + } +} + diff --git a/ACE/ASNMP/examples/trap/Makefile.am b/ACE/ASNMP/examples/trap/Makefile.am new file mode 100644 index 00000000000..a60adce7d30 --- /dev/null +++ b/ACE/ASNMP/examples/trap/Makefile.am @@ -0,0 +1,41 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.asnmp_example_trap.am + +if !BUILD_USES_WCHAR + +noinst_PROGRAMS = trap + +trap_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +trap_SOURCES = \ + trap.cpp + +trap_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_USES_WCHAR + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/ASNMP/examples/trap/trap.cpp b/ACE/ASNMP/examples/trap/trap.cpp new file mode 100644 index 00000000000..59d4f9f25bc --- /dev/null +++ b/ACE/ASNMP/examples/trap/trap.cpp @@ -0,0 +1,188 @@ +// $Id$ + +// ============================================================================ +// +// = 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/Argv_Type_Converter.h" +#include "ace/Get_Opt.h" + +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" + +ACE_RCSID(trap, trap, "$Id$") + +// +// 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; +} + +int 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_Argv_Type_Converter to_tchar (argc, argv); + ACE_Get_Opt get_opt (argc, + to_tchar.get_TCHAR_argv (), + ACE_TEXT ("c:e:t:")); + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'c': // community string + community_ = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + target_.set_read_community(community_); + break; + + case 'e': // trap oid to send + ent = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + break; + + case 't': // trap oid + trap = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + 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; + const char *name = address_.resolve_hostname(rc); + + cout << "Device: " << address_ << " "; + cout << (rc ? "<< did not resolve via gethostbyname() >>" : name) << "\n"; + cout << "[ Community=" << community_.to_string() << " ]"<< endl; + + if (snmp_.trap( pdu_, target_) == SNMP_CLASS_SUCCESS) { + cout << "Trap was written to network...\n"; + } + else { + const 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/ACE/ASNMP/examples/trap/trap.mpc b/ACE/ASNMP/examples/trap/trap.mpc new file mode 100644 index 00000000000..d0d6dc8e897 --- /dev/null +++ b/ACE/ASNMP/examples/trap/trap.mpc @@ -0,0 +1,12 @@ +// $Id$ + +project (asnmp_example_trap) : aceexe { + exename = trap + after += asnmp_lib + libs += asnmp + avoids += uses_wchar + includes += $(ACE_ROOT)/ASNMP + source_files { + trap.cpp + } +} diff --git a/ACE/ASNMP/examples/walk/Makefile.am b/ACE/ASNMP/examples/walk/Makefile.am new file mode 100644 index 00000000000..9cff32a49de --- /dev/null +++ b/ACE/ASNMP/examples/walk/Makefile.am @@ -0,0 +1,41 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.asnmp_example_walk.am + +if !BUILD_USES_WCHAR + +noinst_PROGRAMS = walk + +walk_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +walk_SOURCES = \ + walk.cpp + +walk_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_USES_WCHAR + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/ASNMP/examples/walk/walk.cpp b/ACE/ASNMP/examples/walk/walk.cpp new file mode 100644 index 00000000000..56fc112fd71 --- /dev/null +++ b/ACE/ASNMP/examples/walk/walk.cpp @@ -0,0 +1,266 @@ +// $Id$ + +// ============================================================================ +// +// = 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/Argv_Type_Converter.h" +#include "ace/Get_Opt.h" +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" + +ACE_RCSID(walk, walk, "$Id$") + +// +// 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; +} + +int 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_Argv_Type_Converter to_tchar (argc, argv); + ACE_Get_Opt get_opt (argc, + to_tchar.get_TCHAR_argv (), + ACE_TEXT ("o:c:r:t:")); + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'o': + req = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + if (req.valid() == 0) + cout << "ERROR: oid value: " + << ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()) + << "is not valid. using default.\n"; + break; + + case 'c': + community_ = ACE_TEXT_ALWAYS_CHAR (get_opt.opt_arg()); + target_.set_read_community(community_); + break; + + case 'r': + target_.set_retry(ACE_OS::atoi (get_opt.opt_arg())); + break; + + case 't': + target_.set_timeout(ACE_OS::atoi (get_opt.opt_arg())); + 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), target_(target), pdu_(pdu), first_(0), + valid_(0) +{ + // 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 = const_cast <char*> (snmp_->error_string()); + return 0; + } + + // 2. check for problems + if (pdu_.get_error_status()) { + reason = const_cast <char*> (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; + const char *name = address_.resolve_hostname(rc); + + cout << "Device: " << address_ << " "; + cout << (rc ? "<< did not resolve via gethostbyname() >>" : 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/ACE/ASNMP/examples/walk/walk.mpc b/ACE/ASNMP/examples/walk/walk.mpc new file mode 100644 index 00000000000..aff0fb98d35 --- /dev/null +++ b/ACE/ASNMP/examples/walk/walk.mpc @@ -0,0 +1,12 @@ +// $Id$ + +project (asnmp_example_walk) : aceexe { + exename = walk + after += asnmp_lib + libs += asnmp + avoids += uses_wchar + includes += $(ACE_ROOT)/ASNMP + source_files { + walk.cpp + } +} diff --git a/ACE/ASNMP/mibs/RFC1213-MIB.my b/ACE/ASNMP/mibs/RFC1213-MIB.my new file mode 100644 index 00000000000..f89f8bf125e --- /dev/null +++ b/ACE/ASNMP/mibs/RFC1213-MIB.my @@ -0,0 +1,2618 @@ +-- ***************************************************************** +-- RFC1213-MIB.my: MIB-II MIB file +-- +-- April 1994, Jeffrey T. Johnson +-- +-- Copyright (c) 1994-1996 by cisco Systems, Inc. +-- All rights reserved. +-- +-- ***************************************************************** +-- +-- This mib was extracted from RFC 1213 +-- The following changes have been applied: +-- The enumerations unknown(4) and dormant(5) have been added to +-- ifOperStatus to reflect a change to the ifTable introduced in +-- RFC 1573 +-- +-- The SYNTAX of ifType has been changed to IANAifType, to reflect the +-- change to the ifTable introduced in RFC1573. + + RFC1213-MIB DEFINITIONS ::= BEGIN + + IMPORTS + mgmt, NetworkAddress, IpAddress, Counter, Gauge, + TimeTicks + FROM RFC1155-SMI + OBJECT-TYPE + FROM RFC-1212 + TEXTUAL-CONVENTION + FROM SNMPv2-TC + IANAifType + FROM IANAifType-MIB; + + -- This MIB module uses the extended OBJECT-TYPE macro as + -- defined in [14]; + + + -- MIB-II (same prefix as MIB-I) + + mib-2 OBJECT IDENTIFIER ::= { mgmt 1 } + + -- textual conventions + + DisplayString ::= + OCTET STRING + -- This data type is used to model textual information taken + -- from the NVT ASCII character set. By convention, objects + -- with this syntax are declared as having + -- + -- SIZE (0..255) + + PhysAddress ::= + OCTET STRING + -- This data type is used to model media addresses. For many + -- types of media, this will be in a binary representation. + -- For example, an ethernet address would be represented as + -- a string of 6 octets. + + + -- groups in MIB-II + + system OBJECT IDENTIFIER ::= { mib-2 1 } + + interfaces OBJECT IDENTIFIER ::= { mib-2 2 } + + at OBJECT IDENTIFIER ::= { mib-2 3 } + + ip OBJECT IDENTIFIER ::= { mib-2 4 } + + icmp OBJECT IDENTIFIER ::= { mib-2 5 } + + tcp OBJECT IDENTIFIER ::= { mib-2 6 } + + udp OBJECT IDENTIFIER ::= { mib-2 7 } + + egp OBJECT IDENTIFIER ::= { mib-2 8 } + + -- historical (some say hysterical) + -- cmot OBJECT IDENTIFIER ::= { mib-2 9 } + + transmission OBJECT IDENTIFIER ::= { mib-2 10 } + + snmp OBJECT IDENTIFIER ::= { mib-2 11 } + + + -- the System group + + -- Implementation of the System group is mandatory for all + -- systems. If an agent is not configured to have a value + -- for any of these variables, a string of length 0 is + -- returned. + + sysDescr OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A textual description of the entity. This value + should include the full name and version + identification of the system's hardware type, + software operating-system, and networking + software. It is mandatory that this only contain + printable ASCII characters." + ::= { system 1 } + + sysObjectID OBJECT-TYPE + SYNTAX OBJECT IDENTIFIER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The vendor's authoritative identification of the + network management subsystem contained in the + entity. This value is allocated within the SMI + enterprises subtree (1.3.6.1.4.1) and provides an + easy and unambiguous means for determining `what + kind of box' is being managed. For example, if + vendor `Flintstones, Inc.' was assigned the + subtree 1.3.6.1.4.1.4242, it could assign the + identifier 1.3.6.1.4.1.4242.1.1 to its `Fred + Router'." + ::= { system 2 } + + sysUpTime OBJECT-TYPE + SYNTAX TimeTicks + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The time (in hundredths of a second) since the + network management portion of the system was last + re-initialized." + ::= { system 3 } + + sysContact OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The textual identification of the contact person + for this managed node, together with information + on how to contact this person." + ::= { system 4 } + + sysName OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "An administratively-assigned name for this + managed node. By convention, this is the node's + fully-qualified domain name." + ::= { system 5 } + + sysLocation OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The physical location of this node (e.g., + `telephone closet, 3rd floor')." + ::= { system 6 } + + sysServices OBJECT-TYPE + SYNTAX INTEGER (0..127) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A value which indicates the set of services that + this entity primarily offers. + + The value is a sum. This sum initially takes the + value zero, Then, for each layer, L, in the range + 1 through 7, that this node performs transactions + for, 2 raised to (L - 1) is added to the sum. For + example, a node which performs primarily routing + functions would have a value of 4 (2^(3-1)). In + contrast, a node which is a host offering + application services would have a value of 72 + (2^(4-1) + 2^(7-1)). Note that in the context of + the Internet suite of protocols, values should be + calculated accordingly: + + layer functionality + 1 physical (e.g., repeaters) + 2 datalink/subnetwork (e.g., bridges) + 3 internet (e.g., IP gateways) + 4 end-to-end (e.g., IP hosts) + 7 applications (e.g., mail relays) + + For systems including OSI protocols, layers 5 and + 6 may also be counted." + ::= { system 7 } + + -- the Interfaces group + + -- Implementation of the Interfaces group is mandatory for + -- all systems. + + ifNumber OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of network interfaces (regardless of + their current state) present on this system." + ::= { interfaces 1 } + + + -- the Interfaces table + + -- The Interfaces table contains information on the entity's + -- interfaces. Each interface is thought of as being + -- attached to a `subnetwork'. Note that this term should + -- not be confused with `subnet' which refers to an + -- addressing partitioning scheme used in the Internet suite + -- of protocols. + + ifTable OBJECT-TYPE + SYNTAX SEQUENCE OF IfEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A list of interface entries. The number of + entries is given by the value of ifNumber." + ::= { interfaces 2 } + + ifEntry OBJECT-TYPE + SYNTAX IfEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An interface entry containing objects at the + subnetwork layer and below for a particular + interface." + INDEX { ifIndex } + ::= { ifTable 1 } + + IfEntry ::= + SEQUENCE { + ifIndex + INTEGER, + ifDescr + DisplayString, + ifType + IANAifType, + ifMtu + INTEGER, + ifSpeed + Gauge, + ifPhysAddress + PhysAddress, + ifAdminStatus + INTEGER, + ifOperStatus + INTEGER, + ifLastChange + TimeTicks, + ifInOctets + Counter, + ifInUcastPkts + Counter, + ifInNUcastPkts + Counter, + ifInDiscards + Counter, + ifInErrors + Counter, + ifInUnknownProtos + Counter, + ifOutOctets + Counter, + ifOutUcastPkts + Counter, + ifOutNUcastPkts + Counter, + ifOutDiscards + Counter, + ifOutErrors + Counter, + ifOutQLen + Gauge, + ifSpecific + OBJECT IDENTIFIER + } + + ifIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A unique value for each interface. Its value + ranges between 1 and the value of ifNumber. The + value for each interface must remain constant at + least from one re-initialization of the entity's + network management system to the next re- + initialization." + ::= { ifEntry 1 } + + ifDescr OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A textual string containing information about the + interface. This string should include the name of + the manufacturer, the product name and the version + of the hardware interface." + ::= { ifEntry 2 } + + ifType OBJECT-TYPE + SYNTAX IANAifType + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The type of interface. Additional values for ifType + are assigned by the Internet Assigned Numbers + Authority (IANA), through updating the syntax of the + IANAifType textual convention." + ::= { ifEntry 3 } + + + ifMtu OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The size of the largest datagram which can be + sent/received on the interface, specified in + octets. For interfaces that are used for + transmitting network datagrams, this is the size + of the largest network datagram that can be sent + on the interface." + ::= { ifEntry 4 } + + ifSpeed OBJECT-TYPE + SYNTAX Gauge + ACCESS read-only + STATUS mandatory + DESCRIPTION + "An estimate of the interface's current bandwidth + in bits per second. For interfaces which do not + vary in bandwidth or for those where no accurate + estimation can be made, this object should contain + the nominal bandwidth." + ::= { ifEntry 5 } + + ifPhysAddress OBJECT-TYPE + SYNTAX PhysAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The interface's address at the protocol layer + immediately `below' the network layer in the + protocol stack. For interfaces which do not have + such an address (e.g., a serial line), this object + should contain an octet string of zero length." + ::= { ifEntry 6 } + + ifAdminStatus OBJECT-TYPE + SYNTAX INTEGER { + up(1), -- ready to pass packets + down(2), + testing(3) -- in some test mode + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The desired state of the interface. The + testing(3) state indicates that no operational + packets can be passed." + ::= { ifEntry 7 } + + ifOperStatus OBJECT-TYPE + SYNTAX INTEGER { + up(1), -- ready to pass packets + down(2), + testing(3), -- in some test mode + unknown(4), + dormant(5) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The current operational state of the interface. + The testing(3) state indicates that no operational + packets can be passed." + ::= { ifEntry 8 } + + ifLastChange OBJECT-TYPE + SYNTAX TimeTicks + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The value of sysUpTime at the time the interface + entered its current operational state. If the + current state was entered prior to the last re- + initialization of the local network management + subsystem, then this object contains a zero + value." + ::= { ifEntry 9 } + + ifInOctets OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of octets received on the + interface, including framing characters." + ::= { ifEntry 10 } + + ifInUcastPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of subnetwork-unicast packets + delivered to a higher-layer protocol." + ::= { ifEntry 11 } + + ifInNUcastPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of non-unicast (i.e., subnetwork- + broadcast or subnetwork-multicast) packets + delivered to a higher-layer protocol." + ::= { ifEntry 12 } + + ifInDiscards OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of inbound packets which were chosen + to be discarded even though no errors had been + detected to prevent their being deliverable to a + higher-layer protocol. One possible reason for + discarding such a packet could be to free up + buffer space." + ::= { ifEntry 13 } + + ifInErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of inbound packets that contained + errors preventing them from being deliverable to a + higher-layer protocol." + ::= { ifEntry 14 } + + ifInUnknownProtos OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of packets received via the interface + which were discarded because of an unknown or + unsupported protocol." + ::= { ifEntry 15 } + + ifOutOctets OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of octets transmitted out of the + interface, including framing characters." + ::= { ifEntry 16 } + + ifOutUcastPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of packets that higher-level + protocols requested be transmitted to a + subnetwork-unicast address, including those that + were discarded or not sent." + ::= { ifEntry 17 } + + ifOutNUcastPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of packets that higher-level + protocols requested be transmitted to a non- + unicast (i.e., a subnetwork-broadcast or + subnetwork-multicast) address, including those + that were discarded or not sent." + ::= { ifEntry 18 } + + ifOutDiscards OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of outbound packets which were chosen + to be discarded even though no errors had been + detected to prevent their being transmitted. One + possible reason for discarding such a packet could + be to free up buffer space." + ::= { ifEntry 19 } + + ifOutErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of outbound packets that could not be + transmitted because of errors." + ::= { ifEntry 20 } + + ifOutQLen OBJECT-TYPE + SYNTAX Gauge + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The length of the output packet queue (in + packets)." + ::= { ifEntry 21 } + + ifSpecific OBJECT-TYPE + SYNTAX OBJECT IDENTIFIER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A reference to MIB definitions specific to the + particular media being used to realize the + interface. For example, if the interface is + realized by an ethernet, then the value of this + object refers to a document defining objects + specific to ethernet. If this information is not + present, its value should be set to the OBJECT + IDENTIFIER { 0 0 }, which is a syntactically valid + object identifier, and any conformant + implementation of ASN.1 and BER must be able to + generate and recognize this value." + ::= { ifEntry 22 } + + + -- the Address Translation group + + -- Implementation of the Address Translation group is + -- mandatory for all systems. Note however that this group + -- is deprecated by MIB-II. That is, it is being included + -- solely for compatibility with MIB-I nodes, and will most + -- likely be excluded from MIB-III nodes. From MIB-II and + -- onwards, each network protocol group contains its own + -- address translation tables. + + -- The Address Translation group contains one table which is + -- the union across all interfaces of the translation tables + -- for converting a NetworkAddress (e.g., an IP address) into + -- a subnetwork-specific address. For lack of a better term, + -- this document refers to such a subnetwork-specific address + -- as a `physical' address. + + -- Examples of such translation tables are: for broadcast + -- media where ARP is in use, the translation table is + -- equivalent to the ARP cache; or, on an X.25 network where + -- non-algorithmic translation to X.121 addresses is + -- required, the translation table contains the + -- NetworkAddress to X.121 address equivalences. + + atTable OBJECT-TYPE + SYNTAX SEQUENCE OF AtEntry + ACCESS not-accessible + STATUS deprecated + DESCRIPTION + "The Address Translation tables contain the + NetworkAddress to `physical' address equivalences. + Some interfaces do not use translation tables for + determining address equivalences (e.g., DDN-X.25 + has an algorithmic method); if all interfaces are + of this type, then the Address Translation table + is empty, i.e., has zero entries." + ::= { at 1 } + + atEntry OBJECT-TYPE + SYNTAX AtEntry + ACCESS not-accessible + STATUS deprecated + DESCRIPTION + "Each entry contains one NetworkAddress to + `physical' address equivalence." + INDEX { atIfIndex, + atNetAddress } + ::= { atTable 1 } + + AtEntry ::= + SEQUENCE { + atIfIndex + INTEGER, + atPhysAddress + PhysAddress, + atNetAddress + NetworkAddress + } + + atIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS deprecated + DESCRIPTION + "The interface on which this entry's equivalence + is effective. The interface identified by a + particular value of this index is the same + interface as identified by the same value of + ifIndex." + ::= { atEntry 1 } + + atPhysAddress OBJECT-TYPE + SYNTAX PhysAddress + ACCESS read-write + STATUS deprecated + DESCRIPTION + "The media-dependent `physical' address. + + Setting this object to a null string (one of zero + length) has the effect of invaliding the + corresponding entry in the atTable object. That + is, it effectively disassociates the interface + identified with said entry from the mapping + identified with said entry. It is an + implementation-specific matter as to whether the + agent removes an invalidated entry from the table. + Accordingly, management stations must be prepared + to receive tabular information from agents that + corresponds to entries not currently in use. + Proper interpretation of such entries requires + examination of the relevant atPhysAddress object." + ::= { atEntry 2 } + + atNetAddress OBJECT-TYPE + SYNTAX NetworkAddress + ACCESS read-write + STATUS deprecated + DESCRIPTION + "The NetworkAddress (e.g., the IP address) + corresponding to the media-dependent `physical' + address." + ::= { atEntry 3 } + + + -- the IP group + + -- Implementation of the IP group is mandatory for all + -- systems. + + ipForwarding OBJECT-TYPE + SYNTAX INTEGER { + forwarding(1), -- acting as a gateway + not-forwarding(2) -- NOT acting as a gateway + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The indication of whether this entity is acting + as an IP gateway in respect to the forwarding of + datagrams received by, but not addressed to, this + entity. IP gateways forward datagrams. IP hosts + do not (except those source-routed via the host). + + Note that for some managed nodes, this object may + take on only a subset of the values possible. + Accordingly, it is appropriate for an agent to + return a `badValue' response if a management + station attempts to change this object to an + inappropriate value." + ::= { ip 1 } + + ipDefaultTTL OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The default value inserted into the Time-To-Live + field of the IP header of datagrams originated at + this entity, whenever a TTL value is not supplied + by the transport layer protocol." + ::= { ip 2 } + + ipInReceives OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input datagrams received from + interfaces, including those received in error." + ::= { ip 3 } + + ipInHdrErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of input datagrams discarded due to + errors in their IP headers, including bad + checksums, version number mismatch, other format + errors, time-to-live exceeded, errors discovered + in processing their IP options, etc." + ::= { ip 4 } + + ipInAddrErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of input datagrams discarded because + the IP address in their IP header's destination + field was not a valid address to be received at + this entity. This count includes invalid + addresses (e.g., 0.0.0.0) and addresses of + unsupported Classes (e.g., Class E). For entities + which are not IP Gateways and therefore do not + forward datagrams, this counter includes datagrams + discarded because the destination address was not + a local address." + ::= { ip 5 } + + ipForwDatagrams OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of input datagrams for which this + entity was not their final IP destination, as a + result of which an attempt was made to find a + route to forward them to that final destination. + In entities which do not act as IP Gateways, this + counter will include only those packets which were + Source-Routed via this entity, and the Source- + Route option processing was successful." + ::= { ip 6 } + + ipInUnknownProtos OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of locally-addressed datagrams + received successfully but discarded because of an + unknown or unsupported protocol." + ::= { ip 7 } + + ipInDiscards OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of input IP datagrams for which no + problems were encountered to prevent their + continued processing, but which were discarded + (e.g., for lack of buffer space). Note that this + counter does not include any datagrams discarded + while awaiting re-assembly." + ::= { ip 8 } + + ipInDelivers OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input datagrams successfully + delivered to IP user-protocols (including ICMP)." + ::= { ip 9 } + + ipOutRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of IP datagrams which local IP + user-protocols (including ICMP) supplied to IP in + requests for transmission. Note that this counter + does not include any datagrams counted in + ipForwDatagrams." + ::= { ip 10 } + + ipOutDiscards OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of output IP datagrams for which no + problem was encountered to prevent their + transmission to their destination, but which were + discarded (e.g., for lack of buffer space). Note + that this counter would include datagrams counted + in ipForwDatagrams if any such packets met this + (discretionary) discard criterion." + ::= { ip 11 } + + ipOutNoRoutes OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP datagrams discarded because no + route could be found to transmit them to their + destination. Note that this counter includes any + packets counted in ipForwDatagrams which meet this + `no-route' criterion. Note that this includes any + datagrams which a host cannot route because all of + its default gateways are down." + ::= { ip 12 } + + ipReasmTimeout OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The maximum number of seconds which received + fragments are held while they are awaiting + reassembly at this entity." + ::= { ip 13 } + + ipReasmReqds OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP fragments received which needed + to be reassembled at this entity." + ::= { ip 14 } + + ipReasmOKs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP datagrams successfully re- + assembled." + ::= { ip 15 } + + ipReasmFails OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of failures detected by the IP re- + assembly algorithm (for whatever reason: timed + out, errors, etc). Note that this is not + necessarily a count of discarded IP fragments + since some algorithms (notably the algorithm in + RFC 815) can lose track of the number of fragments + by combining them as they are received." + ::= { ip 16 } + + ipFragOKs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP datagrams that have been + successfully fragmented at this entity." + ::= { ip 17 } + + ipFragFails OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP datagrams that have been + discarded because they needed to be fragmented at + this entity but could not be, e.g., because their + Don't Fragment flag was set." + ::= { ip 18 } + + ipFragCreates OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP datagram fragments that have + been generated as a result of fragmentation at + this entity." + ::= { ip 19 } + + + + -- the IP address table + + -- The IP address table contains this entity's IP addressing + -- information. + + ipAddrTable OBJECT-TYPE + SYNTAX SEQUENCE OF IpAddrEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The table of addressing information relevant to + this entity's IP addresses." + ::= { ip 20 } + + ipAddrEntry OBJECT-TYPE + SYNTAX IpAddrEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The addressing information for one of this + entity's IP addresses." + INDEX { ipAdEntAddr } + ::= { ipAddrTable 1 } + + IpAddrEntry ::= + SEQUENCE { + ipAdEntAddr + IpAddress, + ipAdEntIfIndex + INTEGER, + ipAdEntNetMask + IpAddress, + ipAdEntBcastAddr + INTEGER, + ipAdEntReasmMaxSize + INTEGER (0..65535) + } + + ipAdEntAddr OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The IP address to which this entry's addressing + information pertains." + ::= { ipAddrEntry 1 } + + + ipAdEntIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the + interface to which this entry is applicable. The + interface identified by a particular value of this + index is the same interface as identified by the + same value of ifIndex." + ::= { ipAddrEntry 2 } + + ipAdEntNetMask OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The subnet mask associated with the IP address of + this entry. The value of the mask is an IP + address with all the network bits set to 1 and all + the hosts bits set to 0." + ::= { ipAddrEntry 3 } + + ipAdEntBcastAddr OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The value of the least-significant bit in the IP + broadcast address used for sending datagrams on + the (logical) interface associated with the IP + address of this entry. For example, when the + Internet standard all-ones broadcast address is + used, the value will be 1. This value applies to + both the subnet and network broadcasts addresses + used by the entity on this (logical) interface." + ::= { ipAddrEntry 4 } + + ipAdEntReasmMaxSize OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The size of the largest IP datagram which this + entity can re-assemble from incoming IP fragmented + datagrams received on this interface." + ::= { ipAddrEntry 5 } + + -- the IP routing table + + -- The IP routing table contains an entry for each route + -- presently known to this entity. + + ipRouteTable OBJECT-TYPE + SYNTAX SEQUENCE OF IpRouteEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "This entity's IP Routing table." + ::= { ip 21 } + + ipRouteEntry OBJECT-TYPE + SYNTAX IpRouteEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A route to a particular destination." + INDEX { ipRouteDest } + ::= { ipRouteTable 1 } + + IpRouteEntry ::= + SEQUENCE { + ipRouteDest + IpAddress, + ipRouteIfIndex + INTEGER, + ipRouteMetric1 + INTEGER, + ipRouteMetric2 + INTEGER, + ipRouteMetric3 + INTEGER, + ipRouteMetric4 + INTEGER, + ipRouteNextHop + IpAddress, + ipRouteType + INTEGER, + ipRouteProto + INTEGER, + ipRouteAge + INTEGER, + ipRouteMask + IpAddress, + ipRouteMetric5 + INTEGER, + ipRouteInfo + OBJECT IDENTIFIER + } + + ipRouteDest OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The destination IP address of this route. An + entry with a value of 0.0.0.0 is considered a + default route. Multiple routes to a single + destination can appear in the table, but access to + such multiple entries is dependent on the table- + access mechanisms defined by the network + management protocol in use." + ::= { ipRouteEntry 1 } + + ipRouteIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the + local interface through which the next hop of this + route should be reached. The interface identified + by a particular value of this index is the same + interface as identified by the same value of + ifIndex." + ::= { ipRouteEntry 2 } + + ipRouteMetric1 OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The primary routing metric for this route. The + semantics of this metric are determined by the + routing-protocol specified in the route's + ipRouteProto value. If this metric is not used, + its value should be set to -1." + ::= { ipRouteEntry 3 } + + ipRouteMetric2 OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "An alternate routing metric for this route. The + semantics of this metric are determined by the + routing-protocol specified in the route's + ipRouteProto value. If this metric is not used, + its value should be set to -1." + ::= { ipRouteEntry 4 } + + ipRouteMetric3 OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "An alternate routing metric for this route. The + semantics of this metric are determined by the + routing-protocol specified in the route's + ipRouteProto value. If this metric is not used, + its value should be set to -1." + ::= { ipRouteEntry 5 } + + ipRouteMetric4 OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "An alternate routing metric for this route. The + semantics of this metric are determined by the + routing-protocol specified in the route's + ipRouteProto value. If this metric is not used, + its value should be set to -1." + ::= { ipRouteEntry 6 } + + ipRouteNextHop OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The IP address of the next hop of this route. + (In the case of a route bound to an interface + which is realized via a broadcast media, the value + of this field is the agent's IP address on that + interface.)" + ::= { ipRouteEntry 7 } + + ipRouteType OBJECT-TYPE + SYNTAX INTEGER { + other(1), -- none of the following + + invalid(2), -- an invalidated route + -- route to directly + direct(3), -- connected (sub-)network + + -- route to a non-local + indirect(4) -- host/network/sub-network + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The type of route. Note that the values + direct(3) and indirect(4) refer to the notion of + direct and indirect routing in the IP + architecture. + + Setting this object to the value invalid(2) has + the effect of invalidating the corresponding entry + in the ipRouteTable object. That is, it + effectively disassociates the destination + identified with said entry from the route + identified with said entry. It is an + implementation-specific matter as to whether the + agent removes an invalidated entry from the table. + Accordingly, management stations must be prepared + to receive tabular information from agents that + corresponds to entries not currently in use. + Proper interpretation of such entries requires + examination of the relevant ipRouteType object." + ::= { ipRouteEntry 8 } + + ipRouteProto OBJECT-TYPE + SYNTAX INTEGER { + other(1), -- none of the following + + -- non-protocol information, + -- e.g., manually configured + local(2), -- entries + + -- set via a network + netmgmt(3), -- management protocol + + -- obtained via ICMP, + icmp(4), -- e.g., Redirect + + -- the remaining values are + -- all gateway routing + -- protocols + egp(5), + ggp(6), + hello(7), + rip(8), + is-is(9), + es-is(10), + ciscoIgrp(11), + bbnSpfIgp(12), + ospf(13), + bgp(14) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The routing mechanism via which this route was + learned. Inclusion of values for gateway routing + protocols is not intended to imply that hosts + should support those protocols." + ::= { ipRouteEntry 9 } + + ipRouteAge OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The number of seconds since this route was last + updated or otherwise determined to be correct. + Note that no semantics of `too old' can be implied + except through knowledge of the routing protocol + by which the route was learned." + ::= { ipRouteEntry 10 } + + ipRouteMask OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "Indicate the mask to be logical-ANDed with the + destination address before being compared to the + value in the ipRouteDest field. For those systems + that do not support arbitrary subnet masks, an + agent constructs the value of the ipRouteMask by + determining whether the value of the correspondent + ipRouteDest field belong to a class-A, B, or C + network, and then using one of: + + mask network + 255.0.0.0 class-A + 255.255.0.0 class-B + 255.255.255.0 class-C + + If the value of the ipRouteDest is 0.0.0.0 (a + default route), then the mask value is also + 0.0.0.0. It should be noted that all IP routing + subsystems implicitly use this mechanism." + ::= { ipRouteEntry 11 } + + ipRouteMetric5 OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "An alternate routing metric for this route. The + semantics of this metric are determined by the + routing-protocol specified in the route's + ipRouteProto value. If this metric is not used, + its value should be set to -1." + ::= { ipRouteEntry 12 } + + ipRouteInfo OBJECT-TYPE + SYNTAX OBJECT IDENTIFIER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A reference to MIB definitions specific to the + particular routing protocol which is responsible + for this route, as determined by the value + specified in the route's ipRouteProto value. If + this information is not present, its value should + be set to the OBJECT IDENTIFIER { 0 0 }, which is + a syntactically valid object identifier, and any + conformant implementation of ASN.1 and BER must be + able to generate and recognize this value." + ::= { ipRouteEntry 13 } + + + -- the IP Address Translation table + + -- The IP address translation table contain the IpAddress to + -- `physical' address equivalences. Some interfaces do not + -- use translation tables for determining address + -- equivalences (e.g., DDN-X.25 has an algorithmic method); + -- if all interfaces are of this type, then the Address + -- Translation table is empty, i.e., has zero entries. + + ipNetToMediaTable OBJECT-TYPE + SYNTAX SEQUENCE OF IpNetToMediaEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The IP Address Translation table used for mapping + from IP addresses to physical addresses." + ::= { ip 22 } + + ipNetToMediaEntry OBJECT-TYPE + SYNTAX IpNetToMediaEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Each entry contains one IpAddress to `physical' + address equivalence." + INDEX { ipNetToMediaIfIndex, + ipNetToMediaNetAddress } + ::= { ipNetToMediaTable 1 } + + IpNetToMediaEntry ::= + SEQUENCE { + ipNetToMediaIfIndex + INTEGER, + ipNetToMediaPhysAddress + PhysAddress, + ipNetToMediaNetAddress + IpAddress, + ipNetToMediaType + INTEGER + } + + ipNetToMediaIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The interface on which this entry's equivalence + is effective. The interface identified by a + particular value of this index is the same + interface as identified by the same value of + ifIndex." + ::= { ipNetToMediaEntry 1 } + + ipNetToMediaPhysAddress OBJECT-TYPE + SYNTAX PhysAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The media-dependent `physical' address." + ::= { ipNetToMediaEntry 2 } + + ipNetToMediaNetAddress OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The IpAddress corresponding to the media- + dependent `physical' address." + ::= { ipNetToMediaEntry 3 } + + ipNetToMediaType OBJECT-TYPE + SYNTAX INTEGER { + other(1), -- none of the following + invalid(2), -- an invalidated mapping + dynamic(3), + static(4) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The type of mapping. + + Setting this object to the value invalid(2) has + the effect of invalidating the corresponding entry + in the ipNetToMediaTable. That is, it effectively + disassociates the interface identified with said + entry from the mapping identified with said entry. + It is an implementation-specific matter as to + whether the agent removes an invalidated entry + from the table. Accordingly, management stations + must be prepared to receive tabular information + from agents that corresponds to entries not + currently in use. Proper interpretation of such + entries requires examination of the relevant + ipNetToMediaType object." + ::= { ipNetToMediaEntry 4 } + + + -- additional IP objects + + ipRoutingDiscards OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of routing entries which were chosen + to be discarded even though they are valid. One + possible reason for discarding such an entry could + be to free-up buffer space for other routing + entries." + ::= { ip 23 } + + + -- the ICMP group + + -- Implementation of the ICMP group is mandatory for all + -- systems. + + icmpInMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of ICMP messages which the + entity received. Note that this counter includes + all those counted by icmpInErrors." + ::= { icmp 1 } + + icmpInErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP messages which the entity + received but determined as having ICMP-specific + errors (bad ICMP checksums, bad length, etc.)." + ::= { icmp 2 } + + icmpInDestUnreachs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Destination Unreachable + messages received." + ::= { icmp 3 } + + icmpInTimeExcds OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Time Exceeded messages + received." + ::= { icmp 4 } + + + icmpInParmProbs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Parameter Problem messages + received." + ::= { icmp 5 } + + icmpInSrcQuenchs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Source Quench messages + received." + ::= { icmp 6 } + + icmpInRedirects OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Redirect messages received." + ::= { icmp 7 } + + icmpInEchos OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Echo (request) messages + received." + ::= { icmp 8 } + + icmpInEchoReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Echo Reply messages received." + ::= { icmp 9 } + + icmpInTimestamps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Timestamp (request) messages + received." + ::= { icmp 10 } + + icmpInTimestampReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Timestamp Reply messages + received." + ::= { icmp 11 } + + icmpInAddrMasks OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Address Mask Request messages + received." + ::= { icmp 12 } + + icmpInAddrMaskReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Address Mask Reply messages + received." + ::= { icmp 13 } + + icmpOutMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of ICMP messages which this + entity attempted to send. Note that this counter + includes all those counted by icmpOutErrors." + ::= { icmp 14 } + + icmpOutErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP messages which this entity did + not send due to problems discovered within ICMP + such as a lack of buffers. This value should not + include errors discovered outside the ICMP layer + such as the inability of IP to route the resultant + datagram. In some implementations there may be no + types of error which contribute to this counter's + value." + ::= { icmp 15 } + + icmpOutDestUnreachs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Destination Unreachable + messages sent." + ::= { icmp 16 } + + icmpOutTimeExcds OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Time Exceeded messages sent." + ::= { icmp 17 } + + icmpOutParmProbs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Parameter Problem messages + sent." + ::= { icmp 18 } + + icmpOutSrcQuenchs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Source Quench messages sent." + ::= { icmp 19 } + + icmpOutRedirects OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Redirect messages sent. For a + host, this object will always be zero, since hosts + do not send redirects." + ::= { icmp 20 } + + icmpOutEchos OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Echo (request) messages sent." + ::= { icmp 21 } + + icmpOutEchoReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Echo Reply messages sent." + ::= { icmp 22 } + + icmpOutTimestamps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Timestamp (request) messages + sent." + ::= { icmp 23 } + + icmpOutTimestampReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Timestamp Reply messages + sent." + ::= { icmp 24 } + + icmpOutAddrMasks OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Address Mask Request messages + sent." + ::= { icmp 25 } + + + icmpOutAddrMaskReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Address Mask Reply messages + sent." + ::= { icmp 26 } + + + -- the TCP group + + -- Implementation of the TCP group is mandatory for all + -- systems that implement the TCP. + + -- Note that instances of object types that represent + -- information about a particular TCP connection are + -- transient; they persist only as long as the connection + -- in question. + + tcpRtoAlgorithm OBJECT-TYPE + SYNTAX INTEGER { + other(1), -- none of the following + + constant(2), -- a constant rto + rsre(3), -- MIL-STD-1778, Appendix B + vanj(4) -- Van Jacobson's algorithm [10] + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The algorithm used to determine the timeout value + used for retransmitting unacknowledged octets." + ::= { tcp 1 } + + tcpRtoMin OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The minimum value permitted by a TCP + implementation for the retransmission timeout, + measured in milliseconds. More refined semantics + for objects of this type depend upon the algorithm + used to determine the retransmission timeout. In + particular, when the timeout algorithm is rsre(3), + an object of this type has the semantics of the + LBOUND quantity described in RFC 793." + ::= { tcp 2 } + + + tcpRtoMax OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The maximum value permitted by a TCP + implementation for the retransmission timeout, + measured in milliseconds. More refined semantics + for objects of this type depend upon the algorithm + used to determine the retransmission timeout. In + particular, when the timeout algorithm is rsre(3), + an object of this type has the semantics of the + UBOUND quantity described in RFC 793." + ::= { tcp 3 } + + tcpMaxConn OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The limit on the total number of TCP connections + the entity can support. In entities where the + maximum number of connections is dynamic, this + object should contain the value -1." + ::= { tcp 4 } + + tcpActiveOpens OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of times TCP connections have made a + direct transition to the SYN-SENT state from the + CLOSED state." + ::= { tcp 5 } + + tcpPassiveOpens OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of times TCP connections have made a + direct transition to the SYN-RCVD state from the + LISTEN state." + ::= { tcp 6 } + + tcpAttemptFails OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of times TCP connections have made a + direct transition to the CLOSED state from either + the SYN-SENT state or the SYN-RCVD state, plus the + number of times TCP connections have made a direct + transition to the LISTEN state from the SYN-RCVD + state." + ::= { tcp 7 } + + tcpEstabResets OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of times TCP connections have made a + direct transition to the CLOSED state from either + the ESTABLISHED state or the CLOSE-WAIT state." + ::= { tcp 8 } + + tcpCurrEstab OBJECT-TYPE + SYNTAX Gauge + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of TCP connections for which the + current state is either ESTABLISHED or CLOSE- + WAIT." + ::= { tcp 9 } + + tcpInSegs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of segments received, including + those received in error. This count includes + segments received on currently established + connections." + ::= { tcp 10 } + + tcpOutSegs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of segments sent, including + those on current connections but excluding those + containing only retransmitted octets." + ::= { tcp 11 } + + tcpRetransSegs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of segments retransmitted - that + is, the number of TCP segments transmitted + containing one or more previously transmitted + octets." + ::= { tcp 12 } + + + -- the TCP Connection table + + -- The TCP connection table contains information about this + -- entity's existing TCP connections. + + tcpConnTable OBJECT-TYPE + SYNTAX SEQUENCE OF TcpConnEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A table containing TCP connection-specific + information." + ::= { tcp 13 } + + tcpConnEntry OBJECT-TYPE + SYNTAX TcpConnEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Information about a particular current TCP + connection. An object of this type is transient, + in that it ceases to exist when (or soon after) + the connection makes the transition to the CLOSED + state." + INDEX { tcpConnLocalAddress, + tcpConnLocalPort, + tcpConnRemAddress, + tcpConnRemPort } + ::= { tcpConnTable 1 } + + TcpConnEntry ::= + SEQUENCE { + tcpConnState + INTEGER, + tcpConnLocalAddress + IpAddress, + tcpConnLocalPort + INTEGER (0..65535), + tcpConnRemAddress + IpAddress, + tcpConnRemPort + INTEGER (0..65535) + } + + tcpConnState OBJECT-TYPE + SYNTAX INTEGER { + closed(1), + listen(2), + synSent(3), + synReceived(4), + established(5), + finWait1(6), + finWait2(7), + closeWait(8), + lastAck(9), + closing(10), + timeWait(11), + deleteTCB(12) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The state of this TCP connection. + + The only value which may be set by a management + station is deleteTCB(12). Accordingly, it is + appropriate for an agent to return a `badValue' + response if a management station attempts to set + this object to any other value. + + If a management station sets this object to the + value deleteTCB(12), then this has the effect of + deleting the TCB (as defined in RFC 793) of the + corresponding connection on the managed node, + resulting in immediate termination of the + connection. + + As an implementation-specific option, a RST + segment may be sent from the managed node to the + other TCP endpoint (note however that RST segments + are not sent reliably)." + ::= { tcpConnEntry 1 } + + tcpConnLocalAddress OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The local IP address for this TCP connection. In + the case of a connection in the listen state which + is willing to accept connections for any IP + interface associated with the node, the value + 0.0.0.0 is used." + ::= { tcpConnEntry 2 } + + tcpConnLocalPort OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The local port number for this TCP connection." + ::= { tcpConnEntry 3 } + + tcpConnRemAddress OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The remote IP address for this TCP connection." + ::= { tcpConnEntry 4 } + + tcpConnRemPort OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The remote port number for this TCP connection." + ::= { tcpConnEntry 5 } + + + -- additional TCP objects + + tcpInErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of segments received in error + (e.g., bad TCP checksums)." + ::= { tcp 14 } + + tcpOutRsts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of TCP segments sent containing the + RST flag." + ::= { tcp 15 } + + + -- the UDP group + + -- Implementation of the UDP group is mandatory for all + -- systems which implement the UDP. + + udpInDatagrams OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of UDP datagrams delivered to + UDP users." + ::= { udp 1 } + + udpNoPorts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of received UDP datagrams for + which there was no application at the destination + port." + ::= { udp 2 } + + udpInErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of received UDP datagrams that could + not be delivered for reasons other than the lack + of an application at the destination port." + ::= { udp 3 } + + udpOutDatagrams OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of UDP datagrams sent from this + entity." + ::= { udp 4 } + + + -- the UDP Listener table + + -- The UDP listener table contains information about this + -- entity's UDP end-points on which a local application is + -- currently accepting datagrams. + + udpTable OBJECT-TYPE + SYNTAX SEQUENCE OF UdpEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A table containing UDP listener information." + ::= { udp 5 } + + udpEntry OBJECT-TYPE + SYNTAX UdpEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Information about a particular current UDP + listener." + INDEX { udpLocalAddress, udpLocalPort } + ::= { udpTable 1 } + + UdpEntry ::= + SEQUENCE { + udpLocalAddress + IpAddress, + udpLocalPort + INTEGER (0..65535) + } + + udpLocalAddress OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The local IP address for this UDP listener. In + the case of a UDP listener which is willing to + accept datagrams for any IP interface associated + with the node, the value 0.0.0.0 is used." + ::= { udpEntry 1 } + + udpLocalPort OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The local port number for this UDP listener." + ::= { udpEntry 2 } + + + -- the EGP group + + -- Implementation of the EGP group is mandatory for all + -- systems which implement the EGP. + + egpInMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP messages received without + error." + ::= { egp 1 } + + egpInErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP messages received that proved + to be in error." + ::= { egp 2 } + + egpOutMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of locally generated EGP + messages." + ::= { egp 3 } + + egpOutErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of locally generated EGP messages not + sent due to resource limitations within an EGP + entity." + ::= { egp 4 } + + + -- the EGP Neighbor table + + -- The EGP neighbor table contains information about this + -- entity's EGP neighbors. + + egpNeighTable OBJECT-TYPE + SYNTAX SEQUENCE OF EgpNeighEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The EGP neighbor table." + ::= { egp 5 } + + egpNeighEntry OBJECT-TYPE + SYNTAX EgpNeighEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Information about this entity's relationship with + a particular EGP neighbor." + INDEX { egpNeighAddr } + ::= { egpNeighTable 1 } + + EgpNeighEntry ::= + SEQUENCE { + egpNeighState + INTEGER, + egpNeighAddr + IpAddress, + egpNeighAs + INTEGER, + egpNeighInMsgs + Counter, + egpNeighInErrs + Counter, + egpNeighOutMsgs + Counter, + egpNeighOutErrs + Counter, + egpNeighInErrMsgs + Counter, + egpNeighOutErrMsgs + Counter, + egpNeighStateUps + Counter, + egpNeighStateDowns + Counter, + egpNeighIntervalHello + INTEGER, + egpNeighIntervalPoll + INTEGER, + egpNeighMode + INTEGER, + egpNeighEventTrigger + INTEGER + } + + egpNeighState OBJECT-TYPE + SYNTAX INTEGER { + idle(1), + acquisition(2), + down(3), + up(4), + cease(5) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The EGP state of the local system with respect to + this entry's EGP neighbor. Each EGP state is + represented by a value that is one greater than + the numerical value associated with said state in + RFC 904." + ::= { egpNeighEntry 1 } + + egpNeighAddr OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The IP address of this entry's EGP neighbor." + ::= { egpNeighEntry 2 } + + egpNeighAs OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The autonomous system of this EGP peer. Zero + should be specified if the autonomous system + number of the neighbor is not yet known." + ::= { egpNeighEntry 3 } + + egpNeighInMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP messages received without error + from this EGP peer." + ::= { egpNeighEntry 4 } + + egpNeighInErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP messages received from this EGP + peer that proved to be in error (e.g., bad EGP + checksum)." + ::= { egpNeighEntry 5 } + + egpNeighOutMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of locally generated EGP messages to + this EGP peer." + ::= { egpNeighEntry 6 } + + egpNeighOutErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of locally generated EGP messages not + sent to this EGP peer due to resource limitations + within an EGP entity." + ::= { egpNeighEntry 7 } + + egpNeighInErrMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP-defined error messages received + from this EGP peer." + ::= { egpNeighEntry 8 } + + egpNeighOutErrMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP-defined error messages sent to + this EGP peer." + ::= { egpNeighEntry 9 } + + egpNeighStateUps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP state transitions to the UP + state with this EGP peer." + ::= { egpNeighEntry 10 } + + egpNeighStateDowns OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP state transitions from the UP + state to any other state with this EGP peer." + ::= { egpNeighEntry 11 } + + egpNeighIntervalHello OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The interval between EGP Hello command + retransmissions (in hundredths of a second). This + represents the t1 timer as defined in RFC 904." + ::= { egpNeighEntry 12 } + + egpNeighIntervalPoll OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The interval between EGP poll command + retransmissions (in hundredths of a second). This + represents the t3 timer as defined in RFC 904." + ::= { egpNeighEntry 13 } + + egpNeighMode OBJECT-TYPE + SYNTAX INTEGER { active(1), passive(2) } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The polling mode of this EGP entity, either + passive or active." + ::= { egpNeighEntry 14 } + + egpNeighEventTrigger OBJECT-TYPE + SYNTAX INTEGER { start(1), stop(2) } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "A control variable used to trigger operator- + initiated Start and Stop events. When read, this + variable always returns the most recent value that + egpNeighEventTrigger was set to. If it has not + been set since the last initialization of the + network management subsystem on the node, it + returns a value of `stop'. + + When set, this variable causes a Start or Stop + event on the specified neighbor, as specified on + pages 8-10 of RFC 904. Briefly, a Start event + causes an Idle peer to begin neighbor acquisition + and a non-Idle peer to reinitiate neighbor + acquisition. A stop event causes a non-Idle peer + to return to the Idle state until a Start event + occurs, either via egpNeighEventTrigger or + otherwise." + ::= { egpNeighEntry 15 } + + + -- additional EGP objects + + egpAs OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The autonomous system number of this EGP entity." + ::= { egp 6 } + + -- the Transmission group + + -- Based on the transmission media underlying each interface + -- on a system, the corresponding portion of the Transmission + -- group is mandatory for that system. + + -- When Internet-standard definitions for managing + -- transmission media are defined, the transmission group is + -- used to provide a prefix for the names of those objects. + + -- Typically, such definitions reside in the experimental + -- portion of the MIB until they are "proven", then as a + -- part of the Internet standardization process, the + -- definitions are accordingly elevated and a new object + -- identifier, under the transmission group is defined. By + -- convention, the name assigned is: + -- + -- type OBJECT IDENTIFIER ::= { transmission number } + -- + -- where "type" is the symbolic value used for the media in + -- the ifType column of the ifTable object, and "number" is + -- the actual integer value corresponding to the symbol. + + + -- the SNMP group + + -- Implementation of the SNMP group is mandatory for all + -- systems which support an SNMP protocol entity. Some of + -- the objects defined below will be zero-valued in those + -- SNMP implementations that are optimized to support only + -- those functions specific to either a management agent or + -- a management station. In particular, it should be + -- observed that the objects below refer to an SNMP entity, + -- and there may be several SNMP entities residing on a + -- managed node (e.g., if the node is hosting acting as + -- a management station). + + snmpInPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of Messages delivered to the + SNMP entity from the transport service." + ::= { snmp 1 } + + snmpOutPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Messages which were + passed from the SNMP protocol entity to the + transport service." + ::= { snmp 2 } + + snmpInBadVersions OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Messages which were + delivered to the SNMP protocol entity and were for + an unsupported SNMP version." + ::= { snmp 3 } + + snmpInBadCommunityNames OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Messages delivered to + the SNMP protocol entity which used a SNMP + community name not known to said entity." + ::= { snmp 4 } + + snmpInBadCommunityUses OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Messages delivered to + the SNMP protocol entity which represented an SNMP + operation which was not allowed by the SNMP + community named in the Message." + ::= { snmp 5 } + + snmpInASNParseErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of ASN.1 or BER errors + encountered by the SNMP protocol entity when + decoding received SNMP Messages." + ::= { snmp 6 } + + -- { snmp 7 } is not used + + snmpInTooBigs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + delivered to the SNMP protocol entity and for + which the value of the error-status field is + `tooBig'." + ::= { snmp 8 } + + snmpInNoSuchNames OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + delivered to the SNMP protocol entity and for + which the value of the error-status field is + `noSuchName'." + ::= { snmp 9 } + + snmpInBadValues OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + delivered to the SNMP protocol entity and for + which the value of the error-status field is + `badValue'." + ::= { snmp 10 } + + snmpInReadOnlys OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number valid SNMP PDUs which were + delivered to the SNMP protocol entity and for + which the value of the error-status field is + `readOnly'. It should be noted that it is a + protocol error to generate an SNMP PDU which + contains the value `readOnly' in the error-status + field, as such this object is provided as a means + of detecting incorrect implementations of the + SNMP." + ::= { snmp 11 } + + snmpInGenErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + delivered to the SNMP protocol entity and for + which the value of the error-status field is + `genErr'." + ::= { snmp 12 } + + snmpInTotalReqVars OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of MIB objects which have been + retrieved successfully by the SNMP protocol entity + as the result of receiving valid SNMP Get-Request + and Get-Next PDUs." + ::= { snmp 13 } + + snmpInTotalSetVars OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of MIB objects which have been + altered successfully by the SNMP protocol entity + as the result of receiving valid SNMP Set-Request + PDUs." + ::= { snmp 14 } + + snmpInGetRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Request PDUs which + have been accepted and processed by the SNMP + protocol entity." + ::= { snmp 15 } + + snmpInGetNexts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Next PDUs which have + been accepted and processed by the SNMP protocol + entity." + ::= { snmp 16 } + + snmpInSetRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Set-Request PDUs which + have been accepted and processed by the SNMP + protocol entity." + ::= { snmp 17 } + + snmpInGetResponses OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Response PDUs which + have been accepted and processed by the SNMP + protocol entity." + ::= { snmp 18 } + + snmpInTraps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Trap PDUs which have + been accepted and processed by the SNMP protocol + entity." + ::= { snmp 19 } + + snmpOutTooBigs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + generated by the SNMP protocol entity and for + which the value of the error-status field is + `tooBig.'" + ::= { snmp 20 } + + snmpOutNoSuchNames OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + generated by the SNMP protocol entity and for + which the value of the error-status is + `noSuchName'." + ::= { snmp 21 } + + snmpOutBadValues OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + generated by the SNMP protocol entity and for + which the value of the error-status field is + `badValue'." + ::= { snmp 22 } + + -- { snmp 23 } is not used + + snmpOutGenErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + generated by the SNMP protocol entity and for + which the value of the error-status field is + `genErr'." + ::= { snmp 24 } + + snmpOutGetRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Request PDUs which + have been generated by the SNMP protocol entity." + ::= { snmp 25 } + + snmpOutGetNexts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Next PDUs which have + been generated by the SNMP protocol entity." + ::= { snmp 26 } + + snmpOutSetRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Set-Request PDUs which + have been generated by the SNMP protocol entity." + ::= { snmp 27 } + + snmpOutGetResponses OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Response PDUs which + have been generated by the SNMP protocol entity." + ::= { snmp 28 } + + snmpOutTraps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Trap PDUs which have + been generated by the SNMP protocol entity." + ::= { snmp 29 } + + snmpEnableAuthenTraps OBJECT-TYPE + SYNTAX INTEGER { enabled(1), disabled(2) } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "Indicates whether the SNMP agent process is + permitted to generate authentication-failure + traps. The value of this object overrides any + configuration information; as such, it provides a + means whereby all authentication-failure traps may + be disabled. + + Note that it is strongly recommended that this + object be stored in non-volatile memory so that it + remains constant between re-initializations of the + network management system." + ::= { snmp 30 } + +END diff --git a/ACE/ASNMP/tests/Address_Test.cpp b/ACE/ASNMP/tests/Address_Test.cpp new file mode 100644 index 00000000000..fce2067ab31 --- /dev/null +++ b/ACE/ASNMP/tests/Address_Test.cpp @@ -0,0 +1,549 @@ +// $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 "ace/OS_main.h" +#include "asnmp/address.h" +#include "test_config.h" + +ACE_RCSID(tests, Address_Test, "$Id$") + +// 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 *resolve_hostname(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_private()); + ACE_ASSERT(!ia6.is_multicast()); + ACE_ASSERT(!ia6.is_loopback()); + + IpAddress ia7("172.16.0.1"); + ACE_ASSERT(ia7.is_private()); + + IpAddress ia8("192.168.0.1"); + ACE_ASSERT(ia8.is_private()); + + 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.resolve_hostname(status); + ACE_ASSERT(status == 0); + ACE_ASSERT(ptr != 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpAddress:ia5.resolve_hostname():(\"\") [%s]\n", + ptr)); + + // now lets try one we setup with a hostname + ptr = ia3.resolve_hostname(status); + ACE_ASSERT(status == 0); + ACE_ASSERT(ptr != 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) IpAddress:ia3.resolve_hostname()(\"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); + ACE_ASSERT(nb_server == n1.get_service_type()); +} + +// --------------- 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 +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Address_Test")); + + TestGenAddr(); + TestIpAddress(); + TestUdpAddress(); + TestMacAddress(); + TestNetbiosAddress(); + TestIpxAddress(); + + ACE_END_TEST; + return 0; +} diff --git a/ACE/ASNMP/tests/Counter64_Test.cpp b/ACE/ASNMP/tests/Counter64_Test.cpp new file mode 100644 index 00000000000..f0b9ee8ad56 --- /dev/null +++ b/ACE/ASNMP/tests/Counter64_Test.cpp @@ -0,0 +1,156 @@ +// $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_main.h" +#include "asnmp/ctr64.h" +#include "test_config.h" + +ACE_RCSID(tests, Counter64_Test, "$Id$") + +// TODO: verify this with ACE folks +#if defined(_WIN32) +#define LLONG __int64 +#define ULLONG unsigned __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() +{ +#if !defined (ACE_WIN32) + static unsigned long ul = ULONG_MAX; + LLONG ll = (LLONG) 0x7fffffffffffffffLL; + LLONG mll = (LLONG) ((-ll) - 1); + ULLONG ull = (ULLONG) 0xffffffffffffffffULL; + 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 == static_cast<ACE_UINT64> (ll)); + // try simple arithmetic (needs more test cases) + c5 = mll; + c5 = c5 + (ULLONG) 10; + ACE_ASSERT(c5 == static_cast<ACE_UINT64> (mll + 10)); +#endif /*ACE_WIN32 */ +} + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Counter64_Test")); + + TestCounter64(); + + ACE_END_TEST; + return 0; +} diff --git a/ACE/ASNMP/tests/Counter_Test.cpp b/ACE/ASNMP/tests/Counter_Test.cpp new file mode 100644 index 00000000000..c6b4b4c9b72 --- /dev/null +++ b/ACE/ASNMP/tests/Counter_Test.cpp @@ -0,0 +1,136 @@ +// $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_main.h" +#include "asnmp/counter.h" +#include "test_config.h" + +ACE_RCSID(tests, Counter_Test, "$Id$") + +/* + 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() +{ +#if !defined (ACE_WIN32) + 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 = static_cast<short> (65535); + + // constructors + Counter32 c1; + ACE_ASSERT(c1 == def); + Counter32 c2(l); + ACE_ASSERT(c2 == static_cast<unsigned long> (l)); + Counter32 c3(nl); + ACE_ASSERT(c3 == static_cast<unsigned long> (nl)); + Counter32 c4(ul); + ACE_ASSERT(c4 == ul); + Counter32 c5(i); + ACE_ASSERT(c5 == static_cast<unsigned long> (i)); + Counter32 c6(ni); + ACE_ASSERT(c6 == static_cast<unsigned long> (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 == static_cast<unsigned long> (us)); + c1 = si; // unsigned short + ACE_ASSERT(c1 == static_cast<unsigned long> (si)); +#endif /*ACE_WIN32*/ +} + + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Counter_Test")); + + TestCounter(); + + ACE_END_TEST; + return 0; +} diff --git a/ACE/ASNMP/tests/Gauge_Test.cpp b/ACE/ASNMP/tests/Gauge_Test.cpp new file mode 100644 index 00000000000..45a4ac279e7 --- /dev/null +++ b/ACE/ASNMP/tests/Gauge_Test.cpp @@ -0,0 +1,133 @@ +// $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_main.h" +#include "asnmp/gauge.h" +#include "test_config.h" + +ACE_RCSID (tests, + Gauge_Test, + "$Id$") + +/* + 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 decrease, but which latches at a maximum + value of 2^32-1 (4294967295 dec) for gauges. + */ +static void +TestGuage (void) +{ +#if !defined (ACE_WIN32) + 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 = static_cast<short> (65535); + + // constructors + Gauge32 g1; + ACE_ASSERT(g1 == def); + Gauge32 g2(l); + ACE_ASSERT(g2 == static_cast<unsigned long> (l)); + Gauge32 g3(nl); + ACE_ASSERT(g3 == static_cast<unsigned long> (nl)); + Gauge32 g4(ul); + ACE_ASSERT(g4 == ul); + Gauge32 g5(i); + ACE_ASSERT(g5 == static_cast<unsigned long> (i)); + Gauge32 g6(ni); + ACE_ASSERT(g6 == static_cast<unsigned long> (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 == static_cast<unsigned long> (us)); + g1 = si; // unsigned short + ACE_ASSERT(g1 == static_cast<unsigned long> (si)); +#endif /*ACE_WIN32*/ +} + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Gauge_Test")); + + TestGuage(); + + ACE_END_TEST; + return 0; +} diff --git a/ACE/ASNMP/tests/Integer_Test.cpp b/ACE/ASNMP/tests/Integer_Test.cpp new file mode 100644 index 00000000000..8cea7e33f1b --- /dev/null +++ b/ACE/ASNMP/tests/Integer_Test.cpp @@ -0,0 +1,200 @@ +// $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_main.h" +#include "asnmp/integer.h" +#include "test_config.h" + +ACE_RCSID (tests, + Integer_Test, + "$Id$") + +#if !defined (ACE_WIN32) +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 unsigned short si = 32768; + #endif /*ACE_WIN32*/ + +/* + 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() +{ +#if !defined (ACE_WIN32) + // constructors + SnmpInt32 i1; + ACE_ASSERT(i1 == static_cast<long> (def)); + SnmpInt32 i2(l); + ACE_ASSERT(i2 == l); + SnmpInt32 i3(nl); + ACE_ASSERT(i3 == nl); + SnmpInt32 i4(ul); + ACE_ASSERT(i4 == static_cast<long> (ul)); + SnmpInt32 i5(i); + ACE_ASSERT(i5 == i); + SnmpInt32 i6(ni); + ACE_ASSERT(i6 == ni); + SnmpInt32 i7(ui); + ACE_ASSERT(i7 == static_cast<long> (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 == static_cast<long> (def)); + i1 = us; // unsigned short + ACE_ASSERT(i1 == static_cast<long> (us)); + i1 = si; // unsigned short + ACE_ASSERT(i1 == static_cast<long> (si)); + #endif /*ACE_WIN32*/ +} + +/* + 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() +{ +#if !defined (ACE_WIN32) + // constructors + SnmpUInt32 u1; + ACE_ASSERT(u1 == def); + SnmpUInt32 u2(l); + ACE_ASSERT(u2 == static_cast<unsigned long> (l)); + SnmpUInt32 u3(nl); + ACE_ASSERT(u3 == static_cast<unsigned long> (nl)); + SnmpUInt32 u4(ul); + ACE_ASSERT(u4 == ul); + SnmpUInt32 u5(i); + ACE_ASSERT(u5 == static_cast<unsigned long> (i)); + SnmpUInt32 u6(ni); + ACE_ASSERT(u6 == static_cast<unsigned long> (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 == static_cast<unsigned long> (us)); + u1 = si; // unsigned short + ACE_ASSERT(u1 == static_cast<unsigned long> (si)); +#endif /*ACE_WIN32 */ +} + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Integer_Test")); + + TestInteger32(); + + TestUnsignedInteger32(); + + ACE_END_TEST; + return 0; +} diff --git a/ACE/ASNMP/tests/Makefile.am b/ACE/ASNMP/tests/Makefile.am new file mode 100644 index 00000000000..b8ac30972bf --- /dev/null +++ b/ACE/ASNMP/tests/Makefile.am @@ -0,0 +1,173 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.asnmp_tests_Address_Test.am + +noinst_PROGRAMS = Address_Test + +Address_Test_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +Address_Test_SOURCES = \ + Address_Test.cpp \ + test_config.h + +Address_Test_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.asnmp_tests_Counter64_Test.am + +noinst_PROGRAMS += Counter64_Test + +Counter64_Test_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +Counter64_Test_SOURCES = \ + Counter64_Test.cpp \ + test_config.h + +Counter64_Test_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.asnmp_tests_Counter_Test.am + +noinst_PROGRAMS += Counter_Test + +Counter_Test_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +Counter_Test_SOURCES = \ + Counter_Test.cpp \ + test_config.h + +Counter_Test_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.asnmp_tests_Gauge_Test.am + +noinst_PROGRAMS += Gauge_Test + +Gauge_Test_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +Gauge_Test_SOURCES = \ + Gauge_Test.cpp \ + test_config.h + +Gauge_Test_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.asnmp_tests_Integer_Test.am + +noinst_PROGRAMS += Integer_Test + +Integer_Test_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +Integer_Test_SOURCES = \ + Integer_Test.cpp \ + test_config.h + +Integer_Test_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.asnmp_tests_Octet_Test.am + +noinst_PROGRAMS += Octet_Test + +Octet_Test_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +Octet_Test_SOURCES = \ + Octet_Test.cpp \ + test_config.h + +Octet_Test_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.asnmp_tests_Oid_Test.am + +noinst_PROGRAMS += Oid_Test + +Oid_Test_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +Oid_Test_SOURCES = \ + Oid_Test.cpp \ + test_config.h + +Oid_Test_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.asnmp_tests_Target_Test.am + +noinst_PROGRAMS += Target_Test + +Target_Test_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +Target_Test_SOURCES = \ + Target_Test.cpp \ + test_config.h + +Target_Test_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.asnmp_tests_Varbind_Test.am + +noinst_PROGRAMS += Varbind_Test + +Varbind_Test_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/ASNMP + +Varbind_Test_SOURCES = \ + Varbind_Test.cpp \ + test_config.h + +Varbind_Test_LDADD = \ + $(top_builddir)/ASNMP/asnmp/libasnmp.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/ASNMP/tests/Octet_Test.cpp b/ACE/ASNMP/tests/Octet_Test.cpp new file mode 100644 index 00000000000..a32f1cd2f09 --- /dev/null +++ b/ACE/ASNMP/tests/Octet_Test.cpp @@ -0,0 +1,156 @@ +// $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_main.h" +#include "ace/OS_NS_string.h" +#include "asnmp/octet.h" +#include "test_config.h" + +ACE_RCSID(tests, Octet_Test, "$Id$") + +/* + 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); + + bool operator==( const OctetStr &lhs, const OctetStr &rhs); + bool operator!=( const OctetStr &lhs, const OctetStr &rhs); + bool operator<( const OctetStr &lhs, const OctetStr &rhs); + bool operator<=( const OctetStr &lhs,const OctetStr &rhs); + bool operator>( const OctetStr &lhs, const OctetStr &rhs); + bool operator>=( const OctetStr &lhs, const OctetStr &rhs); + bool operator==( const OctetStr &lhs,const char *rhs); + bool operator!=( const OctetStr &lhs,const char *rhs); + bool operator<( const OctetStr &lhs,const char *rhs); + bool operator<=( const OctetStr &lhs,char *rhs); + bool operator>( const OctetStr &lhs,const char *rhs); + bool 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() +{ + const char *str = "A test of octet strings...!@@#$%^&*()_+|~{}:,./<>?"; + OctetStr o1; + ACE_ASSERT(o1.valid() == 1); + 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 +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Octet_Test")); + + TestOctet(); + ACE_END_TEST; + return 0; +} diff --git a/ACE/ASNMP/tests/Oid_Test.cpp b/ACE/ASNMP/tests/Oid_Test.cpp new file mode 100644 index 00000000000..7add52bd790 --- /dev/null +++ b/ACE/ASNMP/tests/Oid_Test.cpp @@ -0,0 +1,181 @@ +// $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_main.h" +#include "asnmp/oid.h" +#include "test_config.h" + +ACE_RCSID(tests, Oid_Test, "$Id$") + +/* + 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); + bool operator==( const Oid &lhs,const Oid &rhs); + bool operator!=( const Oid &lhs,const Oid &rhs); + bool operator<( const Oid &lhs,const Oid &rhs); + bool operator<=( const Oid &lhs,const Oid &rhs); + bool operator>( const Oid &lhs,const Oid &rhs); + bool 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 +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Oid_Test")); + OidTest(); + ACE_END_TEST; + return 0; +} diff --git a/ACE/ASNMP/tests/Target_Test.cpp b/ACE/ASNMP/tests/Target_Test.cpp new file mode 100644 index 00000000000..28302e11cfd --- /dev/null +++ b/ACE/ASNMP/tests/Target_Test.cpp @@ -0,0 +1,145 @@ +// $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_main.h" +#include "asnmp/octet.h" +#include "asnmp/target.h" +#include "test_config.h" + +ACE_RCSID(tests, Target_Test, "$Id$") + +/* + 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 bool 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); + + // 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 +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Target_Test")); + TestSnmpTarget(); + + ACE_END_TEST; + return 0; +} diff --git a/ACE/ASNMP/tests/Varbind_Test.cpp b/ACE/ASNMP/tests/Varbind_Test.cpp new file mode 100644 index 00000000000..e9c9ecc923b --- /dev/null +++ b/ACE/ASNMP/tests/Varbind_Test.cpp @@ -0,0 +1,197 @@ +// $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_main.h" +#include "asnmp/oid.h" +#include "asnmp/vb.h" +#include "test_config.h" + +ACE_RCSID(tests, Varbind_Test, "$Id$") +/* + 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() +{ +#if !defined (ACE_WIN32) + + 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(12345678901234ULL), 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); +#endif /*if ACE_WIN32*/ +} + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Varbind_Test")); + VbTest(); + ACE_END_TEST; + return 0; +} + diff --git a/ACE/ASNMP/tests/run_tests.bat b/ACE/ASNMP/tests/run_tests.bat new file mode 100644 index 00000000000..985f88b51db --- /dev/null +++ b/ACE/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/ACE/ASNMP/tests/run_tests.sh b/ACE/ASNMP/tests/run_tests.sh new file mode 100755 index 00000000000..c8d911c184c --- /dev/null +++ b/ACE/ASNMP/tests/run_tests.sh @@ -0,0 +1,61 @@ +#!/bin/sh +# 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 [ -z $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/ACE/ASNMP/tests/test_config.h b/ACE/ASNMP/tests/test_config.h new file mode 100644 index 00000000000..a0d2bab7aa8 --- /dev/null +++ b/ACE/ASNMP/tests/test_config.h @@ -0,0 +1,177 @@ +/* -*- 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> +// +// ============================================================================ + +#ifndef ACE_TEST_CONFIG_H +#define ACE_TEST_CONFIG_H + +#include "ace/ACE.h" +#include "ace/Log_Msg.h" +#include "ace/OS_main.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_sys_stat.h" +#include "ace/OS_NS_stdlib.h" + +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" + +#if defined (ACE_WIN32) + +#define ACE_DEFAULT_TEST_FILE ACE_TEXT ("C:\\temp\\ace_test_file") +#define ACE_TEMP_FILE_NAME ACE_TEXT ("C:\\temp\\ace_temp_file") +#define ACE_LOG_DIRECTORY ACE_TEXT ("C:\\temp\\log\\") +#define MAKE_PIPE_NAME(X) ACE_TEXT ("\\\\.\\pipe\\"#X) + +#else + +#define ACE_DEFAULT_TEST_FILE ACE_TEXT ("/tmp/ace_test_file") +#define ACE_TEMP_FILE_NAME ACE_TEXT ("/tmp/ace_temp_file") +#define ACE_LOG_DIRECTORY ACE_TEXT ("log/") +#define MAKE_PIPE_NAME(X) ACE_TEXT (X) + +#endif /* ACE_WIN32 */ + +#ifndef ACE_START_TEST +#define ACE_START_TEST(NAME) \ + const ACE_TCHAR *program = NAME; \ + ACE_LOG_MSG->open (program, ACE_Log_Msg::OSTREAM); \ + if (ace_file_stream.set_output (program) != 0) \ + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("set_output failed")), -1); \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) starting %s test at %D\n"), program)); +#endif /* ACE_START_TEST */ + +#ifndef ACE_END_TEST +#define ACE_END_TEST \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Ending %s test at %D\n"), program)); \ + ace_file_stream.close (); +#endif /* ACE_END_TEST */ + +#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 ACE_TCHAR *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, ACE_TEXT ("%p\n"), ACE_TEXT ("set_output failed")), -1); \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Starting %s test at %D\n"), program)); + +#define ACE_END_LOG \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Ending %s test at %D\n\n"), program)); \ + ace_file_stream.close (); + +#define ACE_INIT_LOG(NAME) \ + char temp[BUFSIZ]; \ + ACE_OS::sprintf (temp, "%s%s%s", \ + ACE_TEXT_ALWAYS_CHAR (ACE_LOG_DIRECTORY), \ + ACE_TEXT_ALWAYS_CHAR (ACE::basename (NAME, ACE_DIRECTORY_SEPARATOR_CHAR)), \ + ".log"); \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Deleting old log file %C (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 ACE_TCHAR *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 ACE_TCHAR *filename, int append) +{ + char temp[BUFSIZ]; + // Ignore the error value since the directory may already exist. + ACE_OS::mkdir (ACE_LOG_DIRECTORY); + ACE_OS::sprintf (temp, "%s%s%s", + ACE_TEXT_ALWAYS_CHAR (ACE_LOG_DIRECTORY), + ACE_TEXT_ALWAYS_CHAR (ACE::basename (filename, ACE_DIRECTORY_SEPARATOR_CHAR)), + ".log"); + + this->output_file_.open (temp, ios::out | (append ? ios::app : ios::trunc)); + 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] = static_cast<int> (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() % static_cast<int> (size); + --size; + int temp = array [index]; + array [index] = array [size]; + array [size] = temp; + } +} + +#endif /* ACE_TEST_CONFIG_H */ diff --git a/ACE/ASNMP/tests/tests.mpc b/ACE/ASNMP/tests/tests.mpc new file mode 100644 index 00000000000..df62404642a --- /dev/null +++ b/ACE/ASNMP/tests/tests.mpc @@ -0,0 +1,91 @@ +// $Id$ + +project (asnmp_tests_Oid_Test) : aceexe { + exename = Oid_Test + after += asnmp_lib + libs += asnmp + includes += $(ACE_ROOT)/ASNMP + source_files { + Oid_Test.cpp + } +} + +project (asnmp_tests_Counter_Test) : aceexe { + exename = Counter_Test + after += asnmp_lib + libs += asnmp + includes += $(ACE_ROOT)/ASNMP + source_files { + Counter_Test.cpp + } +} + +project (asnmp_tests_Counter64_Test) : aceexe { + exename = Counter64_Test + after += asnmp_lib + libs += asnmp + includes += $(ACE_ROOT)/ASNMP + source_files { + Counter64_Test.cpp + } +} + +project (asnmp_tests_Integer_Test) : aceexe { + exename = Integer_Test + after += asnmp_lib + libs += asnmp + includes += $(ACE_ROOT)/ASNMP + source_files { + Integer_Test.cpp + } +} + +project (asnmp_tests_Octet_Test) : aceexe { + exename = Octet_Test + after += asnmp_lib + libs += asnmp + includes += $(ACE_ROOT)/ASNMP + source_files { + Octet_Test.cpp + } +} + +project (asnmp_tests_Gauge_Test) : aceexe { + exename = Gauge_Test + after += asnmp_lib + libs += asnmp + includes += $(ACE_ROOT)/ASNMP + source_files { + Gauge_Test.cpp + } +} + +project (asnmp_tests_Address_Test) : aceexe { + exename = Address_Test + after += asnmp_lib + libs += asnmp + includes += $(ACE_ROOT)/ASNMP + source_files { + Address_Test.cpp + } +} + +project (asnmp_tests_Target_Test) : aceexe { + exename = Target_Test + after += asnmp_lib + libs += asnmp + includes += $(ACE_ROOT)/ASNMP + source_files { + Target_Test.cpp + } +} + +project (asnmp_tests_Varbind_Test) : aceexe { + exename = Varbind_Test + after += asnmp_lib + libs += asnmp + includes += $(ACE_ROOT)/ASNMP + source_files { + Varbind_Test.cpp + } +} |