]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/ip.cpp
5a538cedd10233eb8f2a30ff2303a170bf5baea2
[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 "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 int main(int argc, char* argv[])
26 {
27     bool router = false;
28     bool forward = false;
29     uint8_t proto = 0;
30     uint16_t port = DEVTCP_DEFAULT_PORT;
31     std::string fname = "route.txt";
32     if (argc < 2)
33     {
34         std::cerr << "Uso: " << argv[0] << " ip [router forward routes_file "
35             "port proto]\n";
36         return 1;
37     }
38     IPAddr addr(argv[1]);
39     if (argc > 2)
40         router = atoi(argv[2]);
41     if (argc > 3)
42         forward = atoi(argv[3]);
43     if (argc > 4)
44         fname = argv[4];
45     if (argc > 5)
46         port = atoi(argv[5]);
47     if (argc > 6)
48         proto = atoi(argv[6]);
49     // Creo cola para comunicar el IPIn con IPOut
50     int que_id = msgget(DEVQUE_DEFAULT_KEY-1, IPC_CREAT | 0666); assert(que_id != -1);
51     // Abro archivo con rutas
52     std::ifstream ifs(fname.c_str()); assert(ifs);
53     // Creo medio físico y cola para forwarding
54     DevTCP dev(addr, port);
55     DevQue fwque(addr, DEVQUE_DEFAULT_KEY-1);
56     // Creo procesos
57     pid_t pid_send = fork();
58     if (pid_send == -1)
59     {
60         perror("fork() send");
61         return 2;
62     }
63     if (pid_send) // IPOut
64     {
65         RouteTable table(dev);
66         add_routes(table, ifs, dev);
67         IPOut ipout(addr, table, fwque, std::cerr);
68         pid_t pid_fw = fork();
69         if (pid_fw == -1)
70         {
71             perror("fork() forward");
72             return 3;
73         }
74         if (pid_fw) // Padre (IPOut send)
75         {
76             int ret;
77             send_loop(ipout, proto);
78             kill(pid_send, SIGTERM);
79             waitpid(pid_send, &ret, 0);
80             kill(pid_fw, SIGTERM);
81             waitpid(pid_fw, &ret, 0);
82             return 0;
83         }
84         else // Hijo 1 (IPOut forward)
85         {
86             ipout.forward_loop();
87             return 0;
88         }
89     }
90     else // Hijo 2 (IPIn)
91     {
92         IPIn ipin(addr, dev, fwque, router, forward, std::cerr);
93         while (true)
94         {
95             IPAddr src, dst;
96             std::string s = ipin.recv(proto, src, dst);
97             std::cout << "Recibido '" << s << "' (len " << s.size() << ") de "
98                 << src << " para " << dst << " (proto = " << unsigned(proto)
99                 << ")\n";
100         }
101         return 0;
102     }
103     return 0;
104 }
105
106 void send_loop(IPOut& ipout, unsigned proto)
107 {
108     std::string dst;
109     std::string msg;
110     while (std::getline(std::cin, dst))
111     {
112         if (!std::getline(std::cin, msg))
113             break;
114         if (ipout.send(msg, proto, IPAddr(dst.c_str())))
115             std::cout << "Enviado '" << msg << "' a " << dst << "\n";
116         else
117             std::cout << "NO SE PUDO ENVIAR '" << msg << "' a " << dst << "\n";
118     }
119 }
120
121 // vim: set et sw=4 sts=4 :