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 + -
显示快捷键?