X-Git-Url: https://git.llucax.com/z.facultad/66.09/etherled.git/blobdiff_plain/3978740ee545b373cfaa9f97b899b11c01a3d199..a963ad6157c406337b0d89323469296b5e865495:/src/c/udp.c diff --git a/src/c/udp.c b/src/c/udp.c index 1c4189e..c6fbfcc 100644 --- a/src/c/udp.c +++ b/src/c/udp.c @@ -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() { - /* puerto origen */ + /* 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; }