]> git.llucax.com Git - z.facultad/66.09/etherled.git/blob - pruebas/c/net/udp.c
Bugfix en el cálculo de checksum.
[z.facultad/66.09/etherled.git] / pruebas / c / net / udp.c
1 #include "ip.h"
2 #include "udp.h"
3
4 uint16 udp_port_local;
5
6 uint16 udp_port_remote;
7
8 byte udp_dgram_len;
9
10 /* para calcular checksum */
11 uint16 checksum;
12
13 /* agrega un word al checksum calculado */
14 void udp_checksum_sum(uint16 w)
15 {
16         checksum += w;
17         if (checksum < w) /* corrección de carry (hubo OV) */
18                 ++checksum;
19 }
20
21 /* indica si el checksum calculado está ok */
22 bool udp_checksum_ok()
23 {
24         return (uint16)~checksum;
25 }
26
27 bool udp_read_dgram_header()
28 {
29         uint16 p;
30         /* reseteamos checksum */
31         checksum = 0;
32         /* el UDP tiene un checksum que incluye parte de la cabecera IP */
33         /* ip de origen */
34         udp_checksum_sum(WORD(ip_addr_remote[0], ip_addr_remote[1]));
35         udp_checksum_sum(WORD(ip_addr_remote[2], ip_addr_remote[3]));
36         /* ip de destino */
37         udp_checksum_sum(WORD(ip_addr_local[0], ip_addr_local[1]));
38         udp_checksum_sum(WORD(ip_addr_local[2], ip_addr_local[3]));
39         /* protocolo expresado en 16 bits (0x11 es UDP) */
40         udp_checksum_sum(0x11);
41         /* tamaño del paquete UDP (sin las cabeceras que son 20 bytes) */
42         udp_checksum_sum(ip_packet_len - 20);
43         /* de ahora en más todos los datos del checksum corresponden a UDP */
44         /* puerto origen (remoto) */
45         udp_port_remote = net_getw();
46         /* agregamos puerto de origen al checksum */
47         udp_checksum_sum(udp_port_remote);
48         /* sólo aceptamos datagramas a nuestro puerto */
49         p = net_getw();
50         if (p != udp_port_local)
51                 return false; /* drop */
52         /* agregamos puerto de destino al checksum */
53         udp_checksum_sum(udp_port_local);
54         /* tamaño del datagrama */
55         if (net_getb()) /* no soportamos más de 255 bytes */
56                 return false; /* drop */
57         udp_dgram_len = net_getb();
58         /* agregamos tamaño al checksum */
59         udp_checksum_sum(udp_dgram_len);
60         /* agregamos checksum al checksum */
61         udp_checksum_sum(net_getw());
62         /* falta agregar el cuerpo del mensaje para verificar la suma
63          * esto debe hacerlo el protocolo que sigue para poder seguir obteniendo
64          * los datos de la placa de red byte a byte */
65         return true;
66 }
67
68 void udp_write_dgram_header()
69 {
70         /* puerto origen */
71         net_putw(udp_port_local);
72         /* puerto destino */
73         net_putw(udp_port_remote);
74         /* tamaño del datagrama */
75         net_putb(0x00); /* parte alta en 0 porque no soportamos más de 255 */
76         net_putb(udp_dgram_len);
77         /* indicamos que no se usa checksum */
78         net_putw(0x0000);
79 }
80