7 #include <unordered_map>
15 for (
auto &
byte : addr) {
26 for (
auto &
byte : addr) {
39 void clear(T &queue1, T &queue2) {
40 while (not queue1.empty()) {
62 ret +=
" " + arp.to_string();
82 for (
const auto &x : _expecting_to_receive) {
91 for (
auto it = _expecting_to_receive.begin(); it != _expecting_to_receive.end(); ++it) {
93 _expecting_to_receive.erase(it);
102 , _my_address(my_address)
104 , _next_hop(next_hop) {}
116 cerr <<
"Host " << _name <<
" trying to send datagram (with next hop = " << _next_hop.
ip()
128 const string &
name() {
return _name; }
132 const auto &dgram_received = _interface.
datagrams_out().front();
133 if (not expecting(dgram_received)) {
135 " received unexpected Internet datagram: " + dgram_received.header().summary() +
136 " payload=\"" + dgram_received.payload().concatenate() +
"\"");
138 remove_expectation(dgram_received);
142 if (not _expecting_to_receive.empty()) {
143 auto &expected = _expecting_to_receive.front();
144 throw runtime_error(
"Host " + _name +
" did NOT receive an expected Internet datagram: " +
145 expected.header().summary() +
" payload=\"" + expected.payload().concatenate() +
"\"");
154 size_t default_id, eth0_id, eth1_id, eth2_id,
uun3_id, hs4_id, mit5_id;
160 const string &y_name,
164 deliver(x_name, x_frames, y_name, y);
165 deliver(y_name, y_frames, x_name, x);
173 const string &y_name,
175 const string &z_name,
179 deliver(x_name, x_frames, y_name, y);
180 deliver(x_name, x_frames, z_name, z);
182 deliver(y_name, y_frames, x_name, x);
183 deliver(y_name, y_frames, z_name, z);
185 deliver(z_name, z_frames, x_name, x);
186 deliver(z_name, z_frames, y_name, y);
195 const string &dst_name,
198 while (not to_send.
empty()) {
199 to_send.
front().payload() = to_send.
front().payload().concatenate();
200 cerr <<
"Transferring frame from " << src_name <<
" to " << dst_name <<
": " <<
summary(to_send.
front())
210 , eth0_id(_router.add_interface({random_router_ethernet_address(), {
"10.0.0.1"}}))
211 , eth1_id(_router.add_interface({random_router_ethernet_address(), {
"172.16.0.1"}}))
212 , eth2_id(_router.add_interface({random_router_ethernet_address(), {
"192.168.0.1"}}))
213 , uun3_id(_router.add_interface({random_router_ethernet_address(), {
"198.178.229.1"}}))
214 , hs4_id(_router.add_interface({random_router_ethernet_address(), {
"143.195.0.2"}}))
215 , mit5_id(_router.add_interface({random_router_ethernet_address(), {
"128.30.76.255"}})) {
216 _hosts.insert({
"applesauce", {
"applesauce", {
"10.0.0.2"}, {
"10.0.0.1"}}});
217 _hosts.insert({
"default_router", {
"default_router", {
"171.67.76.1"}, {
"0"}}});
219 _hosts.insert({
"cherrypie", {
"cherrypie", {
"192.168.0.2"}, {
"192.168.0.1"}}});
220 _hosts.insert({
"hs_router", {
"hs_router", {
"143.195.0.1"}, {
"0"}}});
221 _hosts.insert({
"dm42", {
"dm42", {
"198.178.229.42"}, {
"198.178.229.1"}}});
222 _hosts.insert({
"dm43", {
"dm43", {
"198.178.229.43"}, {
"198.178.229.1"}}});
224 _router.add_route(
ip(
"0.0.0.0"), 0, host(
"default_router").address(), default_id);
225 _router.add_route(
ip(
"10.0.0.0"), 8, {}, eth0_id);
226 _router.add_route(
ip(
"172.16.0.0"), 16, {}, eth1_id);
227 _router.add_route(
ip(
"192.168.0.0"), 24, {}, eth2_id);
228 _router.add_route(
ip(
"198.178.229.0"), 24, {}, uun3_id);
229 _router.add_route(
ip(
"143.195.0.0"), 17, host(
"hs_router").address(), hs4_id);
230 _router.add_route(
ip(
"143.195.128.0"), 18, host(
"hs_router").address(), hs4_id);
231 _router.add_route(
ip(
"143.195.192.0"), 19, host(
"hs_router").address(), hs4_id);
232 _router.add_route(
ip(
"128.30.76.255"), 16,
Address{
"128.30.0.1"}, mit5_id);
237 "router.default", _router.interface(default_id),
"default_router", host(
"default_router").interface());
238 exchange_frames(
"router.eth0", _router.interface(eth0_id),
"applesauce", host(
"applesauce").interface());
239 exchange_frames(
"router.eth2", _router.interface(eth2_id),
"cherrypie", host(
"cherrypie").interface());
240 exchange_frames(
"router.hs4", _router.interface(hs4_id),
"hs_router", host(
"hs_router").interface());
241 exchange_frames(
"router.uun3",
242 _router.interface(uun3_id),
244 host(
"dm42").interface(),
246 host(
"dm43").interface());
250 for (
unsigned int i = 0; i < 256; i++) {
252 simulate_physical_connections();
255 for (
auto &host : _hosts) {
261 auto it = _hosts.find(name);
262 if (it == _hosts.end()) {
265 if (it->second.name() != name) {
273 const string green =
"\033[32;1m", normal =
"\033[m";
275 cerr << green <<
"Constructing network." << normal <<
"\n";
279 cout << green <<
"\n\nTesting traffic between two ordinary hosts (applesauce to cherrypie)..." << normal <<
"\n\n";
287 cout << green <<
"\n\nTesting traffic between two ordinary hosts (cherrypie to applesauce)..." << normal <<
"\n\n";
291 network.
host(
"applesauce").
expect(dgram_sent);
295 cout << green <<
"\n\nSuccess! Testing applesauce sending to the Internet." << normal <<
"\n\n";
297 auto dgram_sent = network.
host(
"applesauce").
send_to({
"1.2.3.4"});
299 network.
host(
"default_router").
expect(dgram_sent);
303 cout << green <<
"\n\nSuccess! Testing sending to the HS network and Internet." << normal <<
"\n\n";
305 auto dgram_sent = network.
host(
"applesauce").
send_to({
"143.195.131.17"});
310 dgram_sent = network.
host(
"cherrypie").
send_to({
"143.195.193.52"});
315 dgram_sent = network.
host(
"cherrypie").
send_to({
"143.195.223.255"});
320 dgram_sent = network.
host(
"cherrypie").
send_to({
"143.195.224.0"});
322 network.
host(
"default_router").
expect(dgram_sent);
326 cout << green <<
"\n\nSuccess! Testing two hosts on the same network (dm42 to dm43)..." << normal <<
"\n\n";
334 cout << green <<
"\n\nSuccess! Testing TTL expiration..." << normal <<
"\n\n";
336 auto dgram_sent = network.
host(
"applesauce").
send_to({
"1.2.3.4"}, 1);
339 dgram_sent = network.
host(
"applesauce").
send_to({
"1.2.3.4"}, 0);
343 cout <<
"\n\n\033[32;1mCongratulations! All datagrams were routed successfully.\033[m\n";
351 cerr <<
"\033[31;1mError: " << e.
what() <<
"\033[m\n";