blob: 465e2469950f44f4c5d3b1bc58eb9a6f20be4c2b [file] [log] [blame]
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
susmit91e1d7c2016-10-03 16:16:57 -06003 * Copyright (c) 2014-2016, 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
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 **/
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -070025
Alexander Afanasyev689f0e92014-11-09 12:09:00 -080026#include "network.hpp"
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -070027
Alexander Afanasyev689f0e92014-11-09 12:09:00 -080028namespace nfd {
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -070029
Alexander Afanasyev689f0e92014-11-09 12:09:00 -080030void
31Network::print(std::ostream& os) const
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -070032{
Alexander Afanasyev689f0e92014-11-09 12:09:00 -080033 os << m_minAddress << " <-> " << m_maxAddress;
34}
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -070035
Alexander Afanasyev689f0e92014-11-09 12:09:00 -080036const Network&
37Network::getMaxRangeV4()
38{
39 using boost::asio::ip::address_v4;
40 static Network range = Network(address_v4(0), address_v4(0xFFFFFFFF));
41 return range;
42}
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -070043
Alexander Afanasyev689f0e92014-11-09 12:09:00 -080044const Network&
45Network::getMaxRangeV6()
46{
47 using boost::asio::ip::address_v6;
48 static address_v6::bytes_type maxV6 = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
49 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
50 static Network range = Network(address_v6(), address_v6(maxV6));
51 return range;
52}
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -070053
susmit91e1d7c2016-10-03 16:16:57 -060054bool
55Network::isValidCidr(const std::string& cidr)
56{
57 std::vector<std::string> splitCidr;
58 boost::split(splitCidr, cidr, boost::is_any_of("/"));
59 if (splitCidr.size() != 2) {
60 return false;
61 }
62
63 auto network = splitCidr[0];
64 auto mask = splitCidr[1];
65 auto netmask = 0;
66 if (mask.length() <= 0) {
67 return false;
68 }
69 if (!std::all_of(mask.begin(), mask.end(), ::isdigit)) {
70 return false;
71 }
72
73 netmask = boost::lexical_cast<int>(splitCidr[1]);
74 boost::system::error_code invalidIP;
75 boost::asio::ip::address_v4::from_string(network, invalidIP);
76 if (invalidIP || netmask < 0 || netmask > 32) {
77 return false;
78 }
79 return true;
80}
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -070081
Alexander Afanasyev689f0e92014-11-09 12:09:00 -080082std::ostream&
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -070083operator<<(std::ostream& os, const Network& network)
84{
85 network.print(os);
86 return os;
87}
88
Alexander Afanasyev689f0e92014-11-09 12:09:00 -080089std::istream&
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -070090operator>>(std::istream& is, Network& network)
91{
92 using namespace boost::asio;
93
94 std::string networkStr;
95 is >> networkStr;
96
97 size_t position = networkStr.find('/');
98 if (position == std::string::npos)
99 {
100 network.m_minAddress = ip::address::from_string(networkStr);
101 network.m_maxAddress = ip::address::from_string(networkStr);
102 }
103 else
104 {
105 ip::address address = ip::address::from_string(networkStr.substr(0, position));
106 size_t mask = boost::lexical_cast<size_t>(networkStr.substr(position+1));
107
108 if (address.is_v4())
109 {
Alexander Afanasyevf4e89b42014-05-31 15:54:18 +0300110 ip::address_v4::bytes_type maskBytes = boost::initialized_value;
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -0700111 for (size_t i = 0; i < mask; i++)
112 {
113 size_t byteId = i / 8;
114 size_t bitIndex = 7 - i % 8;
115 maskBytes[byteId] |= (1 << bitIndex);
116 }
117
118 ip::address_v4::bytes_type addressBytes = address.to_v4().to_bytes();
119 ip::address_v4::bytes_type min;
120 ip::address_v4::bytes_type max;
121
122 for (size_t i = 0; i < addressBytes.size(); i++)
123 {
124 min[i] = addressBytes[i] & maskBytes[i];
125 max[i] = addressBytes[i] | ~(maskBytes[i]);
126 }
127
128 network.m_minAddress = ip::address_v4(min);
129 network.m_maxAddress = ip::address_v4(max);
130 }
131 else
132 {
Alexander Afanasyevf4e89b42014-05-31 15:54:18 +0300133 ip::address_v6::bytes_type maskBytes = boost::initialized_value;
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -0700134 for (size_t i = 0; i < mask; i++)
135 {
136 size_t byteId = i / 8;
137 size_t bitIndex = 7 - i % 8;
138 maskBytes[byteId] |= (1 << bitIndex);
139 }
140
141 ip::address_v6::bytes_type addressBytes = address.to_v6().to_bytes();
142 ip::address_v6::bytes_type min;
143 ip::address_v6::bytes_type max;
144
145 for (size_t i = 0; i < addressBytes.size(); i++)
146 {
147 min[i] = addressBytes[i] & maskBytes[i];
148 max[i] = addressBytes[i] | ~(maskBytes[i]);
149 }
150
151 network.m_minAddress = ip::address_v6(min);
152 network.m_maxAddress = ip::address_v6(max);
153 }
154 }
155 return is;
156}
157
Alexander Afanasyev689f0e92014-11-09 12:09:00 -0800158} // namespace nfd