]> git.llucax.com Git - z.facultad/66.09/etherled.git/blob - pruebas/c/net/main.c
Bugfix en el cálculo de checksum.
[z.facultad/66.09/etherled.git] / pruebas / c / net / main.c
1 #include "net.h"
2 #include "eth.h"
3 #include "ip.h"
4 #include "udp.h"
5 #include <stdio.h>
6 #include <string.h>
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <netpacket/packet.h>
10 #include <net/ethernet.h>
11 #include <sys/ioctl.h>
12 #include <net/if.h>
13 #include <netinet/in.h>
14 #include <unistd.h>
15
16 int main()
17 {
18         int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
19         int opt = 1;
20         struct sockaddr_ll sll;
21         socklen_t sll_len = sizeof(sll);
22         struct ifreq ifr;
23         //struct sockaddr_in sin;
24         if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)))
25         {
26                 perror("setsockopt()");
27                 return 3;
28         }
29         memset(&ifr, 0, sizeof(ifr));
30         strncpy(ifr.ifr_name, "eth0", sizeof(ifr));
31         if (ioctl(s, SIOCGIFINDEX, &ifr) == -1)
32         {
33                 perror("ioctl()");
34                 return 1;
35         }
36         memset(&sll, 0, sizeof(struct sockaddr_ll));
37         sll.sll_family = AF_PACKET;
38         sll.sll_halen = 6;
39         sll.sll_ifindex = ifr.ifr_ifindex;
40         sll.sll_pkttype = PACKET_HOST; // nada de recibir broadcasts, etc.
41
42         // Bind
43         if (bind(s, (struct sockaddr*)&sll, sizeof(sll)))
44         {
45                 perror("bind()");
46                 return 3;
47         }
48
49 /*
50         memset(&sin, 0, sizeof(sin));
51         sin.sin_family = AF_INET;
52         sin.sin_port = htons(2900);
53         sin.sin_addr.s_addr = INADDR_ANY;
54         if (bind(s, (struct sockaddr*)&sin, sizeof(sin)))
55         {
56                 perror("bind()");
57                 return 3;
58         }
59 */
60
61         // Setup de ethernet
62         eth_addr_local[0] = 0x00;
63         eth_addr_local[1] = 0x0c;
64         eth_addr_local[2] = 0x6e;
65         eth_addr_local[3] = 0x37;
66         eth_addr_local[4] = 0x19;
67         eth_addr_local[5] = 0xbf;
68         // Setup de IP
69         ip_addr_local[0] = 0x0a;
70         ip_addr_local[1] = 0x0a;
71         ip_addr_local[2] = 0x0a;
72         ip_addr_local[3] = 0x02;
73         // Setup de UDP
74         udp_port_local = WORD(0x0b, 0x54); // 2900
75
76         while (1) // escuchamos forever
77         {
78                 unsigned int i;
79                 net_resetrp();
80                 net_resetwp();
81                 printf("Recibiendo... "); fflush(stdout);
82                 //if (recvfrom(s, net_buffer, sizeof(net_buffer), 0,
83                 //              (struct sockaddr*) &sll, &sll_len) < 0)
84                 if (recv(s, net_buffer, sizeof(net_buffer), 0) < 0)
85                 {
86                         perror("recvfrom()");
87                         return 2;
88                 }
89                 printf("OK!\n");
90                 if (!eth_read_frame_header())
91                 {
92                         printf("Header ethernet inválido: DROP!\n");
93                         continue;
94                 }
95                 if (eth_frame_arp)
96                 {
97                         printf("No le damos bola a ARP por ahora: DROP!\n");
98                         continue;
99                 }
100                 if (!ip_read_packet_header())
101                 {
102                         printf("Header ip inválido: DROP!\n");
103                         continue;
104                 }
105                 if (ip_proto_icmp)
106                 {
107                         printf("No le damos bola a ICMP por ahora: DROP!\n");
108                         continue;
109                 }
110                 if (!udp_read_dgram_header())
111                 {
112                         printf("Header udp inválido: DROP!\n");
113                         continue;
114                 }
115                 printf("Payload: ");
116                 for (i = 0; i < (udp_dgram_len - 8); ++i) // 8 == hdr udp
117                         printf("0x%02X ", net_getb());
118                 printf("\n");
119
120                 // Como hago echo, y el tamaño de las cabeceras no cambian,
121                 // basta con sólo reescribir las cabeceras
122                 eth_write_frame_header();
123                 ip_write_packet_header();
124                 udp_write_dgram_header();
125
126 #if 0
127                 // Setup para escribir header eth
128                 eth_addr_remote[0] = 0x00;
129                 eth_addr_remote[1] = 0xd0;
130                 eth_addr_remote[2] = 0x09;
131                 eth_addr_remote[3] = 0xac;
132                 eth_addr_remote[4] = 0x32;
133                 eth_addr_remote[5] = 0xe0;
134                 eth_frame_arp = 0;
135                 // Escribo header eth
136                 eth_write_frame_header();
137                 // Setup para escribir header ip
138                 ip_addr_remote[0] = 0x0a;
139                 ip_addr_remote[1] = 0x0a;
140                 ip_addr_remote[2] = 0x0a;
141                 ip_addr_remote[3] = 0x01;
142                 // TODO para setear el tamaño del paquete habría que poner solo el
143                 // tamaño del payload de UDP y calcular el resto en base a eso.
144                 ip_packet_len = 20 + 8 + 5; // ip + udp + "hola"
145                 ip_proto_icmp = 0;
146                 // Escribo header ip
147                 ip_write_packet_header();
148                 // Setup para escribir header udp
149                 udp_port_remote = WORD(0x0b, 0x54);
150                 udp_dgram_len = 8 + 5; // udp + "hola"
151                 // Escribo header udp
152                 udp_write_dgram_header();
153                 // Escribo "hola"
154                 net_putb(0x68); net_putb(0x6f); net_putb(0x6c); net_putb(0x61);
155                 net_putb(0x00);
156 #endif
157                 // Trato de mandar...
158                 printf("Mandando a %u.%u.%u.%u:%u (%02X:%02X:%02X:%02X:%02X:%02X)\n",
159                         ip_addr_remote[0], ip_addr_remote[1], ip_addr_remote[2],
160                         ip_addr_remote[3], udp_port_remote,
161                         eth_addr_remote[0], eth_addr_remote[1], eth_addr_remote[2],
162                         eth_addr_remote[3], eth_addr_remote[4], eth_addr_remote[5]);
163                 i = 14 /* eth hdr */ + ip_packet_len;
164                 if (i < 60) // tamaño mínimo de ethernet
165                         i = 60;
166                 if (send(s, net_buffer, i, 0) < 0)
167                 {
168                         perror("send()");
169                         return 1;
170                 }
171         }
172         close(s);
173         return 0;
174 }
175