#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;
}