|
INET Framework for OMNeT++/OMNEST
|
00001 /* 00002 * Copyright (C) 2003 Andras Varga; CTIE, Monash University, Australia 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public License 00015 * along with this program; if not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #include <ctype.h> 00019 #include "MACAddress.h" 00020 #include "InterfaceToken.h" 00021 00022 00023 unsigned int MACAddress::autoAddressCtr; 00024 00025 // 00026 // Converts hex string into a byte array 'destbuf'. Destbuf is 'size' 00027 // chars long -- if hext string is shorter, destbuf is filled with zeros; 00028 // if destbuf is longer, it is truncated. Non-hex characters are 00029 // discarded before conversion. Returns number of bytes converted from hex. 00030 // 00031 static int hextobin(const char *hexstr, unsigned char *destbuf, int size) 00032 { 00033 int k=0; 00034 const char *s = hexstr; 00035 for (int pos=0; pos<size; pos++) 00036 { 00037 if (!s || !*s) 00038 { 00039 destbuf[pos] = 0; 00040 } 00041 else 00042 { 00043 while (*s && !isxdigit(*s)) s++; 00044 if (!*s) {destbuf[pos]=0; continue;} 00045 unsigned char d = isdigit(*s) ? (*s-'0') : islower(*s) ? (*s-'a'+10) : (*s-'A'+10); 00046 d = d<<4; 00047 s++; 00048 00049 while (*s && !isxdigit(*s)) s++; 00050 if (!*s) {destbuf[pos]=0; continue;} 00051 d += isdigit(*s) ? (*s-'0') : islower(*s) ? (*s-'a'+10) : (*s-'A'+10); 00052 s++; 00053 00054 destbuf[pos] = d; 00055 k++; 00056 } 00057 } 00058 return k; 00059 } 00060 00061 const MACAddress MACAddress::UNSPECIFIED_ADDRESS; 00062 const MACAddress MACAddress::BROADCAST_ADDRESS("ff:ff:ff:ff:ff:ff"); 00063 00064 MACAddress::MACAddress() 00065 { 00066 address[0]=address[1]=address[2]=address[3]=address[4]=address[5]=0; 00067 } 00068 00069 MACAddress::MACAddress(const char *hexstr) 00070 { 00071 setAddress(hexstr); 00072 } 00073 00074 MACAddress& MACAddress::operator=(const MACAddress& other) 00075 { 00076 memcpy(address, other.address, MAC_ADDRESS_BYTES); 00077 return *this; 00078 } 00079 00080 unsigned int MACAddress::getAddressSize() const 00081 { 00082 return 6; 00083 } 00084 00085 unsigned char MACAddress::getAddressByte(unsigned int k) const 00086 { 00087 if (k>=6) throw cRuntimeError("Array of size 6 indexed with %d", k); 00088 return address[k]; 00089 } 00090 00091 void MACAddress::setAddressByte(unsigned int k, unsigned char addrbyte) 00092 { 00093 if (k>=6) throw cRuntimeError("Array of size 6 indexed with %d", k); 00094 address[k] = addrbyte; 00095 } 00096 00097 bool MACAddress::tryParse(const char *hexstr) 00098 { 00099 if (!hexstr) 00100 return false; 00101 00102 // check syntax 00103 int numHexDigits = 0; 00104 for (const char *s = hexstr; *s; s++) { 00105 if (isxdigit(*s)) 00106 numHexDigits++; 00107 else if (*s!=' ' && *s!=':' && *s!='-') 00108 return false; // wrong syntax 00109 } 00110 if (numHexDigits != 2*MAC_ADDRESS_BYTES) 00111 return false; 00112 00113 // convert 00114 hextobin(hexstr, address, MAC_ADDRESS_BYTES); 00115 return true; 00116 } 00117 00118 void MACAddress::setAddress(const char *hexstr) 00119 { 00120 if (!tryParse(hexstr)) 00121 throw cRuntimeError("MACAddress: wrong address syntax '%s': 12 hex digits expected, with optional embedded spaces, hyphens or colons", hexstr); 00122 } 00123 00124 void MACAddress::setAddressBytes(unsigned char *addrbytes) 00125 { 00126 memcpy(address, addrbytes, MAC_ADDRESS_BYTES); 00127 } 00128 00129 void MACAddress::setBroadcast() 00130 { 00131 address[0]=address[1]=address[2]=address[3]=address[4]=address[5]=0xff; 00132 } 00133 00134 bool MACAddress::isBroadcast() const 00135 { 00136 return (address[0]&address[1]&address[2]&address[3]&address[4]&address[5])==0xff; 00137 } 00138 00139 bool MACAddress::isUnspecified() const 00140 { 00141 return !(address[0] || address[1] || address[2] || address[3] || address[4] || address[5]); 00142 } 00143 00144 std::string MACAddress::str() const 00145 { 00146 char buf[20]; 00147 char *s = buf; 00148 for (int i=0; i<MAC_ADDRESS_BYTES; i++, s+=3) 00149 sprintf(s,"%2.2X-",address[i]); 00150 *(s-1)='\0'; 00151 return std::string(buf); 00152 } 00153 00154 bool MACAddress::equals(const MACAddress& other) const 00155 { 00156 return memcmp(address, other.address, MAC_ADDRESS_BYTES)==0; 00157 } 00158 00159 int MACAddress::compareTo(const MACAddress& other) const 00160 { 00161 return memcmp(address, other.address, MAC_ADDRESS_BYTES); 00162 } 00163 00164 InterfaceToken MACAddress::formInterfaceIdentifier() const 00165 { 00166 const unsigned char *b = address; 00167 uint32 high = (b[0]<<24) | (b[1]<<16) | (b[2]<<8) | 0xff; 00168 uint32 low = (0xfe<<24) | (b[3]<<16) | (b[4]<<8) | b[5]; 00169 return InterfaceToken(low, high, 64); 00170 } 00171 00172 MACAddress MACAddress::generateAutoAddress() 00173 { 00174 ++autoAddressCtr; 00175 00176 unsigned char addrbytes[6]; 00177 addrbytes[0] = 0x0A; 00178 addrbytes[1] = 0xAA; 00179 addrbytes[2] = (autoAddressCtr>>24)&0xff; 00180 addrbytes[3] = (autoAddressCtr>>16)&0xff; 00181 addrbytes[4] = (autoAddressCtr>>8)&0xff; 00182 addrbytes[5] = (autoAddressCtr)&0xff; 00183 00184 MACAddress addr; 00185 addr.setAddressBytes(addrbytes); 00186 return addr; 00187 } 00188