--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/utils.cc Tue Aug 29 17:42:13 2006 +0200
@@ -0,0 +1,293 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "utils.h"
+
+namespace yans {
+
+uint16_t
+utils_hton_16 (uint16_t v)
+{
+ uint8_t array[2];
+ array[0] = (v >> 8) & 0xff;
+ array[1] = (v >> 0) & 0xff;
+ return *((uint16_t *)array);
+}
+uint32_t
+utils_hton_32 (uint32_t v)
+{
+ uint8_t array[4];
+ array[0] = (v >> 24) & 0xff;
+ array[1] = (v >> 16) & 0xff;
+ array[2] = (v >> 8) & 0xff;
+ array[3] = (v >> 0) & 0xff;
+ return *((uint32_t *)array);
+}
+uint16_t
+utils_ntoh_16 (uint16_t v)
+{
+ uint16_t val;
+ uint8_t *array;
+ array = (uint8_t *)&v;
+ val = (array[0] << 8) | (array[1] << 0);
+ return val;
+}
+uint32_t
+utils_ntoh_32 (uint32_t v)
+{
+ uint32_t val = 0;
+ uint8_t *array = (uint8_t *)&v;
+ val |= array[0] << 24;
+ val |= array[1] << 16;
+ val |= array[2] << 8;
+ val |= array[3] << 0;
+ return val;
+}
+
+#define ASCII_DOT (0x2e)
+#define ASCII_ZERO (0x30)
+#define ASCII_A (0x41)
+#define ASCII_Z (0x5a)
+#define ASCII_a (0x61)
+#define ASCII_z (0x7a)
+#define ASCII_COLON (0x3a)
+
+
+uint32_t
+ascii_to_ipv4_host (char const *address)
+{
+ uint32_t host = 0;
+ while (true) {
+ uint8_t byte = 0;
+ while (*address != ASCII_DOT &&
+ *address != 0) {
+ byte *= 10;
+ byte += *address - ASCII_ZERO;
+ address++;
+ }
+ host <<= 8;
+ host |= byte;
+ if (*address == 0) {
+ break;
+ }
+ address++;
+ }
+ return host;
+}
+
+
+char
+ascii_to_low_case (char c)
+{
+ if (c >= ASCII_a && c <= ASCII_z) {
+ return c;
+ } else if (c >= ASCII_A && c <= ASCII_Z) {
+ return c + (ASCII_a - ASCII_A);
+ } else {
+ return c;
+ }
+}
+void
+ascii_to_mac_network (char const *str, uint8_t address[6])
+{
+ uint8_t i = 0;
+ while (*str != 0 && i < 6) {
+ uint8_t byte = 0;
+ while (*str != ASCII_COLON && *str != 0) {
+ byte <<= 4;
+ char low = ascii_to_low_case (*str);
+ if (low >= ASCII_a) {
+ byte |= low - ASCII_a + 10;
+ } else {
+ byte |= low - ASCII_ZERO;
+ }
+ str++;
+ }
+ address[i] = byte;
+ str++;
+ i++;
+ }
+}
+
+uint16_t
+utils_checksum_calculate (uint16_t checksum, uint8_t *buffer, uint16_t size)
+{
+ /* see RFC 1071 to understand this code. */
+ uint32_t sum = checksum;
+ uint16_t *data = (uint16_t *) buffer;
+ for (uint16_t i = 0; i < (size/2); i++) {
+ sum += data[i];
+ }
+ if ((size % 2) != 0) {
+ uint8_t tmp_buf[2];
+ tmp_buf[0] = buffer[size-1];
+ tmp_buf[1] = 0;
+ data = (uint16_t *)tmp_buf;
+ sum += *data;
+ }
+ while (sum >> 16) {
+ sum = (sum & 0xffff) + (sum >> 16);
+ }
+ return sum;
+}
+
+uint16_t
+utils_checksum_complete (uint16_t checksum)
+{
+ return ~checksum;
+}
+
+
+}; // namespace yans
+
+
+#ifdef RUN_SELF_TESTS
+#include "yans/test.h"
+namespace yans {
+
+class UtilsTest : public Test {
+public:
+ UtilsTest ();
+ virtual bool run_tests (void);
+private:
+ bool test_ipv4_ascii_to_host (char const *str, uint32_t expected);
+ bool test_mac_ascii (char const *str, uint8_t expected[6]);
+ bool test_hton_16 (uint16_t v, uint8_t expected[2]);
+};
+bool
+UtilsTest::test_ipv4_ascii_to_host (char const *str, uint32_t expected)
+{
+ if (ascii_to_ipv4_host (str) != expected) {
+ failure () << "Utils ascii to host --"
+ << " for: \"" << str << "\""
+ << " expected: " << expected
+ << " got: " << ascii_to_ipv4_host (str)
+ << std::endl;
+ return false;
+ }
+ return true;
+}
+
+bool
+UtilsTest::test_mac_ascii (char const *str, uint8_t expected[6])
+{
+ uint8_t got[6];
+ ascii_to_mac_network (str, got);
+ for (uint8_t i = 0; i < 6; i++) {
+ if (got[i] != expected[i]) {
+ failure () << "Utils ascii to mac --"
+ << " for: \"" << str << "\""
+ << " expected: ";
+ failure ().setf (std::ios::hex, std::ios::basefield);
+ failure () << (uint32_t)expected[0] << ":"
+ << (uint32_t)expected[1] << ":"
+ << (uint32_t)expected[2] << ":"
+ << (uint32_t)expected[3] << ":"
+ << (uint32_t)expected[4] << ":"
+ << (uint32_t)expected[5];
+ failure ().setf (std::ios::dec, std::ios::basefield);
+ failure () << " got: ";
+ failure ().setf (std::ios::hex, std::ios::basefield);
+ failure () << (uint32_t)got[0] << ":"
+ << (uint32_t)got[1] << ":"
+ << (uint32_t)got[2] << ":"
+ << (uint32_t)got[3] << ":"
+ << (uint32_t)got[4] << ":"
+ << (uint32_t)got[5];
+ failure ().setf (std::ios::dec, std::ios::basefield);
+ failure () << std::endl;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+UtilsTest::test_hton_16 (uint16_t v, uint8_t expected[2])
+{
+ uint16_t result = utils_hton_16 (v);
+ uint8_t *got = (uint8_t *)&result;
+ if (got[0] != expected[0] ||
+ got[1] != expected[1]) {
+ failure () << "Utils hton 16 --"
+ << " for: \"" << v << "\""
+ << " expected: ";
+ failure ().setf (std::ios::hex, std::ios::basefield);
+ failure () << (uint32_t)expected[0] << ":"
+ << (uint32_t)expected[1];
+ failure () << " got: ";
+ failure () << (uint32_t)got[0] << ":"
+ << (uint32_t)got[1];
+ failure ().setf (std::ios::dec, std::ios::basefield);
+ failure () << std::endl;
+ return false;
+ }
+ return true;
+}
+
+#define TEST_IPV4_ASCII_TO_HOST(a,b) \
+if (!test_ipv4_ascii_to_host (a,b)) { \
+ ok = false; \
+}
+
+#define TEST_MAC_ASCII(ad, a, b, c, d, e, f) \
+{ \
+ uint8_t expected[6] = {a, b, c, d, e, f}; \
+ if (!test_mac_ascii (ad, expected)) { \
+ ok = false; \
+ } \
+}
+
+#define TEST_HTON_16(v, a, b) \
+{ \
+ uint8_t expected[2] = {a, b}; \
+ if (!test_hton_16 (v, expected)) { \
+ ok = false; \
+ } \
+}
+
+
+UtilsTest::UtilsTest ()
+ : Test ("Utils") {}
+
+bool
+UtilsTest::run_tests (void)
+{
+ bool ok = true;
+ TEST_IPV4_ASCII_TO_HOST ("255.255.255.255", 0xffffffff);
+ TEST_IPV4_ASCII_TO_HOST ("255.255.255.0", 0xffffff00);
+ TEST_IPV4_ASCII_TO_HOST ("255.255.255.00", 0xffffff00);
+ TEST_IPV4_ASCII_TO_HOST ("255.255.255.000", 0xffffff00);
+ TEST_IPV4_ASCII_TO_HOST ("255.255.255.0000", 0xffffff00);
+ TEST_IPV4_ASCII_TO_HOST ("255.255.0.255", 0xffff00ff);
+ TEST_IPV4_ASCII_TO_HOST ("192.168.0.1", 0xc0a80001);
+ TEST_IPV4_ASCII_TO_HOST ("0.168.0.1", 0x00a80001);
+ TEST_MAC_ASCII ("00:00:00:00:00:00", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ TEST_MAC_ASCII ("00:00:00:00:00:01", 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);
+ TEST_MAC_ASCII ("01:00:00:00:00:01", 0x01, 0x00, 0x00, 0x00, 0x00, 0x01);
+ TEST_MAC_ASCII ("ff:00:00:ff:00:01", 0xff, 0x00, 0x00, 0xff, 0x00, 0x01);
+ TEST_MAC_ASCII ("f0:00:00:00:5d:01", 0xf0, 0x00, 0x00, 0x00, 0x5d, 0x01);
+ TEST_HTON_16 (0xf00f, 0xf0, 0x0f);
+ return ok;
+}
+static UtilsTest g_utils_test;
+}; //namespace yans
+#endif /* RUN_SELF_TESTS */