blob: d23a5dadd8004cb544f750ba1c9e561a71577a88 [file] [log] [blame]
Junxiao Shi77dcadd2014-10-05 14:40:54 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2014 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "ethernet.hpp"
23
24#include <stdio.h>
25
26namespace ndn {
27namespace util {
28namespace ethernet {
29
30Address
31getBroadcastAddress()
32{
33 static Address bcast(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
34 return bcast;
35}
36
37Address
38getDefaultMulticastAddress()
39{
40 static Address mcast(0x01, 0x00, 0x5E, 0x00, 0x17, 0xAA);
41 return mcast;
42}
43
44Address::Address()
45{
46 assign(0);
47}
48
49Address::Address(uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6)
50{
51 elems[0] = a1;
52 elems[1] = a2;
53 elems[2] = a3;
54 elems[3] = a4;
55 elems[4] = a5;
56 elems[5] = a6;
57}
58
59Address::Address(const uint8_t octets[])
60{
61 std::copy(octets, octets + size(), begin());
62}
63
64Address::Address(const Address& address)
65{
66 std::copy(address.begin(), address.end(), begin());
67}
68
69bool
70Address::isBroadcast() const
71{
72 return elems[0] == 0xFF && elems[1] == 0xFF && elems[2] == 0xFF &&
73 elems[3] == 0xFF && elems[4] == 0xFF && elems[5] == 0xFF;
74}
75
76bool
77Address::isMulticast() const
78{
79 return (elems[0] & 1) != 0;
80}
81
82bool
83Address::isNull() const
84{
85 return elems[0] == 0x0 && elems[1] == 0x0 && elems[2] == 0x0 &&
86 elems[3] == 0x0 && elems[4] == 0x0 && elems[5] == 0x0;
87}
88
89std::string
90Address::toString(char sep) const
91{
92 char s[18]; // 12 digits + 5 separators + null terminator
93 ::snprintf(s, sizeof(s), "%02x%c%02x%c%02x%c%02x%c%02x%c%02x",
94 elems[0], sep, elems[1], sep, elems[2], sep,
95 elems[3], sep, elems[4], sep, elems[5]);
96 return std::string(s);
97}
98
99Address
100Address::fromString(const std::string& str)
101{
102 unsigned short temp[ADDR_LEN];
103 char sep[5][2]; // 5 * (1 separator char + 1 null terminator)
104 int n = 0; // num of chars read from the input string
105
106 // ISO C++98 does not support the 'hh' type modifier
107 /// \todo use SCNx8 (cinttypes) when we enable C++11
108 int ret = ::sscanf(str.c_str(), "%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%n",
109 &temp[0], &sep[0][0], &temp[1], &sep[1][0], &temp[2], &sep[2][0],
110 &temp[3], &sep[3][0], &temp[4], &sep[4][0], &temp[5], &n);
111
112 if (ret < 11 || static_cast<size_t>(n) != str.length())
113 return Address();
114
115 Address a;
116 for (size_t i = 0; i < ADDR_LEN; ++i)
117 {
118 // check that all separators are actually the same char (: or -)
119 if (i < 5 && sep[i][0] != sep[0][0])
120 return Address();
121
122 // check that each value fits into a uint8_t
123 if (temp[i] > 0xFF)
124 return Address();
125
126 a[i] = static_cast<uint8_t>(temp[i]);
127 }
128
129 return a;
130}
131
132std::ostream&
133operator<<(std::ostream& o, const Address& a)
134{
135 return o << a.toString();
136}
137
138} // namespace ethernet
139} // namespace util
140} // namespace ndn