]> git.llucax.com Git - z.facultad/66.09/etherled.git/blobdiff - src/ip.c
Se implementa un sistema primitivo de 'locking' para los leds. Cada vez que se
[z.facultad/66.09/etherled.git] / src / ip.c
index 0b4b2e27b5892f76b88b12a1cb6c15404fd8fd14..de4cc322e20e86af1c862fefe31a960c4a0215b0 100644 (file)
--- a/src/ip.c
+++ b/src/ip.c
@@ -1,6 +1,7 @@
 // vim: set et sw=4 sts=4 :    
 
 #include "netdev.h"
+#include "debug.h"
 #include "ip.h"
 
 /** protocolos soportados */
@@ -29,41 +30,48 @@ bool ip_read_packet_header()
 {
     /* variables utilitarias (iterar y/o buffer) */
     byte h, l;
+    bit ok = true;
+    netdev_read_start(IP_HEADER_SIZE);
     /* reseteamos checksum */
     checksum = 0;
     /* versión y tamaño de cabecera vienen en el 1er byte */
-    h = netdev_recv_byte();
+    h = netdev_read_byte();
     /* sólo soportamos versión 4 */
     if ((h >> 4) != 4)
-        return false; /* drop */
+        ok = false;
     /* tamaño de cabecera */
     if ((h & 0x0F) != 5) /* no aceptamos opciones raras =) */
-        return false; /* drop */
+        ok = false;
     /* ignoramos el TOS y vamos calculando checksum */
-    sum(WORD(h, netdev_recv_byte()));
+    sum(WORD(h, netdev_read_byte()));
     /* obtenemos tamaño del paquete */
-    if (h = netdev_recv_byte()) /* tiene más de 255 bytes (no lo soportamos) */
-        return false; /* drop */
-    ip_packet_len = netdev_recv_byte(); /* hasta 255 bytes tienen los nuestros */
+    if (h = netdev_read_byte()) /* tiene más de 255 bytes (no lo soportamos) */
+        ok = false;
+    ip_packet_len = netdev_read_byte(); /* hasta 255 bytes tienen los nuestros */
+    /* no puede ser más chico que sus cabeceras */
+    if (ip_packet_len < IP_HEADER_SIZE)
+        ok = false; /* drop */
     /* vamos calculando checksum */
     sum(WORD(h, ip_packet_len));
+    /* sacamos la cabecera al tamaño */
+    ip_packet_len -= IP_HEADER_SIZE;
     /* ignoramos identificación (2 bytes) y vamos calculando checksum */
-    sum(netdev_recv_word());
+    sum(netdev_read_word());
     /* si tiene prendido el bit de MF (More Fragments, bit 5 del byte, bit 2
      * de los flags de la cabecera) o si tiene un offset de fragmento (bits
      * del 4 al 0 y todos los bits del byte siguiente), dropeamos (no
      * soportamos fragmentación) */
-    h = netdev_recv_byte();
-    l = netdev_recv_byte();
+    h = netdev_read_byte();
+    l = netdev_read_byte();
     if ((h & 0x3F) || l)
-        return false; /* drop */
+        ok = false;
     /* seguimos calculando checksum */
     sum(WORD(h, l));
     /* no le damos bola al TTL (no le vamos a hacer lío si ya llegó hasta
      * acá el pobre =) */
-    h = netdev_recv_byte();
+    h = netdev_read_byte();
     /* protocolo (sólo soportamos UDP e ICMP) */
-    l = netdev_recv_byte();
+    l = netdev_read_byte();
     switch (l)
     {
         case ICMP:
@@ -73,16 +81,16 @@ bool ip_read_packet_header()
             ip_proto = IP_UDP;
             break;
         default:
-            return false; /* drop */
+            ok = false;
     }
     /* sigo calculando checksum */
     sum(WORD(h, l));
     /* obtenemos checksum y seguimos el cálculo */
-    sum(netdev_recv_word());
+    sum(netdev_read_word());
     /* obtenemos IP de origen (mientras seguimos calculando el checksum) */
     for (l = 0; l < IP_ADDR_SIZE; ++l)
     {
-        ip_addr_remote[l] = netdev_recv_byte();
+        ip_addr_remote[l] = netdev_read_byte();
         if (l % 2)
             sum(WORD(h, ip_addr_remote[l]));
         else
@@ -93,8 +101,8 @@ bool ip_read_packet_header()
     // TODO si soportamos DHCP hay que aceptar broadcasts!
     for (l = 0; l < IP_ADDR_SIZE; ++l)
     {
-        if (ip_addr_local[l] != netdev_recv_byte()) 
-            return false; /* drop (no es para nosotros) */
+        if (ip_addr_local[l] != netdev_read_byte()) 
+            ok = false;
         if (l % 2)
             sum(WORD(h, ip_addr_local[l]));
         else
@@ -102,8 +110,9 @@ bool ip_read_packet_header()
     }
     /* verificamos checksum */
     if ((uint16)~checksum)
-        return false; /* checksum malo, drop */
-    return true;
+        ok = false;
+    netdev_read_end();
+    return ok;
 }
 
 void ip_write_packet_header()
@@ -114,28 +123,29 @@ void ip_write_packet_header()
     static uint16 id;
     /* reseteamos checksum */
     checksum = 0;
+    netdev_write_start(IP_HEADER_SIZE);
     /* versión (4) y tamaño de cabecera (5 words de 4 bytes = 20 bytes) */
-    netdev_send_byte(h = 0x45);
+    netdev_write_byte(h = 0x45);
     /* TOS (0xc0 = Internetwork Control, 0x00 = normal) */
     l = (ip_proto == IP_ICMP) ? 0xc0 : 0x00;
-    netdev_send_byte(l);
+    netdev_write_byte(l);
     sum(WORD(h, l)); /* actualizamos checksum */
     /* escribimos tamaño del paquete */
-    netdev_send_byte(h = 0x00); /* nunca vamos a mandar algo de más de 255 bytes */
-    netdev_send_byte(ip_packet_len);
-    sum(WORD(h, ip_packet_len)); /* actualizamos checksum */
+    netdev_write_byte(h = 0x00); /* nunca vamos a mandar algo de más de 255 bytes */
+    netdev_write_byte(ip_packet_len + IP_HEADER_SIZE);
+    sum(WORD(h, ip_packet_len + IP_HEADER_SIZE)); /* actualizamos checksum */
     /* identificación (sirve para reensamblar paquetes) */
-    netdev_send_word(id);
+    netdev_write_word(++id);
     sum(id); /* actualizamos checksum */
     /* pedimos que no se fragmente */
-    netdev_send_byte(h = 0x40); /* Don't Fragment (DF) = 1 */
-    netdev_send_byte(l = 0x00); /* offset de fragmento = 0 */
+    netdev_write_byte(h = 0x40); /* Don't Fragment (DF) = 1 */
+    netdev_write_byte(l = 0x00); /* offset de fragmento = 0 */
     sum(WORD(h, l)); /* actualizamos checksum */
     /* TTL de 64 saltos porque está de moda */
-    netdev_send_byte(h = 0x40);
+    netdev_write_byte(h = 0x40);
     /* protocolo (sólo soportamos UDP e ICMP) */
     l = (ip_proto == IP_ICMP) ? ICMP : UDP;
-    netdev_send_byte(l);
+    netdev_write_byte(l);
     sum(WORD(h, l)); /* actualizamos checksum */
     /* checksum: antes de poder escribir el checksum hay que terminar de
      * calcularlo según las direcciones IP de origen y destino, así que eso
@@ -151,13 +161,14 @@ void ip_write_packet_header()
         else
             h = ip_addr_remote[l];
     /* ahora sí grabamos el checksum */
-    netdev_send_word(~checksum);
+    netdev_write_word(~checksum);
     /* ahora sí, continuamos poniendo las direcciones */
     /* ponemos como dirección IP de origen la nuestra */
     for (l = 0; l < IP_ADDR_SIZE; ++l)
-        netdev_send_byte(ip_addr_local[l]);
+        netdev_write_byte(ip_addr_local[l]);
     /* IP de destino, la remota */
     for (l = 0; l < IP_ADDR_SIZE; ++l)
-        netdev_send_byte(ip_addr_remote[l]);
+        netdev_write_byte(ip_addr_remote[l]);
+    netdev_write_end();
 }