
Version 4.0.0
## Summary
- Introducing a modular transport architecture with TCP and TLS support.
- Removed the obsolete `IpxAddress` and added a fully functional `TcpAddress` and `TlsAddress` classes.
- Implemented a `TransportMapping` framework (UDP and TCP) to decouple low-level networking from the SNMP logic.
- Fixed multiple `-Woverloaded-virtual` warnings where derived classes unintentionally hid virtual assignment
  operators from their base classes.
- Resolved inheritance-related member hiding in `Oid` and `OctetStr` subclasses.
- Fixed the USM statistics counter and the Report counter OID selected when incoming message authentication fails,
  to conform to RFC 3414 §3.2 (6).
- SECURITY: Verify the identity of the (D)TLS server, reject empty tmSecurityName
- SECURITY: Do not let unauthenticated messages poison the engine id cache
- SECURITY: Bind a received response to the request it claims to answer
- SECURITY: Bound the number of usmTimeTable entries engine discovery creates
- SECURITY: Validate a v3 response/report before consuming its cache entry

### Detailed Changes
- **Address Hierarchy**: Refactored `Address` as an abstract base with a public `get_socket_address` method.
  Port management was centralized in `IpAddress` to support `UdpAddress`, `TcpAddress`, and `TlsAddress`.
- **Transport Mappings**: Created `TransportMapping` (base), `UdpTransportMapping`, and `TcpTransportMapping`.
  These classes now handle socket creation, sending, and receiving.
- **Snmp Class**: Updated `Snmp` to manage a collection of transport mappings. `snmp_engine` and `send_raw_data`
  were refactored to dynamically select the appropriate transport based on the target address.
- **SNMPv3/USM**: Refactored `v3MP` and `USM` classes to use the abstract `Address` class,
  enabling SNMPv3 over any supported transport (e.g., TCP, TLS).
- **Multi-homed Support**: Updated receiving logic in `uxsnmp.cpp` to correctly associate incoming packets
  with their specific transport mappings.
- **Project Configuration**: Updated `CMakeLists.txt` and `config_snmp_pp.h` to reflect version 4.0.0 and
  include the new transport files.
- **OID Definitions**: Added `using Oid::operator=;` to `snmpTrapsOid`, `snmpTrapEnterpriseOid`,
  and their subclasses in `oid_def.h`. This ensures that the base class assignment operators remain accessible
  and are not hidden by the implicitly generated copy assignment operators of the derived classes.
- **Opaque String**: Added `using OctetStr::operator=;` to `OpaqueStr` in `octet.h` to maintain visibility of
  `OctetStr` assignment operators.
- **Inheritance Consistency**: Verified that other key classes in the `SnmpSyntax` hierarchy
  (`IpAddress`, `UdpAddress`, `TcpAddress`, `Counter32`, `Gauge32`, `TimeTicks`) already have the necessary
  `using` declarations or explicit overloads to avoid similar warnings.
- **USM Statistics (RFC 3414 §3.2 (6))**: `USM::process_msg` now increments `usmStatsWrongDigests` for any
  failure reported by the authentication module, instead of `usmStatsUnsupportedSecLevels`. The latter belongs
  to step (5) of the same section, which checks the securityLevel the user supports and is already handled
  before authentication is attempted. The return code is normalized to `SNMPv3_USM_AUTHENTICATION_FAILURE`
  so that the generated Report carries the OID and value of the counter that was actually incremented.
  Note that this code path is only reachable if an `Auth` implementation reports a failure other than
  `SNMPv3_USM_AUTHENTICATION_FAILURE` or `SNMPv3_USM_UNSUPPORTED_AUTHPROTOCOL`.
- **Report Counter OID**: `v3MP::send_report` now maps `SNMPv3_USM_UNSUPPORTED_AUTHPROTOCOL` to
  `usmStatsUnsupportedSecLevels`, which is the counter USM increments for it. Previously this code fell through
  to the default branch and reported `snmpInvalidMsgs`, a counter that had not been incremented.

CHANGES snmp++v3.6.6
====================
- Fixed: Memory leak in AuthPriv when decrypting/encrypting DES-EDE3-CBC data.
- Fixed: Changed include <openssl/macros.h> to <openssl/opensslv.h>, as
         macros.h is only available in recent OpenSSL versions.
- Improved: Replaced sprintf usage in usm_v3.cpp with snprintf.
- Improved: Moved legacy provider cleanup before v3_MP deletion in the console
         examples to avoid a warning log.

CHANGES snmp++v3.6.5
====================
- Fixed: Fixed memory violation in OpenSSL legacy provider used by AuthPriv when more than one
  instance is created concurrently. Added new static load and unload methods for OpenSSL legacy provider.
  AuthPriv constructor now calls load_openssl_legacy_provider() if OpenSSL legacy provider is available.
  AuthPriv destructor now warns if OpenSSL legacy provider is not unloaded yet, but will not unload it.

CHANGES snmp++v3.6.4
====================
- Fixed: Memory leak in AuthPriv destructor. Added unload of OpenSSL legacy provider.
- Improved: OpenSSL legacy provider initialization for DES.

Changes snmp++v3.6.3
====================
- Added: Install CMake package configuration files (Forum member hb-stulz)
- Fixed: Responses to requests sent with SNMPv1/2c were dropped if the
         user code provided a Pdu with a SNMPv3 message id. 

Changes snmp++v3.6.2
====================
- Fixed: Bug in UTarget.set_coexistence_security_name not saving the set security_name
  and not retaining it with copy constructor and assignment if set.

Changes snmp++v3.6.1
====================
- Fixed: Compilation error with SNMPv3 disabled in UTarget destructor.

Changes snmp++v3.6.0
====================
- Upgraded: autoconf minimum supported version requirement to v2.71.
- Changed: Do not disable Priv3DES_EDE class when compiling with OpenSSL and
  do not use deprecated API of OpenSSL 3.
- Added: Allow storing coexistence_security_name values (i.e., v1/v2c communities) to return them
  in response messages instead of using the mapped security name, as required by RFC 3584 §5.2.2.

Changes snmp++v3.5.2
====================
- Fixed: Retries for async SNMPv3 requests where not sent (caused by changes for version 3.5.0).
- Fixed: Added missing definition for pid_t as configure script does
- Fixed: Removed /WX option as a workaround for yet unfixed warnings
- Added: Link ws2 library
- Fixed: DLL exported no symbols
- Improved: Removed snmpWalkThreads example from windows build
- Improved: Link examples with static library
- Fixed: Prototype of local defined snprintf function

Changes snmp++v3.5.1
====================
- Fixed: Compilation error if _SNMPv3 is not defined (Fabrice Fontaine)

Changes snmp++v3.5.0
====================

- Fixed: When using an IPv6 socket to send a SNMPv3 request to an IPv4 target,
  the engine id could not be discovered.
- Fixed: Compile error with libressl >= 3.5.0 (Fabrice Fontaine)
- Improved: Set message_id in Pdu after sending a request to be able to detect old responses:
  Fixed scenario: Send request, send retry, response to first request is received and
  processed to unknown pdu handler because of unknown message id. Matching to retry
  request is done because of known request id.
- Improved (security): Avoid timing attacks on authentication verification.

Changes snmp++v3.4.10
=====================

- Fixed: Winsock has to be included before windows header.
- Fixed: Added SnmpTarget::version_to_string() function
- Fixed: Fixed compiler warning on MSYS2 g++

Changes snmp++v3.4.9
====================

- Fixed [APP-66]: Compiler warning in Counter64 printf.
- Fixed: Removed unnecessary cast in uxsnmp.cpp debug output.
- Updated: libtool guess and config files to better support Linux ARM builds. 
- Improved [APP-67]: Introduced arc4random usage and improved comments 
  about rand() and srand() usage. Added srand() to snmpWalk.cpp. 
  cmake does not generate HAVE_ARC4RANDOM #define correctly yet.

Changes snmp++v3.4.8
====================

- Fixed: Use #warning instead of #warn.
- Fixed: Check for stdc++11

Changes snmp++v3.4.7
====================

- Fixed: Snmp::error_msg() returns a string with "Unknown error code" for
  invalid error codes.
- Fixed: v3MP::remove_engine_id() did not remove localized users from USM
  because USM::remove_engine_id() did not remove the localized users.
- Fixed: Build failure if older snmp++ headers were installed in the same directory as
  the used crypto library.

Changes snmp++v3.4.6
====================

- Fixed: SNMPv3_USM_ENCRYPTION_ERROR when using PrivAES with new EVP
  functions from SSL library.
- Fixed COMITFAIL SNMP status error code typo with backward compatibility.
  Please use COMMITFAIL in future development.

Changes snmp++v3.4.5
====================

- New: Added cmake support. Support for autoconf will be continued together with cmake.
  Any other build methods are now deprecated and no longer supported. The corresponding
  Makefile.<platform> are still included but will be removed with SNMP++ 4.0.
- Changed: PrivAES now uses EVP functions from SSL library
- Changed: While waiting for a response, EventListHolder calls select/poll
  with a timeout of 100 milli seconds (was 1000).

Changes snmp++v3.4.2
====================

- Fixed: consoleExamples did not call Snmp::set_mpv3().
- Fixed compiler warning about initialization order in Snmp class.
- Fixed: The USM counter usmStatsUnsupportedSecLevels was increased twice
  because of a missing break.
- Removed unused variable logfilename in v3.cpp.

Changes snmp++v3.4.1
====================

- Fixed compilation if SNMPv3 is disabled.
- Fixed: possible double definition of INT8_MIN.
- Fixed: consoleExamples did not accept "-v1" and -L option.
- Fixed: "make install" copied Makefile.am to <PREFIX>/include/snmp_pp folder.
- Removed snmp++-3.3.pc.in, as snmp++-3.pc.in is used.

Changes snmp++v3.4.0a
=====================
- Fixed in 3.4.0a incorrect packaging which did not include refactoring of
  Snmp::get_mpv3() in distribution file.
- Fixed [APP-63]: Removed usage of static v3MP::I instance to allow using
  several Snmp sessions with independent v3 message processing models within
  a single process.
- Fixed [APP-61]: Reduced buffer size to prevent warning about possible 
  buffer overflow ;-)
- Fixed [APP-61]: Use unique_ptr instead of deprecated auto_ptr

Changes snmp++v3.3.13
=====================
- Fixed [APP-60]: SECURITY: SNMP++ contains "out-of-bounds read" vulnerability 
  in function asn_parse_objid.
  The vulnerability was discovered by Radu Motspan, "Kaspersky".

Changes snmp++v3.3.12a
======================
- Fixed: Compilation error in md5c.cpp caused by extern "C" declaration removal

Changes snmp++v3.3.12
=====================
- Fixed: Memory leak for every SHA1 and MD5 digest calculation when
  using OpenSSL >= 1.1.0 (Oleg Bt)
- Fixed: md5.h: Removed the extern "C" declaration, as it not needed 
  and does not allow to use namespaces.
- Fixed: Some cppcheck warnings.

Changes snmp++v3.3.11a
======================
- OpenSSL: Switched MD5 and SHA1 to use the EVP API of OpenSSL.
  Tested with: libressl-2.6.4, openssl-1.0.2n, openssl-1.1.0g, 
  openssl-1.1.1-pre1
- Fixed [APP-49]: Added option to reactivate historic threading control 
  (recursive threads) in AGENT++.

Changes snmp++v3.3.10
=====================
- Improved: Set the FD_CLOEXEC flag on sockets, so they are not "leaked"
  to spawned processes (suggested by Isaac Nickaein)
- Changed: Removed unused "#define ON".

Changes snmp++v3.3.9
====================

- Fixed [APP-46]: SHA384 and SHA512 authentication protocols used block size 
  of 64 instead 128.

Changes snmp++v3.3.8
====================

- Security: A buffer overflow could be triggered in Ipaddress class if a
  host name was longer than 80 characters. The overflow was triggered
  when a too long host name was passed to the class or if a DNS reverse
  lookup returned a too long host name.
- Fixed: It was not possible to assign a numeric IPv4 address to the IpAddress
  class if IPv4 was disabled at OS level. The same was true for IPv6 addresses
  if IPv6 was disabled at OS level. Parsing of variable bindings containing
  an IP address failed in such configurations.
- Fixed: Compilation without OpenSSL and without libtomcrypt was not possible.
- Changed: Use newer DES API of OpenSSL.
- Fixed: Installed header files no longer need the internal config.h.
- Fixed: Invalid use of static_cast in log.cpp on MacOS.
- Fixed: SNMPv3 requests always resulted in an unknown engine id report, if
  the used SnmpTarget did not contain any port information.

Changes snmp++v3.3.7
====================

- Fixed: Added missing operator=() functions for Mac, Ipx and IpxSockAddress.
- Fixed: Fixed copy-paste-error for ipxaddress option in auto_conf build.

Changes snmp++v3.3.6
====================

- Added: SHA-2 (SHA-224,-256,-384,-512) support to USM as defined by RFC 7630
- Changed: Counter64::get_printable() does no longer produce hex output for
  values larger than 2^32. (Florian Lohoff)

Changes snmp++v3.3.5
====================

- Fixed: Added missing length check for key in Priv3DES_EDE::decrypt().
- Added: PrivAESW3DESKeyExt class to allow to contact some Cisco devices.
- Fixed: Configure with --disable-threads
- Fixed: Usage of uninitialized data.
- Added: get_net_address_type().
- Added: clone_as_hex().
- Added: IpAddress::clone_as_hex.
- Fixed: Possible NPE.
- Updated: Version info and fixed old Makefile distribution.

Changes snmp++v3.3.4
====================

- Fixed: Incorrect time values conversion in += and -= operators of the 
  msec class in msec.cpp.

Changes snmp++v3.3.3
====================

- Fixed: [APP-30] SNMP++ cannot BER decode Oids starting with 2 and
  with second sub-identifier >39 correctly. 
- Fixed: [APP-31] SNMP++ does not encode Oids starting with 2 and 
  second sub-ID greater than 47 correctly. 

Changes snmp++v3.3.2
====================

- Fixed: Regression through [APP-19] which lead to too long timeouts
  on systems with clock_gettime.
- Fixed: Restored missing files (CHANGES, READMEs) to distribution. 
- Fixed: Fixed compilation error when using poll syscall.
- Fixed: Do not use _vscprintf as it is not portable, instead just 
  truncate the log message.
- Fixed: Fixed test that produced an error during configure:
  checking which _XOPEN_SOURCE macro must be defined... 
  ./configure: line 6229: test: : integer expression expected
- Fixed: msec.cpp: timezone is a struct and not a class.

Changes snmp++v3.3.1
====================

- Fixed: Replaced strcasecmp usage in consoleExamples by _stricmp
  for WIN32 platform.
- Improved: Debug output buffer length is now computed exactly on
  WIN32.
- Fixed: Compilation of IPv6Utility.h with Visual Studio 2013.
- Fixed: Removed #define of Uint32 in eventlistholder.h.

Changes snmp++v3.3
==================

- Added: Autoconf support.
- Added: console Examples log output profile options (activation by 
  compiler switch).
- Fixed: Setting the exception status of a Vb object did not clear the
  value of the Vb (found from Dominik Vogt)
- Fixed: TimeTicks, Gauge, Counter and Integer classes did not properly
  set/reset the valid flag and some get_printable() functions did ignore
  the valid flag.
- Fixed: In rare conditions, CNotifyEventQueue::AddEntry()
  could be left in an inconsistent state after returning
  SNMP_CLASS_INTERNAL_ERROR (Luc Van Walleghem)
- Fixed: Reports are now sent with the same security level, as the
  received request.
- Fixed bool vs. int issues and WIN32 compilation problems.
- Improved: Implemented portable pthread_t printing in log.cpp.

Changes snmp++v3.2.25
=====================

- Improved: Request id and salt initializations; Makefile target improvements;
  Documentation of Snmp::start/stop_poll_thread functions (Dominik Vogt)
- Fixed: Possible off-by-one error in various XAddress::parse_Y() functions,
  if input values are filled with spaces. (Dave White)
- Fixed: Async inform requests did not work because of incorrect PDU type
  (APP-2)
- Changed: The QtExample now uses Qt4 (Don Radick).
- Fixed: Snmp::notify_unregister() did not work.
- Changed: Removed AddressCollection param of Snmp::notify_register()
  function.

Changes snmp++v3.2.24
=====================

- Fixed: Counter64 was not encoded correctly on 64 bit
  platforms (Alex.Agranov).

- Fixed: 64bit problem in asn1.cpp on some 64bit platforms.
- Added: Set soname in shared library for inclusion in Fedora
  (suggested by Hayden James)
- Improved: Compilation on MacOS 10.5
- Changed: First step for Fedora rpm packages (Hayden James)
- Fixed: Compilation problem in msgqueue if SNMPv3 is not defined.
- Fixed: Various possible null pointer dereferences in ASN1 code
  and in OctetStr::get_printableXXX functions (found from Abil George).
- Changed: Use Snmp::get_eventListHolder() instead of 
  Snmp::eventListHolder.
- Fixed: Compilation problem on WIN32 if _THREADS is not defined
  (Arnaud Compan)
- Improved: Added get and set functions to vb class for
  unsigned int values.
- Fixed: Bug in Snmp::stop_poll_thread() could lead to crash at
  application exit.
- Improved: Snmp class will no longer send snmpv3 message if all of
  the following is true: a) engine id discovery is diabled. b) local
  entity is not authoritative. c) engine id is not set in target.
  In this case an invalid target error is returned.
- Improved: snmp++ used select() syscall. On most unix like systems
  select() can not deal with file descriptors larger than FD_SETSIZE
  (which is most likely defined as 1024). If HAVE_POLL_SYSCALL is
  enabled in config_snmp_pp.h, snmp++ will use poll() syscall.
- Fixed: Through a race condition requests could return
  SNMPv3_MP_UNKNOWN_PDU_HANDLERS error.

Changes snmp++v3.2.23
=====================

- Fixed: SNMPv3 message id creation was not thread safe.
- Added: IPv6 utility functions to allow IPv6 for VC++
  compiler (Ragavan Tetchinamourty).
- Fixed: Key change algorithm now works for keys longer than
  16 bytes.
- Fixed: ASN parse error on 64 bit platforms.
- Improved: Address classes can now handle IPv6 scope id.
  Length defines for IPv6 have been renamed, see address.h
  for new names if you get compile errors.
- Fixed: With IPv6 disabled, transport errors could trigger IPv6
  related warning.

Changes snmp++v3.2.22
=====================

- Fixed: After a CTarget::clear() get_type() returned type_base
  instead of type_ctarget (Lior Klibansky).
- Fixed: The message id could be negative if engine boots is
  greater than 0x7fff. (Wai-Kiong Choy)
- Fixed: Removed lots of compiler warnings (-Wcast-qual, -Wshadow),
  unused code, and other things (Jeremy Nimmer)
- Added: User defined log class USER_LOG.
- Fixed: Thread handle was not closed on Snmp::stop_poll_thread() on
  WIN32 platform. (found from Stoyan Haralampiev).
- Fixed: Possible deadlock after a call to Snmp::engine_id_discovery().
- Fixed: debughexprintf() did not print the last output line.
- Fixed: Check for duplicate entries in engine id table.
- Fixed: Don't allow SNMP INFORM over SNMPv1.
- Fixed: If a SNMPv3 response was received from a different address/port
  than the request was sent to, no valid mapping address/port <-> enigne id
  was stored, so no communication was possible.

Changes snmp++v3.2.21
=====================

- Added: New overloeaded Oid::set_data() that takes a char array instead
  of ulong array.
- Fixed: The dotted oid string parser no longer accepts strings like
  "1.3.6.$public", "1.3.6$public$" or "1.3.6.$public$1".
- Fixed: Removed a lot of compiler warnings on Windows x64 (with help of
  Sanjay Bhatia). Introduced new type for sockets (SnmpSocket), and
  removed SNMPHANDLE type.
- Changed: Removed global mutex for v3MP and USM.
- Fixed: sockets were not closed if bind failed. (found from John McCaskey)
- Fixed: Engine id discovery did not work when sending SNMPv3 request
  to IPv4 Address over IPv6 socket.
- Fixed: For async SNMPv3 requests that resulted always in a unknown
  engine id or not in time report from the agent the Snmp class continued
  to resend a request to the agent.
- Fixed: USM was not thread safe (found from John McCaskey):
  Changing users from two different threads or changing users
  while messages of these users are processed could cause
  segmentation faults. The following functions of USM now behave
  different than before or require calls to new functions:
  all three get_user() functions, peek_first_user(), peek_next_user(),
  peek_first_luser(), peek_next_luser(), get_user_count().
  If you use any of these functions, read the new documentation in
  usm_v3.h and change your code (like it was done for the QtExample).
- Changed: The functions to set/get the trap listen port of
  CNotifyEventQueue ar no longer static. Use the new functions
  Snmp::notify_set/get_listen_port() instead.
- Removed: Old X11 code, user defined events and timeouts.
- Improved: Counter64 now uses 64 bit integer for math
  operations, instead of long double. 
- Fixed: Zero length UDP packets will no longer trigger
  a transport-level-failed callback.

Changes snmp++v3.2.20a
======================

- Improved: Detect too large received messages.
- Improved: Removed hard coded limit for max number of Vbs
  (PDU_MAX_VBS) in a Pdu object.
- Fixed: Bug in SNMPv3 encryption code which will lead to a
  crash after a random number of encryptions (Stuart Marks).

- Improved: Compilation of address.cpp for Solaris.

Changes snmp++v3.2.19
=====================

- Fixed: Requests with nonzero but wrong security engine id
  now result in a unknown engine id report.
- Added: New functions USM::add_usm_user() and
  new functions to remove engine ids and hosts from
  the v3MP and USM tables.
- Changed: command line arguments of consoleExamples.

Changes snmp++v3.2.18
=====================

- Added: Privacy protocol 3DES. The Auth/Priv interface was
  modifed. (based on patch from Pierre Pacchioni)
- Fixed: Possible memory leak in mp_v3.cpp v3MP::snmp_parse(..).
- Fixed: Uninitialized variable in asn1.cpp asn_parse_length(..).
- Fixed: Uninitialized variables in snmpmsg.cpp 
  SnmpMessage::unload when v3MP::I->snmp_parse() fails.
  (Reported by Rob Crawford)
- Changed: ID of privacy protocol AES128 now is 4
  as required by the RFC.
- Fixed: Vb::get_value(ptr, len, maxlen) may write
  maxlen+1 bytes into ptr buffer (Daniel Suman).
  This function now is  Vb::get_value(ptr, len, maxlen,
  add_null_byte) where the default for add_null_byte
  is false.
- Improved: Workaround for Cisco SNMP agents that set
  request ids to 0x7fffffff in report messages.
- Fixed: Make auth_priv.h/cpp compile if both OpenSSL and
  LibTomCrypt are defined.
- Added: Basic support for VxWorks with PPC603 (Thanks to
  Lee Noll).

Changes snmp++v3.2.17
=====================

- Changed: Updated auth_priv.cpp for LibTomCrypt 1.02
- Changed: Moved logging classes from agent++ into
  snmp++. (Fedja Jeleskovic)
  Function debug_set_logfile() has been removed, use
  DefaultLog::init(new AgentLogImpl("filename")) and
  DefaultLog::log()->set_filter() instead.
  All logging within snmp++ will be moved to the LOG_XXX
  macros and the debugprintf() function will be removed.
- Changed: Renamed "#ifdef alpha" to "#ifdef __osf__". When
  compiling for DigitalUnix/Tru64 make sure, that __osf__
  is defined.

Changes snmp++v3.2.16
=====================

- Improved: notify_register() now returns correct error codes.
- Added: Snmp::start_poll_thread() that starts a new thread
  that polls for async responses and informs/traps. The thread
  will be stopped automatically in the destructor. It also can
  be stopped using Snmp::stop_poll_thread(). (Fedja Jeleskovic)
- Added: New transport layer error code
  SNMP_CLASS_TL_ACCESS_DENIED for (errno == EACCES)
- Improved: new define SNMP_PP_MUTABLE that can be
  defined to mutable for compilers that support
  mutable member variables.
- Changed: renamed OctetStr::set_hex_np_char() to
  set_np_char()
- Improved: get_printable() will return the same buffer
  for each call if the object wasn't changed.
- Added: Pdu::get_max_vbs() to get the value of
  PDU_MAX_VBS at runtime.
- Fixed: Bug in snmperrs.h (Jason Olenhouse)

Changes snmp++v3.2.15
=====================

- Fixed: Bug in asn1.cpp for systems where
  sizeof(long) != sizeof(*long) (Hu Shu)
- Fixed: timeout calculation in
  EventListHolder::SNMPProcessEvents() (Xu Manjiang)
- Fixed: OctetStr::clear() now sets the length to
  zero (Mr. AWD)

- Fixed: Set sin_len of struct sockaddr_in before calling
  bind(). Define CYGPKG_NET_OPENBSD_STACK to enable it.
  (Harald Kuethe)
- Changed: Pdu class checks Vb validity after all
  assignments. It is no longer possible to add
  a Vb that is not valid.
  Some set/get member functions now return bool
  instead of void.

Changes snmp++v3.2.14
=====================

- Improved: Return value of Pdu functions 
  get/set_notify_id and get/set_notify_enterprise. 
  (Marek Malowidzki)
- Fixed: Check return value of new in
  SnmpCollection::operator+=() (Marek Malowidzki)
- Fixed: Setting a byte with Address::operator[] will
  set validity of the object to true.
- Improved: Behaviour of OctetStr::get_printable() for
  non printable strings can now be configured.

Changes snmp++v3.2.13a
======================

- Fixed: Version info was not updated.
- Fixed: Compilation problems with _NO_SNMPv3

- Changed: The user "initial" is no longer automatically
  added to the USM.
- Fixed: Oid class freed memory twice after
  failed call to operator+=().
- Added: Support for AIX 5 (by courtesy of
  Anders Malmborg)

Changes snmp++v3.2.12a
======================

- Fixed: wrong encryption/decryption for
  DES and IDEA.
- Fixed: consoleExamples can use IPv6.

- Fixed: Do not accept illegal lengths for
  authentication parameters.
- Removed: Obsolete XExample.
- Fixed: Compilation problem in address.cpp
  if __sun is defined (Kostas Lykiardopoulos)
- Improved: Modified constructor of Snmp class
  to allow binding to IPv6 socket.
- Added: AES can now be used with OpenSSL.
- Improved: Compilation under Tru64.
- Fixed: Return code of delete_entry and 
  delete_entries in class USMUserTable returned
  SNMPv3_MP_OK instead SNMPv3_USM_OK.

Changes snmp++v3.2.11
=====================

- Improved: Declared some methods as const
  (Marek Malowidzki).
- Improved: Use shortest possible encoding for
  serializing SNMP messages to improve compatibility
  with buggy/broken SNMP-Tools (Henning Eggers).
- Fixed: Compilation problems on SUN
  (Fabrice Bacchella)
- Improved: declared some methods as const
- Improved: Moved the headers to include/snmp_pp/
  to avoid name colissions.
- Improved: QtExample can receive traps/informs.
- Fixed: Compilation problems with BC++ 5.0
  (Vinoth, Christian Cheney)
- Improved: Added namespace Snmp_pp (Sorin C.)

Changes snmp++v3.2.10a
======================

- Changed: Added two defines _USER_DEFINED_EVENTS
  and _USER_DEFINED_TMEOUTS (enabled by default)
  to switch off the user defined event/timeout queues.
- Improved: Added const to various functions and
  function arguments (Marek Malowidzki)

- Fixed: Added missing DLLOPTs in msec.h (Christian Cheney).

- Improved: The v3MP uses the Snmp object that received
  the message for sending out report messages (needed
  for systems with multiple IP addresses).
  The constructor of the v3MP class was changed, as
  the pointer to the Snmp object is no longer needed
  at construction time.

- Changed: Snmp::notify_register() no longer binds
  to all interfaces, but to the address specified
  in the constructor of the Snmp object.

Changes snmp++v3.2.9d
=====================

- Improved: Removed usage of some multi-threading 
  critical C routines (for example strtok). Although
  on many systems, these routines are multi-threading
  safe, this may not be true for some systems. 

- Fixed: High CPU usage in SNMPProcessEvents() on
  Win32 platform.

- Fixed: SNMPv1 trap sysUpTime TimeTicks where not
  decoded correctly as unsigned integer value, resulting
  in a parse error when sysUpTime > 2^31-1.
- Improved: Log levels.
- Fixed: USMUserNameTable::add_entry() did not update
  the privacy password length.

- Improved: Examples now use the 
  Snmp::socket_startup() on Win32 platforms.

- Added: Two static methods Snmp::socket_startup() and
  Snmp::socket_cleanup() that initialize/cleanup
  Winsock library on WIN32 and do nothing for
  other platforms. The startup method must be
  called before creating Snmp or Address objects.

- Changed: Type of some vars in UsmUserNameTableEntry
  from uchar* to OctetStr. Check if your code uses 
  this struct.
- Changed: engineBoots and engineTime are set to 0 for
  SNMPv3 noAuthNoPriv messages.

Changes snmp++v3.2.8
====================

- Added: Support for OpenSSL.
- Fixed: Compile problem in uxsnmp.cpp. 

Changes snmp++v3.2.7c
=====================

- Fixed: Synchronization problem with mpV3::Cache.
  (Henning Eggers)

- Fixed: Memory leak in OctetStr::from_hex_string.
  (Kent Gibson)
- Changed: EventListHolder::SNMPProcessEvents() 
  param is now in milliseconds (was seconds).

- Fixed: Memory leak if an async SNMPv3 message timed
  out (Henning Eggers).
- Added: Method Snmp::broadcast_discovery() to do
  SNMP broadcast discovery. 
- Improved: Console examples now accept 0 retries,
  removed warnings with gcc 3.2, and v3MP is now
  always created.

- Added: Qt 3.1 example that demonstrates SNMP++v3
  usage with a GUI (Trolltechs Qt 3.1).
- Added: Methods to store, load, and query USM users.
- Improved: Some minor clean-ups.

Changes snmp++v3.2.6b
=====================

- Fixed: GenAddress passed IPv4 addresses as IPv6 
  addresses.
- Changed: By default IDEA is not compiled into 
  SNMP++ by default because patent licensing is
  required for commercial use. Please #define 
  _USE_IDEA if you want to compile IDEA into SNMP++.
  For more details please read also README.v3.

- Fixed: Do not add -Dsun to compile command. If
  you have problems with the SnmpCollection template
  look at the instructions in collect.h. 
- Fixed: Destroy Mutex in ~EventListHolder(). 
- Improved: Lots of cleanups for the address classes.
  This leads to the following incompatibilities to 
  former versions:
  + Enums addr_type and version_type are now inside
    class Address
  + MacAddress, IpxAddress and IpxSockAddress are no
    longer included by default, but can be enabled
    in config_snmp_pp.h 

Changes snmp++v3.2.5d
=====================

- Improved: Made AuthMD5::password_to_key more
  robust against empty passwords.
- Changed: The Win32 DLL export macros now use
  SNMP_PP_DLL instead _USRDLL.
- Changed: Moved VC++ project files in a 
  separate package. 

- Improved: Minor issues with IPv6 support.
- Improved: Socket handling.

- Fixed: uxsnmp.cpp: Detecting error from socket()
  return values.

- Fixed: Moved SNMPAddInput() SNMPRemoveInput()
  SNMPAddTimeout and SNMPREmoveTimeout to the
  class EventListHolder
- Fixed: Unique Id generation in CUDEventQueue and
  CUTEventQueue.
- Fixed: Bugs in Vb::get_value() methods that take a
  char* or unsigned char* as argument
- Added: operator+() for Oids (Alexander Gutkin)
- Improved: Cleanups in queues 

Changes snmp++v3.2.4a
=====================

- Improved: Synchronous and asynchronous SNMP
  request processing is now separated. Thus,
  the global event lists have been removed. 
  Each Snmp class now holds its own event 
  lists.
  To eliminate the use of global event lists
  a new class EventListHolder was defined. Two
  new files eventListHolder.h and 
  eventListHolder.cpp contain now declaration
  and definition of that class respectively.
  That new class is a container of former
  eventList global data structure and former
  global user defined events, user-defined 
  timeouts, notifications and all outstanding
  messages. (LiorK)
- Improved: collect.h (Bill McKinnon)
- Improved: FreeBSD 5.0 support.

- Added: Makefile.gcc_solaris for compilation
  with GNU C++ compiler on Solaris.	


Changes snmp++v3.2.3b
=====================

- Fixed: Counter64::get_printable() could print
  negative values (Yakov Y.)

- Note: New Makefiles assume that you have
  defined _USE_LIBTOMCRYPT when a "crypt"
  directory is present in the same folder as
  the "snmp++" and "agent++" directories. 
- Fixed: Compilation problems without _SNMPv3
  defined.
- Fixed: PDU length computation for encrypted
  SNMPv3 PDUs.

- Improved: New v3MP class.
- Fixed: Estimated length calculation for 
  encoded PDU.


Changes snmp++v3.2.2d
=====================

- Fixed: Possible timeouts under heavy load
  in a multi-threaded environment. 
  [Pavel Spakovsky]

- Fixed: DLL support for VC++ did not allow
  static linking.
- Added: Computation of BER encoded length of
  a Pdu. 

- Added: VC++.NET project files and fixed DLL
  support.

- Fixed: Errors in Counter64::c64_to_ld() and
  Counter64::ld_to_c64() [Mikhail Evstiounin]

- Improved: Prepared for AES usage replacing
  libDES. 
- Fixed: Compilation problems with G++3.2
  (needs updated libDES download).

Changes snmp++v3.2.1d
=====================

- Fixed: Memory leak (40 bytes) when adding an
  user to usm.
- Improved: Some cleanups (#include, const).
- Fixed: Due to possible race condition in
  MyMakeReqId() (uxsnmp.cpp) two requests could
  get the same request id. 
- Fixed: const casting caused problems with
  AIX compiler.

Changes snmp++v3.2.1
====================

- Improved: Use zero length user name for
  SNMPv3 discovery.
- Lots of cleanups.

Changes snmp++v3.2a
===================

- Fixed: Compilation problem with address.cpp on
  Solaris. 

Changes snmp++v3.2
==================

- Added: IPv6 support.
- Improved: moved the USM functions into the class
  USM. To add or delete users, you will now have to
  do the following (see usm_v3.h for more details):
     Usm *usm = mpGetUsm();
     usm->add_usm_user(...);
     usm->delete_usm_user(...);

- Fixed: Possible SegFault in notify queue
  (Lior Klibansky)
- Fixed: Timeout problem in event list (Don Dietz)
- Fixed: Don't use isdigit() for BCC (Eric Zerbib)
- Added: clear() method to SnmpCollection
- Fixed: added clone() method to Pdu class, so
  SnmpCollection<Pdu> will work again.
- Added: Make notify socket decriptor available in
  Snmp class (Don Dietz)

Changes snmp++v3.1.6c
=====================

- Fixed: mp_v3.cpp: Unsigned integer values were
  not BER decoded correctly for SNMPv3 messages.
- Fixed: Some errors when compiling with -ansi
- Improved: Class AuthPriv does no longer depend
  on USM. 

Changes snmp++v3.1.6b
=====================

- Added: BCC32 support.
- Added: DLLOPT decoration for debugprintf.

Changes snmp++v3.1.6a
=====================

- Fixed: Agent address of v1 trap PDUs is set from
  received SNMPmessage if address is not "0.0.0.0".
- Improved: Free BSD support.
- Improved: UdpAddress performance.

- Added: Pdu::set_v1_trap_address to set v1
  trap address. If not set, SNMP++ will use the
  default host address.
- Improved: Added casts in auth_priv.cpp and 
  idea.cpp.

Changes snmp++v3.1.5
====================

- Fixed: Memory leak during processing of
         SNMPv3 traps
- Fixed: Memory leak in agents when sending a
         UnknownEngineID report
- Fixed: Set contextEngineId in Pdu if it was
         not set by the user.
- Improved: Prepared authentication/privacy module
            for easy extensibility.
- Fixed: Convert asn1.cpp back to unix CR/LF ;-)

Changes snmp++v3.1.4b
=====================

- Fixed: Possible crash in ASN.1 BER decoding 
  caused by incorrect SNMP BER encodings.

Changes snmp++v3.1.4a
=====================

- Fixed: Compilation problems with non Linux
  systems regarding *_r system calls.
- Fixed: Handling of unusual v3 msgFlags and
  msgSecurityModels.

Changes snmp++v3.1.4
====================

- Added: Support for Opaque type. The Opaque
  type is implemented as OpaqueStr as subclass
  of OctetStr.

Changes snmp++v3.1.3i
=====================

- Fixed: ASN.1 encoding of very long OIDs
  (128 subidentifiers) could cause seg.fault.
- Improved: Removed obsolete #includes and
  comments. 

Changes snmp++v3.1.3h
=====================

- Fixed: Compilation problems introduced by 
  debugging output redirection on Solaris.
- Added: Makefile.hpux11 for HPUX11 aCC.
- Improved: ASN.1 decoding of integers.
- Fixed: Sending SNMP requests form within
  asynchronous callback functions.

Changes snmp++v3.1.3g
=====================

- Fixed: ASN.1 parse error when parsing some 
  unsigned integers introduced in v3.1.3c.

- Fixed: Completed work on redirecting debugging
  output. 

Changes snmp++v3.1.3f
=====================

- Improved: SNMP++ is no longer busy looping
  when waiting for synchronous requests.
  (Changed select timeout in ProcessPendingEvents 
   in eventlist.cpp from 0 to 10 usec).

- Improved: Debugging output can now be 
  redirected to a file.

Changes snmp++v3.1.3e
=====================

- Fixed: Dropped v1 traps because of a wrongly
  detected ASN.1 parse error.

- Fixed: Wrongly added trap oid and timestamp
  variable bindings for received notifications.

- Added: _NO_THREADS in config.h to facilitate
  disabling of threads (contributed by Martin 
  Janzen).

Changes snmp++v3.1.3d
=====================

- Fixed: Traps sent out may had wrong security
  level noAuthNoPriv.

Changes snmp++v3.1.3c
=====================

- Fixed: Missing type checks in BER decoding
  have been added.

Changes snmp++v3.1.3b
=====================

- Fixed: A pdu with an unknown engineId report 
  was overwritten by a second pdu with an 
  unknown message id status when they both were
  send from a multi-homed agent that sends 
  responses not only from one source address.

- Fixed: User name returned by agent in error
  conditions did not match configured user by
  command generator in some cases.

Changes snmp++v3.1.3a
=====================

- Fixed: Bugs related Solaris 64bit support.
- Fixed: Handling of the OPAQUE syntax in
  snmpmsg.cpp.

Changes snmp++v3.1.3
====================

- Fixed: Now using reentrant system functions
  like gethostbyname_r, gethostbyaddr_r, and 
  strtok_r.
- Fixed: Command line parameter handling of
  the consoleExamples.
- Fixed: MyMakeReqID did not locked its call to
  snmpEventList->GetEntry against other threads.
- Fixed: Locking for eventlist.cpp
- Added: Remove operation in SnmpCollection 
  template.

Changes snmp++v3.1.2a
=====================

- Target::get_type() is now const.
- Improved: Trap receiver example.

Changes snmp++v3.1.2
====================

- Fixed: Handling of responses to INFORM-requests.  

Changes snmp++v3.1.1
====================

- Fixed: Added locking for SNMPv3 MP cache. 
- Improved: AGENT++ is no longer needed for console
  examples.
- Fixed: SNMP version was not set for received 
  notifications.

Changes snmp++v3.1
==================

- Replaced RSAEURO by LIBDES which is free even for
  commercial use.

Changes snmp++v3.0.2b
=====================

- Added: Snmpx::Snmpx(int&, const UdpAddress&) to 
  support binding on a specific IP address.

Changes snmp++v3.0.2a
=====================

- Fixed: Filtering notifications.

Changes snmp++v3.0.2
====================

- Fixed: Compilation problems when using async requests
  on Win32 platforms.
- Improved: In v3.0.1 pending requests could block 
  requests from other threads. This has been fixed. 

Changes snmp++v3.0.1
====================

- Added: SNMP++v3.0.1 is now thread-safe! 
- Added: Snmp::report can send SNMPv3 reports. 

Changes snmp++v3.0n
===================

- Added: SNMP++ sets the contextEngineID of a SNMPv3
  PDU if it is not set by the user.

Changes snmp++v3.0m
===================

- Fixed: Removed all deprecated #include <values.h>. 
- Fixed: Solaris makefile for Solaris 7.0 (removed 
  Templates.DB related stuff)

Changes snmp++v3.0l
===================

- Fixed: Entries added to the SNMP++ usmUserTable during
  discovery did not appear in the AGENT++ USM MIB.

Changes snmp++v3.0k
===================

- Fixed: Setting a usmOwnKeyChange object with a zero 
  length string caused a segmentation fault.

- Fixed: Compilation problems with BSD Unix.

- Fixed: Renaming of snmpv3BootCounter file on WinNT.

Changes snmp++v3.0j
===================

- Fixed: snmpmsg.cpp: Check for exceeding maximum 
  response PDU size, did not check response PDUs only.
  This bug caused SNMP++ to not send v3 traps.

- Fixed: Setting trap OIDs when receiving traps.


Changes snmp++v3.0i
===================

- Fixed: OIDs for snmpAuthProtocols and snmpPrivProtocols

- Fixed: Sending of v1 traps did not set IP address of
  the sending host correctly when the gethostname failed
  for that host.


Changes snmp++v3.0h
===================

- Fixed: (usm_v3.cpp): Handling of maxMsgSize.

- Fixed: (asn1.cpp): BER encoding of ASN.1 header
  length did not support length above 65535 bytes. Now 
  lengths up to 2^31-1 bytes are supported.

- Fixed: (usm_v3.cpp): Did not check length of userName
  before copying it. Could have caused problems with
  incorrect SNMPv3 implementations.
 

Changes snmp++v3.0g
===================

- Fixed: BER encoding of unsigned 64bit integers.
  High values (all nine most significant bits are 1) were 
  incorrect encoded.

- Fixed: Removed compilation warnings for timetick.cpp and
  integer.cpp


Changes snmp++v3.0f
===================

- Fixed: Several DLLOPT decorators had been missing in asn1.h.

- Added: Prototype for freeSmivalDescriptor in snmpmsg.h.


Changes snmp++v3.0e
===================

- Fixed: Bug in idea.h.

- Fixed: Bug in mp_v3.cpp.


Changes snmp++v3.0d
===================

- Fixed: Bug in Oid::RnCompare()

- Fixed: mpIncSnmpUnknownSecurityModels() increased the
         wrong counter.

- Update: The changes of the official SNMP++ 2.84 from HP were
          merged into snmp++v3.

- Changed: The snmpEngineBoots counters for different
           snmpEntities can now be saved in one file. For this
           the function mpInit had to be changed. See
           include/v3.h for more information about the new functions
           getBootCounter, saveBootCounter and decodeEngineId.
           Example:

           char *filename = "snmpv3_boot_counter";
           unsigned int snmpEngineBoots = 0;
           OctetStr engineId("exampleId");

           // you may use your own methods to load/store this counter
           status = getBootCounter(filename, engineId, snmpEngineBoots);
           if ((status != SNMPv3_OK) && (status < SNMPv3_FILEOPEN_ERROR))
             cerr << "Error getBootCounter: " << status << endl;

           snmpEngineBoots++;
           status = saveBootCounter(filename, engineId, snmpEngineBoots);
           if (status != SNMPv3_OK)
             cerr << "Error saveBootCounter: " << status << endl;

           mpInit(&snmp, engineId, snmpEngineBoots);

- Fixed: Reports for encryption error were sent with a
         securityLevel authPriv, now authNoPriv is used.
         Reports for unknown security name were sent with
         user 'initial', now the user name of the request
         is used.

- Fixed: Snmp::trap now sets the timestamp of traps for WIN32
         and for non WIN32 to the same value if the user didn't
         set it with pdu::set_notify_timestamp().
         Note: Snmp::trap does not set the timestamp to the
         uptime of the system or the application. The timestamp
	 is computed from the time elapsed since 1970/1/1.

- Fixed: msec::refresh() now sets the correct time for WIN32 

- Changed: mpAddToEngineIDTable now replaces host and port
           when adding an engineID that is already in the table

- Fixed: OctetStr::from_hex_string()


Changes snmp++v3.0c
===================

- Fixed: Class Address had no default constructor.

- Added: mpIncSnmpUnknownSecurityModels(),
	 mpIncSnmpInvalidMsgs(),
	 mpIncSnmpUnknownPDUHandlers().

Changes snmp++v3.0b
===================

- Fixed: SNMPv3 reports for inform requests are now sent
         through the socket that is used to listen for
         traps/informs. 

- Added the static method
  CNotifyEventQueue::set_listen_port(int port);
  to set the trap listen port. Call this method before calling
  Snmp::notify_register(...). The default port is 162.


Changes snmp++v3.0a
===================

- Internal changes in SNMPv3 implementation

- Changes in structures for SNMPv3 async requests

- Some documentation added.

- Fixed: usmDeleteUserName mixed userName and securityName.
         Changed parameter of usmDeleteUserName to userName
         and added new function usmDeleteSecurityName.

- Fixed: the SNMP version of targets created through 
         CTarget(const CTarget) was set to version1
         (same for operator=(constCTarget))

- Changed call of "delete X" to "delete [] X" where necessary

- Moved some structure definitions from header files to cpp-files.
  Changed some internal structures from unsigned char to OctetStr.


Changes snmp++v3.0:
===================

- uxsnmp.cpp: line 656-660

  Added WSACleanup() routine for NT.

- smi.h: line 141

  Changed ASN.1 tag value of UInt32 to 2 (same as Gauge32)

  #define sNMP_SYNTAX_UINT32    sNMP_SYNTAX_GAUGE32

  removed duplicate case labels in asn1.cpp, snmpmsg.cpp and gauge.cpp

- snmpmsg.cpp: line 355

  Changed snmpTrapOID to

   tempvb.set_oid("1.3.6.1.6.3.1.1.4.1.0");

- Added const to Pdu::get methods where applicable. 

- Added static function OctetStr::from_hex_string().

- Added DLLOPT to all public functions / classes.

- Using memset and memcpy instead the deprecated counterparts 
  bzero and bcopy.

- Using WinSockets on WIN32 platforms.

- When converting an oid string to an oid (Oid::StrToOid) now an
  arbitrary part of the oid can be given as a string value enclosed in
  $ characters. For example the oid string

  "1.3.6.1.6.1.12.1.3.$public0$" 

  will result to the oid

  1.3.6.1.6.1.12.1.3.112.117.98.108.105.99.95.48

- the function mpInit is now called with a pointer to an Snmp object
  and an engineID: int mpInit(Snmp *snmp, const OctetStr& snmpEngineID);

- New target (UTarget for SNMPv3):
  - Methods to get/set security_name and security_model:
    void get_security_name( OctetStr& security_name_oct);
    void set_security_name( const OctetStr& new_security_name);

    void set_security_model(int sec_model);
    int get_security_model();

  - If you know the engine_id of the target (no engine_id discovery):
    void set_engine_id( const OctetStr& new_engine_id);
    void get_engine_id( OctetStr& engine_id_oct);

  --> most methods of CTarget do exist for UTaget: see target.h

  For SNMPv3 there is only one valid security_model (SNMP_SECURITY_MODEL_USM).
  If you set the security_model to SNMP_SECURITY_MODEL_V1 (or V2) you can use
  te UTarget to send SNMPv1 (v2c) requests.

- New methods for Pdu objects:

  void set_security_level( const int level);
  int get_security_level();

  void set_context_name(const OctetStr &name);
  void get_context_name(OctetStr &name);

  void set_context_engine_id(const OctetStr &id);
  void get_context_engine_id(OctetStr &id);

  valid security_levels are: SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV,
  SNMP_SECURITY_LEVEL_AUTH_NOPRIV and SNMP_SECURITY_LEVEL_AUTH_PRIV


- The CTarget can no longer be used as a SNMPv3 target. The methods
  mpBuildCommunity and mpParseCommunity don't exist any longer.


- The consoleExamples now use a CTarget for SNMPv1/v2c requests and
  UTarget for SNMPv3 requests. There are new examples: snmpInform
  (to send inform Requests) and receive_trap.


