address.cpp
上传用户:czjinwang
上传日期:2007-01-12
资源大小:2484k
文件大小:55k
源码类别:

SNMP编程

开发平台:

Visual C++

  1. /*===================================================================
  2.    
  3.   Copyright (c) 1999
  4.   Hewlett-Packard Company
  5.   ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  6.   Permission to use, copy, modify, distribute and/or sell this software 
  7.   and/or its documentation is hereby granted without fee. User agrees 
  8.   to display the above copyright notice and this license notice in all 
  9.   copies of the software and any documentation of the software. User 
  10.   agrees to assume all liability for the use of the software; Hewlett-Packard 
  11.   makes no representations about the suitability of this software for any 
  12.   purpose. It is provided "AS-IS without warranty of any kind,either express 
  13.   or implied. User hereby grants a royalty-free license to any and all 
  14.   derivatives based upon this software code base. 
  15.   A D D R E S S. C P P
  16.   ADDRESS CLASS IMPLEMENTATION
  17.   VERSION 2.8
  18.   DESIGN:
  19.   Peter E. Mellquist
  20.   AUTHOR:
  21.   Peter E Mellquist
  22.   DESCRIPTION:
  23.   Implementation file for Address classes.
  24.   LANGUAGE:
  25.   ANSI C++
  26.   OPERATING SYSTEM(S):
  27.   MS-Windows Win32
  28.   BSD UNIX
  29. =====================================================================*/
  30. char address_cpp_version[]="@(#) SNMP++ 2.8 $Header: address.cpp,v 1.38 96/09/11 14:01:44 hmgr Exp $";
  31. #include "address.h"
  32. extern "C"
  33. {
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <ctype.h>
  37. }
  38. //=================================================================
  39. //======== Abstract Address Class Implementation ==================
  40. //=================================================================
  41. // allow destruction of derived classes
  42. Address::~Address() 
  43. {};
  44. //-----------------------------------------------------------------
  45. // is the address object valid?
  46. int Address::valid() const
  47. { return valid_flag; };
  48. //------------[ Address::trim_white_space( char * ptr) ]------------
  49. // destructive trim white space
  50. void Address::trim_white_space( char * ptr)
  51. {
  52.    char *tmp;
  53.    tmp = ptr;
  54.    // skip leading white space
  55.    while (*tmp==' ')tmp++;
  56.    strcpy(ptr,tmp);
  57.    // find end of string
  58.    while ((*tmp!=' ') && (*tmp !=0)) tmp++;
  59.    if (*tmp!=0) *tmp=0;
  60. };
  61. //TM: this is not used nor needed, remove?
  62. //-----[ element access ]----------------------------------------------
  63. unsigned char& Address::operator[]( const int position)
  64.   if ( position < BUFSIZE)
  65.     return  address_buffer[ position];
  66.   else
  67.     return address_buffer[0]; 
  68. };
  69. //-----------------------------------------------------------------------
  70. // overloaded equivlence operator, are two addresses equal?
  71. int operator==( const Address &lhs, const Address &rhs)
  72. {
  73.   if ( strcmp( (const char*) lhs, (const char*)rhs)==0)
  74.     return TRUE;
  75.   else
  76.     return FALSE;
  77. };
  78. //-----------------------------------------------------------------------
  79. // overloaded equivlence operator, are two addresses equal?
  80. int operator!=( const Address &lhs, const Address &rhs)
  81. {
  82.   return (!( lhs == rhs));
  83. };
  84. //------------------------------------------------------------------
  85. // overloaded > operator, is a1 > a2
  86. int operator>( const Address &lhs, const Address &rhs)
  87. {
  88.    if ( strcmp( (const char*) lhs, (const char*)rhs)>0)
  89.       return TRUE;
  90.    else
  91.       return FALSE;
  92. };
  93. // overloaded >= operator, is a1 > a2
  94. int operator>=( const Address &lhs,const Address &rhs)
  95. {
  96.   if (( lhs > rhs) || ( lhs == rhs))
  97.      return TRUE;
  98.   else
  99.      return FALSE;
  100. };
  101. // overloaded < operator, is a1 <= a2
  102. int operator<=( const Address &lhs,const Address &rhs)
  103. {
  104.   if (( lhs < rhs) || ( lhs == rhs))
  105.      return TRUE;
  106.   else
  107.      return FALSE;
  108. };
  109. //-----------------------------------------------------------------
  110. // overloaded < operator, is a1 < a2
  111. int operator<( const Address &lhs, const Address &rhs)
  112. {
  113.    if ( strcmp( (const char*) lhs, (const char*)rhs)<0)
  114.       return TRUE;
  115.    else
  116.       return FALSE;
  117. };
  118. //------------------------------------------------------------------
  119. // equivlence operator overloaded, are an address and a string equal?
  120. int operator==( const Address &lhs,const char *rhs)
  121. {
  122.   if (!rhs && !lhs.valid())
  123.     return TRUE;
  124.   if (strcmp( (const char *) lhs, rhs)== 0)
  125.      return TRUE;
  126.   else
  127.      return FALSE;
  128. };
  129. //------------------------------------------------------------------
  130. // not equal operator overloaded, are an address and a string not equal?
  131. int operator!=( const Address &lhs,const char *rhs)
  132. {
  133.   return (!( lhs == rhs));
  134. };
  135. //------------------------------------------------------------------
  136. // overloaded > , is a > inaddr
  137. int operator>( const Address &lhs,const char *rhs)
  138. {
  139.   if (!rhs)
  140.     return lhs.valid();  // if lhs valid then > NULL, else invalid !> NULL
  141.   if (strcmp( (const char *) lhs, rhs)> 0)
  142.      return TRUE;
  143.   else
  144.      return FALSE;
  145. };
  146. //------------------------------------------------------------------
  147. // overloaded >= , is a >= inaddr
  148. int operator>=( const Address &lhs,const char *rhs)
  149. {
  150.   if (!rhs)
  151.     return TRUE; // always >= NULL
  152.   if (strcmp( (const char *) lhs, rhs)>= 0)
  153.      return TRUE;
  154.   else
  155.      return FALSE;
  156. };
  157. //-----------------------------------------------------------------
  158. // overloaded < , are an address and a string equal?
  159. int operator<( const Address &lhs,const char *rhs)
  160. {
  161.   if (!rhs)
  162.     return FALSE; // always >= NULL
  163.   if (strcmp( (const char *) lhs, rhs)< 0)
  164.      return TRUE;
  165.   else
  166.      return FALSE;
  167. };
  168. //-----------------------------------------------------------------
  169. // overloaded <= , is a <= inaddr
  170. int operator<=( const Address &lhs,const char *rhs)
  171. {
  172.   if (!rhs)
  173.     return !lhs.valid(); // invalid == NULL, else valid > NULL
  174.   if (strcmp( (const char *) lhs, rhs)<= 0)
  175.      return TRUE;
  176.   else
  177.      return FALSE;
  178. };
  179. //=====================================================================
  180. //============ IPAddress Implementation ===============================
  181. //=====================================================================
  182. //-----------[ syntax type ]----------------------------------------------
  183. SmiUINT32 IpAddress::get_syntax()
  184. { return sNMP_SYNTAX_IPADDR; };
  185. //-----[ IP Address copy constructor ]---------------------------------
  186. IpAddress::IpAddress(const IpAddress &ipaddr)
  187. {
  188.   // always initialize what type this object is
  189.   smival.syntax = sNMP_SYNTAX_IPADDR;
  190.   smival.value.string.len = IPLEN;
  191.   smival.value.string.ptr = address_buffer;
  192.   iv_friendly_name[0]=0;
  193.   iv_friendly_name_status=0;  
  194.   valid_flag = ipaddr.valid_flag; 
  195.   if (valid_flag)
  196.   {
  197.     // copy the address data    
  198.     MEMCPY(address_buffer, ipaddr.address_buffer, IPLEN);
  199.     // and the friendly name
  200.     strcpy( iv_friendly_name, ipaddr.iv_friendly_name);
  201.   }
  202.   IpAddress::format_output();
  203. };
  204. //-------[ construct an IP address with no agrs ]----------------------
  205. IpAddress::IpAddress( void):Address()
  206.   // always initialize what type this object is
  207.   smival.syntax = sNMP_SYNTAX_IPADDR;
  208.   smival.value.string.len = IPLEN;
  209.   smival.value.string.ptr = address_buffer;
  210.   valid_flag=FALSE; 
  211.   iv_friendly_name[0]=0; 
  212.   iv_friendly_name_status=0; 
  213.   IpAddress::format_output();
  214. };
  215. //-------[ construct an IP address with a string ]---------------------
  216. IpAddress::IpAddress( const char *inaddr):Address()
  217.   // always initialize what type this object is
  218.   smival.syntax = sNMP_SYNTAX_IPADDR;
  219.   smival.value.string.len = IPLEN;
  220.   smival.value.string.ptr = address_buffer;
  221.   // parse_address initializes valid, address_buffer & iv_friendly_name
  222.   valid_flag = parse_address(inaddr); 
  223.   IpAddress::format_output();
  224. };
  225. //-----[ construct an IP address with a GenAddress ]---------------------
  226. IpAddress::IpAddress( const GenAddress &genaddr)
  227. {
  228.   // always initialize what type this object is
  229.   smival.syntax = sNMP_SYNTAX_IPADDR;
  230.   smival.value.string.len = IPLEN;
  231.   smival.value.string.ptr = address_buffer;
  232.   valid_flag = FALSE;
  233.   iv_friendly_name[0]=0;
  234.   iv_friendly_name_status=0;
  235.   // allow use of an ip or udp genaddress
  236.   if (genaddr.get_type() == type_ip)
  237.   {
  238.     valid_flag = genaddr.valid();
  239.     if ( valid_flag)
  240.     {
  241.       // copy in the IP address data
  242.       IpAddress temp_ip( (const char *) genaddr);
  243.       *this = temp_ip;
  244.     }
  245.   } 
  246.   else
  247.   if (genaddr.get_type() == type_udp)
  248.   {
  249.     valid_flag = genaddr.valid();
  250.     if ( valid_flag)
  251.     {
  252.       // copy in the IP address data
  253.       UdpAddress temp_udp( (const char *) genaddr);
  254.       *this = temp_udp;
  255.     }
  256.   } 
  257.   IpAddress::format_output();
  258. };
  259. //-----[ destructor ]--------------------------------------------------
  260. IpAddress::~IpAddress()
  261. {};
  262. //-----[ IP Address general = operator ]-------------------------------
  263. SnmpSyntax& IpAddress::operator=( SnmpSyntax &val)
  264. {
  265.   // protect against assignment from itself
  266.   if ( this == &val )
  267.       return *this;
  268.   valid_flag = 0; // will get set TRUE if really valid
  269.   iv_friendly_name[0]=0;  
  270.   if (val.valid()){
  271.     switch (val.get_syntax()){
  272.     case sNMP_SYNTAX_IPADDR:
  273.     case sNMP_SYNTAX_OCTETS:
  274.       if (((IpAddress &)val).smival.value.string.len == IPLEN){
  275.          MEMCPY(address_buffer, ((IpAddress &)val).smival.value.string.ptr, IPLEN);
  276.          valid_flag=1;
  277.       }
  278.     break;
  279.     // NOTE: as a value add, other types could have "logical"
  280.     // mappings, i.e. integer32 and unsigned32 
  281.     }
  282.   }
  283.   IpAddress::format_output();
  284.   return *this;
  285. };
  286. //------[ assignment to another ipaddress object overloaded ]-----------------
  287. IpAddress& IpAddress::operator=( const IpAddress &ipaddress)
  288. {
  289.   // protect against assignment from itself
  290.   if ( this == &ipaddress )
  291.       return *this;
  292.   valid_flag = ipaddress.valid_flag; 
  293.   iv_friendly_name[0]=0;  
  294.   if (valid_flag){
  295.     MEMCPY(address_buffer, ipaddress.address_buffer, IPLEN);
  296.     strcpy(iv_friendly_name, ipaddress.iv_friendly_name);
  297.   }
  298.   IpAddress::format_output();
  299.   return *this;
  300. };
  301. //--------[ create a new instance of this Value ]-----------------------
  302. SnmpSyntax WINFAR *IpAddress::clone() const 
  303.     { return (SnmpSyntax *) new IpAddress(*this); };
  304. //-------[ return the friendly name ]----------------------------------
  305. char *IpAddress::friendly_name(int &status)
  306. {  
  307.   if ((iv_friendly_name[0]==0) && (valid_flag))
  308.     this->addr_to_friendly();
  309.   status = iv_friendly_name_status;
  310.   return iv_friendly_name; 
  311. };
  312. // parse a dotted string
  313. int IpAddress::parse_dotted_ipstring( const char *inaddr)
  314. {
  315.    char *ip_token;
  316.    int token_count=0;
  317.    unsigned int value;
  318.    int error_status = FALSE;
  319.    char temp[30];  // temp buffer for destruction
  320.    int z,w;
  321.    // check len, an ip can never be bigger than 15
  322.    // 123456789012345
  323.    // XXX.XXX.XXX.XXX
  324.    if ( !inaddr || (strlen( inaddr) > 30)) return FALSE;
  325.    strcpy( temp, inaddr);
  326.    trim_white_space( temp);
  327.    if ( strlen( temp) > 15) return FALSE;
  328.    // must only have three dots
  329.    // strtok will not catch this !
  330.    char *ptr = temp;
  331.    int dot_count = 0;
  332.    while ( *ptr != 0)
  333.    {
  334.    if ( *ptr == '.') dot_count++;
  335.        ptr++;
  336.    }
  337.    if ( dot_count != 3)
  338.    return FALSE;
  339.    // look for dot token separator
  340.    ip_token = strtok( (char *) temp,".");
  341.    // while more tokens..
  342.    while ( ip_token != NULL)
  343.    {
  344.      // verify that the token is all numerics
  345.      w = strlen( ip_token);
  346.      if (w>3) return FALSE;
  347.      for (z=0;z<w;z++)
  348.        if (( ip_token[z] < '0') || ( ip_token[z] > '9'))
  349.  return FALSE;
  350.      value = ( unsigned int) strtod(ip_token,NULL);
  351.      if (( value > 0)&& ( value <=255))
  352.        address_buffer[token_count] = (unsigned char) value;
  353.      else
  354.        if ( strcmp(ip_token,"0")==0)
  355.  address_buffer[token_count]= (unsigned char) 0;
  356.        else
  357.  error_status = TRUE;
  358.      token_count++;
  359.      ip_token = strtok( NULL, ".");
  360.    }
  361.    // gota be four in len
  362.    if ( token_count != 4)
  363.      return FALSE;
  364.    // any parsing errors?
  365.    if ( error_status)
  366.      return FALSE;
  367.   return TRUE;
  368. };
  369. //-----[ IP Address parse Address ]---------------------------------
  370. int IpAddress::parse_address( const char *inaddr)
  371. {
  372.    // parse the input char array
  373.    // fill up internal buffer with four ip bytes
  374.    // set and return validity flag
  375.    IN_ADDR ipAddr;
  376.    hostent *lookupResult;
  377.    char    *namePtr = NULL;
  378.    char ds[30];
  379.    // intialize the friendly_name member variable
  380.    iv_friendly_name[0] = 0;
  381.    iv_friendly_name_status = 0;
  382.    // is this a dotted IP notation string or
  383.    // a friendly name
  384.    if ( parse_dotted_ipstring( inaddr))
  385.    {
  386.      // since this is a valid dotted string
  387.      // don't do any DNS
  388.      return TRUE;
  389.    }
  390.    else
  391.    // not a dotted string, try to resolve it via DNS
  392.    {
  393.    
  394.       lookupResult = gethostbyname( inaddr);
  395.       if ( lookupResult)
  396.       {
  397.  if (lookupResult->h_length == sizeof(in_addr))
  398.  {
  399.    memcpy((void *) &ipAddr, (void *) lookupResult->h_addr_list[0],
  400.   sizeof(IN_ADDR));
  401.    // now lets check out the dotted string
  402.    strcpy( ds,inet_ntoa(ipAddr));
  403.    if ( !parse_dotted_ipstring( ds))
  404.      return FALSE;
  405.    // save the friendly name
  406.    strcpy( iv_friendly_name, inaddr);
  407.    return TRUE;
  408.  }
  409.       }  // end if lookup result
  410.       else
  411.       {
  412. iv_friendly_name_status = h_errno;
  413. return FALSE;
  414.       }
  415.    }  // end else not a dotted string
  416.    return TRUE;
  417. };
  418. // using the currently defined address, do a DNS
  419. // and try to fill up the name
  420. int IpAddress::addr_to_friendly()
  421. {
  422.     IN_ADDR ipAddr;
  423.     hostent *lookupResult;
  424.     char    *namePtr = NULL;
  425.     char    ds[30];
  426.     // can't look up an invalid address
  427.     if ( !valid_flag) return -1;
  428.     // otherwise lets look it up
  429.     // lets try and get the friendly name
  430.     // from the DNS
  431.     strcpy( ds, this->IpAddress::get_printable());
  432.     if ((ipAddr.s_addr = inet_addr((char *) ds)) == -1)
  433.       return -1;    // bad address
  434.     lookupResult = gethostbyaddr((char *) &ipAddr, sizeof(in_addr), AF_INET);
  435.     // if we found the name, then update the
  436.     // iv friendly name
  437.     if ( lookupResult)
  438.     {
  439.       namePtr = lookupResult->h_name;
  440.       strcpy( iv_friendly_name, namePtr);
  441.       return 0;
  442.     }
  443.     else
  444.     {
  445.       iv_friendly_name_status = h_errno;
  446.       return iv_friendly_name_status;
  447.     }
  448. };
  449. //----[ IP address char * cast ]--------------------------------------
  450. IpAddress::operator const char *() const
  451. {
  452.   return (char *)output_buffer;
  453. }
  454. //----[ IP address get char representation ]--------------------------
  455. char * WINFAR IpAddress::get_printable()
  456. {
  457.   return (char *)output_buffer;
  458. }
  459. //----[ IP address format output ]------------------------------------
  460. void IpAddress::format_output()
  461. {
  462.   // if valid format else null it
  463.   if ( valid_flag)
  464.     sprintf( (char *) output_buffer,"%d.%d.%d.%d",address_buffer[0],
  465.      address_buffer[1], address_buffer[2], address_buffer[3]);
  466.   else
  467.     output_buffer[0]=0;
  468. };
  469. //------[ return the type ]----------------------------------
  470. addr_type IpAddress::get_type() const
  471. { return type_ip; };
  472. //-----------------------------------------------------------------
  473. // logically and two IPaddresses and
  474. // return the new one
  475. void IpAddress::mask( const IpAddress& ipaddr)
  476.   if ( this->valid() && ipaddr.valid())
  477.   {
  478.      this->address_buffer[0] = this->address_buffer[0] & ipaddr.address_buffer[0];
  479.      this->address_buffer[1] = this->address_buffer[1] & ipaddr.address_buffer[1];
  480.      this->address_buffer[2] = this->address_buffer[2] & ipaddr.address_buffer[2];
  481.      this->address_buffer[3] = this->address_buffer[3] & ipaddr.address_buffer[3];
  482.      format_output();
  483.   };
  484.  
  485. };
  486. //=======================================================================
  487. //========== Udp Address Implementation =================================
  488. //=======================================================================
  489. //-----------[ syntax type ]----------------------------------------------
  490. SmiUINT32 UdpAddress::get_syntax()
  491. { return sNMP_SYNTAX_OCTETS; };
  492. //-------[ construct an IP address with no agrs ]----------------------
  493. UdpAddress::UdpAddress( void):IpAddress()
  494.   // Inherits IP Address attributes
  495.   // Always initialize (override) what type this object is
  496.   smival.syntax = sNMP_SYNTAX_OCTETS;
  497.   smival.value.string.len = UDPIPLEN;
  498.   smival.value.string.ptr = address_buffer;
  499.   set_port(0);
  500.   format_output();
  501. };
  502. //-----------------[ construct an Udp address with another Udp address ]---
  503. UdpAddress::UdpAddress( const UdpAddress  &udpaddr):IpAddress(udpaddr)
  504. {
  505.   // always initialize SMI info
  506.   smival.syntax = sNMP_SYNTAX_OCTETS;
  507.   smival.value.string.len = UDPIPLEN;
  508.   smival.value.string.ptr = address_buffer;
  509.   // Copy the port value
  510.   set_port(udpaddr.get_port());
  511.   format_output();
  512. };
  513. // constructor with a dotted string
  514. UdpAddress::UdpAddress( const char *inaddr):IpAddress()
  515. {
  516.   // always initialize SMI info
  517.   smival.syntax = sNMP_SYNTAX_OCTETS;
  518.   smival.value.string.len = UDPIPLEN;
  519.   smival.value.string.ptr = address_buffer;
  520.    valid_flag = parse_address( (char *)inaddr); 
  521.    format_output();
  522. }
  523. //-----------------[ construct a UdpAddress from a GenAddress ]--------------
  524. UdpAddress::UdpAddress( const GenAddress &genaddr):IpAddress()
  525. {
  526.   // always initialize SMI info
  527.   smival.syntax = sNMP_SYNTAX_OCTETS;
  528.   smival.value.string.len = UDPIPLEN;
  529.   smival.value.string.ptr = address_buffer;
  530.   unsigned int port = 0;
  531.   valid_flag = FALSE;
  532.   // allow use of an ip or udp genaddress
  533.   if (genaddr.get_type() == type_udp)
  534.   {
  535.     valid_flag = genaddr.valid();
  536.     if ( valid_flag)
  537.     {
  538.       // copy in the IP address data
  539.       UdpAddress temp_udp( (const char *) genaddr);
  540.       *this = temp_udp;
  541.       //  port info since are making an UpAddress
  542.       port = temp_udp.get_port();
  543.     }
  544.   }
  545.   else
  546.   if (genaddr.get_type() == type_ip)
  547.   {
  548.     valid_flag = genaddr.valid();
  549.     if ( valid_flag)
  550.     {
  551.       // copy in the IP address data
  552.       IpAddress temp_ip( (const char *) genaddr);
  553.       *this = temp_ip;
  554.     }
  555.   }
  556.   set_port(port);
  557.   format_output();
  558. };
  559. //--------[ construct a udp from an IpAddress ]--------------------------
  560. UdpAddress::UdpAddress( const IpAddress &ipaddr):IpAddress(ipaddr)
  561. {
  562.   // always initialize SMI info
  563.   smival.syntax = sNMP_SYNTAX_OCTETS;
  564.   smival.value.string.len = UDPIPLEN;
  565.   smival.value.string.ptr = address_buffer;
  566.   set_port(0);
  567.   format_output();
  568. };
  569. //-----[ destructor ]--------------------------------------------------
  570. UdpAddress::~UdpAddress()
  571. {};
  572.   // copy an instance of this Value
  573. SnmpSyntax& UdpAddress::operator=( SnmpSyntax &val)
  574. {
  575.   // protect against assignment from itself
  576.   if ( this == &val )
  577.       return *this;
  578.   valid_flag=0; // will get set TRUE if really valid
  579.   if (val.valid()){
  580.     switch (val.get_syntax()){
  581.     case sNMP_SYNTAX_IPADDR: 
  582.     {
  583.       UdpAddress temp_udp(val.get_printable());
  584.       *this = temp_udp; // valid_flag is set by the udp assignment
  585.     }
  586.     break;
  587.     case sNMP_SYNTAX_OCTETS:
  588.       if (((UdpAddress &)val).smival.value.string.len == UDPIPLEN){
  589.          MEMCPY(address_buffer,((UdpAddress &)val).smival.value.string.ptr,UDPIPLEN);
  590.          iv_friendly_name[0]=0;
  591.          valid_flag=1;
  592.       }
  593.     break;
  594.     // NOTE: as a value add, other types could have "logical"
  595.     // mappings, i.e. integer32 and unsigned32 
  596.     }
  597.   }
  598.   format_output();
  599.   return *this;
  600. }
  601.   // assignment to another UdpAddress object overloaded
  602. UdpAddress& UdpAddress::operator=( const UdpAddress &udpaddr)
  603. {
  604.   // protect against assignment from itself
  605.   if ( this == &udpaddr )
  606.       return *this;
  607.   (IpAddress &)*this = udpaddr; // use ancestor assignment for ipaddr value
  608.   set_port(udpaddr.get_port()); // copy to port value
  609.   format_output();
  610.   return *this;
  611. }
  612. //-----[ IP Address parse Address ]---------------------------------
  613. int UdpAddress::parse_address( const char *inaddr)
  614. {
  615.    char buffer[MAX_FRIENDLY_NAME];
  616.    unsigned short port = 0;
  617.    if (inaddr && (strlen( inaddr)< MAX_FRIENDLY_NAME))
  618.      strcpy( buffer, inaddr);
  619.    else
  620.    {
  621.      valid_flag = FALSE;
  622.      return FALSE;
  623.    }
  624.    // look for port info @ the end of the string
  625.    // port can be delineated by a ':' or a '/'
  626.    // if neither are present then just treat it 
  627.    // like a normal IpAddress
  628.    char *tmp;
  629.    tmp = strstr( buffer,":");
  630.    if (tmp==NULL) 
  631.      tmp = strstr(buffer,"/");
  632.    if ( tmp != NULL)
  633.    {
  634.      *tmp=0;   // new null terminator
  635.      tmp++;
  636.      port = atoi( tmp);
  637.  set_port( port);
  638.      return IpAddress::parse_address( buffer);
  639.    }
  640.    else
  641.    {
  642.        port = 0;
  643.    set_port( port);
  644.    return IpAddress::parse_address ( buffer);
  645.    }
  646. };
  647. //----------[ create a new instance of this Value ]------------------------
  648. SnmpSyntax WINFAR *UdpAddress::clone() const 
  649. { return (SnmpSyntax *) new UdpAddress(*this); };
  650. //--------[ set the port number ]---------------------------------------
  651. void UdpAddress::set_port( const unsigned short p)
  652.   unsigned short port_nbo = htons(p);
  653.   MEMCPY(&address_buffer[IPLEN], &port_nbo, 2);
  654.   format_output();
  655. };
  656. //---------[ get the port number ]--------------------------------------
  657. unsigned short UdpAddress::get_port() const
  658.   if (valid_flag) 
  659.   {
  660.     unsigned short port_nbo;
  661.     MEMCPY(&port_nbo, &address_buffer[IPLEN], 2);
  662.     return ntohs(port_nbo); 
  663.   }
  664.   else
  665.     return 0;// don't use uninitialized memory
  666. };
  667. //------[ return the type ]--------------------------------------------
  668. addr_type UdpAddress::get_type() const
  669. { return type_udp; };
  670. //----[ UDP address char * cast ]--------------------------------------
  671. UdpAddress::operator const char *() const
  672. {
  673.   return (char *)output_buffer;
  674. }
  675. //----[ UDP address get char representation ]--------------------------
  676. char * WINFAR UdpAddress::get_printable()
  677. {
  678.   return (char *)output_buffer;
  679. }
  680. //----[ UDP address format output ]------------------------------------
  681. void UdpAddress::format_output()
  682. {
  683.   IpAddress::format_output(); // allow ancestors to format their buffers
  684.   // if valid format else null it
  685.   if ( valid_flag)
  686.     sprintf( (char *) output_buffer,"%s/%d",
  687.      IpAddress::get_printable(), 
  688.      get_port() );
  689.   else
  690.     output_buffer[0]=0;
  691. };
  692. //=======================================================================
  693. //=========== IPX Address Implementation ================================
  694. //=======================================================================
  695. //-----------[ syntax type ]----------------------------------------------
  696. SmiUINT32 IpxAddress::get_syntax()
  697. { return sNMP_SYNTAX_OCTETS; };
  698. //----------[ constructor no args ]--------------------------------------
  699. IpxAddress::IpxAddress( void):Address()
  700. {
  701.   // always initialize SMI info
  702.   smival.syntax = sNMP_SYNTAX_OCTETS;
  703.   smival.value.string.len = IPXLEN;
  704.   smival.value.string.ptr = address_buffer;
  705.   separator = ''; 
  706.   valid_flag=FALSE;
  707.   IpxAddress::format_output();
  708. };
  709. //----------[ constructor with a string arg ]---------------------------
  710. IpxAddress::IpxAddress( const char  *inaddr):Address( )
  711.   // always initialize SMI info
  712.   smival.syntax = sNMP_SYNTAX_OCTETS;
  713.   smival.value.string.len = IPXLEN;
  714.   smival.value.string.ptr = address_buffer;
  715.   separator = '';
  716.   valid_flag = parse_address( (char *) inaddr); 
  717.   IpxAddress::format_output();
  718. };
  719. //-----[ IPX Address copy constructor ]----------------------------------
  720. IpxAddress::IpxAddress(const IpxAddress &ipxaddr)
  721. {
  722.   // always initialize SMI info
  723.   smival.syntax = sNMP_SYNTAX_OCTETS;
  724.   smival.value.string.len = IPXLEN;
  725.   smival.value.string.ptr = address_buffer;
  726.   separator = '';
  727.   valid_flag = ipxaddr.valid_flag;
  728.   if (valid_flag)
  729.      MEMCPY(address_buffer, ipxaddr.address_buffer, IPXLEN);
  730.   IpxAddress::format_output();
  731. };
  732. //----[ construct an IpxAddress from a GenAddress ]---------------------------
  733. IpxAddress::IpxAddress( const GenAddress &genaddr)
  734. {
  735.   // always initialize SMI info
  736.   smival.syntax = sNMP_SYNTAX_OCTETS;
  737.   smival.value.string.len = IPXLEN;
  738.   smival.value.string.ptr = address_buffer;
  739.   valid_flag = FALSE;
  740.   // allow use of an ipx or ipxsock address
  741.   if ( (genaddr.get_type() == type_ipx) )
  742.   {
  743.     valid_flag = genaddr.valid();
  744.     if ( valid_flag)
  745.     {
  746.       // copy in the Ipx address data
  747.       IpxAddress temp_ipx( (const char *) genaddr);
  748.       *this = temp_ipx;
  749.     }
  750.   }
  751.   else
  752.   if ( (genaddr.get_type() == type_ipxsock) )
  753.   {
  754.     valid_flag = genaddr.valid();
  755.     if ( valid_flag)
  756.     {
  757.       // copy in the Ipx address data
  758.       IpxSockAddress temp_ipxsock( (const char *) genaddr);
  759.       *this = temp_ipxsock;
  760.     }
  761.   }
  762.   IpxAddress::format_output();
  763. };
  764. //-----[ destructor ]--------------------------------------------------
  765. IpxAddress::~IpxAddress()
  766. {};
  767. //-----[ IPX Address general = operator ]-------------------------------
  768. SnmpSyntax& IpxAddress::operator=( SnmpSyntax &val)
  769. {
  770.   // protect against assignment from itself
  771.   if ( this == &val )
  772.       return *this;
  773.   valid_flag=0;       // will set to TRUE if really valid
  774.   if (val.valid()){
  775.     switch (val.get_syntax()){
  776.     case sNMP_SYNTAX_OCTETS: 
  777.       if (((IpxAddress &)val).smival.value.string.len == IPXLEN){
  778. MEMCPY(address_buffer, ((IpxAddress &)val).smival.value.string.ptr, IPXLEN);
  779. valid_flag=1;
  780.       }
  781.     break;
  782.     }
  783.   }
  784.   IpxAddress::format_output();
  785.   return *this;
  786. };
  787. //--------[ assignment to another IpAddress object overloaded ]----------
  788. IpxAddress& IpxAddress::operator=( const IpxAddress &ipxaddress)
  789. {
  790.   // protect against assignment from itself
  791.   if ( this == &ipxaddress )
  792.       return *this;
  793.   valid_flag = ipxaddress.valid_flag; 
  794.   if (valid_flag)
  795.     MEMCPY(address_buffer, ipxaddress.address_buffer, IPXLEN);
  796.   IpxAddress::format_output();
  797.   return *this;
  798. };
  799. // create a new instance of this Value
  800. SnmpSyntax WINFAR *IpxAddress::clone() const 
  801. { return (SnmpSyntax *) new IpxAddress(*this); };
  802. //-----[ IPX Address parse Address ]-----------------------------------
  803. // Convert a string to a ten byte ipx address
  804. // On success sets validity  TRUE or FALSE
  805. //
  806. //     IPX address format
  807. //
  808. //  NETWORK ID| MAC ADDRESS
  809. // 01 02 03 04|05 06 07 08 09 10
  810. // XX XX XX XX|XX XX XX XX XX XX
  811. //
  812. //   Valid input format
  813. //
  814. //   XXXXXXXX.XXXXXXXXXXXX
  815. //   Total length must be 21
  816. //   Must have a separator in it
  817. //   First string length must be 8
  818. //   Second string length must be 12
  819. //   Each char must take on value 0-F
  820. //
  821. //
  822. // Input formats recognized
  823. // 
  824. //  XXXXXXXX.XXXXXXXXXXXX
  825. //  XXXXXXXX:XXXXXXXXXXXX
  826. //  XXXXXXXX-XXXXXXXXXXXX
  827. //  XXXXXXXX.XXXXXX-XXXXXX
  828. //  XXXXXXXX:XXXXXX-XXXXXX
  829. //  XXXXXXXX-XXXXXX-XXXXXX
  830. int IpxAddress::parse_address( const char *inaddr)
  831. {
  832.   char unsigned *str1,*str2;
  833.   char temp[30];    // don't destroy original
  834.   char unsigned *tmp;
  835.   size_t z, tmplen;
  836.   // save the orginal source
  837.   if (!inaddr || (strlen( inaddr) >(sizeof(temp)-1))) return FALSE;
  838.   strcpy( temp, inaddr);
  839.   trim_white_space( temp);
  840.   tmplen = strlen(temp);
  841.   // bad total length check
  842.   // 123456789012345678901
  843.   // XXXXXXXX-XXXXXXXXXXXX  21 len
  844.   //
  845.   // XXXXXXXX-XXXXXX-XXXXXX 22 len
  846.   // need at least 21 chars and no more than 22
  847.   if ( (tmplen <21) || (tmplen >22)) 
  848.     return FALSE;
  849.   // convert the string to all lower case
  850.   // this allows hex values to be in upper or lower
  851.   for (z=0;z< tmplen;z++)
  852.     temp[z] = tolower(temp[z]);
  853.   // check for separated nodeid
  854.   // if found remove it
  855.   if (temp[15] == '-')
  856.   {
  857.      for(z=16;z<tmplen;z++)
  858.         temp[z-1] = temp[z];
  859.      temp[tmplen-1] = 0;
  860.   }
  861.   // no dot or colon separator check
  862.   separator = temp[8];
  863.   if (( separator != ':') && 
  864.       ( separator != '.') && 
  865.       ( separator != '-') && 
  866.       ( separator != ' '))
  867.     return FALSE;
  868.   // separate the strings
  869.   str1 = ( unsigned char *) temp;
  870.   while( *str1 != separator) str1++;
  871.   str2 = str1 + 1;
  872.   *str1 = 0;
  873.   str1= ( unsigned char *) temp;
  874.   // check len of the network portion
  875.   if ( strlen((char *) str1) != 8) return FALSE;
  876.   // check len of mac portion
  877.   if ( strlen( (char *) str2) != 12) return FALSE;
  878.   // ok we like then lens, make sure that all chars are 0-f
  879.   // check out the net id
  880.   tmp = str1;
  881.   while( *tmp != 0)
  882.     if (((*tmp >= '0') && (*tmp <= '9'))||   // good 0-9
  883. ((*tmp >= 'a') && (*tmp <= 'f')))    // or a-f
  884.       tmp++;
  885.     else
  886.       return FALSE;
  887.   // check out the MAC address
  888.   tmp = str2;
  889.   while( *tmp != 0)
  890.     if (((*tmp >= '0') && (*tmp <= '9'))||   // good 0-9
  891. ((*tmp >= 'a') && (*tmp <= 'f')))    // or a-f
  892.       tmp++;
  893.     else
  894.       return FALSE;
  895.   // convert to target string
  896.   tmp = str1;
  897.   while ( *tmp != 0)
  898.   {
  899.   if (( *tmp >= '0') && ( *tmp <= '9'))
  900.     *tmp = *tmp - (char unsigned )'0';
  901.   else
  902.     *tmp = *tmp - (char unsigned) 'a' + (char unsigned) 10;
  903.   tmp++;
  904.   }
  905.   // network id portion
  906.   address_buffer[0] = (str1[0]*16) + str1[1];
  907.   address_buffer[1] = (str1[2]*16) + str1[3];
  908.   address_buffer[2] = (str1[4]*16) + str1[5];
  909.   address_buffer[3] = (str1[6]*16) + str1[7];
  910.   tmp = str2;
  911.   while ( *tmp != 0)
  912.   {
  913.   if (( *tmp >= '0') && ( *tmp <= '9'))
  914.     *tmp = *tmp - (char unsigned) '0';
  915.   else
  916.     *tmp = *tmp - (char unsigned) 'a'+ (char unsigned) 10;
  917.   tmp++;
  918.   }
  919.   address_buffer[4] = (str2[0]*16)  + str2[1];
  920.   address_buffer[5] = (str2[2]*16)  + str2[3];
  921.   address_buffer[6] = (str2[4]*16)  + str2[5];
  922.   address_buffer[7] = (str2[6]*16)  + str2[7];
  923.   address_buffer[8] = (str2[8]*16)  + str2[9];
  924.   address_buffer[9] = (str2[10]*16) + str2[11];
  925.   return TRUE;
  926. };
  927. //----[ IPX address char * cast ]--------------------------------------
  928. IpxAddress::operator const char *() const
  929. {
  930.   return (char *)output_buffer;
  931. }
  932. //----[ IPX address get char representation ]--------------------------
  933. char * WINFAR IpxAddress::get_printable()
  934. {
  935.   return (char *)output_buffer;
  936. }
  937. //----[ IPX address format output ]-------------------------------------
  938. void IpxAddress::format_output()
  939. {
  940.   if ( valid_flag)
  941.     sprintf((char *) output_buffer,
  942.     "%02x%02x%02x%02x%c%02x%02x%02x%02x%02x%02x",
  943.     address_buffer[0],address_buffer[1],
  944.     address_buffer[2],address_buffer[3],'-',
  945.     address_buffer[4],address_buffer[5],
  946.     address_buffer[6],address_buffer[7],
  947.     address_buffer[8],address_buffer[9]);
  948.   else
  949.     output_buffer[0] = 0;
  950. };
  951. // get the host id portion of an ipx address
  952. int IpxAddress::get_hostid( MacAddress& mac)
  953. {
  954.    if ( valid_flag)
  955.    {
  956.        char buffer[18];
  957.        sprintf( buffer,"%02x:%02x:%02x:%02x:%02x:%02x", address_buffer[4],
  958.                 address_buffer[5], address_buffer[6], address_buffer[7],
  959.                 address_buffer[8], address_buffer[9]);
  960.        MacAddress temp( buffer);
  961.        // mac = (SnmpSyntax&) temp;
  962.        mac = temp;
  963.        if ( mac.valid())
  964.           return TRUE;
  965.        else
  966.           return FALSE;
  967.    }
  968.    else
  969.       return FALSE;
  970. };
  971. //------[ return the type ]----------------------------------
  972. addr_type IpxAddress::get_type() const
  973. { return type_ipx; };
  974. //========================================================================
  975. //======== IpxSockAddress Implementation =================================
  976. //========================================================================
  977. //-----------[ syntax type ]----------------------------------------------
  978. SmiUINT32 IpxSockAddress::get_syntax()
  979. { return sNMP_SYNTAX_OCTETS; };
  980. //----------[ constructor no args ]--------------------------------------
  981. IpxSockAddress::IpxSockAddress( void):IpxAddress()
  982. {
  983.   // always initialize SMI info
  984.   smival.syntax = sNMP_SYNTAX_OCTETS;
  985.   smival.value.string.len = IPXSOCKLEN;
  986.   smival.value.string.ptr = address_buffer;
  987.   set_socket(0);
  988.   format_output();
  989. };
  990. //-----------[ construct an IpxSockAddress with another IpxSockAddress]----
  991. IpxSockAddress::IpxSockAddress( const IpxSockAddress &ipxaddr):IpxAddress(ipxaddr)
  992. {
  993.   // always initialize SMI info
  994.   smival.syntax = sNMP_SYNTAX_OCTETS;
  995.   smival.value.string.len = IPXSOCKLEN;
  996.   smival.value.string.ptr = address_buffer;
  997.   // copy the socket value
  998.   set_socket(ipxaddr.get_socket());
  999.   format_output();
  1000. };
  1001. //---------------[ construct a IpxSockAddress from a string ]--------------
  1002. IpxSockAddress::IpxSockAddress( const char *inaddr):IpxAddress()
  1003. {
  1004.   // always initialize SMI info
  1005.   smival.syntax = sNMP_SYNTAX_OCTETS;
  1006.   smival.value.string.len = IPXSOCKLEN;
  1007.   smival.value.string.ptr = address_buffer;
  1008.    valid_flag = parse_address( (char *) inaddr); 
  1009.    format_output();
  1010. };
  1011. //---------------[ construct a IpxSockAddress from a GenAddress ]----------
  1012. IpxSockAddress::IpxSockAddress( const GenAddress &genaddr):IpxAddress()
  1013. {
  1014.   // always initialize SMI info
  1015.   smival.syntax = sNMP_SYNTAX_OCTETS;
  1016.   smival.value.string.len = IPXSOCKLEN;
  1017.   smival.value.string.ptr = address_buffer;
  1018.   valid_flag = FALSE;
  1019.   unsigned short socketid = 0;
  1020.   // allow use of an ipx or ipxsock address
  1021.   if ( (genaddr.get_type() == type_ipx) )
  1022.   {
  1023.     valid_flag = genaddr.valid();
  1024.     if ( valid_flag)
  1025.     {
  1026.       // copy in the Ipx address data
  1027.       IpxAddress temp_ipx( (const char *) genaddr);
  1028.       *this = temp_ipx;
  1029.     }
  1030.   }
  1031.   else
  1032.   if ( (genaddr.get_type() == type_ipxsock) )
  1033.   {
  1034.     valid_flag = genaddr.valid();
  1035.     if ( valid_flag)
  1036.     {
  1037.       // copy in the Ipx address data
  1038.       IpxSockAddress temp_ipxsock( (const char *) genaddr);
  1039.       *this = temp_ipxsock;
  1040.       //  socketid info since are making an IpxSockAddress
  1041.       socketid = temp_ipxsock.get_socket();
  1042.     }
  1043.   }
  1044.   set_socket(socketid);
  1045.   format_output();
  1046. };
  1047. //------------[ construct an IpxSockAddress from a IpxAddress ]--------------
  1048. IpxSockAddress::IpxSockAddress( const IpxAddress &ipxaddr):IpxAddress(ipxaddr)
  1049. {
  1050.   // always initialize SMI info
  1051.   smival.syntax = sNMP_SYNTAX_OCTETS;
  1052.   smival.value.string.len = IPXSOCKLEN;
  1053.   smival.value.string.ptr = address_buffer;
  1054.   set_socket(0);
  1055.   format_output();
  1056. };
  1057. //-----[ destructor ]--------------------------------------------------
  1058. IpxSockAddress::~IpxSockAddress()
  1059. {};
  1060. // copy an instance of this Value
  1061. SnmpSyntax& IpxSockAddress::operator=( SnmpSyntax &val)
  1062. {
  1063.   // protect against assignment from itself
  1064.   if ( this == &val )
  1065.       return *this;
  1066.   valid_flag=0;       // will set to TRUE if really valid
  1067.   if (val.valid()){
  1068.     switch (val.get_syntax()){
  1069.     case sNMP_SYNTAX_OCTETS: 
  1070.       {
  1071.         // See if it is of the Ipx address family
  1072.         // This handles IpxSockAddress == IpxAddress
  1073.         IpxSockAddress temp_ipx(val.get_printable());
  1074.         if (temp_ipx.valid()){
  1075.           *this = temp_ipx; // ipxsock = ipxsock
  1076.         }
  1077.         // See if it is an OctetStr of appropriate length
  1078.         else if (((IpxSockAddress &)val).smival.value.string.len == IPXSOCKLEN){
  1079.   MEMCPY(address_buffer, 
  1080.  ((IpxSockAddress &)val).smival.value.string.ptr, 
  1081.  IPXSOCKLEN);
  1082.   valid_flag=1;
  1083.         }
  1084.       }
  1085.       break;
  1086.     }
  1087.   }
  1088.   format_output();
  1089.   return *this;
  1090. };
  1091. // assignment to another IpAddress object overloaded
  1092. IpxSockAddress& IpxSockAddress::operator=( const IpxSockAddress &ipxaddr)
  1093. {
  1094.   // protect against assignment from itself
  1095.   if ( this == &ipxaddr )
  1096.       return *this;
  1097.   (IpxAddress&)*this = ipxaddr;  // use ancestor assignment for ipx addr
  1098.   set_socket(ipxaddr.get_socket()); // copy socket value
  1099.   format_output();
  1100.   return *this;
  1101. }
  1102. //----------[ create a new instance of this Value ]------------------------
  1103. SnmpSyntax WINFAR *IpxSockAddress::clone() const 
  1104. { return (SnmpSyntax *) new IpxSockAddress(*this); };
  1105. //----[ IPXSock address char * cast ]--------------------------------------
  1106. IpxSockAddress::operator const char *() const
  1107. {
  1108.   return (char *)output_buffer;
  1109. }
  1110. //----[ IPXSock address get char representation ]--------------------------
  1111. char * WINFAR IpxSockAddress::get_printable()
  1112. {
  1113.   return (char *)output_buffer;
  1114. }
  1115. //----[ IPX address format output ]-------------------------------------
  1116. void IpxSockAddress::format_output()
  1117. {
  1118.   IpxAddress::format_output(); // allow ancestors to format their buffers
  1119.   if ( valid_flag)
  1120.     sprintf((char *) output_buffer,"%s/%d",
  1121.     IpxAddress::get_printable(), get_socket());
  1122.   else
  1123.     output_buffer[0] = 0;
  1124. };
  1125. //-----[ IP Address parse Address ]---------------------------------
  1126. int IpxSockAddress::parse_address( const char *inaddr)
  1127. {
  1128.    char buffer[MAX_FRIENDLY_NAME];
  1129.    unsigned short socketid=0;
  1130.    if (inaddr && (strlen( inaddr)< MAX_FRIENDLY_NAME))
  1131.      strcpy( buffer, inaddr);
  1132.    else
  1133.    {
  1134.      valid_flag = FALSE;
  1135.      return FALSE;
  1136.    }
  1137.    // look for port info @ the end of the string
  1138.    // port can be delineated by a ':' or a '/'
  1139.    // if neither are present then just treat it 
  1140.    // like a normal IpAddress
  1141.    char *tmp;
  1142.    tmp = strstr( buffer,"/");
  1143.    if (tmp != NULL)
  1144.    {
  1145.      *tmp=0;   // new null terminator
  1146.      tmp++;
  1147.      socketid = atoi( tmp);
  1148.    }
  1149.    set_socket(socketid);
  1150.    return IpxAddress::parse_address( buffer);
  1151. };
  1152. //-------------[ set the socket number ]----------------------------------
  1153. void IpxSockAddress::set_socket( const unsigned short s)
  1154.   unsigned short sock_nbo = htons(s);
  1155.   MEMCPY(&address_buffer[IPXLEN], &sock_nbo, 2);
  1156. };
  1157. //--------------[ get the socket number ]---------------------------------
  1158. unsigned short IpxSockAddress::get_socket() const
  1159.   if (valid_flag)
  1160.   {
  1161.     unsigned short sock_nbo;
  1162.     MEMCPY(&sock_nbo, &address_buffer[IPXLEN], 2);
  1163.     return ntohs(sock_nbo); 
  1164.   }
  1165.   else
  1166.     return 0; // don't use uninitialized memory
  1167. }
  1168. //------[ return the type ]----------------------------------------------
  1169. addr_type IpxSockAddress::get_type() const
  1170. { return type_ipxsock; };
  1171. //========================================================================
  1172. //======== MACAddress Implementation =====================================
  1173. //========================================================================
  1174. //-----------[ syntax type ]----------------------------------------------
  1175. SmiUINT32 MacAddress::get_syntax()
  1176. { return sNMP_SYNTAX_OCTETS; };
  1177. //--------[ constructor, no arguments ]-----------------------------------
  1178. MacAddress::MacAddress( void): Address( )
  1179.   // always initialize SMI info
  1180.   smival.syntax = sNMP_SYNTAX_OCTETS;
  1181.   smival.value.string.len = MACLEN;
  1182.   smival.value.string.ptr = address_buffer;
  1183.   valid_flag=FALSE; 
  1184.   format_output();
  1185. };
  1186. //-----[ MAC Address copy constructor ]---------------------------------
  1187. MacAddress::MacAddress(const MacAddress &macaddr)
  1188. {
  1189.   // always initialize SMI info
  1190.   smival.syntax = sNMP_SYNTAX_OCTETS;
  1191.   smival.value.string.len = MACLEN;
  1192.   smival.value.string.ptr = address_buffer;
  1193.   valid_flag = macaddr.valid_flag;
  1194.   if (valid_flag)
  1195.     MEMCPY(address_buffer, macaddr.address_buffer, MACLEN);
  1196.   format_output();
  1197. };
  1198. //---------[ constructor with a string argument ]-------------------------
  1199. MacAddress::MacAddress( const char  *inaddr):Address( )
  1200.   // always initialize SMI info
  1201.   smival.syntax = sNMP_SYNTAX_OCTETS;
  1202.   smival.value.string.len = MACLEN;
  1203.   smival.value.string.ptr = address_buffer;
  1204.   valid_flag = parse_address( (char *) inaddr); 
  1205.   format_output();
  1206. }
  1207. //-----[ construct a MacAddress from a GenAddress ]------------------------
  1208. MacAddress::MacAddress( const GenAddress &genaddr)
  1209. {
  1210.   // always initialize SMI info
  1211.   smival.syntax = sNMP_SYNTAX_OCTETS;
  1212.   smival.value.string.len = MACLEN;
  1213.   smival.value.string.ptr = address_buffer;
  1214.   valid_flag = FALSE;
  1215.   // allow use of mac address
  1216.   if (genaddr.get_type() == type_mac)
  1217.   {
  1218.     valid_flag = genaddr.valid();
  1219.     if ( valid_flag)
  1220.     {
  1221.       // copy in the Mac address data
  1222.       MacAddress temp_mac( (const char *) genaddr);
  1223.       *this = temp_mac;
  1224.     }
  1225.   }
  1226.   format_output();
  1227. };
  1228. //-----[ destructor ]--------------------------------------------------
  1229. MacAddress::~MacAddress()
  1230. {};
  1231. //---------[ MacAddress clone ]-------------------------------------------
  1232. SnmpSyntax WINFAR *MacAddress::clone() const
  1233.   return (SnmpSyntax *) new MacAddress(*this); 
  1234. };
  1235. //------[ assignment to another ipaddress object overloaded ]--------------
  1236. MacAddress& MacAddress::operator=( const MacAddress &macaddress)
  1237. {
  1238.   // protect against assignment from itself
  1239.   if ( this == &macaddress )
  1240.       return *this;
  1241.   valid_flag = macaddress.valid_flag; 
  1242.   if (valid_flag)
  1243.     MEMCPY(address_buffer, macaddress.address_buffer, MACLEN);
  1244.   format_output();
  1245.   return *this;
  1246. };
  1247. //-----[ MAC Address general = operator ]---------------------------------
  1248. SnmpSyntax& MacAddress::operator=( SnmpSyntax &val)
  1249. {
  1250.   // protect against assignment from itself
  1251.   if ( this == &val )
  1252.       return *this;
  1253.   valid_flag=0;       // will set to TRUE if really valid
  1254.   if (val.valid()){
  1255.     switch (val.get_syntax()){
  1256.     case sNMP_SYNTAX_OCTETS:
  1257.       if (((MacAddress &)val).smival.value.string.len == MACLEN){
  1258. MEMCPY(address_buffer, ((MacAddress &)val).smival.value.string.ptr, MACLEN);
  1259. valid_flag=1;
  1260.       }
  1261.     break;
  1262.     }
  1263.   }
  1264.   format_output();
  1265.   return *this;
  1266. };
  1267. //-----[ MAC Address parse Address ]--------------------------------------
  1268. // Convert a string to a six byte MAC address
  1269. // On success sets validity TRUE or FALSE
  1270. //
  1271. //     MAC address format
  1272. //
  1273. //   MAC ADDRESS
  1274. //   01 02 03 04 05 06
  1275. //   XX:XX:XX:XX:XX:XX
  1276. //   Valid input format
  1277. //
  1278. //   XXXXXXXXXXXX
  1279. //   Total length must be 17
  1280. //   Each char must take on value 0-F
  1281. //
  1282. //
  1283. int MacAddress::parse_address( const char *inaddr)
  1284. {
  1285.   char temp[30];    // don't destroy original
  1286.   char unsigned *tmp;
  1287.   size_t z;
  1288.   // save the orginal source
  1289.   if ( !inaddr || (strlen( inaddr) > 30)) return FALSE;
  1290.   strcpy( temp, inaddr);
  1291.   trim_white_space( temp);
  1292.   // bad total length check
  1293.   if ( strlen(temp) != 17)  
  1294.      return FALSE;
  1295.   // check for colons
  1296.   if ((temp[2] != ':')||(temp[5] != ':')||(temp[8]!=':')||(temp[11]!=':')||(temp[14] !=':'))
  1297.      return FALSE;
  1298.   // strip off the colons
  1299.   tmp = ( unsigned char *) temp;
  1300.   int i = 0;
  1301.   while ( *tmp != 0)
  1302.   {
  1303.      if (*tmp != ':')
  1304.      {
  1305.         temp[i] = *tmp;
  1306.         i++;
  1307.      }
  1308.      tmp++;
  1309.   }
  1310.   temp[i] = 0;
  1311.   
  1312.   // convert to lower
  1313.   for(z=0;z<strlen(temp);z++)
  1314.      temp[z] = tolower( temp[z]);
  1315.   
  1316.   // check out the MAC address
  1317.   tmp = ( unsigned char *) temp;
  1318.   while( *tmp != 0)
  1319.     if (((*tmp >= '0') && (*tmp <= '9'))||   // good 0-9
  1320. ((*tmp >= 'a') && (*tmp <= 'f')))    // or a-f
  1321.       tmp++;
  1322.     else
  1323.       return FALSE;
  1324.   // convert to target string
  1325.   tmp = (unsigned char *) temp;
  1326.   while ( *tmp != 0)
  1327.   {
  1328.   if (( *tmp >= '0') && ( *tmp <= '9'))
  1329.     *tmp = *tmp - (char unsigned )'0';
  1330.   else
  1331.     *tmp = *tmp - (char unsigned) 'a' + (char unsigned) 10;
  1332.   tmp++;
  1333.   }
  1334.   address_buffer[0] =  (temp[0]*16) + temp[1];
  1335.   address_buffer[1] =  (temp[2]*16) + temp[3];
  1336.   address_buffer[2] =  (temp[4]*16) + temp[5];
  1337.   address_buffer[3] =  (temp[6]*16) + temp[7];
  1338.   address_buffer[4] =  (temp[8]*16) + temp[9];
  1339.   address_buffer[5] =  (temp[10]*16) + temp[11];
  1340.   return TRUE;
  1341. };
  1342. //----[ MAC address char * cast ]--------------------------------------
  1343. MacAddress::operator const char *() const
  1344. {
  1345.   return (char *)output_buffer;
  1346. }
  1347. //----[ MAC address get char representation ]--------------------------
  1348. char * WINFAR MacAddress::get_printable()
  1349. {
  1350.   return (char *)output_buffer;
  1351. }
  1352. //----[ MAC address format output ]---------------------------------
  1353. void MacAddress::format_output()
  1354. {
  1355.   if ( valid_flag)
  1356.     sprintf(output_buffer,"%02x:%02x:%02x:%02x:%02x:%02x",address_buffer[0],
  1357.     address_buffer[1],address_buffer[2],address_buffer[3],
  1358.     address_buffer[4],address_buffer[5]);
  1359.   else
  1360.     output_buffer[0] = 0;
  1361. };
  1362. //------[ return the type ]----------------------------------
  1363. addr_type MacAddress::get_type() const
  1364. { return type_mac; };
  1365. unsigned int MacAddress::hashFunction() const
  1366. {
  1367.         return ((((address_buffer[0] << 8) + address_buffer[1]) * HASH0)
  1368.                 + (((address_buffer[2] << 8) + address_buffer[3]) * HASH1)
  1369.                 + (((address_buffer[4] << 8) + address_buffer[5]) * HASH2));
  1370. }
  1371. //========================================================================
  1372. //========== Generic Address Implementation ==============================
  1373. //========================================================================
  1374. //-----------[ get the syntax]----------------------------------------------
  1375. SmiUINT32 GenAddress::get_syntax()
  1376.    if (address != 0)
  1377.        return address->get_syntax();
  1378.    return sNMP_SYNTAX_NULL;
  1379. };
  1380. //-----------[ constructor, no arguments ]--------------------------------
  1381. GenAddress::GenAddress( void):Address()
  1382.   // initialize SMI info
  1383.   // BOK: this is generally not used for GenAddress,
  1384.   // but we need this to be a replica of the real address'
  1385.   // smival info so that operator=SnmpSyntax will work.
  1386.   smival.syntax = sNMP_SYNTAX_NULL; // to be overridden
  1387.   smival.value.string.len = 0; // to be overridden
  1388.   smival.value.string.ptr = address_buffer; // constant
  1389.   valid_flag = FALSE;
  1390.   address = 0;
  1391.   format_output();
  1392. };
  1393. //-----------[ constructor with a string argument ]----------------------
  1394. GenAddress::GenAddress( const char  *addr)
  1395. {
  1396.   // initialize SMI info
  1397.   // BOK: smival is generally not used for GenAddress, but 
  1398.   //      we need this to be a replica of the real address'
  1399.   //      smival info so that <class>::operator=SnmpSyntax 
  1400.   //      will work.
  1401.   smival.syntax = sNMP_SYNTAX_NULL; // to be overridden
  1402.   smival.value.string.len = 0; // to be overridden
  1403.   smival.value.string.ptr = address_buffer; // constant
  1404.   address = 0;
  1405.   parse_address(addr);
  1406.   // Copy real address smival info into GenAddr smival
  1407.   // BOK: smival is generally not used for GenAddress, but 
  1408.   //      we need this to be a replica of the real address'
  1409.   //      smival info so that <class>::operator=SnmpSyntax 
  1410.   //      will work.
  1411.   if ( valid_flag ) {
  1412.       smival.syntax = ((GenAddress *)address)->smival.syntax;
  1413.       smival.value.string.len = 
  1414.   ((GenAddress *)address)->smival.value.string.len;
  1415.       memcpy(smival.value.string.ptr, 
  1416.           ((GenAddress *)address)->smival.value.string.ptr,
  1417.           (size_t)smival.value.string.len);
  1418.   }
  1419. };
  1420. //-----------[ constructor with an Address argument ]--------------------
  1421. GenAddress::GenAddress( const Address &addr)
  1422. {
  1423.   // initialize SMI info
  1424.   // BOK: this is generally not used for GenAddress,
  1425.   // but we need this to be a replica of the real address'
  1426.   // smival info so that operator=SnmpSyntax will work.
  1427.   smival.syntax = sNMP_SYNTAX_NULL; // to be overridden
  1428.   smival.value.string.len = 0; // to be overridden
  1429.   smival.value.string.ptr = address_buffer; // constant
  1430.   valid_flag = FALSE;
  1431.   // make sure that the object is valid
  1432.   if (!addr.valid()) {
  1433.     address = 0;
  1434.     format_output();
  1435.     return;
  1436.   }
  1437.   
  1438.   address = (Address*)addr.clone();
  1439.   if (address)
  1440.     valid_flag = address->valid();
  1441.   
  1442.   // Copy real address smival info into GenAddr smival
  1443.   // BOK: smival is generally not used for GenAddress, but 
  1444.   //      we need this to be a replica of the real address'
  1445.   //      smival info so that <class>::operator=SnmpSyntax 
  1446.   //      will work.
  1447.   if ( valid_flag ) {
  1448.       smival.syntax = address->get_syntax();
  1449.       smival.value.string.len = 
  1450.   ((GenAddress *)address)->smival.value.string.len;
  1451.       memcpy(smival.value.string.ptr, 
  1452.           ((GenAddress *)address)->smival.value.string.ptr,
  1453.           (size_t)smival.value.string.len);
  1454.   }
  1455.   format_output();
  1456. }
  1457. //-----------------[ constructor with another GenAddress object ]-------------
  1458. GenAddress::GenAddress( const GenAddress &addr)
  1459. {
  1460.   // initialize SMI info
  1461.   // BOK: this is generally not used for GenAddress,
  1462.   // but we need this to be a replica of the real address'
  1463.   // smival info so that operator=SnmpSyntax will work.
  1464.   smival.syntax = sNMP_SYNTAX_OCTETS;
  1465.   smival.value.string.len = 0;
  1466.   smival.value.string.ptr = address_buffer;
  1467.   valid_flag = FALSE;
  1468.   // make sure that the object is valid
  1469.   if (!addr.valid_flag) {
  1470.     address = 0;
  1471.     format_output();
  1472.     return;
  1473.   }
  1474.   
  1475.   address = (Address *)addr.address->clone();
  1476.   if (address)
  1477.     valid_flag = address->valid();
  1478.   
  1479.   // Copy real address smival info into GenAddr smival
  1480.   // BOK: smival is generally not used for GenAddress, but 
  1481.   //      we need this to be a replica of the real address'
  1482.   //      smival info so that <class>::operator=SnmpSyntax 
  1483.   //      will work.
  1484.   if ( valid_flag ) {
  1485.       smival.syntax = ((GenAddress *)address)->smival.syntax;
  1486.       smival.value.string.len = 
  1487.   ((GenAddress *)address)->smival.value.string.len;
  1488.       memcpy(smival.value.string.ptr, 
  1489.           ((GenAddress *)address)->smival.value.string.ptr,
  1490.           (size_t)smival.value.string.len);
  1491.   }
  1492.   format_output();
  1493. };
  1494. //----------[ destructor ] ------------------------------------------------
  1495. GenAddress::~GenAddress() 
  1496. {
  1497.   if ( address != 0)
  1498.      delete address;
  1499. };
  1500. //----------[ create a new instance of this Value ]------------------------
  1501. SnmpSyntax WINFAR *GenAddress::clone() const 
  1502.   return (SnmpSyntax *) new GenAddress(*this); 
  1503. };
  1504. //------[ assignment GenAddress = GenAddress ]-----------------------------
  1505. GenAddress& GenAddress::operator=( const GenAddress &addr)
  1506. {
  1507.   // protect against assignment from itself
  1508.   if ( this == &addr )
  1509.       return *this;
  1510.   valid_flag = FALSE;
  1511.   if (address) {
  1512.     delete address;
  1513.     address = 0;
  1514.   }
  1515.   if (addr.address)
  1516.     address = (Address *)(addr.address)->clone();
  1517.   if (address)
  1518.     valid_flag = address->valid();
  1519.   
  1520.   // Copy real address smival info into GenAddr smival
  1521.   // BOK: smival is generally not used for GenAddress, but 
  1522.   //      we need this to be a replica of the real address'
  1523.   //      smival info so that <class>::operator=SnmpSyntax 
  1524.   //      will work.
  1525.   if ( valid_flag ) {
  1526.       smival.syntax = ((GenAddress *)address)->smival.syntax;
  1527.       smival.value.string.len = 
  1528.   ((GenAddress *)address)->smival.value.string.len;
  1529.       memcpy(smival.value.string.ptr, 
  1530.           ((GenAddress *)address)->smival.value.string.ptr,
  1531.           (size_t)smival.value.string.len);
  1532.   }
  1533.   format_output();
  1534.   return *this;
  1535. }
  1536. //------[ assignment GenAddress = any SnmpSyntax ]-----------------------
  1537. SnmpSyntax& GenAddress::operator=( SnmpSyntax &val)
  1538. {
  1539.   // protect against assignment from itself
  1540.   if ( this == &val )
  1541.       return *this;
  1542.   valid_flag = FALSE; // will get set to TRUE if really valid
  1543.   if ( address != 0) {
  1544.     delete address;
  1545.     address = 0;
  1546.   }
  1547.   if (val.valid())
  1548.   {
  1549.     switch ( val.get_syntax() ) {
  1550.       //-----[ ip address case ]-------------
  1551.       // BOK: this case shouldn't be needed since there is an explicit 
  1552.       // GenAddr=Address assignment that will override this assignment. 
  1553.       // Left here for posterity.
  1554.     case sNMP_SYNTAX_IPADDR:
  1555.     {
  1556.       address = (Address *)val.clone();
  1557.       if (address)
  1558. valid_flag = address->valid();
  1559.     }
  1560.     break;
  1561.       //-----[ udp address case ]------------
  1562.       //-----[ ipx address case ]------------
  1563.       //-----[ mac address case ]------------
  1564.       // BOK:  This is here only to support GenAddr = primitive OctetStr. 
  1565.       // The explicit GenAddr=Address assignment will handle the cases 
  1566.       // GenAddr = [UdpAdd|IpxAddr|IpxSock|MacAddr].  
  1567.       // Note, using the heuristic of octet str len to determine type of 
  1568.       // address to create is not accurate when address lengths are equal
  1569.       // (e.g., UDPIPLEN == MACLEN).  It gets worse if we add AppleTalk or 
  1570.       // OSI which use variable length addresses!
  1571.     case sNMP_SYNTAX_OCTETS:
  1572.     {
  1573.       unsigned long val_len;
  1574.       val_len = ((GenAddress &)val).smival.value.string.len;
  1575.       if (val_len == UDPIPLEN){
  1576. address = new UdpAddress;
  1577.       }
  1578.       else if (val_len == IPLEN){
  1579. address = new IpAddress;
  1580.       }
  1581.       else if (val_len == IPXLEN){
  1582. address = new IpxAddress;
  1583.       }
  1584.       else if (val_len == IPXSOCKLEN){
  1585. address = new IpxSockAddress;
  1586.       }
  1587.       else  if (val_len == MACLEN)
  1588.       {
  1589. address = new MacAddress;
  1590.       }
  1591.       if (address){
  1592. *address = val;
  1593. valid_flag = address->valid();
  1594.       }
  1595.     }
  1596.     break;
  1597.     }   // end switch
  1598.   }
  1599.   // Copy real address smival info into GenAddr smival
  1600.   // BOK: smival is generally not used for GenAddress, but 
  1601.   //      we need this to be a replica of the real address'
  1602.   //      smival info so that <class>::operator=SnmpSyntax 
  1603.   //      will work.
  1604.   if ( valid_flag ) {
  1605.       smival.syntax = ((GenAddress *)address)->smival.syntax;
  1606.       smival.value.string.len = 
  1607.   ((GenAddress *)address)->smival.value.string.len;
  1608.       memcpy(smival.value.string.ptr, 
  1609.           ((GenAddress *)address)->smival.value.string.ptr,
  1610.           (size_t)smival.value.string.len);
  1611.   }
  1612.   format_output();
  1613.   return *this;
  1614. };
  1615. // redefined parse address for macs
  1616. int GenAddress::parse_address( const char *addr)
  1617. {
  1618.    if ( address != 0)
  1619.       delete address;
  1620.    // try to create each of the addresses until the correct one
  1621.    // is found
  1622. //BOK: Need to try IPX Sock and IPX before UDP since on Win32,
  1623. //     gethostbyname() seems to think the ipx network number
  1624. //     portion is a valid ipaddress string... stupid WinSOCK!
  1625.     // ipxsock address
  1626.     address = new IpxSockAddress( addr);
  1627.     valid_flag = address->valid();
  1628.     if ( valid_flag && ((IpxSockAddress*)address)->get_socket())
  1629.     {
  1630.        format_output();
  1631.        return TRUE;   // ok its an ipxsock address
  1632.     }
  1633. // otherwise delete it and try another
  1634.     delete address;
  1635.     // ipx address
  1636.     address = new IpxAddress( addr);
  1637.     valid_flag = address->valid();
  1638.     if ( valid_flag)
  1639.     {
  1640.        format_output();
  1641.        return TRUE;   // ok its an ipx address
  1642.     }
  1643. // otherwise delete it and try another
  1644.     delete address;
  1645. //TM: Must try the derived classes first...one pitfall of the
  1646. //following solution is if someone creates with a port/socket of 0 the
  1647. //class will get demoted to ip/ipx.  The only proper way to do this is
  1648. //to parse the strings ourselves.
  1649. // udp address
  1650.     address = new UdpAddress( addr);
  1651.     valid_flag = address->valid();
  1652.     if ( valid_flag && ((UdpAddress*)address)->get_port()) 
  1653.     {
  1654.        format_output();
  1655.        return TRUE;       // ok its a udp address
  1656.     }
  1657.     // otherwise delete it and try another
  1658.     delete address;
  1659.     // ip address
  1660.     address = new IpAddress( addr);
  1661.     valid_flag = address->valid();
  1662.     if ( valid_flag) 
  1663.     {
  1664.        format_output();
  1665.        return TRUE;       // ok its an ip address
  1666.     }
  1667. // otherwise delete it and try another
  1668.     delete address;
  1669.     // mac address
  1670.     address = new MacAddress( addr);
  1671.     valid_flag = address->valid();
  1672.     if ( valid_flag)
  1673.     {
  1674.        format_output();
  1675.        return TRUE;    // ok, its a mac
  1676.     }
  1677. // otherwise its invalid
  1678.     delete address;
  1679.     address = 0;
  1680.     format_output();
  1681.     return FALSE;
  1682. };
  1683. GenAddress::operator const char *() const
  1684. {
  1685.   if ( address != 0)
  1686.     return (const char *)*address; // pass thru
  1687.   else
  1688.     return (char *)output_buffer;
  1689. }
  1690. // get_printable form of the contained address
  1691. char * WINFAR GenAddress::get_printable() 
  1692. {
  1693.   if ( address != 0)
  1694.     return address->get_printable(); // pass thru
  1695.   else
  1696.     return (char *)output_buffer;
  1697. }
  1698. // format output
  1699. void GenAddress::format_output()
  1700. {
  1701.   output_buffer[0]='';
  1702. };
  1703. //------[ return the type ]----------------------------------
  1704. addr_type GenAddress::get_type() const
  1705. { if (!valid())
  1706.      return type_invalid;
  1707.   else
  1708.      return address->get_type();
  1709. };