]> git.llucax.com Git - z.facultad/66.09/etherled.git/blobdiff - src/c/udp.c
Seguían habiendo problemas al recibir varios paquetes seguidos, al parecer se
[z.facultad/66.09/etherled.git] / src / c / udp.c
index 05dcdb13e61658a7765ecb14fb9aa640f90cb8a3..c6fbfcce599d8e1346b03be280114ef4d85c3baf 100644 (file)
@@ -1,24 +1,65 @@
 #include "ip.h"
+#include "udp.h"
 
-extern uint16 udp_port_local;
+uint16 udp_port_local;
 
-extern uint16 udp_port_remote;
+uint16 udp_port_remote;
 
-extern byte udp_dgram_len;
+byte udp_dgram_len;
+
+/* para calcular checksum */
+uint16 checksum;
+
+/* agrega un word al checksum calculado */
+void udp_checksum_sum(uint16 w)
+{
+       checksum += w;
+       if (checksum < w) /* corrección de carry (hubo OV) */
+               ++checksum;
+}
+
+/* indica si el checksum calculado está ok */
+bool udp_checksum_ok()
+{
+       return ~checksum;
+}
 
 bool udp_read_dgram_header()
 {
+       /* reseteamos checksum */
+       checksum = 0;
+       /* el UDP tiene un checksum que incluye parte de la cabecera IP */
+       /* ip de origen */
+       udp_checksum_sum(WORD(ip_addr_remote[0], ip_addr_remote[1]));
+       udp_checksum_sum(WORD(ip_addr_remote[2], ip_addr_remote[3]));
+       /* ip de destino */
+       udp_checksum_sum(WORD(ip_addr_local[0], ip_addr_local[1]));
+       udp_checksum_sum(WORD(ip_addr_local[2], ip_addr_local[3]));
+       /* protocolo expresado en 16 bits (0x11 es UDP) */
+       udp_checksum_sum(0x11);
+       /* tamaño del paquete UDP (sin las cabeceras que son 20 bytes) */
+       udp_checksum_sum(ip_packet_len - 20);
+       /* de ahora en más todos los datos del checksum corresponden a UDP */
        /* puerto origen (remoto) */
        udp_port_remote = net_getw();
+       /* agregamos puerto de origen al checksum */
+       udp_checksum_sum(udp_port_remote);
        /* sólo aceptamos datagramas a nuestro puerto */
        if (net_getw() != udp_port_local)
                return false; /* drop */
+       /* agregamos puerto de destino al checksum */
+       udp_checksum_sum(udp_port_local);
        /* tamaño del datagrama */
        if (net_getb()) /* no soportamos más de 255 bytes */
                return false; /* drop */
        udp_dgram_len = net_getb();
-       /* descartamos checksum */
-       net_getw();
+       /* agregamos tamaño al checksum */
+       udp_checksum_sum(udp_dgram_len);
+       /* agregamos checksum al checksum */
+       udp_checksum_sum(net_getw());
+       /* falta agregar el cuerpo del mensaje para verificar la suma
+        * esto debe hacerlo el protocolo que sigue para poder seguir obteniendo
+        * los datos de la placa de red byte a byte */
        return true;
 }