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