blob: d2d3cfef1f4f49c38267ad05cf21932ad52470fc [file] [log] [blame]
Alexander Afanasyev82afa1a2014-03-20 16:56:56 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#ifndef NFD_TOOLS_NETWORK_HPP
8#define NFD_TOOLS_NETWORK_HPP
9
10#include <boost/asio.hpp>
11
12class Network
13{
14public:
15 Network()
16 {
17 }
18
19 Network(const boost::asio::ip::address& minAddress,
20 const boost::asio::ip::address& maxAddress)
21 : m_minAddress(minAddress)
22 , m_maxAddress(maxAddress)
23 {
24 }
25
26 void
27 print(std::ostream& os) const
28 {
29 os << m_minAddress << " <-> " << m_maxAddress;
30 }
31
32 bool
33 doesContain(const boost::asio::ip::address& address) const
34 {
35 return (m_minAddress <= address && address <= m_maxAddress);
36 }
37
38 static const Network&
39 getMaxRangeV4()
40 {
41 using boost::asio::ip::address_v4;
42 static Network range = Network(address_v4(0), address_v4(0xFFFFFFFF));
43 return range;
44 }
45
46 static const Network&
47 getMaxRangeV6()
48 {
49 using boost::asio::ip::address_v6;
50 static address_v6::bytes_type maxV6 = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
51 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
52 static Network range = Network(address_v6(), address_v6(maxV6));
53 return range;
54 }
55
56private:
57 boost::asio::ip::address m_minAddress;
58 boost::asio::ip::address m_maxAddress;
59
60 friend std::istream&
61 operator>>(std::istream& is, Network& network);
62
63 friend std::ostream&
64 operator<<(std::ostream& os, const Network& network);
65};
66
67inline std::ostream&
68operator<<(std::ostream& os, const Network& network)
69{
70 network.print(os);
71 return os;
72}
73
74inline std::istream&
75operator>>(std::istream& is, Network& network)
76{
77 using namespace boost::asio;
78
79 std::string networkStr;
80 is >> networkStr;
81
82 size_t position = networkStr.find('/');
83 if (position == std::string::npos)
84 {
85 network.m_minAddress = ip::address::from_string(networkStr);
86 network.m_maxAddress = ip::address::from_string(networkStr);
87 }
88 else
89 {
90 ip::address address = ip::address::from_string(networkStr.substr(0, position));
91 size_t mask = boost::lexical_cast<size_t>(networkStr.substr(position+1));
92
93 if (address.is_v4())
94 {
95 ip::address_v4::bytes_type maskBytes = {};
96 for (size_t i = 0; i < mask; i++)
97 {
98 size_t byteId = i / 8;
99 size_t bitIndex = 7 - i % 8;
100 maskBytes[byteId] |= (1 << bitIndex);
101 }
102
103 ip::address_v4::bytes_type addressBytes = address.to_v4().to_bytes();
104 ip::address_v4::bytes_type min;
105 ip::address_v4::bytes_type max;
106
107 for (size_t i = 0; i < addressBytes.size(); i++)
108 {
109 min[i] = addressBytes[i] & maskBytes[i];
110 max[i] = addressBytes[i] | ~(maskBytes[i]);
111 }
112
113 network.m_minAddress = ip::address_v4(min);
114 network.m_maxAddress = ip::address_v4(max);
115 }
116 else
117 {
118 ip::address_v6::bytes_type maskBytes = {};
119 for (size_t i = 0; i < mask; i++)
120 {
121 size_t byteId = i / 8;
122 size_t bitIndex = 7 - i % 8;
123 maskBytes[byteId] |= (1 << bitIndex);
124 }
125
126 ip::address_v6::bytes_type addressBytes = address.to_v6().to_bytes();
127 ip::address_v6::bytes_type min;
128 ip::address_v6::bytes_type max;
129
130 for (size_t i = 0; i < addressBytes.size(); i++)
131 {
132 min[i] = addressBytes[i] & maskBytes[i];
133 max[i] = addressBytes[i] | ~(maskBytes[i]);
134 }
135
136 network.m_minAddress = ip::address_v6(min);
137 network.m_maxAddress = ip::address_v6(max);
138 }
139 }
140 return is;
141}
142
143#endif // NFD_TOOLS_NETWORK_HPP