]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi-2da-entrega/src/ip.cpp
Tag de 2da entrega.
[z.facultad/75.74/practicos.git] / practicas / pipi-2da-entrega / src / ip.cpp
1
2 #include "ipout.h"
3 #include "ipin.h"
4 #include "ipaddr.h"
5 #include "routetable.h"
6 #include "devtcp.h"
7 #include "devque.h"
8 #include <iostream>
9 #include <fstream>
10 #include <sstream>
11 #include <string>
12 #include <cassert>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <sys/types.h>
16 #include <sys/wait.h>
17 #include <sys/ipc.h>
18 #include <sys/msg.h>
19 #include <signal.h>
20
21 // Uso: ./ip ip [router forward routes_file port proto]
22
23 void send_loop(IPOut& ipout, unsigned proto);
24
25 void add_routes(RouteTable& rt, std::istream& is, Dev& dev);
26
27 int main(int argc, char* argv[])
28 {
29     bool router = false;
30     bool forward = false;
31     uint8_t proto = 0;
32     uint16_t port = DEVTCP_DEFAULT_PORT;
33     std::string fname = "route.txt";
34     if (argc < 2)
35     {
36         std::cerr << "Uso: " << argv[0] << " ip [router forward routes_file "
37             "port proto]\n";
38         return 1;
39     }
40     IPAddr addr(argv[1]);
41     if (argc > 2)
42         router = atoi(argv[2]);
43     if (argc > 3)
44         forward = atoi(argv[3]);
45     if (argc > 4)
46         fname = argv[4];
47     if (argc > 5)
48         port = atoi(argv[5]);
49     if (argc > 6)
50         proto = atoi(argv[6]);
51     // Creo cola para comunicar el IPIn con IPOut
52     int 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     DevTCP dev(addr, port);
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 = " << unsigned(proto)
101                 << ")\n";
102         }
103         return 0;
104     }
105     return 0;
106 }
107
108 void send_loop(IPOut& ipout, unsigned proto)
109 {
110     std::string dst;
111     std::string msg;
112     while (std::getline(std::cin, dst))
113     {
114         if (!std::getline(std::cin, msg))
115             break;
116         if (ipout.send(msg, proto, IPAddr(dst.c_str())))
117             std::cout << "Enviado '" << msg << "' a " << dst << "\n";
118         else
119             std::cout << "NO SE PUDO ENVIAR '" << msg << "' a " << dst << "\n";
120     }
121 }
122
123 void add_routes(RouteTable& rt, std::istream& is, Dev& dev)
124 {
125     std::string line;
126     while (std::getline(is, line))
127     {
128         std::istringstream iss(line);
129         std::string net;
130         std::string gw;
131         unsigned mtu;
132         unsigned metric;
133         iss >> net >> gw >> mtu >> metric;
134         if (net == "0") net = "0.0.0.0";
135         if (gw == "0") gw = "0.0.0.0";
136         rt.add(net, gw, metric, mtu, dev);
137     }
138 }
139
140 // vim: set et sw=4 sts=4 :