]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/ip.cpp
db99e1aec0b57e41f6871cee74e16e8567d93ab1
[z.facultad/75.74/practicos.git] / practicas / pipi / src / ip.cpp
1
2 #include "ipout.h"
3 #include "ipin.h"
4 #include "ipaddr.h"
5 #include "routetable.h"
6 #include "devque.h"
7 #include <iostream>
8 #include <fstream>
9 #include <sstream>
10 #include <string>
11 #include <cassert>
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <sys/types.h>
15 #include <sys/wait.h>
16 #include <sys/ipc.h>
17 #include <sys/msg.h>
18 #include <signal.h>
19
20 // Uso: ./test_ipout ip [router forward routes_file queue_id proto]
21
22 void send_loop(IPOut& ipout, unsigned proto);
23
24 void add_routes(RouteTable& rt, std::istream& is, Dev& dev);
25
26 int main(int argc, char* argv[])
27 {
28     bool router = false;
29     bool forward = false;
30     unsigned proto = 0;
31     key_t queue_id = DEVQUE_DEFAULT_KEY;
32     std::string fname = "route.txt";
33     if (argc < 2)
34     {
35         std::cerr << "Uso: ./test_ipout ip [router forward routes_file "
36             "queue_id proto]\n";
37         return 1;
38     }
39     IPAddr addr(argv[1]);
40     if (argc > 2)
41         router = atoi(argv[2]);
42     if (argc > 3)
43         forward = atoi(argv[3]);
44     if (argc > 4)
45         fname = argv[4];
46     if (argc > 5)
47         queue_id = atoi(argv[5]);
48     if (argc > 6)
49         proto = atoi(argv[6]);
50     // Creo colas
51     int que_id = msgget(queue_id, IPC_CREAT | 0666); assert(que_id != -1);
52     que_id = msgget(DEVQUE_DEFAULT_KEY-1, IPC_CREAT | 0666); assert(que_id != -1);
53     // Abro archivo con rutas
54     std::ifstream ifs(fname.c_str()); assert(ifs);
55     // Creo medio físico y cola para forwarding
56     DevQue dev(addr, queue_id);
57     DevQue fwque(addr, DEVQUE_DEFAULT_KEY-1);
58     // Creo procesos
59     pid_t pid_send = fork();
60     if (pid_send == -1)
61     {
62         perror("fork() send");
63         return 2;
64     }
65     if (pid_send) // IPOut
66     {
67         RouteTable table(dev);
68         add_routes(table, ifs, dev);
69         IPOut ipout(addr, table, fwque, std::cerr);
70         pid_t pid_fw = fork();
71         if (pid_fw == -1)
72         {
73             perror("fork() forward");
74             return 3;
75         }
76         if (pid_fw) // Padre (IPOut send)
77         {
78             int ret;
79             send_loop(ipout, proto);
80             kill(pid_send, SIGTERM);
81             waitpid(pid_send, &ret, 0);
82             kill(pid_fw, SIGTERM);
83             waitpid(pid_fw, &ret, 0);
84             return 0;
85         }
86         else // Hijo 1 (IPOut forward)
87         {
88             ipout.forward_loop();
89             return 0;
90         }
91     }
92     else // Hijo 2 (IPIn)
93     {
94         IPIn ipin(addr, dev, fwque, router, forward, std::cerr);
95         while (true)
96         {
97             IPAddr src, dst;
98             std::string s = ipin.recv(proto, src, dst);
99             std::cout << "Recibido '" << s << "' (len " << s.size() << ") de "
100                 << src << " para " << dst << " (proto = " << proto << ")\n";
101         }
102         return 0;
103     }
104     return 0;
105 }
106
107 void send_loop(IPOut& ipout, unsigned proto)
108 {
109     std::string dst;
110     std::string msg;
111     while (std::getline(std::cin, dst))
112     {
113         if (!std::getline(std::cin, msg))
114             break;
115         if (ipout.send(msg, proto, IPAddr(dst.c_str())))
116             std::cout << "Enviado '" << msg << "' a " << dst << "\n";
117         else
118             std::cout << "NO SE PUDO ENVIAR '" << msg << "' a " << dst << "\n";
119     }
120 }
121
122 void add_routes(RouteTable& rt, std::istream& is, Dev& dev)
123 {
124     std::string line;
125     while (std::getline(is, line))
126     {
127         std::istringstream iss(line);
128         std::string net;
129         std::string gw;
130         unsigned mtu;
131         unsigned metric;
132         iss >> net >> gw >> mtu >> metric;
133         if (net == "0") net = "0.0.0.0";
134         if (gw == "0") gw = "0.0.0.0";
135         rt.add(net.c_str(), gw.c_str(), metric, mtu, dev);
136     }
137 }
138
139 // vim: set et sw=4 sts=4 :