blob: ae5200533293859697551fa34ce2fe966c3d7776 [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
Davide Pesavento51dc2ef2014-11-04 20:04:19 +010030#include <cstdio>
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
Junxiao Shi77dcadd2014-10-05 14:40:54 -070037Address::Address()
38{
Davide Pesavento51dc2ef2014-11-04 20:04:19 +010039 fill(0);
Junxiao Shi77dcadd2014-10-05 14:40:54 -070040}
41
42Address::Address(uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6)
43{
Davide Pesavento51dc2ef2014-11-04 20:04:19 +010044 data()[0] = a1;
45 data()[1] = a2;
46 data()[2] = a3;
47 data()[3] = a4;
48 data()[4] = a5;
49 data()[5] = a6;
Junxiao Shi77dcadd2014-10-05 14:40:54 -070050}
51
52Address::Address(const uint8_t octets[])
53{
54 std::copy(octets, octets + size(), begin());
55}
56
Junxiao Shi77dcadd2014-10-05 14:40:54 -070057bool
58Address::isBroadcast() const
59{
Davide Pesavento51dc2ef2014-11-04 20:04:19 +010060 return *this == getBroadcastAddress();
Junxiao Shi77dcadd2014-10-05 14:40:54 -070061}
62
63bool
64Address::isMulticast() const
65{
Davide Pesavento51dc2ef2014-11-04 20:04:19 +010066 return (at(0) & 1) != 0;
Junxiao Shi77dcadd2014-10-05 14:40:54 -070067}
68
69bool
70Address::isNull() const
71{
Davide Pesavento51dc2ef2014-11-04 20:04:19 +010072 return *this == Address();
Junxiao Shi77dcadd2014-10-05 14:40:54 -070073}
74
75std::string
76Address::toString(char sep) const
77{
78 char s[18]; // 12 digits + 5 separators + null terminator
Davide Pesavento51dc2ef2014-11-04 20:04:19 +010079
80 // apparently gcc-4.6 does not support the 'hh' type modifier
81 std::snprintf(s, sizeof(s), "%02x%c%02x%c%02x%c%02x%c%02x%c%02x",
82 at(0), sep, at(1), sep, at(2), sep, at(3), sep, at(4), sep, at(5));
83
Junxiao Shi77dcadd2014-10-05 14:40:54 -070084 return std::string(s);
85}
86
87Address
88Address::fromString(const std::string& str)
89{
Davide Pesavento51dc2ef2014-11-04 20:04:19 +010090 Address a;
91 unsigned short temp[a.size()];
Junxiao Shi77dcadd2014-10-05 14:40:54 -070092 char sep[5][2]; // 5 * (1 separator char + 1 null terminator)
93 int n = 0; // num of chars read from the input string
94
Davide Pesavento51dc2ef2014-11-04 20:04:19 +010095 // apparently gcc-4.6 does not support the 'hh' type modifier
96 int ret = std::sscanf(str.c_str(), "%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%n",
97 &temp[0], &sep[0][0], &temp[1], &sep[1][0], &temp[2], &sep[2][0],
98 &temp[3], &sep[3][0], &temp[4], &sep[4][0], &temp[5], &n);
Junxiao Shi77dcadd2014-10-05 14:40:54 -070099
100 if (ret < 11 || static_cast<size_t>(n) != str.length())
101 return Address();
102
Davide Pesavento51dc2ef2014-11-04 20:04:19 +0100103 for (size_t i = 0; i < a.size(); ++i)
Junxiao Shi77dcadd2014-10-05 14:40:54 -0700104 {
105 // check that all separators are actually the same char (: or -)
106 if (i < 5 && sep[i][0] != sep[0][0])
107 return Address();
108
109 // check that each value fits into a uint8_t
110 if (temp[i] > 0xFF)
111 return Address();
112
113 a[i] = static_cast<uint8_t>(temp[i]);
114 }
115
116 return a;
117}
118
Davide Pesavento51dc2ef2014-11-04 20:04:19 +0100119Address
120getBroadcastAddress()
121{
122 return { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
123}
124
125Address
126getDefaultMulticastAddress()
127{
128 return { 0x01, 0x00, 0x5E, 0x00, 0x17, 0xAA };
129}
130
Junxiao Shi77dcadd2014-10-05 14:40:54 -0700131std::ostream&
132operator<<(std::ostream& o, const Address& a)
133{
134 return o << a.toString();
135}
136
137} // namespace ethernet
138} // namespace util
139} // namespace ndn