X-Git-Url: https://git.llucax.com/z.facultad/66.09/etherled.git/blobdiff_plain/cbf2122a2f610a2b92f1dfcb0f554b4bf7c4757e..f5186e12ed5aedf98d0fa0d8299a73c830046c75:/src/udp.c diff --git a/src/udp.c b/src/udp.c index 9da1b25..09b9bfc 100644 --- a/src/udp.c +++ b/src/udp.c @@ -1,5 +1,6 @@ // vim: set et sw=4 sts=4 : +#include "debug.h" #include "netdev.h" #include "ip.h" #include "udp.h" @@ -12,6 +13,8 @@ byte udp_dgram_len; /* para calcular checksum */ static uint16 checksum; +static byte byte_count; +static byte last_byte; /* agrega un word al checksum calculado */ static void sum(uint16 w) @@ -23,9 +26,12 @@ static void sum(uint16 w) bool udp_read_dgram_header() { - uint16 p; + byte tmp; + bit ok = true; + netdev_read_start(UDP_HEADER_SIZE); /* reseteamos checksum */ checksum = 0; + byte_count = 0; /* el UDP tiene un checksum que incluye parte de la cabecera IP */ /* ip de origen */ sum(WORD(ip_addr_remote[0], ip_addr_remote[1])); @@ -39,45 +45,62 @@ bool udp_read_dgram_header() sum(ip_packet_len - 20); /* de ahora en más todos los datos del checksum corresponden a UDP */ /* puerto origen (remoto) */ - udp_port_remote = netdev_recv_word(); + udp_port_remote = netdev_read_word(); /* agregamos puerto de origen al checksum */ sum(udp_port_remote); /* sólo aceptamos datagramas a nuestro puerto */ - p = netdev_recv_word(); - if (p != udp_port_local) - return false; /* drop */ + if (netdev_read_word() != udp_port_local) + ok = false; /* drop */ /* agregamos puerto de destino al checksum */ sum(udp_port_local); /* tamaño del datagrama */ - if (netdev_recv_byte()) /* no soportamos más de 255 bytes */ - return false; /* drop */ - udp_dgram_len = netdev_recv_byte(); + if (tmp = netdev_read_byte()) /* no soportamos más de 255 bytes */ + ok = false; /* drop */ + udp_dgram_len = netdev_read_byte(); /* parte baja */ + if (udp_dgram_len < 8) /* no puede ser más chico que sus cabeceras */ + ok = false; /* drop */ /* agregamos tamaño al checksum */ - sum(udp_dgram_len); + sum(WORD(tmp, udp_dgram_len)); /* agregamos checksum al checksum */ - sum(netdev_recv_word()); + sum(netdev_read_word()); /* 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 */ + netdev_read_end(); return true; } -uint16 udp_read_word() +byte udp_read_byte() { - uint16 w = netdev_recv_word(); - sum(w); - return w; + byte b; + if (byte_count % 2) // impar, tengo 2, sumo + { + b = netdev_read_byte(); + sum(WORD(last_byte, b)); + } + else // par, guardo para sumar cuando tenga 2 + { + b = netdev_read_byte(); + last_byte = b; + } + ++byte_count; + return b; } bool udp_checksum_ok() { - return (uint16)~checksum; + // Verifico si falta sumar algo (UDP debe sumar de a un word) + if (byte_count == (udp_dgram_len - UDP_HEADER_SIZE)) + sum(WORD(last_byte, 0x00)); // Relleno el byte que falta con 0x00 + return !(uint16)~checksum; } void udp_write_dgram_header() { + netdev_write_start(UDP_HEADER_SIZE); /* reseteamos checksum */ checksum = 0; + byte_count = 0; /* el UDP tiene un checksum que incluye parte de la cabecera IP */ /* ip de origen */ sum(WORD(ip_addr_remote[0], ip_addr_remote[1])); @@ -90,29 +113,45 @@ void udp_write_dgram_header() /* tamaño del paquete UDP (IP sin las cabeceras, que son 20 bytes) */ sum(ip_packet_len - 20); // FIXME /* puerto origen */ - netdev_send_word(udp_port_local); + netdev_write_word(udp_port_local); sum(udp_port_local); /* puerto destino */ - netdev_send_word(udp_port_remote); + netdev_write_word(udp_port_remote); sum(udp_port_remote); /* tamaño del datagrama */ - netdev_send_byte(0x00); /* parte alta en 0 porque no soportamos más de 255 */ - netdev_send_byte(udp_dgram_len); + netdev_write_byte(0x00); /* parte alta en 0 porque no soportamos más de 255 */ + netdev_write_byte(udp_dgram_len); sum(WORD(0x00, udp_dgram_len)); /* indicamos que no se usa checksum */ - netdev_send_word(0x0000); + netdev_write_word(0x0000); sum(0x0000); + netdev_write_end(); } -void udp_write_word(uint16 w) +void udp_write_byte(byte b) { - sum(w); - netdev_send_word(w); + if (byte_count % 2) // impar, tengo 2, sumo + { + netdev_write_byte(b); + sum(WORD(last_byte, b)); + } + else // par, guardo para sumar cuando tenga 2 + { + netdev_write_byte(b); + last_byte = b; + } + ++byte_count; } -void udp_write_checksum() +void udp_write_checksum(byte offset) { - // XXX TODO FIXME + // Verifico si falta sumar algo (UDP debe sumar de a un word) + if (byte_count == (udp_dgram_len - UDP_HEADER_SIZE)) + sum(WORD(last_byte, 0x00)); // Relleno el byte que falta con 0x00 + // Escribo checksum en el buffer de la placa de red + netdev_write_start_at(offset + 6, 2); // 6 bytes de offset hasta el checksum + netdev_write_word((uint16)~checksum); // Guardo checksum + netdev_write_end(); return; }