diff --git a/include/hwaddress.h b/include/hwaddress.h new file mode 100644 index 0000000..85a2d2d --- /dev/null +++ b/include/hwaddress.h @@ -0,0 +1,117 @@ +/* + * libtins is a net packet wrapper library for crafting and + * interpreting sniffed packets. + * + * Copyright (C) 2011 Nasel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef TINS_HWADDRESS_H +#define TINS_HWADDRESS_H + +#include +#include +#include +#include //borrame + +namespace Tins { +template +class HWAddress { +public: + typedef uint8_t element_type; + typedef element_type* iterator; + typedef const element_type* const_iterator; + static const size_t address_size = n; + + HWAddress() { + std::fill(buffer, buffer + address_size, element_type()); + } + + HWAddress(const std::string &address) { + convert(address, buffer); + } + + iterator begin() { + return buffer; + } + + const_iterator begin() const { + return buffer; + } + + iterator end() { + return buffer + address_size; + } + + const_iterator end() const { + return buffer + address_size; + } + + friend std::ostream &operator<<(std::ostream &os, const HWAddress &addr) { + std::transform( + addr.buffer, + addr.buffer + HWAddress::address_size - 1, + std::ostream_iterator(os, ":"), + &HWAddress::to_string + ); + return os << to_string(addr.buffer[HWAddress::address_size-1]); + } +private: + template + static void convert(const std::string &hw_addr, OutputIterator output); + + static std::string to_string(element_type element) { + std::ostringstream oss; + oss << std::hex; + if(element < 0x10) + oss << '0'; + oss << (unsigned)element; + return oss.str(); + } + + element_type buffer[n]; +}; + +template +template +void HWAddress::convert(const std::string &hw_addr, OutputIterator output) { + unsigned i(0); + element_type tmp; + while(i < hw_addr.size()) { + const unsigned end = i+2; + tmp = element_type(); + while(i < end) { + if(hw_addr[i] >= 'a' && hw_addr[i] <= 'f') + tmp = (tmp << 4) | (hw_addr[i] - 'a' + 10); + else if(hw_addr[i] >= '0' && hw_addr[i] <= '9') + tmp = (tmp << 4) | (hw_addr[i] - '0'); + else if(hw_addr[i] == ':') + break; + else + throw std::runtime_error("Invalid byte found"); + i++; + } + *(output++) = tmp; + if(i < hw_addr.size()) { + if(hw_addr[i] == ':') + i++; + else + throw std::runtime_error("Invalid separator"); + } + } +} +} +#endif // TINS_HWADDRESS_H diff --git a/tests/src/hwaddress.cpp b/tests/src/hwaddress.cpp new file mode 100644 index 0000000..4e93d42 --- /dev/null +++ b/tests/src/hwaddress.cpp @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include "hwaddress.h" + +using namespace Tins; + + +class HWAddressTest : public testing::Test { +public: + static const std::string address; + static const uint8_t *byte_address, *empty_addr; +}; + +const std::string HWAddressTest::address = "00:de:ad:be:ef:00"; +const uint8_t *HWAddressTest::byte_address = (const uint8_t*)"\x00\xde\xad\xbe\xef\x00", + *HWAddressTest::empty_addr = (const uint8_t*)"\x00\x00\x00\x00\x00\x00"; + + + +TEST_F(HWAddressTest, DefaultConstructor) { + HWAddress<6> addr; + EXPECT_TRUE(std::equal(addr.begin(), addr.end(), empty_addr)); +} + +TEST_F(HWAddressTest, ConstructorFromAddress) { + HWAddress<6> addr(address); + EXPECT_TRUE(std::equal(addr.begin(), addr.end(), byte_address)); +} + +TEST_F(HWAddressTest, OutputOperator) { + HWAddress<6> addr(address); + std::ostringstream oss; + oss << addr; + EXPECT_EQ(oss.str(), address); +}