]> git.llucax.com Git - z.facultad/66.09/etherled.git/blobdiff - src/udp.c
Se implementa un sistema primitivo de 'locking' para los leds. Cada vez que se
[z.facultad/66.09/etherled.git] / src / udp.c
index a7b93fa431b17dfd1c37f17954ab70a2fbb9aac4..bd6f9c276bf2da8452b2e3b4f41b9eac90bcd323 100644 (file)
--- 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]));
@@ -35,51 +41,69 @@ bool udp_read_dgram_header()
     sum(WORD(ip_addr_local[2], ip_addr_local[3]));
     /* protocolo expresado en 16 bits (0x11 es UDP) */
     sum(0x0011);
-    /* tamaño del paquete UDP (sin las cabeceras que son 20 bytes) */
-    sum(ip_packet_len - 20);
+    /* tamaño del paquete UDP (IP ya está sin las cabeceras) */
+    sum(ip_packet_len);
     /* 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 (udp_dgram_len < 8) /* no puede ser más chico que sus cabeceras */
-        return false; /* drop */
+    if (tmp = netdev_read_byte()) /* no soportamos más de 255 bytes */
+        ok = false; /* drop */
+    udp_dgram_len = netdev_read_byte(); /* parte baja */
+    /* no puede ser más chico que sus cabeceras */
+    if (udp_dgram_len < UDP_HEADER_SIZE)
+        ok = false; /* drop */
     /* agregamos tamaño al checksum */
-    sum(udp_dgram_len);
+    sum(WORD(tmp, udp_dgram_len));
+    /* sacamos la cabecera al tamaño */
+    udp_dgram_len -= UDP_HEADER_SIZE;
     /* 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 % 2)
+        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]));
@@ -89,32 +113,48 @@ void udp_write_dgram_header()
     sum(WORD(ip_addr_local[2], ip_addr_local[3]));
     /* protocolo expresado en 16 bits (0x11 es UDP) */
     sum(0x0011);
-    /* tamaño del paquete UDP (IP sin las cabeceras, que son 20 bytes) */
-    sum(ip_packet_len - 20); // FIXME
+    /* tamaño del paquete UDP */
+    sum(WORD(0x00, udp_dgram_len + UDP_HEADER_SIZE));
     /* 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);
-    sum(WORD(0x00, udp_dgram_len));
+    netdev_write_byte(0x00); /* parte alta en 0 porque no soportamos más de 255 */
+    netdev_write_byte(udp_dgram_len + UDP_HEADER_SIZE);
+    sum(WORD(0x00, udp_dgram_len + UDP_HEADER_SIZE));
     /* 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 % 2)
+        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;
 }