address.cpp

来自「HP公司的SNMP++的Win32版本源码」· C++ 代码 · 共 2,016 行 · 第 1/4 页

CPP
2,016
字号
//-----[ MAC Address parse Address ]--------------------------------------
// Convert a string to a six byte MAC address
// On success sets validity TRUE or FALSE
//
//     MAC address format
//
//   MAC ADDRESS
//   01 02 03 04 05 06
//   XX:XX:XX:XX:XX:XX
//   Valid input format
//
//   XXXXXXXXXXXX
//   Total length must be 17
//   Each char must take on value 0-F
//
//
int MacAddress::parse_address( const char *inaddr)
{
  char temp[30];    // don't destroy original
  char unsigned *tmp;
  size_t z;


  // save the orginal source
  if ( !inaddr || (strlen( inaddr) > 30)) return FALSE;
  strcpy( temp, inaddr);
  trim_white_space( temp);

  // bad total length check
  if ( strlen(temp) != 17)  
     return FALSE;

  // check for colons
  if ((temp[2] != ':')||(temp[5] != ':')||(temp[8]!=':')||(temp[11]!=':')||(temp[14] !=':'))
     return FALSE;

  // strip off the colons
  tmp = ( unsigned char *) temp;
  int i = 0;
  while ( *tmp != 0)
  {
     if (*tmp != ':')
     {
        temp[i] = *tmp;
        i++;
     }
     tmp++;
  }
  temp[i] = 0;
  
  // convert to lower
  for(z=0;z<strlen(temp);z++)
     temp[z] = tolower( temp[z]);

  
  // check out the MAC address
  tmp = ( unsigned char *) temp;
  while( *tmp != 0)
    if (((*tmp >= '0') && (*tmp <= '9'))||   // good 0-9
	((*tmp >= 'a') && (*tmp <= 'f')))    // or a-f
      tmp++;
    else
      return FALSE;

  // convert to target string
  tmp = (unsigned char *) temp;
  while ( *tmp != 0)
  {
  if (( *tmp >= '0') && ( *tmp <= '9'))
    *tmp = *tmp - (char unsigned )'0';
  else
    *tmp = *tmp - (char unsigned) 'a' + (char unsigned) 10;
  tmp++;
  }

  address_buffer[0] =  (temp[0]*16) + temp[1];
  address_buffer[1] =  (temp[2]*16) + temp[3];
  address_buffer[2] =  (temp[4]*16) + temp[5];
  address_buffer[3] =  (temp[6]*16) + temp[7];
  address_buffer[4] =  (temp[8]*16) + temp[9];
  address_buffer[5] =  (temp[10]*16) + temp[11];

  return TRUE;
};

//----[ MAC address char * cast ]--------------------------------------
MacAddress::operator const char *() const
{
  return (char *)output_buffer;
}
//----[ MAC address get char representation ]--------------------------
char * WINFAR MacAddress::get_printable()
{
  return (char *)output_buffer;
}

//----[ MAC address format output ]---------------------------------
void MacAddress::format_output()
{
  if ( valid_flag)
    sprintf(output_buffer,"%02x:%02x:%02x:%02x:%02x:%02x",address_buffer[0],
	    address_buffer[1],address_buffer[2],address_buffer[3],
	    address_buffer[4],address_buffer[5]);
  else
    output_buffer[0] = 0;
};

//------[ return the type ]----------------------------------
addr_type MacAddress::get_type() const
{ return type_mac; };


unsigned int MacAddress::hashFunction() const
{
        return ((((address_buffer[0] << 8) + address_buffer[1]) * HASH0)
                + (((address_buffer[2] << 8) + address_buffer[3]) * HASH1)
                + (((address_buffer[4] << 8) + address_buffer[5]) * HASH2));
}

//========================================================================
//========== Generic Address Implementation ==============================
//========================================================================

//-----------[ get the syntax]----------------------------------------------
SmiUINT32 GenAddress::get_syntax()
{ 
   if (address != 0)
       return address->get_syntax();

   return sNMP_SYNTAX_NULL;
};

//-----------[ constructor, no arguments ]--------------------------------
GenAddress::GenAddress( void):Address()
{ 
  // initialize SMI info
  // BOK: this is generally not used for GenAddress,
  // but we need this to be a replica of the real address'
  // smival info so that operator=SnmpSyntax will work.
  smival.syntax = sNMP_SYNTAX_NULL;		// to be overridden
  smival.value.string.len = 0;			// to be overridden
  smival.value.string.ptr = address_buffer;	// constant

  valid_flag = FALSE;
  address = 0;
  format_output();
};

//-----------[ constructor with a string argument ]----------------------
GenAddress::GenAddress( const char  *addr)
{
  // initialize SMI info
  // BOK: smival is generally not used for GenAddress, but 
  //      we need this to be a replica of the real address'
  //      smival info so that <class>::operator=SnmpSyntax 
  //      will work.
  smival.syntax = sNMP_SYNTAX_NULL;		// to be overridden
  smival.value.string.len = 0;			// to be overridden
  smival.value.string.ptr = address_buffer;	// constant

  address = 0;
  parse_address(addr);

  // Copy real address smival info into GenAddr smival
  // BOK: smival is generally not used for GenAddress, but 
  //      we need this to be a replica of the real address'
  //      smival info so that <class>::operator=SnmpSyntax 
  //      will work.
  if ( valid_flag ) {
      smival.syntax = ((GenAddress *)address)->smival.syntax;
      smival.value.string.len = 
	  ((GenAddress *)address)->smival.value.string.len;
      memcpy(smival.value.string.ptr, 
          ((GenAddress *)address)->smival.value.string.ptr,
          (size_t)smival.value.string.len);
  }
};

//-----------[ constructor with an Address argument ]--------------------
GenAddress::GenAddress( const Address &addr)
{
  // initialize SMI info
  // BOK: this is generally not used for GenAddress,
  // but we need this to be a replica of the real address'
  // smival info so that operator=SnmpSyntax will work.
  smival.syntax = sNMP_SYNTAX_NULL;		// to be overridden
  smival.value.string.len = 0;			// to be overridden
  smival.value.string.ptr = address_buffer;	// constant

  valid_flag = FALSE;
  // make sure that the object is valid
  if (!addr.valid()) {
    address = 0;
    format_output();
    return;
  }
  
  address = (Address*)addr.clone();
  if (address)
    valid_flag = address->valid();
  
  // Copy real address smival info into GenAddr smival
  // BOK: smival is generally not used for GenAddress, but 
  //      we need this to be a replica of the real address'
  //      smival info so that <class>::operator=SnmpSyntax 
  //      will work.
  if ( valid_flag ) {
      smival.syntax = address->get_syntax();
      smival.value.string.len = 
	  ((GenAddress *)address)->smival.value.string.len;
      memcpy(smival.value.string.ptr, 
          ((GenAddress *)address)->smival.value.string.ptr,
          (size_t)smival.value.string.len);
  }

  format_output();
}

//-----------------[ constructor with another GenAddress object ]-------------
GenAddress::GenAddress( const GenAddress &addr)
{

  // initialize SMI info
  // BOK: this is generally not used for GenAddress,
  // but we need this to be a replica of the real address'
  // smival info so that operator=SnmpSyntax will work.
  smival.syntax = sNMP_SYNTAX_OCTETS;
  smival.value.string.len = 0;
  smival.value.string.ptr = address_buffer;

  valid_flag = FALSE;
  // make sure that the object is valid
  if (!addr.valid_flag) {
    address = 0;
    format_output();
    return;
  }
  
  address = (Address *)addr.address->clone();
  if (address)
    valid_flag = address->valid();
  
  // Copy real address smival info into GenAddr smival
  // BOK: smival is generally not used for GenAddress, but 
  //      we need this to be a replica of the real address'
  //      smival info so that <class>::operator=SnmpSyntax 
  //      will work.
  if ( valid_flag ) {
      smival.syntax = ((GenAddress *)address)->smival.syntax;
      smival.value.string.len = 
	  ((GenAddress *)address)->smival.value.string.len;
      memcpy(smival.value.string.ptr, 
          ((GenAddress *)address)->smival.value.string.ptr,
          (size_t)smival.value.string.len);
  }

  format_output();
};

//----------[ destructor ] ------------------------------------------------
GenAddress::~GenAddress() 
{
  if ( address != 0)
     delete address;
};

//----------[ create a new instance of this Value ]------------------------
SnmpSyntax WINFAR *GenAddress::clone() const 
{ 
  return (SnmpSyntax *) new GenAddress(*this); 
};

//------[ assignment GenAddress = GenAddress ]-----------------------------
GenAddress& GenAddress::operator=( const GenAddress &addr)
{
  // protect against assignment from itself
  if ( this == &addr )
      return *this;

  valid_flag = FALSE;
  if (address) {
    delete address;
    address = 0;
  }
  if (addr.address)
    address = (Address *)(addr.address)->clone();
  if (address)
    valid_flag = address->valid();
  
  // Copy real address smival info into GenAddr smival
  // BOK: smival is generally not used for GenAddress, but 
  //      we need this to be a replica of the real address'
  //      smival info so that <class>::operator=SnmpSyntax 
  //      will work.
  if ( valid_flag ) {
      smival.syntax = ((GenAddress *)address)->smival.syntax;
      smival.value.string.len = 
	  ((GenAddress *)address)->smival.value.string.len;
      memcpy(smival.value.string.ptr, 
          ((GenAddress *)address)->smival.value.string.ptr,
          (size_t)smival.value.string.len);
  }

  format_output();
  return *this;
}


//------[ assignment GenAddress = any SnmpSyntax ]-----------------------
SnmpSyntax& GenAddress::operator=( SnmpSyntax &val)
{
  // protect against assignment from itself
  if ( this == &val )
      return *this;

  valid_flag = FALSE;		// will get set to TRUE if really valid
  if ( address != 0) {
    delete address;
    address = 0;
  }

  if (val.valid())
  {
    switch ( val.get_syntax() ) {
      //-----[ ip address case ]-------------
      // BOK: this case shouldn't be needed since there is an explicit 
      // GenAddr=Address assignment that will override this assignment. 
      // Left here for posterity.
    case sNMP_SYNTAX_IPADDR:
    {
      address = (Address *)val.clone();
      if (address)
	valid_flag = address->valid();
    }
    break;

      //-----[ udp address case ]------------
      //-----[ ipx address case ]------------
      //-----[ mac address case ]------------
      // BOK:  This is here only to support GenAddr = primitive OctetStr. 
      // The explicit GenAddr=Address assignment will handle the cases 
      // GenAddr = [UdpAdd|IpxAddr|IpxSock|MacAddr].  
      // Note, using the heuristic of octet str len to determine type of 
      // address to create is not accurate when address lengths are equal
      // (e.g., UDPIPLEN == MACLEN).  It gets worse if we add AppleTalk or 
      // OSI which use variable length addresses!
    case sNMP_SYNTAX_OCTETS:
    {
      unsigned long val_len;
      val_len = ((GenAddress &)val).smival.value.string.len;

      if (val_len == UDPIPLEN){
	address = new UdpAddress;
      }
      else if (val_len == IPLEN){
	address = new IpAddress;
      }
      else if (val_len == IPXLEN){
	address = new IpxAddress;
      }
      else if (val_len == IPXSOCKLEN){
	address = new IpxSockAddress;
      }
      else  if (val_len == MACLEN)
      {
	address = new MacAddress;
      }
      if (address){
	*address = val;
	valid_flag = address->valid();
      }
    }
    break;
    }   // end switch
  }

  // Copy real address smival info into GenAddr smival
  // BOK: smival is generally not used for GenAddress, but 
  //      we need this to be a replica of the real address'
  //      smival info so that <class>::operator=SnmpSyntax 
  //      will work.
  if ( valid_flag ) {
      smival.syntax = ((GenAddress *)address)->smival.syntax;
      smival.value.string.len = 
	  ((GenAddress *)address)->smival.value.string.len;
      memcpy(smival.value.string.ptr, 
          ((GenAddress *)address)->smival.value.string.ptr,
          (size_t)smival.value.string.len);
  }

  format_output();
  return *this;
};


// redefined parse address for macs
int GenAddress::parse_address( const char *addr)
{
   if ( address != 0)
      delete address;

   // try to create each of the addresses until the correct one
   // is found

//BOK: Need to try IPX Sock and IPX before UDP since on Win32,
//     gethostbyname() seems to think the ipx network number
//     portion is a valid ipaddress string... stupid WinSOCK!

    // ipxsock address
    address = new IpxSockAddress( addr);
    valid_flag = address->valid();
    if ( valid_flag && ((IpxSockAddress*)address)->get_socket())
    {
       format_output();
       return TRUE;   // ok its an ipxsock address
    }
	// otherwise delete it and try another
    delete address;

    // ipx address
    address = new IpxAddress( addr);
    valid_flag = address->valid();
    if ( valid_flag)
    {
       format_output();
       return TRUE;   // ok its an ipx address
    }
	// otherwise delete it and try another
    delete address;

//TM: Must try the derived classes first...one pitfall of the
//following solution is if someone creates with a port/socket of 0 the
//class will get demoted to ip/ipx.  The only proper way to do this is
//to parse the strings ourselves.

	// udp address
    address = new UdpAddress( addr);
    valid_flag = address->valid();
    if ( valid_flag && ((UdpAddress*)address)->get_port()) 
    {
       format_output();
       return TRUE;       // ok its a udp address
    }
    // otherwise delete it and try another
    delete address;

    // ip address
    address = new IpAddress( addr);
    valid_flag = address->valid();
    if ( valid_flag) 
    {
       format_output();
       return TRUE;       // ok its an ip address
    }
	// otherwise delete it and try another
    delete address;

    // mac address
    address = new MacAddress( addr);
    valid_flag = address->valid();
    if ( valid_flag)
    {
       format_output();
       return TRUE;    // ok, its a mac
    }
	// otherwise its invalid
    delete address;
    address = 0;
    format_output();
    return FALSE;
};

GenAddress::operator const char *() const
{
  if ( address != 0)
    return (const char *)*address;	// pass thru
  else
    return (char *)output_buffer;
}

// get_printable form of the contained address
char * WINFAR GenAddress::get_printable() 
{
  if ( address != 0)
    return address->get_printable();	// pass thru
  else
    return (char *)output_buffer;
}

// format output
void GenAddress::format_output()
{
  output_buffer[0]='\0';
};

//------[ return the type ]----------------------------------
addr_type GenAddress::get_type() const
{ if (!valid())
     return type_invalid;
  else
     return address->get_type();
};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?