Merge branch 'master' into jwi-bcc64xsingletonwarning
[ACE_TAO.git] / ACE / ASNMP / asnmp / address.cpp
blob001337d36f32ef12d698089df0b7a845911df72a
2 //=============================================================================
3 /**
4 * @file address.cpp
6 * The Vb class is an encapsulation of the snmp variable binding.
7 * This module contains the class definition for the variable binding (VB)
8 * class. The VB class is an encapsulation of a SNMP VB. A VB object is
9 * composed of one SNMP++ Oid and one SMI value. The Vb class utilizes Oid
10 * objects and thus requires the Oid class. To use this class,
11 * set oid, value then call valid() to be sure object was constructed correctly.
13 * @author Peter E MellquistMichael R MacFaden mrm@cisco.com - rework & ACE port
15 //=============================================================================
17 /*===================================================================
18 Copyright (c) 1996
19 Hewlett-Packard Company
21 ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
22 Permission to use, copy, modify, distribute and/or sell this software
23 and/or its documentation is hereby granted without fee. User agrees
24 to display the above copyright notice and this license notice in all
25 copies of the software and any documentation of the software. User
26 agrees to assume all liability for the use of the software; Hewlett-Packard
27 makes no representations about the suitability of this software for any
28 purpose. It is provided "AS-IS without warranty of any kind,either express
29 or implied. User hereby grants a royalty-free license to any and all
30 derivatives based upon this software code base.
31 =====================================================================*/
33 #include "asnmp/address.h"
34 #include "ace/OS_NS_string.h"
35 #include "ace/OS_NS_arpa_inet.h"
36 #include "ace/OS_NS_netdb.h"
37 #include "ace/OS_NS_stdlib.h"
38 #include "ace/OS_NS_stdio.h"
39 #include "ace/OS_NS_ctype.h"
40 #include "ace/OS_Memory.h"
42 //=================================================================
43 //======== Abstract Address Class Implementation ==================
44 //=================================================================
46 // allow destruction of derived classes
47 Address::~Address()
52 //-----------------------------------------------------------------
53 // is the address object valid?
54 int Address::valid() const
56 return valid_flag;
59 //------------[ Address::trim_white_space( char * ptr) ]------------
60 // destructive trim white space
61 void Address::trim_white_space( char * ptr)
63 char *tmp;
65 tmp = ptr;
66 // skip leading white space
67 while (*tmp==' ')tmp++;
68 ACE_OS::strcpy(ptr,tmp);
70 // find end of string
71 while ((*tmp!=' ') && (*tmp !=0)) tmp++;
72 if (*tmp!=0) *tmp=0;
75 //TM: this is not used nor needed, remove?
76 //-----[ element access ]----------------------------------------------
77 unsigned char& Address::operator[]( const int position)
79 if ( position < MAX_ADDR_SZ)
80 return address_buffer[ position];
81 else
82 return address_buffer[0];
86 //-----------------------------------------------------------------------
87 // overloaded equivlence operator, are two addresses equal?
88 bool operator==( const Address &lhs, const Address &rhs)
90 if ( ACE_OS::strcmp( (const char*) lhs, (const char*)rhs)==0)
91 return true;
92 else
93 return false;
96 //-----------------------------------------------------------------------
97 // overloaded equivlence operator, are two addresses equal?
98 bool operator!=( const Address &lhs, const Address &rhs)
100 return (!( lhs == rhs));
104 //------------------------------------------------------------------
105 // overloaded > operator, is a1 > a2
106 bool operator>( const Address &lhs, const Address &rhs)
108 if (ACE_OS::strcmp( (const char*) lhs, (const char*)rhs)>0)
109 return true;
110 else
111 return false;
114 // overloaded >= operator, is a1 > a2
115 bool operator>=( const Address &lhs,const Address &rhs)
117 if (( lhs > rhs) || ( lhs == rhs))
118 return true;
119 else
120 return false;
123 // overloaded < operator, is a1 <= a2
124 bool operator<=( const Address &lhs,const Address &rhs)
126 if (( lhs < rhs) || ( lhs == rhs))
127 return true;
128 else
129 return false;
133 //-----------------------------------------------------------------
134 // overloaded < operator, is a1 < a2
135 bool operator<( const Address &lhs, const Address &rhs)
137 if (ACE_OS::strcmp( (const char*) lhs, (const char*)rhs)<0)
138 return true;
139 else
140 return false;
143 //------------------------------------------------------------------
144 // equivlence operator overloaded, are an address and a string equal?
145 bool operator==( const Address &lhs,const char *rhs)
147 if (!rhs && !lhs.valid())
148 return true;
149 if (ACE_OS::strcmp( (const char *) lhs, rhs)== 0)
150 return true;
151 else
152 return false;
155 //------------------------------------------------------------------
156 // not equal operator overloaded, are an address and a string not equal?
157 bool operator!=( const Address &lhs,const char *rhs)
159 return (!( lhs == rhs));
162 //------------------------------------------------------------------
163 // overloaded > , is a > inaddr
164 bool operator>( const Address &lhs,const char *rhs)
166 if (!rhs)
167 return lhs.valid(); // if lhs valid then > 0, else invalid !> 0
168 if (ACE_OS::strcmp( (const char *) lhs, rhs)> 0)
169 return true;
170 else
171 return false;
174 //------------------------------------------------------------------
175 // overloaded >= , is a >= inaddr
176 bool operator>=( const Address &lhs,const char *rhs)
178 if (!rhs)
179 return true; // always >= 0
180 if (ACE_OS::strcmp( (const char *) lhs, rhs)>= 0)
181 return true;
182 else
183 return false;
186 //-----------------------------------------------------------------
187 // overloaded < , are an address and a string equal?
188 bool operator<( const Address &lhs,const char *rhs)
190 if (!rhs)
191 return false; // always >= 0
192 if (ACE_OS::strcmp( (const char *) lhs, rhs)< 0)
193 return true;
194 else
195 return false;
198 //-----------------------------------------------------------------
199 // overloaded <= , is a <= inaddr
200 bool operator<=( const Address &lhs,const char *rhs)
202 if (!rhs)
203 return !lhs.valid(); // invalid == 0, else valid > 0
204 if (ACE_OS::strcmp( (const char *) lhs, rhs) <= 0)
205 return true;
206 else
207 return false;
211 //=====================================================================
212 //============ IPAddress Implementation ===============================
213 //=====================================================================
215 //-----------[ syntax type ]----------------------------------------------
216 SmiUINT32 IpAddress::get_syntax()
218 return sNMP_SYNTAX_IPADDR;
221 //-----[ IP Address copy constructor ]---------------------------------
222 IpAddress::IpAddress(const IpAddress &ipaddr)
223 : Address (ipaddr)
225 // always initialize what type this object is
226 smival.syntax = sNMP_SYNTAX_IPADDR;
227 smival.value.string.len =IPV4LEN;
228 smival.value.string.ptr = address_buffer;
230 iv_friendly_name_[0] = 0;
231 iv_friendly_name_status_ = 0;
232 valid_flag = ipaddr.valid_flag;
233 if (valid_flag) {
234 ACE_OS::memcpy(address_buffer, ipaddr.address_buffer,IPV4LEN);
235 ACE_OS::strcpy( iv_friendly_name_, ipaddr.iv_friendly_name_);
238 IpAddress::format_output();
242 //-------[ default construct, an IP address with a string ]---------------------
243 IpAddress::IpAddress( const char *inaddr): Address()
245 // always initialize what type this object is
246 smival.syntax = sNMP_SYNTAX_IPADDR;
247 smival.value.string.len = IPV4LEN;
248 smival.value.string.ptr = address_buffer;
250 if (ACE_OS::strlen(inaddr) == 0) {
251 valid_flag = 0;
252 iv_friendly_name_[0] = 0;
253 iv_friendly_name_status_ = 0;
254 IpAddress::format_output();
255 return;
258 // parse_address initializes valid, address_buffer & iv_friendly_name_
259 valid_flag = parse_address(inaddr);
260 IpAddress::format_output();
264 //-----[ construct an IP address with a GenAddress ]---------------------
265 IpAddress::IpAddress( const GenAddress &genaddr)
267 // always initialize what type this object is
268 smival.syntax = sNMP_SYNTAX_IPADDR;
269 smival.value.string.len = IPV4LEN;
270 smival.value.string.ptr = address_buffer;
272 valid_flag = 0;
273 iv_friendly_name_[0] = 0;
274 iv_friendly_name_status_ = 0;
275 // allow use of an ip or udp genaddress
276 if (genaddr.get_type() == type_ip) {
277 valid_flag = genaddr.valid();
278 if ( valid_flag) {
279 // copy in the IP address data
280 IpAddress temp_ip( (const char *) genaddr);
281 *this = temp_ip;
284 else
285 if (genaddr.get_type() == type_udp) {
286 valid_flag = genaddr.valid();
287 if ( valid_flag) {
288 // copy in the IP address data
289 UdpAddress temp_udp( (const char *) genaddr);
290 *this = temp_udp;
293 IpAddress::format_output();
296 //-----[ destructor ]--------------------------------------------------
297 IpAddress::~IpAddress()
301 // assumes member data is word aligned to avoid sigbus
302 int IpAddress::is_loopback() const
304 if (valid()) {
305 u_long *pl = (u_long *)&address_buffer;
306 return (*pl == INADDR_LOOPBACK);
308 return 0;
311 int IpAddress::is_multicast() const
313 if (valid()) {
314 u_long *pl = (u_long *)&address_buffer;
315 return (IN_MULTICAST(*pl));
317 return 0;
320 // Private addressess not are not assignable in the Internet, they are
321 // defined in RFC 1597 as: 10, 172.16, and 192.168.0
322 // Some companies use them internally and apply NAT to allow translation
323 // instead of paying for ip networks.
324 // Cisco IOS devices can provide NAT aka Network Address Translation
325 // but don't expect SNMP based networks to handle cross-NAT address spaces.
326 // assumes storage in network byte order mrm@cisco.com 7/28/97
328 int IpAddress::is_private() const
330 if (valid()) {
331 if (address_buffer[0] == 10)
332 return 1;
333 if (address_buffer[0] == 172 && address_buffer[1] == 16)
334 return 1;
335 if (address_buffer[0] == 192 && address_buffer[1] == 168 &&
336 address_buffer[2] == 0)
337 return 1;
339 return 0;
343 // convert address into octet string format in network byte order
344 void IpAddress::to_octet(OctetStr& octet) const
346 octet.set_data( smival.value.string.ptr, smival.value.string.len);
350 int IpAddress::is_broadcast() const
352 if (valid()) {
353 u_long *pl = (u_long *)&address_buffer;
354 return ( (*pl) & INADDR_BROADCAST);
356 return 0;
359 //-----[ IP Address general = operator ]-------------------------------
360 SnmpSyntax& IpAddress::operator=( SnmpSyntax &val)
362 // protect against assignment from itself
363 if ( this == &val )
364 return *this;
366 valid_flag = 0; // will get set 1 if really valid
367 iv_friendly_name_[0]=0;
369 if (val.valid()) {
370 switch (val.get_syntax()) {
371 case sNMP_SYNTAX_IPADDR:
372 case sNMP_SYNTAX_OCTETS:
373 if (((IpAddress &)val).smival.value.string.len ==IPV4LEN) {
374 ACE_OS::memcpy(address_buffer,
375 ((IpAddress &)val).smival.value.string.ptr,IPV4LEN);
376 valid_flag = 1;
378 break;
380 // NOTE: as a value add, other types could have "logical"
381 // mappings, i.e. integer32 and unsigned32
384 IpAddress::format_output();
385 return *this;
388 //------[ assignment to another ipaddress object overloaded ]-----------------
389 IpAddress& IpAddress::operator=( const IpAddress &ipaddress)
391 // protect against assignment from itself
392 if ( this == &ipaddress )
393 return *this;
395 valid_flag = ipaddress.valid_flag;
396 iv_friendly_name_[0]=0;
398 if (valid_flag) {
399 ACE_OS::memcpy(address_buffer, ipaddress.address_buffer, IPV4LEN);
400 ACE_OS::strcpy(iv_friendly_name_, ipaddress.iv_friendly_name_);
402 IpAddress::format_output();
403 return *this;
407 //--------[ create a new instance of this Value ]-----------------------
408 SnmpSyntax *IpAddress::clone() const
410 return (SnmpSyntax *) new IpAddress(*this);
413 //-------[ return the Fully Qualified Domain Name ]----------------------
414 const char *IpAddress::resolve_hostname(int &status)
416 if ((iv_friendly_name_[0] == 0) && valid_flag)
417 addr_to_friendly();
418 status = iv_friendly_name_status_;
419 return iv_friendly_name_;
422 // parse a dotted string
423 int IpAddress::parse_dotted_ipstring( const char *inaddr)
425 char *ip_token;
426 int token_count=0;
427 unsigned int value;
428 int error_status = 0;
429 char temp[MAXHOSTNAMELEN +1]; // temp buffer for destruction
430 int z,w;
432 // check len, an ip can never be bigger than 15
433 // 123456789012345
434 // XXX.XXX.XXX.XXX
435 if ( !inaddr || (ACE_OS::strlen( inaddr) > 30))
436 return 0;
437 ACE_OS::strcpy( temp, inaddr);
438 trim_white_space( temp);
439 if ( ACE_OS::strlen( temp) > 15)
440 return 0;
442 // must only have three dots
443 // strtok will not catch this !
444 char *ptr = temp;
445 int dot_count = 0;
446 while ( *ptr != 0) {
447 if ( *ptr == '.') dot_count++;
448 ptr++;
450 if ( dot_count != 3)
451 return 0;
453 // look for dot token separator
454 ip_token = ACE_OS::strtok( (char *) temp,".");
456 // while more tokens..
457 while ( ip_token != 0) {
458 // verify that the token is all numerics
459 w = ACE_OS::strlen( ip_token);
460 if (w>3)
461 return 0;
462 for (z=0;z<w;z++)
463 if (( ip_token[z] < '0') || ( ip_token[z] > '9'))
464 return 0;
466 value = ( unsigned int) ACE_OS::strtod(ip_token,0);
467 if (( value > 0)&& ( value <=255))
468 address_buffer[token_count] = (unsigned char) value;
469 else
470 if (ACE_OS::strcmp(ip_token,"0")==0)
471 address_buffer[token_count]= (unsigned char) 0;
472 else
473 error_status = 1;
474 token_count++;
475 ip_token = ACE_OS::strtok( 0, ".");
478 // gota be four in len
479 if ( token_count != 4)
480 return 0;
482 // any parsing errors?
483 if ( error_status)
484 return 0;
486 return 1;
489 //-----[ IP Address parse Address ]---------------------------------
490 int IpAddress::parse_address( const char *inaddr)
492 // parse the input char array
493 // fill up internal buffer with four ip bytes
494 // set and return validity flag
496 in_addr ipAddr;
497 char ds[MAXHOSTNAMELEN +1];
499 // intialize the friendly_name member variable
500 iv_friendly_name_[0] = 0;
501 iv_friendly_name_status_ = 0;
503 // is this a dotted IP notation string or
504 // a friendly name
505 if ( parse_dotted_ipstring( inaddr)) {
506 // since this is a valid dotted string
507 // don't do any DNS (Performance!)
508 return 1;
510 else {
511 int rc;
512 if ((rc = resolve_to_address(inaddr, ipAddr)) == 0) {
513 // now lets check out the dotted string
514 ACE_OS::strncpy( ds, ACE_OS::inet_ntoa(ipAddr), MAXHOSTNAMELEN);
516 if ( !parse_dotted_ipstring( ds))
517 return 0;
519 // save the friendly name
520 ACE_OS::strcpy( iv_friendly_name_, inaddr);
521 } // end if lookup result
522 else {
523 iv_friendly_name_status_ = rc;
524 return 0;
526 } // end else not a dotted string
527 return 1;
530 // using the currently defined address, do a DNS
531 // and try to fill up the name
532 int IpAddress::addr_to_friendly()
534 in_addr ipAddr;
535 long result = ACE_OS::inet_addr(to_string());
536 if (result == -1)
537 return -1; // expected a dotted quad!
539 ipAddr.s_addr = result;
541 // set iv_friendly_name_ from ipAddr
542 if (resolve_to_hostname(ipAddr, iv_friendly_name_) == 0) {
543 return 0;
545 else {
546 #if defined (VXWORKS)
547 // VxWorks doesn't have h_errno
548 iv_friendly_name_status_ = errno;
549 #else
550 iv_friendly_name_status_ = h_errno;
551 #endif /* VXWORKS */
552 return iv_friendly_name_status_;
556 // static aka class member function (1.2.3.4 -> foo.com)
557 int IpAddress::resolve_to_hostname(const in_addr& quad_addr, char *hostname)
559 struct hostent lookupResult;
560 int loc_errno = 0;
561 ACE_HOSTENT_DATA buffer;
562 ACE_OS::memset(&lookupResult, 0, sizeof(struct hostent));
563 ACE_OS::memset(&buffer, 0, sizeof(ACE_HOSTENT_DATA));
565 // reverse lookup (requires in-addr.arpa to be setup in DNS
566 if (ACE_OS::gethostbyaddr_r((const char *)&quad_addr.s_addr, IPV4LEN,
567 AF_INET, &lookupResult, buffer, &loc_errno)) {
568 // verify right type of record
569 if (lookupResult.h_addrtype == AF_INET &&
570 lookupResult.h_length == IPV4LEN) {
571 ACE_OS::strcpy( hostname, lookupResult.h_name);
572 // setup multiple entries
573 return 0;
575 else {
576 ACE_ASSERT(0); // todo add trace and debug and dump
577 return -1; // wrong resource record type
581 return loc_errno;
584 // static aka class member function (foo.com -> 1.2.3.4)
585 int IpAddress::resolve_to_address(const char *hostname, in_addr& quad_addr)
587 struct hostent lookupResult;
588 ACE_HOSTENT_DATA buffer;
589 ACE_OS::memset(&buffer, 0, sizeof(ACE_HOSTENT_DATA));
590 ACE_OS::memset(&lookupResult, 0, sizeof(struct hostent));
591 int loc_errno = 0;
592 if (ACE_OS::gethostbyname_r( hostname, &lookupResult, buffer, &loc_errno)) {
593 if (lookupResult.h_length == (int) sizeof(in_addr) &&
594 lookupResult.h_addrtype == AF_INET) {
595 ACE_OS::memcpy((void *) &quad_addr,
596 (void *) lookupResult.h_addr_list[0], sizeof(in_addr));
597 return 0;
599 else
600 return -1; // wrong address size
602 return loc_errno;
605 //----[ IP address char * cast ]--------------------------------------
606 IpAddress::operator const char *() const
608 return (char *)output_buffer;
611 //----[ IP address get char representation ]--------------------------
612 const char * IpAddress::to_string()
614 return (char *)output_buffer;
617 //----[ IP address format output ]------------------------------------
618 void IpAddress::format_output()
620 // if valid format else null it
621 if ( valid_flag)
622 ACE_OS::sprintf( (char *) output_buffer,"%d.%d.%d.%d",address_buffer[0],
623 address_buffer[1], address_buffer[2], address_buffer[3]);
624 else
625 output_buffer[0] = 0;
628 //------[ return the type ]----------------------------------
629 addr_type IpAddress::get_type() const
631 return type_ip;
634 //-----------------------------------------------------------------
635 // logically and two IPaddresses and
636 // return the new one
637 void IpAddress::mask( const IpAddress& ipaddr)
639 if ( this->valid() && ipaddr.valid()) {
640 this->address_buffer[0] = this->address_buffer[0] & ipaddr.address_buffer[0];
641 this->address_buffer[1] = this->address_buffer[1] & ipaddr.address_buffer[1];
642 this->address_buffer[2] = this->address_buffer[2] & ipaddr.address_buffer[2];
643 this->address_buffer[3] = this->address_buffer[3] & ipaddr.address_buffer[3];
644 format_output();
649 //=======================================================================
650 //========== DNS Iterator Implementation ================================
651 //=======================================================================
654 Address_Iter::Address_Iter (const char *hostname)
655 : valid_(0),
656 count_(0),
657 entry_(0)
659 ACE_OS::memset (&buffer_, 0, sizeof (ACE_HOSTENT_DATA));
660 ACE_OS::memset (&lookupResult_, 0, sizeof (struct hostent));
662 if (ACE_OS::inet_addr (hostname) == (unsigned long) -1)
664 valid_ = query_dns (hostname);
666 else
668 ACE_ASSERT (0); // don't support dot-quad lookup yet
671 // count number of hostnames
672 int n;
673 char **pc;
675 for (n = 0, pc = lookupResult_.h_addr_list; *pc != 0; ++n, ++pc)
677 // Do nothing.
680 count_ = n; // plus first one
681 entry_ = lookupResult_.h_addr_list;
684 int Address_Iter::valid() const
686 return (valid_ == 1);
689 int Address_Iter::how_many_addresses()
691 return count_;
694 // return next entry, rc = 0, if entry is null return 0
695 int Address_Iter::next(IpAddress& addr)
697 if (!entry_ || *entry_ == 0)
698 return 1;
700 IpAddress tmp(*entry_++); // return data
701 addr = tmp;
702 if (*entry_ == 0)
703 return 1;
704 return 0;
707 // query DNS here
708 int Address_Iter::query_dns(const char *hostname)
710 int loc_errno = 0;
711 if (ACE_OS::gethostbyname_r( hostname, &lookupResult_, buffer_,
712 &loc_errno)) {
713 if (lookupResult_.h_length == (int) sizeof(IPV4LEN) &&
714 lookupResult_.h_addrtype == AF_INET) {
715 return 0;
717 else
718 return -1; // wrong address size
720 return loc_errno;
723 //=======================================================================
724 //========== Udp Address Implementation =================================
725 //=======================================================================
727 //-----------[ syntax type ]----------------------------------------------
728 SmiUINT32 UdpAddress::get_syntax()
730 return sNMP_SYNTAX_OCTETS;
733 //-----------------[ construct an Udp address with another Udp address ]---
734 UdpAddress::UdpAddress( const UdpAddress &udpaddr):IpAddress(udpaddr)
736 // always initialize SMI info
737 smival.syntax = sNMP_SYNTAX_OCTETS;
738 smival.value.string.len = UDPIPV4LEN;
739 smival.value.string.ptr = address_buffer;
741 // Copy the port value
742 set_port(udpaddr.get_port());
743 format_output();
746 // default constructor with a dotted string
747 UdpAddress::UdpAddress( const char *inaddr):IpAddress()
749 if (ACE_OS::strlen(inaddr) == 0) {
750 // Inherits IP Address attributes
751 // Always initialize (override) what type this object is
752 smival.syntax = sNMP_SYNTAX_OCTETS;
753 smival.value.string.len = UDPIPV4LEN;
754 smival.value.string.ptr = address_buffer;
755 set_port(0);
756 format_output();
757 return;
760 // always initialize SMI info
761 smival.syntax = sNMP_SYNTAX_OCTETS;
762 smival.value.string.len = UDPIPV4LEN;
763 smival.value.string.ptr = address_buffer;
765 valid_flag = parse_address( (char *)inaddr);
766 format_output();
769 //-----------------[ construct a UdpAddress from a GenAddress ]--------------
770 UdpAddress::UdpAddress( const GenAddress &genaddr):IpAddress()
772 // always initialize SMI info
773 smival.syntax = sNMP_SYNTAX_OCTETS;
774 smival.value.string.len = UDPIPV4LEN;
775 smival.value.string.ptr = address_buffer;
777 unsigned int port = 0;
778 valid_flag = 0;
780 // allow use of an ip or udp genaddress
781 if (genaddr.get_type() == type_udp)
783 valid_flag = genaddr.valid();
784 if ( valid_flag)
786 // copy in the IP address data
787 UdpAddress temp_udp( (const char *) genaddr);
788 *this = temp_udp;
790 // port info since are making an UpAddress
791 port = temp_udp.get_port();
794 else
795 if (genaddr.get_type() == type_ip)
797 valid_flag = genaddr.valid();
798 if ( valid_flag)
800 // copy in the IP address data
801 IpAddress temp_ip( (const char *) genaddr);
802 *this = temp_ip;
805 set_port(port);
806 format_output();
810 //--------[ construct a udp from an IpAddress ]--------------------------
811 UdpAddress::UdpAddress( const IpAddress &ipaddr):IpAddress(ipaddr)
813 // always initialize SMI info
814 smival.syntax = sNMP_SYNTAX_OCTETS;
815 smival.value.string.len = UDPIPV4LEN;
816 smival.value.string.ptr = address_buffer;
818 set_port(0);
819 format_output();
823 //-----[ destructor ]--------------------------------------------------
824 UdpAddress::~UdpAddress()
829 // copy an instance of this Value
830 SnmpSyntax& UdpAddress::operator=( SnmpSyntax &val)
832 // protect against assignment from itself
833 if ( this == &val )
834 return *this;
836 valid_flag=0; // will get set 1 if really valid
837 if (val.valid()){
838 switch (val.get_syntax()){
839 case sNMP_SYNTAX_IPADDR:
841 UdpAddress temp_udp(val.to_string());
842 *this = temp_udp; // valid_flag is set by the udp assignment
844 break;
846 case sNMP_SYNTAX_OCTETS:
847 if (((UdpAddress &)val).smival.value.string.len == UDPIPV4LEN){
848 ACE_OS::memcpy(address_buffer,
849 ((UdpAddress &)val).smival.value.string.ptr, UDPIPV4LEN);
850 iv_friendly_name_[0] = 0;
851 valid_flag = 1;
853 break;
855 // NOTE: as a value add, other types could have "logical"
856 // mappings, i.e. integer32 and unsigned32
859 format_output();
860 return *this;
863 // assignment to another UdpAddress object overloaded
864 UdpAddress& UdpAddress::operator=( const UdpAddress &udpaddr)
866 // protect against assignment from itself
867 if ( this == &udpaddr )
868 return *this;
870 (IpAddress &)*this = udpaddr; // use ancestor assignment for ipaddr value
871 set_port(udpaddr.get_port()); // copy to port value
872 format_output();
873 return *this;
877 //-----[ IP Address parse Address ]---------------------------------
878 int UdpAddress::parse_address( const char *inaddr)
880 char buffer[MAXHOSTNAMELEN +1];
882 unsigned short port = 0;
883 if (inaddr && (ACE_OS::strlen( inaddr)< MAXHOSTNAMELEN +1))
884 ACE_OS::strcpy( buffer, inaddr);
885 else {
886 valid_flag = 0;
887 return 0;
889 // look for port info @ the end of the string
890 // port can be delineated by a ':' or a '/'
891 // if neither are present then just treat it
892 // like a normal IpAddress
893 char *tmp;
894 tmp = ACE_OS::strstr( buffer,":");
895 if (tmp==0)
896 tmp = ACE_OS::strstr(buffer,"/");
898 if ( tmp != 0) {
899 *tmp=0; // null terminator
900 tmp++;
901 port = ACE_OS::atoi( tmp);
904 set_port(port);
905 return IpAddress::parse_address( buffer);
909 //----------[ create a new instance of this Value ]------------------------
910 SnmpSyntax *UdpAddress::clone() const
912 return (SnmpSyntax *) new UdpAddress(*this);
915 //--------[ set the port number ]---------------------------------------
916 void UdpAddress::set_port( const unsigned short p)
918 unsigned short port_nbo = htons(p);
919 ACE_OS::memcpy(&address_buffer[IPV4LEN], &port_nbo, 2);
920 format_output();
923 //---------[ get the port number ]--------------------------------------
924 unsigned short UdpAddress::get_port() const
926 if (valid_flag) {
927 unsigned short port_nbo;
928 ACE_OS::memcpy(&port_nbo, &address_buffer[IPV4LEN], 2);
929 return ntohs(port_nbo);
931 else
932 return 0; // don't use uninitialized memory
935 //------[ return the type ]--------------------------------------------
936 addr_type UdpAddress::get_type() const
938 return type_udp;
941 //----[ UDP address char * cast ]--------------------------------------
942 UdpAddress::operator const char *() const
944 return (char *)output_buffer;
947 //----[ UDP address get char representation ]--------------------------
948 const char * UdpAddress::to_string()
950 return (char *)output_buffer;
953 // make format same as ACE_INET_Addr class (addr:port)
954 void UdpAddress::format_output()
956 IpAddress::format_output(); // allow ancestors to format their buffers
958 // if valid format else null it
959 if ( valid_flag)
960 ACE_OS::sprintf( (char *) output_buffer,"%s:%d",
961 IpAddress::to_string(),
962 get_port() );
963 else
964 output_buffer[0] = 0;
968 //=======================================================================
969 //=========== Netbios Address Implementation ============================
970 //=======================================================================
972 void NetbiosAddress::format_output()
974 if ( valid_flag)
975 ACE_OS::memcpy(output_buffer, address_buffer, NETBIOSLEN);
976 else
977 output_buffer[0] = 0;
980 void NetbiosAddress::InitNBAddr(const char *inaddr)
982 if (ACE_OS::strlen(inaddr) == 0) {
983 // always initialize SMI info
984 smival.syntax = sNMP_SYNTAX_OCTETS;
985 smival.value.string.len = NETBIOSLEN;
986 smival.value.string.ptr = address_buffer;
988 valid_flag=0;
989 NetbiosAddress::format_output();
990 return;
993 // always initialize SMI info
994 smival.syntax = sNMP_SYNTAX_OCTETS;
995 smival.value.string.len = IPXLEN;
996 smival.value.string.ptr = address_buffer;
998 valid_flag = parse_address( (char *) inaddr);
999 NetbiosAddress::format_output();
1002 // TODO: how to handle addresses < 15 chars (zero out or pad with ' ')
1003 NetbiosAddress::NetbiosAddress( const char *inaddr)
1005 InitNBAddr(inaddr);
1008 NetbiosAddress::NetbiosAddress( const char *inaddr, nb_service svc)
1010 InitNBAddr(inaddr);
1011 address_buffer[15] = svc;
1014 // TODO: go back over ms/ibm specs and verify this
1015 // 16 chars, 15 can be any character, 16th is service number between 0 and 20
1016 // names beginning with IBM are reserved, and hence invalid
1017 // and doubt IBM would use this class anyway
1018 int NetbiosAddress::parse_address(const char *address)
1020 if (ACE_OS::strlen(address) > NETBIOSLEN)
1021 return 0; // invalid
1023 if (ACE_OS::strncmp(address, "IBM", 3) == 0)
1024 return 0; // invalid
1026 // addresses are free form but this check may need to be expose to user
1028 //if (address[15] < nb_workstation || address[15] > nb_server)
1029 // return 0; //invalid service type
1031 ACE_OS::memset(address_buffer, 0, NETBIOSLEN);
1032 ACE_OS::memcpy(address_buffer, address, NETBIOSLEN);
1034 return 1; // valid
1037 NetbiosAddress::NetbiosAddress( const NetbiosAddress& nbaddr)
1038 : Address (nbaddr)
1040 // always initialize SMI info
1041 smival.syntax = sNMP_SYNTAX_OCTETS;
1042 smival.value.string.len = NETBIOSLEN;
1043 smival.value.string.ptr = address_buffer;
1045 valid_flag = nbaddr.valid_flag;
1046 if (valid_flag)
1047 ACE_OS::memcpy(address_buffer, nbaddr.address_buffer, NETBIOSLEN);
1048 NetbiosAddress::format_output();
1051 NetbiosAddress::NetbiosAddress( const GenAddress& genaddr)
1053 // always initialize SMI info
1054 smival.syntax = sNMP_SYNTAX_OCTETS;
1055 smival.value.string.len = NETBIOSLEN;
1056 smival.value.string.ptr = address_buffer;
1058 valid_flag = 0;
1059 // allow use of an ipx or ipxsock address
1060 if ( (genaddr.get_type() == type_nb) ) {
1061 valid_flag = genaddr.valid();
1062 if ( valid_flag) {
1063 // copy in the Ipx address data
1064 NetbiosAddress temp_nb( (const char *) genaddr);
1065 *this = temp_nb;
1068 NetbiosAddress::format_output();
1071 NetbiosAddress::~NetbiosAddress()
1075 const char *NetbiosAddress::to_string()
1077 return (char *)output_buffer;
1080 void NetbiosAddress::to_octet(OctetStr& octet) const
1082 octet.set_data( smival.value.string.ptr, smival.value.string.len);
1085 NetbiosAddress& NetbiosAddress::operator=( const NetbiosAddress &val)
1087 // protect against assignment from itself
1088 if ( this == &val )
1089 return *this;
1091 valid_flag = 0; // will set to 1 if really valid
1092 if (val.valid()) {
1093 switch (((NetbiosAddress *) &val)->get_syntax()) {
1094 case sNMP_SYNTAX_OCTETS:
1095 ACE_OS::memcpy(address_buffer,
1096 ((NetbiosAddress &)val).smival.value.string.ptr, NETBIOSLEN);
1097 valid_flag = 1;
1098 break;
1101 NetbiosAddress::format_output();
1102 return *this;
1105 nb_service NetbiosAddress::get_service_type() const
1107 return (nb_service) address_buffer[15];
1110 void NetbiosAddress::set_service_type(nb_service nbservice)
1112 address_buffer[15] = nbservice;
1113 NetbiosAddress::format_output();
1116 NetbiosAddress::operator const char *() const
1118 return (char *)output_buffer;
1121 SnmpSyntax& NetbiosAddress::operator=( SnmpSyntax &val)
1123 // protect against assignment from itself
1124 if ( this == &val )
1125 return *this;
1127 valid_flag = 0; // will set to 1 if really valid
1128 if (val.valid()) {
1129 switch (val.get_syntax()) {
1130 case sNMP_SYNTAX_OCTETS:
1131 if (((NetbiosAddress &)val).smival.value.string.len == NETBIOSLEN) {
1132 ACE_OS::memcpy(address_buffer,
1133 ((NetbiosAddress &)val).smival.value.string.ptr, NETBIOSLEN);
1134 valid_flag=1;
1136 break;
1139 NetbiosAddress::format_output();
1140 return *this;
1143 SnmpSyntax *NetbiosAddress::clone() const
1145 return (SnmpSyntax *) new NetbiosAddress(*this);
1148 SmiUINT32 NetbiosAddress::get_syntax()
1150 return sNMP_SYNTAX_OCTETS;
1153 addr_type NetbiosAddress::get_type() const
1155 return type_nb;
1158 //=======================================================================
1159 //=========== IPX Address Implementation ================================
1160 //=======================================================================
1162 //-----------[ syntax type ]----------------------------------------------
1163 SmiUINT32 IpxAddress::get_syntax()
1165 return sNMP_SYNTAX_OCTETS;
1169 //----------[ default constructor with a string arg ]---------------------------
1170 IpxAddress::IpxAddress( const char *inaddr):Address( )
1172 if (ACE_OS::strlen(inaddr) == 0) {
1173 // always initialize SMI info
1174 smival.syntax = sNMP_SYNTAX_OCTETS;
1175 smival.value.string.len = IPXLEN;
1176 smival.value.string.ptr = address_buffer;
1178 separator = '\0';
1179 valid_flag=0;
1180 IpxAddress::format_output();
1181 return;
1183 // always initialize SMI info
1184 smival.syntax = sNMP_SYNTAX_OCTETS;
1185 smival.value.string.len = IPXLEN;
1186 smival.value.string.ptr = address_buffer;
1188 separator = '\0';
1189 valid_flag = parse_address( (char *) inaddr);
1190 IpxAddress::format_output();
1194 //-----[ IPX Address copy constructor ]----------------------------------
1195 IpxAddress::IpxAddress(const IpxAddress &ipxaddr)
1196 : Address (ipxaddr)
1198 // always initialize SMI info
1199 smival.syntax = sNMP_SYNTAX_OCTETS;
1200 smival.value.string.len = IPXLEN;
1201 smival.value.string.ptr = address_buffer;
1203 separator = '\0';
1204 valid_flag = ipxaddr.valid_flag;
1205 if (valid_flag)
1206 ACE_OS::memcpy(address_buffer, ipxaddr.address_buffer, IPXLEN);
1207 IpxAddress::format_output();
1211 //----[ construct an IpxAddress from a GenAddress ]---------------------------
1212 IpxAddress::IpxAddress( const GenAddress &genaddr)
1214 // always initialize SMI info
1215 smival.syntax = sNMP_SYNTAX_OCTETS;
1216 smival.value.string.len = IPXLEN;
1217 smival.value.string.ptr = address_buffer;
1219 valid_flag = 0;
1220 // allow use of an ipx or ipxsock address
1221 if ( (genaddr.get_type() == type_ipx) ) {
1222 valid_flag = genaddr.valid();
1223 if ( valid_flag) {
1224 // copy in the Ipx address data
1225 IpxAddress temp_ipx( (const char *) genaddr);
1226 *this = temp_ipx;
1229 else
1230 if ( (genaddr.get_type() == type_ipxsock) ) {
1231 valid_flag = genaddr.valid();
1232 if ( valid_flag) {
1233 // copy in the Ipx address data
1234 IpxSockAddress temp_ipxsock( (const char *) genaddr);
1235 *this = temp_ipxsock;
1238 IpxAddress::format_output();
1242 //-----[ destructor ]--------------------------------------------------
1243 IpxAddress::~IpxAddress()
1248 //-----[ IPX Address general = operator ]-------------------------------
1249 SnmpSyntax& IpxAddress::operator=( SnmpSyntax &val)
1251 // protect against assignment from itself
1252 if ( this == &val )
1253 return *this;
1255 valid_flag=0; // will set to 1 if really valid
1256 if (val.valid()){
1257 switch (val.get_syntax()){
1258 case sNMP_SYNTAX_OCTETS:
1259 if (((IpxAddress &)val).smival.value.string.len == IPXLEN){
1260 ACE_OS::memcpy(address_buffer, ((IpxAddress &)val).smival.value.string.ptr, IPXLEN);
1261 valid_flag=1;
1263 break;
1266 IpxAddress::format_output();
1267 return *this;
1270 //--------[ assignment to another IpAddress object overloaded ]----------
1271 IpxAddress& IpxAddress::operator=( const IpxAddress &ipxaddress)
1273 // protect against assignment from itself
1274 if ( this == &ipxaddress )
1275 return *this;
1277 valid_flag = ipxaddress.valid_flag;
1278 if (valid_flag)
1279 ACE_OS::memcpy(address_buffer, ipxaddress.address_buffer, IPXLEN);
1280 IpxAddress::format_output();
1281 return *this;
1285 // create a new instance of this Value
1286 SnmpSyntax *IpxAddress::clone() const
1288 return (SnmpSyntax *) new IpxAddress(*this);
1291 //-----[ IPX Address parse Address ]-----------------------------------
1292 // Convert a string to a ten byte ipx address
1293 // On success sets validity 1 or 0
1295 // IPX address format
1297 // NETWORK ID| MAC ADDRESS
1298 // 01 02 03 04|05 06 07 08 09 10
1299 // XX XX XX XX|XX XX XX XX XX XX
1301 // Valid input format
1303 // XXXXXXXX.XXXXXXXXXXXX
1304 // Total length must be 21
1305 // Must have a separator in it
1306 // First string length must be 8
1307 // Second string length must be 12
1308 // Each char must take on value 0-F
1310 // Input formats recognized
1312 // XXXXXXXX.XXXXXXXXXXXX
1313 // XXXXXXXX:XXXXXXXXXXXX
1314 // XXXXXXXX-XXXXXXXXXXXX
1315 // XXXXXXXX.XXXXXX-XXXXXX
1316 // XXXXXXXX:XXXXXX-XXXXXX
1317 // XXXXXXXX-XXXXXX-XXXXXX
1318 int IpxAddress::parse_address( const char *inaddr)
1320 char unsigned *str1,*str2;
1321 char temp[30]; // don't destroy original
1322 char unsigned *tmp;
1323 size_t z, tmplen;
1326 // save the orginal source
1327 if (!inaddr || (ACE_OS::strlen( inaddr) >(sizeof(temp)-1))) return 0;
1328 ACE_OS::strcpy( temp, inaddr);
1329 trim_white_space( temp);
1330 tmplen = ACE_OS::strlen(temp);
1332 // bad total length check
1333 // 123456789012345678901
1334 // XXXXXXXX-XXXXXXXXXXXX 21 len
1336 // XXXXXXXX-XXXXXX-XXXXXX 22 len
1337 // need at least 21 chars and no more than 22
1338 if ( (tmplen <21) || (tmplen >22))
1339 return 0;
1341 // convert the string to all lower case
1342 // this allows hex values to be in upper or lower
1343 for (z=0;z< tmplen;z++)
1344 temp[z] = ACE_OS::ace_tolower(temp[z]);
1346 // check for separated nodeid
1347 // if found remove it
1348 if (temp[15] == '-')
1350 for(z=16;z<tmplen;z++)
1351 temp[z-1] = temp[z];
1352 temp[tmplen-1] = 0;
1355 // no dot or colon separator check
1356 separator = temp[8];
1357 if (( separator != ':') &&
1358 ( separator != '.') &&
1359 ( separator != '-') &&
1360 ( separator != ' '))
1361 return 0;
1363 // separate the strings
1364 str1 = ( unsigned char *) temp;
1365 while( *str1 != separator) str1++;
1366 str2 = str1 + 1;
1367 *str1 = 0;
1368 str1= ( unsigned char *) temp;
1370 // check len of the network portion
1371 if ( ACE_OS::strlen((char *) str1) != 8)
1372 return 0;
1374 // check len of mac portion
1375 if ( ACE_OS::strlen( (char *) str2) != 12)
1376 return 0;
1378 // ok we like then lens, make sure that all chars are 0-f
1379 // check out the net id
1380 tmp = str1;
1381 while( *tmp != 0)
1382 if (((*tmp >= '0') && (*tmp <= '9'))|| // good 0-9
1383 ((*tmp >= 'a') && (*tmp <= 'f'))) // or a-f
1384 tmp++;
1385 else
1386 return 0;
1388 // check out the MAC address
1389 tmp = str2;
1390 while( *tmp != 0)
1391 if (((*tmp >= '0') && (*tmp <= '9'))|| // good 0-9
1392 ((*tmp >= 'a') && (*tmp <= 'f'))) // or a-f
1393 tmp++;
1394 else
1395 return 0;
1397 // convert to target string
1398 tmp = str1;
1399 while ( *tmp != 0)
1401 if (( *tmp >= '0') && ( *tmp <= '9'))
1402 *tmp = *tmp - (char unsigned )'0';
1403 else
1404 *tmp = *tmp - (char unsigned) 'a' + (char unsigned) 10;
1405 tmp++;
1408 // network id portion
1409 address_buffer[0] = (str1[0]*16) + str1[1];
1410 address_buffer[1] = (str1[2]*16) + str1[3];
1411 address_buffer[2] = (str1[4]*16) + str1[5];
1412 address_buffer[3] = (str1[6]*16) + str1[7];
1414 tmp = str2;
1415 while ( *tmp != 0)
1417 if (( *tmp >= '0') && ( *tmp <= '9'))
1418 *tmp = *tmp - (char unsigned) '0';
1419 else
1420 *tmp = *tmp - (char unsigned) 'a'+ (char unsigned) 10;
1421 tmp++;
1424 address_buffer[4] = (str2[0]*16) + str2[1];
1425 address_buffer[5] = (str2[2]*16) + str2[3];
1426 address_buffer[6] = (str2[4]*16) + str2[5];
1427 address_buffer[7] = (str2[6]*16) + str2[7];
1428 address_buffer[8] = (str2[8]*16) + str2[9];
1429 address_buffer[9] = (str2[10]*16) + str2[11];
1431 return 1;
1434 //----[ IPX address char * cast ]--------------------------------------
1435 IpxAddress::operator const char *() const
1437 return (char *)output_buffer;
1440 //----[ IPX address get char representation ]--------------------------
1441 const char * IpxAddress::to_string()
1443 return (char *)output_buffer;
1447 //----[ IPX address format output ]-------------------------------------
1448 void IpxAddress::format_output()
1450 if ( valid_flag)
1451 ACE_OS::sprintf((char *) output_buffer,
1452 "%02x%02x%02x%02x%c%02x%02x%02x%02x%02x%02x",
1453 address_buffer[0],address_buffer[1],
1454 address_buffer[2],address_buffer[3],'-',
1455 address_buffer[4],address_buffer[5],
1456 address_buffer[6],address_buffer[7],
1457 address_buffer[8],address_buffer[9]);
1458 else
1459 output_buffer[0] = 0;
1463 // get the host id portion of an ipx address
1464 int IpxAddress::get_hostid( MacAddress& mac)
1466 if ( valid_flag)
1468 char buffer[18];
1469 ACE_OS::sprintf( buffer,"%02x:%02x:%02x:%02x:%02x:%02x",
1470 address_buffer[4],
1471 address_buffer[5], address_buffer[6], address_buffer[7],
1472 address_buffer[8], address_buffer[9]);
1473 MacAddress temp( buffer);
1474 // mac = (SnmpSyntax&) temp;
1475 mac = temp;
1476 if ( mac.valid())
1477 return 1;
1478 else
1479 return 0;
1481 else
1482 return 0;
1486 //------[ return the type ]----------------------------------
1487 addr_type IpxAddress::get_type() const
1489 return type_ipx;
1492 void IpxAddress::to_octet(OctetStr& octet) const
1494 octet.set_data( smival.value.string.ptr, smival.value.string.len);
1498 //========================================================================
1499 //======== IpxSockAddress Implementation =================================
1500 //========================================================================
1502 //-----------[ syntax type ]----------------------------------------------
1503 SmiUINT32 IpxSockAddress::get_syntax()
1505 return sNMP_SYNTAX_OCTETS;
1508 //-----------[ construct an IpxSockAddress with another IpxSockAddress]----
1509 IpxSockAddress::IpxSockAddress( const IpxSockAddress &ipxaddr):IpxAddress(ipxaddr)
1511 // always initialize SMI info
1512 smival.syntax = sNMP_SYNTAX_OCTETS;
1513 smival.value.string.len = IPXSOCKLEN;
1514 smival.value.string.ptr = address_buffer;
1516 // copy the socket value
1517 set_socket(ipxaddr.get_socket());
1518 format_output();
1522 //---------------[ default construct a IpxSockAddress ]--------------
1523 IpxSockAddress::IpxSockAddress( const char *inaddr):IpxAddress()
1525 if (ACE_OS::strlen(inaddr) == 0) {
1526 // always initialize SMI info
1527 smival.syntax = sNMP_SYNTAX_OCTETS;
1528 smival.value.string.len = IPXSOCKLEN;
1529 smival.value.string.ptr = address_buffer;
1531 set_socket(0);
1532 format_output();
1533 return;
1536 // always initialize SMI info
1537 smival.syntax = sNMP_SYNTAX_OCTETS;
1538 smival.value.string.len = IPXSOCKLEN;
1539 smival.value.string.ptr = address_buffer;
1541 valid_flag = parse_address( (char *) inaddr);
1542 format_output();
1546 //---------------[ construct a IpxSockAddress from a GenAddress ]----------
1547 IpxSockAddress::IpxSockAddress( const GenAddress &genaddr):IpxAddress()
1549 // always initialize SMI info
1550 smival.syntax = sNMP_SYNTAX_OCTETS;
1551 smival.value.string.len = IPXSOCKLEN;
1552 smival.value.string.ptr = address_buffer;
1554 valid_flag = 0;
1555 unsigned short socketid = 0;
1556 // allow use of an ipx or ipxsock address
1557 if ( (genaddr.get_type() == type_ipx) )
1559 valid_flag = genaddr.valid();
1560 if ( valid_flag)
1562 // copy in the Ipx address data
1563 IpxAddress temp_ipx( (const char *) genaddr);
1564 *this = temp_ipx;
1567 else
1568 if ( (genaddr.get_type() == type_ipxsock) )
1570 valid_flag = genaddr.valid();
1571 if ( valid_flag)
1573 // copy in the Ipx address data
1574 IpxSockAddress temp_ipxsock( (const char *) genaddr);
1575 *this = temp_ipxsock;
1576 // socketid info since are making an IpxSockAddress
1577 socketid = temp_ipxsock.get_socket();
1580 set_socket(socketid);
1581 format_output();
1585 //------------[ construct an IpxSockAddress from a IpxAddress ]--------------
1586 IpxSockAddress::IpxSockAddress( const IpxAddress &ipxaddr):IpxAddress(ipxaddr)
1588 // always initialize SMI info
1589 smival.syntax = sNMP_SYNTAX_OCTETS;
1590 smival.value.string.len = IPXSOCKLEN;
1591 smival.value.string.ptr = address_buffer;
1593 set_socket(0);
1594 format_output();
1597 //-----[ destructor ]--------------------------------------------------
1598 IpxSockAddress::~IpxSockAddress()
1602 // copy an instance of this Value
1603 SnmpSyntax& IpxSockAddress::operator=( SnmpSyntax &val)
1605 // protect against assignment from itself
1606 if ( this == &val )
1607 return *this;
1609 valid_flag=0; // will set to 1 if really valid
1610 if (val.valid()){
1611 switch (val.get_syntax()){
1612 case sNMP_SYNTAX_OCTETS:
1614 // See if it is of the Ipx address family
1615 // This handles IpxSockAddress == IpxAddress
1616 IpxSockAddress temp_ipx(val.to_string());
1617 if (temp_ipx.valid()){
1618 *this = temp_ipx; // ipxsock = ipxsock
1620 // See if it is an OctetStr of appropriate length
1621 else if (((IpxSockAddress &)val).smival.value.string.len == IPXSOCKLEN){
1622 ACE_OS::memcpy(address_buffer,
1623 ((IpxSockAddress &)val).smival.value.string.ptr,
1624 IPXSOCKLEN);
1625 valid_flag=1;
1628 break;
1631 format_output();
1632 return *this;
1635 // assignment to another IpAddress object overloaded
1636 IpxSockAddress& IpxSockAddress::operator=( const IpxSockAddress &ipxaddr)
1638 // protect against assignment from itself
1639 if ( this == &ipxaddr )
1640 return *this;
1642 (IpxAddress&)*this = ipxaddr; // use ancestor assignment for ipx addr
1643 set_socket(ipxaddr.get_socket()); // copy socket value
1644 format_output();
1645 return *this;
1649 //----------[ create a new instance of this Value ]------------------------
1650 SnmpSyntax *IpxSockAddress::clone() const
1652 return (SnmpSyntax *) new IpxSockAddress(*this);
1655 //----[ IPXSock address char * cast ]--------------------------------------
1656 IpxSockAddress::operator const char *() const
1658 return (char *)output_buffer;
1661 //----[ IPXSock address get char representation ]--------------------------
1662 const char * IpxSockAddress::to_string()
1664 return (char *)output_buffer;
1667 //----[ IPX address format output ]-------------------------------------
1668 void IpxSockAddress::format_output()
1670 IpxAddress::format_output(); // allow ancestors to format their buffers
1672 if ( valid_flag)
1673 ACE_OS::sprintf((char *) output_buffer,"%s/%d",
1674 IpxAddress::to_string(), get_socket());
1675 else
1676 output_buffer[0] = 0;
1679 //-----[ IP Address parse Address ]---------------------------------
1680 int IpxSockAddress::parse_address( const char *inaddr)
1682 char buffer[MAXHOSTNAMELEN +1];
1683 unsigned short socketid=0;
1685 if (inaddr && (ACE_OS::strlen( inaddr)< MAXHOSTNAMELEN))
1686 ACE_OS::strcpy( buffer, inaddr);
1687 else
1689 valid_flag = 0;
1690 return 0;
1692 // look for port info @ the end of the string
1693 // port can be delineated by a ':' or a '/'
1694 // if neither are present then just treat it
1695 // like a normal IpAddress
1696 char *tmp;
1697 tmp = ACE_OS::strstr( buffer,"/");
1699 if (tmp != 0)
1701 *tmp=0; // null terminator
1702 tmp++;
1703 socketid = ACE_OS::atoi( tmp);
1705 set_socket(socketid);
1706 return IpxAddress::parse_address( buffer);
1710 //-------------[ set the socket number ]----------------------------------
1711 void IpxSockAddress::set_socket( const unsigned short s)
1713 unsigned short sock_nbo = htons(s);
1714 ACE_OS::memcpy(&address_buffer[IPXLEN], &sock_nbo, 2);
1717 //--------------[ get the socket number ]---------------------------------
1718 unsigned short IpxSockAddress::get_socket() const
1720 if (valid_flag)
1722 unsigned short sock_nbo;
1723 ACE_OS::memcpy(&sock_nbo, &address_buffer[IPXLEN], 2);
1724 return ntohs(sock_nbo);
1726 else
1727 return 0; // don't use uninitialized memory
1730 //------[ return the type ]----------------------------------------------
1731 addr_type IpxSockAddress::get_type() const
1733 return type_ipxsock;
1737 //========================================================================
1738 //======== MACAddress Implementation =====================================
1739 //========================================================================
1741 //-----------[ syntax type ]----------------------------------------------
1742 SmiUINT32 MacAddress::get_syntax()
1744 return sNMP_SYNTAX_OCTETS;
1747 //-----[ MAC Address copy constructor ]---------------------------------
1748 MacAddress::MacAddress(const MacAddress &macaddr)
1749 : Address (macaddr)
1751 // always initialize SMI info
1752 smival.syntax = sNMP_SYNTAX_OCTETS;
1753 smival.value.string.len = MACLEN;
1754 smival.value.string.ptr = address_buffer;
1756 valid_flag = macaddr.valid_flag;
1757 if (valid_flag)
1758 ACE_OS::memcpy(address_buffer, macaddr.address_buffer, MACLEN);
1759 format_output();
1762 //---------[ constructor with a string argument ]-------------------------
1763 MacAddress::MacAddress( const char *inaddr):Address( )
1765 if (ACE_OS::strlen(inaddr) == 0) {
1766 // always initialize SMI info
1767 smival.syntax = sNMP_SYNTAX_OCTETS;
1768 smival.value.string.len = MACLEN;
1769 smival.value.string.ptr = address_buffer;
1771 valid_flag=0;
1772 format_output();
1773 return;
1776 // always initialize SMI info
1777 smival.syntax = sNMP_SYNTAX_OCTETS;
1778 smival.value.string.len = MACLEN;
1779 smival.value.string.ptr = address_buffer;
1781 valid_flag = parse_address( (char *) inaddr);
1782 format_output();
1785 //-----[ construct a MacAddress from a GenAddress ]------------------------
1786 MacAddress::MacAddress( const GenAddress &genaddr)
1788 // always initialize SMI info
1789 smival.syntax = sNMP_SYNTAX_OCTETS;
1790 smival.value.string.len = MACLEN;
1791 smival.value.string.ptr = address_buffer;
1793 valid_flag = 0;
1794 // allow use of mac address
1795 if (genaddr.get_type() == type_mac)
1797 valid_flag = genaddr.valid();
1798 if ( valid_flag)
1800 // copy in the Mac address data
1801 MacAddress temp_mac( (const char *) genaddr);
1802 *this = temp_mac;
1805 format_output();
1808 //-----[ destructor ]--------------------------------------------------
1809 MacAddress::~MacAddress()
1813 //---------[ MacAddress clone ]-------------------------------------------
1814 SnmpSyntax *MacAddress::clone() const
1816 return (SnmpSyntax *) new MacAddress(*this);
1819 //------[ assignment to another ipaddress object overloaded ]--------------
1820 MacAddress& MacAddress::operator=( const MacAddress &macaddress)
1822 // protect against assignment from itself
1823 if ( this == &macaddress )
1824 return *this;
1826 valid_flag = macaddress.valid_flag;
1827 if (valid_flag)
1828 ACE_OS::memcpy(address_buffer, macaddress.address_buffer, MACLEN);
1829 format_output();
1830 return *this;
1834 //-----[ MAC Address general = operator ]---------------------------------
1835 SnmpSyntax& MacAddress::operator=( SnmpSyntax &val)
1837 // protect against assignment from itself
1838 if ( this == &val )
1839 return *this;
1841 valid_flag=0; // will set to 1 if really valid
1842 if (val.valid()){
1843 switch (val.get_syntax()){
1844 case sNMP_SYNTAX_OCTETS:
1845 if (((MacAddress &)val).smival.value.string.len == MACLEN){
1846 ACE_OS::memcpy(address_buffer,
1847 ((MacAddress &)val).smival.value.string.ptr, MACLEN);
1848 valid_flag=1;
1850 break;
1853 format_output();
1854 return *this;
1857 //-----[ MAC Address parse Address ]--------------------------------------
1858 // Convert a string to a six byte MAC address
1859 // On success sets validity 1 or 0
1861 // MAC address format
1863 // MAC ADDRESS
1864 // 01 02 03 04 05 06
1865 // XX:XX:XX:XX:XX:XX
1866 // Valid input format
1868 // XXXXXXXXXXXX
1869 // Total length must be 17
1870 // Each char must take on value 0-F
1872 int MacAddress::parse_address( const char *inaddr)
1874 char temp[MAXHOSTNAMELEN +1]; // don't destroy original
1875 char unsigned *tmp;
1876 size_t z;
1879 // save the orginal source
1880 if ( !inaddr || (ACE_OS::strlen( inaddr) > 30)) return 0;
1881 ACE_OS::strcpy( temp, inaddr);
1882 trim_white_space( temp);
1884 // bad total length check
1885 if ( ACE_OS::strlen(temp) != 17)
1886 return 0;
1888 // check for colons
1889 if ((temp[2] != ':')||(temp[5] != ':')||(temp[8]!=':')||(temp[11]!=':')
1890 ||(temp[14] !=':'))
1891 return 0;
1893 // strip off the colons
1894 tmp = ( unsigned char *) temp;
1895 int i = 0;
1896 while ( *tmp != 0)
1898 if (*tmp != ':')
1900 temp[i] = *tmp;
1901 i++;
1903 tmp++;
1905 temp[i] = 0;
1907 // convert to lower
1908 for(z=0;z<ACE_OS::strlen(temp);z++)
1909 temp[z] = ACE_OS::ace_tolower( temp[z]);
1912 // check out the MAC address
1913 tmp = ( unsigned char *) temp;
1914 while( *tmp != 0)
1915 if (((*tmp >= '0') && (*tmp <= '9'))|| // good 0-9
1916 ((*tmp >= 'a') && (*tmp <= 'f'))) // or a-f
1917 tmp++;
1918 else
1919 return 0;
1921 // convert to target string
1922 tmp = (unsigned char *) temp;
1923 while ( *tmp != 0)
1925 if (( *tmp >= '0') && ( *tmp <= '9'))
1926 *tmp = *tmp - (char unsigned )'0';
1927 else
1928 *tmp = *tmp - (char unsigned) 'a' + (char unsigned) 10;
1929 tmp++;
1932 address_buffer[0] = (temp[0]*16) + temp[1];
1933 address_buffer[1] = (temp[2]*16) + temp[3];
1934 address_buffer[2] = (temp[4]*16) + temp[5];
1935 address_buffer[3] = (temp[6]*16) + temp[7];
1936 address_buffer[4] = (temp[8]*16) + temp[9];
1937 address_buffer[5] = (temp[10]*16) + temp[11];
1939 return 1;
1942 //----[ MAC address char * cast ]--------------------------------------
1943 MacAddress::operator const char *() const
1945 return (char *)output_buffer;
1947 //----[ MAC address get char representation ]--------------------------
1948 const char * MacAddress::to_string()
1950 return (char *)output_buffer;
1953 //----[ MAC address format output ]---------------------------------
1954 void MacAddress::format_output()
1956 if ( valid_flag)
1957 ACE_OS::sprintf(output_buffer,"%02x:%02x:%02x:%02x:%02x:%02x",address_buffer[0],
1958 address_buffer[1],address_buffer[2],address_buffer[3],
1959 address_buffer[4],address_buffer[5]);
1960 else
1961 output_buffer[0] = 0;
1964 //------[ return the type ]----------------------------------
1965 addr_type MacAddress::get_type() const
1967 return type_mac;
1971 unsigned int MacAddress::hashFunction() const
1973 return ((((address_buffer[0] << 8) + address_buffer[1]) * HASH0LEN)
1974 + (((address_buffer[2] << 8) + address_buffer[3]) * HASH1LEN)
1975 + (((address_buffer[4] << 8) + address_buffer[5]) * HASH2LEN));
1978 void MacAddress::to_octet(OctetStr& octet) const
1980 octet.set_data( smival.value.string.ptr, smival.value.string.len);
1983 //========================================================================
1984 //========== Generic Address Implementation ==============================
1985 //========================================================================
1987 //-----------[ get the syntax]----------------------------------------------
1988 SmiUINT32 GenAddress::get_syntax()
1990 if (address != 0)
1991 return address->get_syntax();
1993 return sNMP_SYNTAX_NULL;
1996 void GenAddress::init_smi()
1998 smival.syntax = sNMP_SYNTAX_NULL; // to be overridden
1999 smival.value.string.len = 0; // to be overridden
2000 smival.value.string.ptr = address_buffer; // constant
2003 //-----------[ constructor with a string argument ]----------------------
2004 GenAddress::GenAddress( const char *addr): address(0)
2006 valid_flag = 0;
2007 // initialize SMI info
2008 // BOK: smival is generally not used for GenAddress, but
2009 // we need this to be a replica of the real address'
2010 // smival info so that <class>::operator=SnmpSyntax
2011 // will work.
2012 init_smi();
2014 if (addr && ACE_OS::strlen(addr) == 0) {
2015 format_output();
2016 return;
2019 parse_address(addr);
2021 // Copy real address smival info into GenAddr smival
2022 // BOK: smival is generally not used for GenAddress, but
2023 // we need this to be a replica of the real address'
2024 // smival info so that <class>::operator=SnmpSyntax
2025 // will work.
2026 if ( valid_flag ) {
2027 smival.syntax = ((GenAddress *)address)->smival.syntax;
2028 smival.value.string.len =
2029 ((GenAddress *)address)->smival.value.string.len;
2030 ACE_OS::memcpy(smival.value.string.ptr,
2031 ((GenAddress *)address)->smival.value.string.ptr,
2032 (size_t)smival.value.string.len);
2036 //-----------[ constructor with an Address argument ]--------------------
2037 GenAddress::GenAddress( const Address &addr): address(0)
2039 valid_flag = 0;
2041 // initialize SMI info
2042 // BOK: this is generally not used for GenAddress,
2043 // but we need this to be a replica of the real address'
2044 // smival info so that operator=SnmpSyntax will work.
2045 init_smi();
2046 // make sure that the object is valid
2047 if (!addr.valid()) {
2048 format_output();
2049 return;
2052 address = (Address*)addr.clone();
2053 if (address)
2054 valid_flag = address->valid();
2056 // Copy real address smival info into GenAddr smival
2057 // BOK: smival is generally not used for GenAddress, but
2058 // we need this to be a replica of the real address'
2059 // smival info so that <class>::operator=SnmpSyntax
2060 // will work.
2061 if ( valid_flag ) {
2062 smival.syntax = address->get_syntax();
2063 smival.value.string.len =
2064 ((GenAddress *)address)->smival.value.string.len;
2065 ACE_OS::memcpy(smival.value.string.ptr,
2066 ((GenAddress *)address)->smival.value.string.ptr,
2067 (size_t)smival.value.string.len);
2070 format_output();
2073 //-----------------[ constructor with another GenAddress object ]-------------
2074 GenAddress::GenAddress( const GenAddress &addr)
2075 : Address (addr),
2076 address(0)
2078 valid_flag = 0;
2080 // initialize SMI info
2081 // BOK: this is generally not used for GenAddress,
2082 // but we need this to be a replica of the real address'
2083 // smival info so that operator=SnmpSyntax will work.
2084 init_smi();
2086 // make sure that the object is valid
2087 if (!addr.valid_flag) {
2088 format_output();
2089 return;
2092 address = (Address *)addr.address->clone();
2093 if (address)
2094 valid_flag = address->valid();
2096 // Copy real address smival info into GenAddr smival
2097 // BOK: smival is generally not used for GenAddress, but
2098 // we need this to be a replica of the real address'
2099 // smival info so that <class>::operator=SnmpSyntax
2100 // will work.
2101 if ( valid_flag ) {
2102 smival.syntax = ((GenAddress *)address)->smival.syntax;
2103 smival.value.string.len =
2104 ((GenAddress *)address)->smival.value.string.len;
2105 ACE_OS::memcpy(smival.value.string.ptr,
2106 ((GenAddress *)address)->smival.value.string.ptr,
2107 (size_t)smival.value.string.len);
2110 format_output();
2113 //----------[ destructor ] ------------------------------------------------
2114 GenAddress::~GenAddress()
2116 if ( address != 0)
2117 delete address;
2120 //----------[ create a new instance of this Value ]------------------------
2121 SnmpSyntax *GenAddress::clone() const
2123 return (SnmpSyntax *) new GenAddress(*this);
2126 //------[ assignment GenAddress = GenAddress ]-----------------------------
2127 GenAddress& GenAddress::operator=( const GenAddress &addr)
2129 // protect against assignment from itself
2130 if ( this == &addr )
2131 return *this;
2133 valid_flag = 0;
2134 if (address) {
2135 delete address;
2136 address = 0;
2139 if (addr.address)
2140 address = (Address *)(addr.address)->clone();
2142 if (address)
2143 valid_flag = address->valid();
2145 // Copy real address smival info into GenAddr smival
2146 // BOK: smival is generally not used for GenAddress, but
2147 // we need this to be a replica of the real address'
2148 // smival info so that <class>::operator=SnmpSyntax
2149 // will work.
2150 if ( valid_flag ) {
2151 smival.syntax = ((GenAddress *)address)->smival.syntax;
2152 smival.value.string.len =
2153 ((GenAddress *)address)->smival.value.string.len;
2154 ACE_OS::memcpy(smival.value.string.ptr,
2155 ((GenAddress *)address)->smival.value.string.ptr,
2156 (size_t)smival.value.string.len);
2159 format_output();
2160 return *this;
2164 //------[ assignment GenAddress = any SnmpSyntax ]-----------------------
2165 SnmpSyntax& GenAddress::operator=( SnmpSyntax &val)
2167 // protect against assignment from itself
2168 if ( this == &val )
2169 return *this;
2171 valid_flag = 0; // will get set to 1 if really valid
2172 if ( address != 0) {
2173 delete address;
2174 address = 0;
2177 if (val.valid()) {
2178 switch ( val.get_syntax() ) {
2179 //-----[ ip address case ]-------------
2180 // BOK: this case shouldn't be needed since there is an explicit
2181 // GenAddr=Address assignment that will override this assignment.
2182 // Left here for posterity.
2183 case sNMP_SYNTAX_IPADDR:
2185 address = (Address *)val.clone();
2186 if (address)
2187 valid_flag = address->valid();
2189 break;
2191 //-----[ udp address case ]------------
2192 //-----[ ipx address case ]------------
2193 //-----[ mac address case ]------------
2194 // BOK: This is here only to support GenAddr = primitive OctetStr.
2195 // The explicit GenAddr=Address assignment will handle the cases
2196 // GenAddr = [UdpAdd|IpxAddr|IpxSock|MacAddr|DecNetAddr|NetbiosAddr|AppleTlk].
2197 // Note, using the heuristic of octet str len to determine type of
2198 // address to create is not accurate when address lengths are equal
2199 // (e.g., UDPIPV4LEN == MACLEN). It gets worse if we add AppleTalk or
2200 // OSI which use variable length addresses! assume AppleTalk as used in IOS Mibs
2201 // is defined in CISCO-TC.my as fixed length of 3 octets
2203 case sNMP_SYNTAX_OCTETS:
2205 unsigned long val_len;
2206 val_len = ((GenAddress &)val).smival.value.string.len;
2208 if (val_len == UDPIPV4LEN) {
2209 ACE_NEW_RETURN(address, UdpAddress, *this);
2211 else if (val_len ==IPV4LEN) {
2212 ACE_NEW_RETURN(address, IpAddress, *this);
2214 else if (val_len == IPXLEN) {
2215 ACE_NEW_RETURN(address, IpxAddress, *this);
2217 else if (val_len == IPXSOCKLEN) {
2218 ACE_NEW_RETURN(address, IpxSockAddress, *this);
2220 else if (val_len == MACLEN) {
2221 ACE_NEW_RETURN(address, MacAddress, *this);
2223 else if (val_len == APPLETKLEN) {
2224 ACE_NEW_RETURN(address, AppleTalkAddress, *this);
2226 else if (val_len == DECNETLEN) {
2227 ACE_NEW_RETURN(address, DecNetAddress, *this);
2229 else if (val_len == NETBIOSLEN) {
2230 ACE_NEW_RETURN(address, DecNetAddress, *this);
2233 if (address) {
2234 *address = val;
2235 valid_flag = address->valid();
2238 break;
2239 } // end switch
2242 // Copy real address smival info into GenAddr smival
2243 // BOK: smival is generally not used for GenAddress, but
2244 // we need this to be a replica of the real address'
2245 // smival info so that <class>::operator=SnmpSyntax
2246 // will work.
2247 if ( valid_flag ) {
2248 smival.syntax = ((GenAddress *)address)->smival.syntax;
2249 smival.value.string.len =
2250 ((GenAddress *)address)->smival.value.string.len;
2251 ACE_OS::memcpy(smival.value.string.ptr,
2252 ((GenAddress *)address)->smival.value.string.ptr,
2253 (size_t)smival.value.string.len);
2256 format_output();
2257 return *this;
2261 // redefined parse address for macs
2262 // TODO: Add netbios, appletalk, and decnet addresses here
2263 int GenAddress::parse_address( const char *addr)
2265 if ( address != 0)
2266 delete address;
2268 // try to create each of the addresses until the correct one
2269 // is found
2271 //BOK: Need to try IPX Sock and IPX before UDP since on Win32,
2272 // gethostbyname() seems to think the ipx network number
2273 // portion is a valid ipaddress string... stupid WinSOCK!
2275 // ipxsock address
2276 ACE_NEW_RETURN(address, IpxSockAddress( addr), -1);
2277 valid_flag = address->valid();
2278 if ( valid_flag && ((IpxSockAddress*)address)->get_socket()) {
2279 format_output();
2280 return 1; // ok its an ipxsock address
2282 // otherwise delete it and try another
2283 delete address;
2285 // ipx address
2286 ACE_NEW_RETURN(address, IpxAddress( addr), -1);
2287 valid_flag = address->valid();
2288 if ( valid_flag) {
2289 format_output();
2290 return 1; // ok its an ipx address
2292 // otherwise delete it and try another
2293 delete address;
2295 //TM: Must try the derived classes first...one pitfall of the
2296 //following solution is if someone creates with a port/socket of 0 the
2297 //class will get demoted to ip/ipx. The only proper way to do this is
2298 //to parse the strings ourselves.
2300 // udp address
2301 ACE_NEW_RETURN(address, UdpAddress( addr), -1);
2302 valid_flag = address->valid();
2303 if ( valid_flag && ((UdpAddress*)address)->get_port()) {
2304 format_output();
2305 return 1; // ok its a udp address
2308 // otherwise delete it and try another
2309 delete address;
2311 // ip address
2312 ACE_NEW_RETURN(address, IpAddress( addr), -1);
2313 valid_flag = address->valid();
2314 if ( valid_flag)
2316 format_output();
2317 return 1; // ok its an ip address
2319 // otherwise delete it and try another
2320 delete address;
2322 // mac address
2323 ACE_NEW_RETURN(address, MacAddress( addr), -1);
2324 valid_flag = address->valid();
2325 if ( valid_flag) {
2326 format_output();
2327 return 1; // ok, its a mac
2330 // guess by length of argument the type of address
2331 switch (ACE_OS::strlen(addr)) {
2332 case NETBIOSLEN:
2333 ACE_NEW_RETURN(address, NetbiosAddress( addr), -1);
2334 valid_flag = address->valid();
2335 if ( valid_flag) {
2336 format_output();
2337 return 1; // ok, its a mac
2339 break;
2341 case APPLETKLEN:
2342 ACE_NEW_RETURN(address, AppleTalkAddress( addr), -1);
2343 valid_flag = address->valid();
2344 if ( valid_flag) {
2345 format_output();
2346 return 1; // ok, its a mac
2348 break;
2350 case DECNETLEN:
2351 ACE_NEW_RETURN(address, DecNetAddress( addr), -1);
2352 valid_flag = address->valid();
2353 if ( valid_flag) {
2354 format_output();
2355 return 1; // ok, its a mac
2357 break;
2359 // otherwise its invalid
2360 delete address;
2361 address = 0;
2362 format_output();
2363 return 0;
2366 GenAddress::operator const char *() const
2368 if ( address != 0)
2369 return (const char *)*address; // pass thru
2370 else
2371 return (char *)output_buffer;
2374 // to_string form of the contained address
2375 const char * GenAddress::to_string()
2377 if ( address != 0)
2378 return address->to_string(); // pass thru
2379 else
2380 return (char *)output_buffer;
2383 // format output
2384 void GenAddress::format_output()
2386 output_buffer[0] = '\0';
2389 //------[ return the type ]----------------------------------
2390 addr_type GenAddress::get_type() const
2392 if (!valid())
2393 return type_invalid;
2394 else
2395 return address->get_type();
2398 // call the particular type class here
2399 void GenAddress::to_octet(OctetStr& octet) const
2401 if (!valid())
2402 return;
2404 address->to_octet(octet);
2407 //------------------------------------------------------------------------
2408 //---------[ DecNet Address Class ]---------------------------------------
2409 //------------------------------------------------------------------------
2411 DecNetAddress::DecNetAddress( const char *inaddr): Address()
2413 if (ACE_OS::strlen(inaddr) == 0) {
2414 // always initialize SMI info
2415 smival.syntax = sNMP_SYNTAX_OCTETS;
2416 smival.value.string.len = DECNETLEN;
2417 smival.value.string.ptr = address_buffer;
2419 valid_flag=0;
2420 DecNetAddress::format_output();
2421 return;
2424 // always initialize SMI info
2425 smival.syntax = sNMP_SYNTAX_OCTETS;
2426 smival.value.string.len = DECNETLEN;
2427 smival.value.string.ptr = address_buffer;
2429 valid_flag = parse_address( (char *) inaddr);
2430 DecNetAddress::format_output();
2433 DecNetAddress::DecNetAddress( const DecNetAddress& addr)
2434 : Address (addr)
2438 DecNetAddress::DecNetAddress( const GenAddress& genaddr)
2440 smival.syntax = sNMP_SYNTAX_OCTETS;
2441 smival.value.string.len = DECNETLEN;
2442 smival.value.string.ptr = address_buffer;
2444 valid_flag = 0;
2445 // allow use of an ipx or ipxsock address
2446 if ( (genaddr.get_type() == type_decnet) ) {
2447 valid_flag = genaddr.valid();
2448 if ( valid_flag) {
2449 // copy in the Ipx address data
2450 DecNetAddress temp_ipx( (const char *) genaddr);
2451 *this = temp_ipx;
2454 DecNetAddress::format_output();
2457 DecNetAddress::~DecNetAddress()
2461 const char *DecNetAddress::to_string()
2463 return (char *)output_buffer;
2466 DecNetAddress& DecNetAddress::operator=( const DecNetAddress &decaddr)
2468 // protect against assignment from itself
2469 if ( this == &decaddr )
2470 return *this;
2471 valid_flag = decaddr.valid_flag;
2472 if (valid_flag)
2473 ACE_OS::memcpy(address_buffer, decaddr.address_buffer, DECNETLEN);
2474 format_output();
2475 return *this;
2478 void DecNetAddress::to_octet(OctetStr& octet) const
2480 octet.set_data( smival.value.string.ptr, smival.value.string.len);
2483 DecNetAddress::operator const char *() const
2485 return (char *)output_buffer;
2488 SmiUINT32 DecNetAddress::get_syntax()
2490 return sNMP_SYNTAX_OCTETS;
2493 SnmpSyntax& DecNetAddress::operator=( SnmpSyntax &val)
2495 // protect against assignment from itself
2496 if ( this == &val )
2497 return *this;
2499 valid_flag = 0; // will get set 1 if really valid
2501 if (val.valid()) {
2502 if (((DecNetAddress &)val).smival.value.string.len ==DECNETLEN) {
2503 ACE_OS::memcpy(address_buffer,
2504 ((DecNetAddress &)val).smival.value.string.ptr, DECNETLEN);
2505 valid_flag = 1;
2508 DecNetAddress::format_output();
2509 return *this;
2512 SnmpSyntax *DecNetAddress::clone() const
2514 return (SnmpSyntax *) new DecNetAddress(*this);
2517 addr_type DecNetAddress::get_type() const
2519 return type_decnet;
2522 void DecNetAddress::format_output()
2524 // if valid format else null it
2525 if ( valid_flag)
2526 ACE_OS::sprintf( (char *) output_buffer,"%d.%d",address_buffer[0],
2527 address_buffer[1]);
2528 else
2529 output_buffer[0] = 0;
2532 int DecNetAddress::parse_address( const char *address)
2534 if (ACE_OS::strlen(address) > DECNETLEN)
2535 return 0; // invalid
2537 ACE_OS::memset(address_buffer, 0, DECNETLEN);
2538 ACE_OS::memcpy(address_buffer, address, DECNETLEN);
2540 return 1; // valid
2544 //------------------------------------------------------------------------
2545 //---------[ AppleTalk Address Class ]------------------------------------
2546 //------------------------------------------------------------------------
2548 AppleTalkAddress::AppleTalkAddress( const char *inaddr): Address()
2550 if (ACE_OS::strlen(inaddr) == 0) {
2551 // always initialize SMI info
2552 smival.syntax = sNMP_SYNTAX_OCTETS;
2553 smival.value.string.len = APPLETKLEN;
2554 smival.value.string.ptr = address_buffer;
2556 valid_flag=0;
2557 AppleTalkAddress::format_output();
2558 return;
2561 // always initialize SMI info
2562 smival.syntax = sNMP_SYNTAX_OCTETS;
2563 smival.value.string.len = APPLETKLEN;
2564 smival.value.string.ptr = address_buffer;
2566 valid_flag = parse_address( (char *) inaddr);
2567 AppleTalkAddress::format_output();
2569 AppleTalkAddress::AppleTalkAddress( const AppleTalkAddress& addr)
2570 : Address (addr)
2574 AppleTalkAddress::AppleTalkAddress( const GenAddress& genaddr)
2576 smival.syntax = sNMP_SYNTAX_OCTETS;
2577 smival.value.string.len = APPLETKLEN;
2578 smival.value.string.ptr = address_buffer;
2580 valid_flag = 0;
2581 // allow use of an ipx or ipxsock address
2582 if ( (genaddr.get_type() == type_atk) ) {
2583 valid_flag = genaddr.valid();
2584 if ( valid_flag) {
2585 // copy in the Ipx address data
2586 AppleTalkAddress temp_ipx( (const char *) genaddr);
2587 *this = temp_ipx;
2590 AppleTalkAddress::format_output();
2593 AppleTalkAddress::~AppleTalkAddress()
2597 const char *AppleTalkAddress::to_string()
2599 return (char *)output_buffer;
2602 AppleTalkAddress& AppleTalkAddress::operator=( const AppleTalkAddress &ataddr)
2604 // protect against assignment from itself
2605 if ( this == &ataddr )
2606 return *this;
2607 valid_flag = ataddr.valid_flag;
2608 if (valid_flag)
2609 ACE_OS::memcpy(address_buffer, ataddr.address_buffer, APPLETKLEN);
2610 format_output();
2611 return *this;
2614 void AppleTalkAddress::to_octet(OctetStr& octet) const
2616 octet.set_data( smival.value.string.ptr, smival.value.string.len);
2619 AppleTalkAddress::operator const char *() const
2621 return (char *)output_buffer;
2624 SmiUINT32 AppleTalkAddress::get_syntax()
2626 return sNMP_SYNTAX_OCTETS;
2629 SnmpSyntax& AppleTalkAddress::operator=( SnmpSyntax &val)
2631 // protect against assignment from itself
2632 if ( this == &val )
2633 return *this;
2635 valid_flag = 0; // will get set 1 if really valid
2637 if (val.valid()) {
2638 if (((AppleTalkAddress &)val).smival.value.string.len ==APPLETKLEN) {
2639 ACE_OS::memcpy(address_buffer,
2640 ((AppleTalkAddress &)val).smival.value.string.ptr,APPLETKLEN);
2641 valid_flag = 1;
2644 AppleTalkAddress::format_output();
2645 return *this;
2648 SnmpSyntax *AppleTalkAddress::clone() const
2650 return (SnmpSyntax *) new AppleTalkAddress(*this);
2653 addr_type AppleTalkAddress::get_type() const
2655 return type_atk;
2658 void AppleTalkAddress::format_output()
2660 // if valid format else null it
2661 if ( valid_flag)
2662 ACE_OS::sprintf( (char *) output_buffer,"%d.%d.%d", address_buffer[0],
2663 address_buffer[1], address_buffer[3]);
2664 else
2665 output_buffer[0] = 0;
2668 int AppleTalkAddress::parse_address( const char *address)
2670 if (ACE_OS::strlen(address) > APPLETKLEN)
2671 return 0; // invalid
2673 ACE_OS::memset(address_buffer, 0, APPLETKLEN);
2674 ACE_OS::memcpy(address_buffer, address, APPLETKLEN);
2676 return 1; // valid
2679 char AppleTalkAddress::get_host_address() const
2681 return address_buffer[2];
2684 void AppleTalkAddress::set_host_address(const char host)
2686 address_buffer[2] = host;
2689 short AppleTalkAddress::get_net_address() const
2691 short net;
2692 ACE_OS::memcpy(&net, address_buffer, APPLETKLEN - 1);
2693 return net;
2696 void AppleTalkAddress::set_net_address(const short atknet)
2698 ACE_OS::memcpy(address_buffer, &atknet, APPLETKLEN -1);