diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1999-04-07 02:09:22 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1999-04-07 02:09:22 +0000 |
commit | 11441abcf9d4b8a782874801b314372234a8d377 (patch) | |
tree | df425288e66d1f5323807e845ffeaa6275876320 | |
parent | 4bf13a546b1c5a38c23afa3a9a22fc1796028f22 (diff) | |
download | ATCD-11441abcf9d4b8a782874801b314372234a8d377.tar.gz |
.
-rw-r--r-- | ace/ATM_Addr.cpp | 443 | ||||
-rw-r--r-- | ace/ATM_Addr.h | 144 | ||||
-rw-r--r-- | ace/ATM_Addr.i | 19 |
3 files changed, 606 insertions, 0 deletions
diff --git a/ace/ATM_Addr.cpp b/ace/ATM_Addr.cpp new file mode 100644 index 00000000000..95bfc390b12 --- /dev/null +++ b/ace/ATM_Addr.cpp @@ -0,0 +1,443 @@ +// $Id$ + +// Defines the Internet domain address family address format. + +#define ACE_BUILD_DLL +#include "ace/ATM_Addr.h" + +#if !defined (__ACE_INLINE__) +#include "ace/ATM_Addr.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, ATM_Addr, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_ATM_Addr) + +#if defined (ACE_HAS_FORE_ATM_XTI) +#define BHLI_MAGIC "FORE_ATM" + +// This is line rate in cells/s for an OC-3 MM interface. +const long ACE_ATM_Addr::LINE_RATE = 353207; +const int ACE_ATM_Addr::OPT_FLAGS_CPID = 0x1; +const int ACE_ATM_Addr::OPT_FLAGS_PMP = 0x2; +const int ACE_ATM_Addr::SELECTOR = 0x99; +#endif /* ACE_HAS_FORE_ATM_XTI */ + +// Default constructor + +ACE_ATM_Addr::ACE_ATM_Addr (void) + : ACE_Addr (AF_ATM, + sizeof this->atm_addr_) +{ + // ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr"); + (void) ACE_OS::memset ((void *) &this->atm_addr_, + 0, + sizeof this->atm_addr_); + this->init (); +} + +// Copy constructor. + +ACE_ATM_Addr::ACE_ATM_Addr (const ACE_ATM_Addr &sap) +{ + ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr"); + this->init (); + this->set (sap); +} + +ACE_ATM_Addr::ACE_ATM_Addr (const ATMSAPAddress *sap) +{ + ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr"); + this->init (); + this->set (sap); +} + +ACE_ATM_Addr::ACE_ATM_Addr (const ASYS_TCHAR sap[]) +{ + ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr"); + + // @@ Joe, you might consider putting the call to init() into set(). + this->init (); + this->set (sap); +} + +void +ACE_ATM_Addr::init (void) +{ + // Note: this approach may be FORE implementation-specific. When we + // bind with tag_addr ABSENT and tag_selector PRESENT, only the + // selector (i.e. address[19]) is used by the TP. The rest of the + // local address is filled in by the TP and can be obtained via the + // 'ret' parameter or with t_getname()/t_getprotaddr(). + + atm_addr_.addressType = (u_int16_t) AF_ATM; + + atm_addr_.sap.t_atm_sap_addr.SVE_tag_addr = (int8_t) T_ATM_ABSENT; + atm_addr_.sap.t_atm_sap_addr.SVE_tag_selector = (int8_t) T_ATM_PRESENT; + + atm_addr_.sap.t_atm_sap_addr.address_format = (u_int8_t) T_ATM_ENDSYS_ADDR; + atm_addr_.sap.t_atm_sap_addr.address_length = ATMNSAP_ADDR_LEN; + atm_addr_.sap.t_atm_sap_addr.address[ATMNSAP_ADDR_LEN - 1] = SELECTOR; + + atm_addr_.sap.t_atm_sap_layer2.SVE_tag = (int8_t) T_ATM_ABSENT; + atm_addr_.sap.t_atm_sap_layer3.SVE_tag = (int8_t) T_ATM_ABSENT; + + atm_addr_.sap.t_atm_sap_appl.SVE_tag = (int8_t) T_ATM_PRESENT; + atm_addr_.sap.t_atm_sap_appl.ID_type = (u_int8_t) T_ATM_USER_APP_ID; + + ACE_OS::memcpy (atm_addr_.sap.t_atm_sap_appl.ID.user_defined_ID, + BHLI_MAGIC, + sizeof atm_addr_.sap.t_atm_sap_appl.ID); +} + +int +ACE_ATM_Addr::set (const ACE_ATM_Addr &sap) +{ + ACE_TRACE ("ACE_ATM_Addr::set"); + + this->ACE_Addr::base_set (sap.get_type (), + sap.get_size ()); + + ACE_ASSERT (sap.get_type () == AF_ATM); + + // It's ok to make the copy. + (void) ACE_OS::memcpy ((void *) &this->atm_addr_, + (void *) &sap.atm_addr_, + sizeof this->atm_addr_); + return 0; +} + +int +ACE_ATM_Addr::set (const ATMSAPAddress *sap) +{ + ACE_TRACE ("ACE_ATM_Addr::set"); + + this->ACE_Addr::base_set (AF_ATM, + sizeof (*sap)); + + // It's ok to make the copy. + (void) ACE_OS::memcpy ((void *) &this->atm_addr_, + (void *) sap, + sizeof this->atm_addr_); + return 0; +} + +int +ACE_ATM_Addr::set (const ASYS_TCHAR address[]) +{ + ACE_TRACE ("ACE_ATM_Addr::set"); + + atm_addr_.sap.t_atm_sap_addr.SVE_tag_addr = + (int8_t) T_ATM_PRESENT; + return this->string_to_addr (address); +} + +// Transform the string into the current addressing format. + +int +ACE_ATM_Addr::string_to_addr (const ASYS_TCHAR sap[]) +{ + ACE_TRACE ("ACE_ATM_Addr::string_to_addr"); + + this->ACE_Addr::base_set (AF_ATM, + sizeof this->atm_addr_); + struct hostent *entry; + struct atmnsap_addr *nsap; + + // Yow, someone gave us a NULL ATM address! + if (sap == 0) + { + errno = EINVAL; + return -1; + } + else if ((entry = gethostbyname_atmnsap((ASYS_TCHAR *)sap)) != 0) + { + ACE_OS::memcpy (atm_addr_.sap.t_atm_sap_addr.address, + entry->h_addr_list[0], + ATMNSAP_ADDR_LEN - 1); + } + else if ((nsap = atmnsap_addr (sap)) != 0) + { + ACE_OS::memcpy (atm_addr_.sap.t_atm_sap_addr.address, + nsap->atmnsap, + ATMNSAP_ADDR_LEN); + } + else + { + errno = EINVAL; + return -1; + } + + return 0; +} + +// Transform the current address into string format. + +int +ACE_ATM_Addr::addr_to_string (ASYS_TCHAR addr[], + size_t addrlen) const +{ + ACE_TRACE ("ACE_ATM_Addr::addr_to_string"); + + ASYS_TCHAR buffer[MAXNAMELEN + 1]; + struct atmnsap_addr nsap; + ACE_OS::memcpy (nsap.atmnsap, + atm_addr_.sap.t_atm_sap_addr.address, + ATMNSAP_ADDR_LEN); + ACE_OS::sprintf (buffer, + ASYS_TEXT ("%s"), + ASYS_WIDE_STRING (atmnsap_ntoa (nsap))); + + size_t total_len = ACE_OS::strlen (buffer) + + sizeof ('\0'); // For trailing '\0'. + + if (addrlen < total_len) + return -1; + else + ACE_OS::strcpy(addr, buffer); + + return 0; +} + +const ASYS_TCHAR * +ACE_ATM_Addr::addr_to_string (void) const +{ + ACE_TRACE ("ACE_ATM_Addr::addr_to_string"); + + static ASYS_TCHAR addr[MAXHOSTNAMELEN + 1]; + this->addr_to_string (addr, + MAXHOSTNAMELEN + 1); + return addr; +} + +// Set a pointer to the address. +void +ACE_ATM_Addr::set_addr (void *addr, int len) +{ + ACE_TRACE ("ACE_ATM_Addr::set_addr"); + + this->ACE_Addr::base_set (AF_ATM, len); + ACE_OS::memcpy ((void *) &this->atm_addr_, + (void *) addr, len); +} + +// Compare two addresses for inequality. + +int +ACE_ATM_Addr::operator != (const ACE_ATM_Addr &sap) const +{ + ACE_TRACE ("ACE_ATM_Addr::operator !="); + return !((*this) == sap); +} + +// Compare two addresses for equality. + +int +ACE_ATM_Addr::operator == (const ACE_ATM_Addr &sap) const +{ + ACE_TRACE ("ACE_ATM_Addr::operator =="); + + return ACE_OS::memcmp (&atm_addr_, + &sap.atm_addr_, + sizeof (struct ATMSAPAddress)) == 0; +} + +void +ACE_ATM_Addr::dump (void) const +{ + ACE_TRACE ("ACE_ATM_Addr::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ASYS_TCHAR s[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16]; + ACE_OS::sprintf (s, + ASYS_TEXT ("%s"), + ASYS_WIDE_STRING (this->addr_to_string ())); + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("%s"), s)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Some OSes (namely, AIX) have implemented the v5 t_getprotaddr() +// command. Others, like Irix, still use the v4 t_getname(). Both +// are offered here. + +#ifdef aix +#define T_GETPROTADDR(fd, laddr, raddr) ACE_OS::t_getprotaddr(fd, laddr, raddr) +#else +#define T_GETPROTADDR(fd, laddr, raddr) ACE_OS::t_getname(fd, laddr.addr, LOCALNAME) +#endif /* aix */ + +int +ACE_ATM_Addr::get_local_address (ACE_HANDLE fd, + u_char addr[]) +{ + ATMSAPAddress local_addr; + struct t_bind boundaddr; + + boundaddr.addr.maxlen = sizeof local_addr; + boundaddr.addr.buf = (char *) &local_addr; + + if (T_GETPROTADDR (fd, &boundaddr, 0) == -1) + { + ACE_OS::t_error ("T_GETPROTADDR (local_address)"); + return -1; + } + + ACE_OS::memcpy (addr, + local_addr.sap.t_atm_sap_addr.address, + ATMNSAP_ADDR_LEN); + return 0; +} + +char * +ACE_ATM_Addr::construct_options(ACE_HANDLE fd, + int qos_kb, + int flags, + long *optsize) +{ + struct t_opthdr *popt; + char *buf; + int qos_cells; + struct t_info info; + + if (ACE_OS::t_getinfo (fd, &info) == -1) + { + ACE_OS::t_error ("t_getinfo"); + return 0; + } + + buf = (char *) ACE_OS::malloc (info.options); + + if (buf == 0) + ACE_ERROR_RETURN (("Unable to allocate %ld bytes for options\n", + info.options), + 0); + + popt = (struct t_opthdr *) buf; + + if (flags & OPT_FLAGS_CPID) + { + // This constructs the T_ATM_ORIG_ADDR option, which is used to + // signal the UNI 3.1 Calling Party ID Information Element. + t_atm_addr *source_addr; + + popt->len = sizeof (struct t_opthdr) + sizeof (t_atm_addr); + popt->level = T_ATM_SIGNALING; + popt->name = T_ATM_ORIG_ADDR; + popt->status = 0; + + source_addr = + (t_atm_addr *)((char *) popt + sizeof (struct t_opthdr)); + + source_addr->address_format = T_ATM_ENDSYS_ADDR; + source_addr->address_length = ATMNSAP_ADDR_LEN; + + if (get_local_address (fd, source_addr->address)) + { + ACE_ERROR ("Can't get local address!\n"); + ACE_OS::free (buf); + return 0; + } + + popt = T_OPT_NEXTHDR (buf, info.options , popt); + } + + // This constructs all options necessary (bearer cap., QoS, and + // Traffic Descriptor) to signal for a CBR connection with the + // specified QoS in kbit/sec., and/or specify a PMP connection. + + // For FORE 200e cards, the adapter shapes traffic to CBR with rate + // equal to PCR CLP=0+1 (traffic.forward.PCR_all_traffic) + + qos_cells = (qos_kb * 1000) / (48*8); + + if ((qos_cells > 0 && qos_cells < LINE_RATE) + || (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP))) + { + struct t_atm_bearer *bearer; + struct t_atm_traffic *traffic; + + // T_ATM_BEARER_CAP: Broadband bearer capability + popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_bearer); + popt->level = T_ATM_SIGNALING; + popt->name = T_ATM_BEARER_CAP; + popt->status = 0; + + bearer = (struct t_atm_bearer *)((char *) popt + sizeof (struct t_opthdr)); + bearer->bearer_class = T_ATM_CLASS_X; + + if (qos_cells) + { + bearer->traffic_type = T_ATM_CBR; + bearer->timing_requirements = T_ATM_END_TO_END; + } + else + { + bearer->traffic_type = 0; // UBR + bearer->timing_requirements = 0; + } + bearer->clipping_susceptibility = T_ATM_NULL; + + if (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP)) + bearer->connection_configuration = T_ATM_1_TO_MANY; + else + bearer->connection_configuration = T_ATM_1_TO_1; + + popt = T_OPT_NEXTHDR (buf, info.options, popt); + + // T_ATM_TRAFFIC: traffic descriptor + popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_traffic); + popt->level = T_ATM_SIGNALING; + popt->name = T_ATM_TRAFFIC; + popt->status = 0; + + traffic = (struct t_atm_traffic *)((char *) popt + sizeof (struct t_opthdr)); + + traffic->forward.PCR_high_priority = T_ATM_ABSENT; + traffic->forward.PCR_all_traffic = qos_cells ? qos_cells : LINE_RATE; + traffic->forward.SCR_high_priority = T_ATM_ABSENT; + traffic->forward.SCR_all_traffic = T_ATM_ABSENT; + traffic->forward.MBS_high_priority = T_ATM_ABSENT; + traffic->forward.MBS_all_traffic = T_ATM_ABSENT; + traffic->forward.tagging = T_NO; + + traffic->backward.PCR_high_priority = T_ATM_ABSENT; + traffic->backward.PCR_all_traffic = + (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP)) + ? 0 : qos_cells ? qos_cells : LINE_RATE; + traffic->backward.SCR_high_priority = T_ATM_ABSENT; + traffic->backward.SCR_all_traffic = T_ATM_ABSENT; + traffic->backward.MBS_high_priority = T_ATM_ABSENT; + traffic->backward.MBS_all_traffic = T_ATM_ABSENT; + traffic->backward.tagging = T_NO; + + traffic->best_effort = qos_cells ? T_NO : T_YES; + + popt = T_OPT_NEXTHDR (buf, + info.options, + popt); + } + + if (qos_cells > 0 && qos_cells < LINE_RATE) + { + struct t_atm_qos *qos; + + // T_ATM_QOS: Quality of Service + popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_qos); + popt->level = T_ATM_SIGNALING; + popt->name = T_ATM_QOS; + popt->status = 0; + + qos = (struct t_atm_qos *)((char *) popt + sizeof (struct t_opthdr)); + qos->coding_standard = T_ATM_ITU_CODING; + qos->forward.qos_class = T_ATM_QOS_CLASS_1; + qos->backward.qos_class = T_ATM_QOS_CLASS_1; + + popt = T_OPT_NEXTHDR (buf, info.options, popt); + } + + // return actual size of options and option buffer to user + *optsize = (char *) popt - buf; + + return buf; +} diff --git a/ace/ATM_Addr.h b/ace/ATM_Addr.h new file mode 100644 index 00000000000..de7c5354a30 --- /dev/null +++ b/ace/ATM_Addr.h @@ -0,0 +1,144 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// ATM_Addr.h +// +// = AUTHOR +// Joe Hoffert <joeh@cs.wustl.edu> +// +// ============================================================================ + +#ifndef ACE_ATM_ADDR_H +#define ACE_ATM_ADDR_H + +#include "ace/ACE.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Addr.h" + +class ACE_Export ACE_ATM_Addr : public ACE_Addr +{ + // = TITLE + // Defines the ATM domain address family address format. +public: + // Constants used for ATM options + static const long LINE_RATE; + static const int OPT_FLAGS_CPID; + static const int OPT_FLAGS_PMP; + static const int SELECTOR; + + // = Initialization methods. + ACE_ATM_Addr (void); + // Default constructor. + + ACE_ATM_Addr (const ACE_ATM_Addr &); + // Copy constructor. + + ACE_ATM_Addr (const ATMSAPAddress *); + // Creates an <ACE_ATM_Addr> from an ATMSAPAddress structure. This + // is vendor specific (FORE systems). May need to change when other + // vendors are supported. + + ACE_ATM_Addr (const ASYS_TCHAR sap[]); + // Initializes an <ACE_ATM_Addr> from the <sap> which can be + // "atm-address" (e.g., + // "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") or "hostname" + // (e.g., "frisbee.cs.wustl.edu"). + + ~ACE_ATM_Addr (void); + // Default dtor. + + // = Initialization methods (useful after object construction). + void init (void); + // Default initialization for non-address values (e.g., + // t_atm_sap_addr.SVE_tag_addr, t_atm_sap_addr.SVE_tag_selector) + + int set (const ACE_ATM_Addr &); + // Initializes from another <ACE_ATM_Addr>. + + int set (const ATMSAPAddress *); + // Initializes an <ACE_ATM_Addr> from an ATMSAPAddress + // structure. This is vendor specific (FORE systems). May need to + // change when other vendors are supported. + + int set (const ASYS_TCHAR sap[]); + // Initializes an <ACE_ATM_Addr> from the <sap> which can be + // "atm-address" (e.g., + // "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") or "hostname" + // (e.g., "frisbee.cs.wustl.edu"). + + virtual int string_to_addr (const ASYS_TCHAR sap[]); + // Initializes an <ACE_ATM_Addr> from the <sap> which can be + // "atm-address" (e.g., + // "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") or "hostname" + // (e.g., "frisbee.cs.wustl.edu"). + + virtual int addr_to_string (ASYS_TCHAR addr[], + size_t addrlen) const; + // Return the character representation of the ATM address (e.g., + // "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") storing it in + // the <addr> (which is assumed to be <addrlen> bytes long). This + // version is reentrant. Returns -1 if the <addrlen> of the <addr> + // is too small, else 0. + + const ASYS_TCHAR *addr_to_string (void) const; + // Return the character representation of the ATM address (e.g., + // "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00"). Returns -1 + // if the <size> of the <buffer> is too small, else 0.(This version + // is non-reentrant since it returns a pointer to a static data + // area.) + + virtual void *get_addr (void) const; + // Return a pointer to the underlying network address. + + virtual void set_addr (void *, int); + // Set a pointer to the address. + + int operator == (const ACE_ATM_Addr &SAP) const; + // Compare two addresses for equality. The addresses are considered + // equal if they contain the same ATM address. Q: Is there any + // other check for equality needed for ATM? + + int operator != (const ACE_ATM_Addr &SAP) const; + // Compare two addresses for inequality. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + static char *construct_options (ACE_HANDLE fd, + int qos_kb, + int flags, + long *optsize); + // Construct options for ATM connections + +protected: + static int get_local_address (ACE_HANDLE handle, + u_char addr[]); + // Get the local ATM address. + +private: + ATMSAPAddress atm_addr_; + // Underlying representation - this may be very + // vendor-implementation specific. Other vendors (besides FORE) may + // name and define this structure differently. We can work around + // that problem when we run into other vendors supporting XTI on top + // of ATM. Is this class specific to XTI? Not sure. +}; + +#if defined (__ACE_INLINE__) +#include "ace/ATM_Addr.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_ATM_ADDR_H */ diff --git a/ace/ATM_Addr.i b/ace/ATM_Addr.i new file mode 100644 index 00000000000..86a0c3ccc8c --- /dev/null +++ b/ace/ATM_Addr.i @@ -0,0 +1,19 @@ +/* -*- C++ -*- */ +// $Id$ + +// ATM_Addr.i + +// Default dtor. +ACE_INLINE +ACE_ATM_Addr::~ACE_ATM_Addr (void) +{ +} + +// Return the address. + +ACE_INLINE void * +ACE_ATM_Addr::get_addr (void) const +{ + ACE_TRACE ("ACE_ATM_Addr::get_addr"); + return (void *) &this->atm_addr_; +} |