]> git.llucax.com Git - z.facultad/66.09/etherled.git/commitdiff
ARP implementado y andando (más pequeños bugfixes)!
authorLeandro Lucarella <llucax@gmail.com>
Wed, 14 Dec 2005 05:12:26 +0000 (05:12 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Wed, 14 Dec 2005 05:12:26 +0000 (05:12 +0000)
src/Makefile
src/arp.c [new file with mode: 0644]
src/arp.h [new file with mode: 0644]
src/dp8390.c
src/leds.asm
src/main.c

index d51639d20b8572bd12895bd6d2b9e53d16059bd3..b1e25d89522a82674b2ddaa49bba0c037e03d079 100644 (file)
@@ -1,7 +1,7 @@
 
 # Compilador
 CC=sdcc
-CFLAGS=-DDEBUG
+#CFLAGS=-DDEBUG
 
 # Assembler
 AS=asx8051
@@ -15,7 +15,7 @@ LDFLAGS=-cn
 SHELL=bash
 
 # Archivos
-cmodules=main dp8390 eth ip udp elp
+cmodules=main dp8390 eth arp ip udp elp
 amodules=leds
 modules=$(cmodules) $(amodules)
 
@@ -33,6 +33,8 @@ eth.h: types.h
 
 ip.h: types.h
 
+arp.h: types.h eth.h ip.h
+
 udp.h: types.h
 
 elp.h: types.h
@@ -43,6 +45,9 @@ dp8390.rel: dp8390.asm
 eth.asm: eth.c eth.h netdev.h debug.h
 eth.rel: eth.asm
 
+arp.asm: arp.c arp.h netdev.h debug.h
+arp.rel: arp.asm
+
 ip.asm: ip.c ip.h netdev.h debug.h
 ip.rel: ip.asm
 
diff --git a/src/arp.c b/src/arp.c
new file mode 100644 (file)
index 0000000..7cb114e
--- /dev/null
+++ b/src/arp.c
@@ -0,0 +1,80 @@
+// vim: set et sw=4 sts=4 :    
+
+#include "arp.h"
+#include "netdev.h"
+#include "debug.h"
+#include "eth.h"
+#include "ip.h"
+
+bool arp_read_packet()
+{
+    byte i;
+    bit ok = true;
+    netdev_read_start(ARP_HEADER_SIZE);
+    /* hardware type (solo soportamos ethernet: 0x0001)*/
+    if (netdev_read_word() != 0x0001)
+        ok = false;
+    /* protocolo (sólo soportamos IP: 0x0800) */
+    if (netdev_read_word() != 0x0800)
+        ok = false;
+    /* tamaño de dirección de hardware (sólo soportamos ethernet) */
+    if (netdev_read_byte() != ETH_ADDR_SIZE)
+        ok = false;
+    /* tamaño de dirección de protocolo (sólo soportamos IPv4) */
+    if (netdev_read_byte() != IP_ADDR_SIZE)
+        ok = false;
+    /* opcode (sólo le damos bola a los requests: 0x0001) */
+    if (netdev_read_word() != 0x0001)
+        ok = false;
+    netdev_read_end();
+    /* si las cosas no vienen bien a esta altura, ni nos gastamos en seguir */
+    if (!ok)
+        return ok;
+    netdev_read_start(ARP_PAYLOAD_SIZE);
+    /* obtenemos MAC de origen (ya la teníamos pero por las dudas) */
+    for (i = 0; i < ETH_ADDR_SIZE; ++i)
+        eth_addr_remote[i] = netdev_read_byte();
+    /* obtenemos IP de origen */
+    for (i = 0; i < IP_ADDR_SIZE; ++i)
+        ip_addr_remote[i] = netdev_read_byte();
+    /* la MAC de destino no nos importa, seguramente es broadcast */
+    for (i = 0; i < ETH_ADDR_SIZE; ++i)
+        netdev_read_byte();
+    /* sí nos importa qué IP andan buscando */
+    for (i = 0; i < IP_ADDR_SIZE; ++i)
+        if (ip_addr_local[i] != netdev_read_byte())
+            ok = false; /* si no buscan la nuestra, perdemos interés */
+    netdev_read_end();
+    return ok;
+}
+
+void arp_write_packet()
+{
+    byte i;
+    bit ok = true;
+    netdev_write_start(ARP_PACKET_SIZE);
+    /* hardware type (ethernet: 0x0001)*/
+    netdev_write_word(0x0001);
+    /* protocolo type (IP: 0x0800) */
+    netdev_write_word(0x0800);
+    /* tamaño de dirección de hardware */
+    netdev_write_byte(ETH_ADDR_SIZE);
+    /* tamaño de dirección de protocolo */
+    netdev_write_byte(IP_ADDR_SIZE);
+    /* opcode (response: 0x0002) */
+    netdev_write_word(0x0002);
+    /* MAC de origen */
+    for (i = 0; i < ETH_ADDR_SIZE; ++i)
+        netdev_write_byte(eth_addr_local[i]);
+    /* IP de origen */
+    for (i = 0; i < IP_ADDR_SIZE; ++i)
+        netdev_write_byte(ip_addr_local[i]);
+    /* MAC de destino */
+    for (i = 0; i < ETH_ADDR_SIZE; ++i)
+        netdev_write_byte(eth_addr_remote[i]);
+    /* IP de destino */
+    for (i = 0; i < IP_ADDR_SIZE; ++i)
+        netdev_write_byte(ip_addr_remote[i]);
+    netdev_write_end();
+}
+
diff --git a/src/arp.h b/src/arp.h
new file mode 100644 (file)
index 0000000..6018c1c
--- /dev/null
+++ b/src/arp.h
@@ -0,0 +1,57 @@
+// vim: set et sw=4 sts=4 :    
+
+#ifndef _ARP_H_
+#define _ARP_H_
+
+#include "types.h"
+#include "eth.h"
+#include "ip.h"
+
+/** @file
+ * Paquete ARP.
+ *
+ *  0                   1                   2                   3   
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |          Hardware Type        |         Protocol Type         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Hardware Size | Protocol Size |            Opcode             |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  Sender MAC (cant. de bytes especificados por Hardware size)  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  Sender IP  (cant. de bytes especificados por Protocol size)  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  Target MAC (cant. de bytes especificados por Hardware size)  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  Target IP  (cant. de bytes especificados por Protocol size)  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 
+ * Nosotros sólo implementamos la respuesta a un request ARP, ya que sólo
+ * respondemos paquetes, nunca tenemos que enviar un paquete a una IP
+ * arbitraria. De esta manera nos evitamos, además, la necesidad de tener una
+ * tabla de cache ARP y de enviar peticiones ARP.
+ */
+
+/** Tamaño de la cabecera ARP (en bytes) */
+#define ARP_HEADER_SIZE 8
+
+/** Tamaño del payload del paquete ARP que soportamos nosotros (en bytes) */
+#define ARP_PAYLOAD_SIZE (2*ETH_ADDR_SIZE + 2*IP_ADDR_SIZE)
+
+/** Tamaño del paquete ARP que soportamos nosotros (en bytes) */
+#define ARP_PACKET_SIZE (ARP_HEADER_SIZE + ARP_PAYLOAD_SIZE)
+
+/** Lee el paquete ARP.
+ *
+ * Si devuelve false (0) es que hubo un error o es un paquete no soportado, por
+ * lo que hay que descartarlo.
+ */
+bool arp_read_packet();
+
+/** Escribe el paquete ARP.
+ *
+ * Responde al request recibido con la ip de ip_addr_local.
+ */
+void arp_write_packet();
+
+#endif /* _ARP_H_ */
index 76d0c6d3a292d321eb74457c11df9aadcba48809..1b48e9b5de256dc629aa1dead3def1b34e7e6ce4 100644 (file)
@@ -1,6 +1,7 @@
 // vim: set et sw=4 sts=4 :    
 
 #include "debug.h"
+#include "leds.h"
 #include "eth.h"
 #include "dp8390.h"
 
index 558f13fd04acdf8a8164220f9d07732df8ec3d86..e32ac13be12a6e44dc3ca5da4488e89ba69ed375 100644 (file)
@@ -335,39 +335,39 @@ DEFAULT_MATRIX_LEN:
     ;.db     32
 
 DEFAULT_MATRIX:
-;    .dw     0b0000111111110000    ; columna 0
-;    .dw     0b0011111111111100    ; columna 1
-;    .dw     0b0111000000001110    ; columna 2
-;    .dw     0b0110000000000110    ; columna 3
-;    .dw     0b1100001100000011    ; columna 4
-;    .dw     0b1100011000110011    ; columna 5
-;    .dw     0b1100110000110011    ; columna 6
-;    .dw     0b1100110000000011    ; columna 7
-;    .dw     0b1100110000000011    ; columna 8
-;    .dw     0b1100110000110011    ; columna 9
-;    .dw     0b1100011000110011    ; columna 10
-;    .dw     0b1100001100000011    ; columna 11
-;    .dw     0b0110000000000110    ; columna 12
-;    .dw     0b0111000000001110    ; columna 13
-;    .dw     0b0011111111111100    ; columna 14
-;    .dw     0b0000111111110000    ; columna 15
-
-    .dw     0b0000011111100000
-    .dw     0b0001111111111000
-    .dw     0b0011100000011100
-    .dw     0b0111110000000110
-    .dw     0b0110111000000110
-    .dw     0b1100011100000011
-    .dw     0b1100001110000011
-    .dw     0b1111111111111111
-    .dw     0b1111111111111111
-    .dw     0b1100001110000011
-    .dw     0b1100011100000011
-    .dw     0b0110111000000110
-    .dw     0b0111110000000110
-    .dw     0b0011100000011100
-    .dw     0b0001111111111000
-    .dw     0b0000011111100000
+    .dw     0b0000111111110000    ; columna 0
+    .dw     0b0011111111111100    ; columna 1
+    .dw     0b0111000000001110    ; columna 2
+    .dw     0b0110000000000110    ; columna 3
+    .dw     0b1100001100000011    ; columna 4
+    .dw     0b1100011000110011    ; columna 5
+    .dw     0b1100110000110011    ; columna 6
+    .dw     0b1100110000000011    ; columna 7
+    .dw     0b1100110000000011    ; columna 8
+    .dw     0b1100110000110011    ; columna 9
+    .dw     0b1100011000110011    ; columna 10
+    .dw     0b1100001100000011    ; columna 11
+    .dw     0b0110000000000110    ; columna 12
+    .dw     0b0111000000001110    ; columna 13
+    .dw     0b0011111111111100    ; columna 14
+    .dw     0b0000111111110000    ; columna 15
+
+;    .dw     0b0000011111100000
+;    .dw     0b0001111111111000
+;    .dw     0b0011100000011100
+;    .dw     0b0111110000000110
+;    .dw     0b0110111000000110
+;    .dw     0b1100011100000011
+;    .dw     0b1100001110000011
+;    .dw     0b1111111111111111
+;    .dw     0b1111111111111111
+;    .dw     0b1100001110000011
+;    .dw     0b1100011100000011
+;    .dw     0b0110111000000110
+;    .dw     0b0111110000000110
+;    .dw     0b0011100000011100
+;    .dw     0b0001111111111000
+;    .dw     0b0000011111100000
 
 ;    .dw     0b1111000000001111    ; columna 0
 ;    .dw     0b1100000000000011    ; columna 1
index 9714789a5ad855b0e53a54c70cca47e7f46be20d..070804402c392471e2df984cfb5a4a9c761bbcfa 100644 (file)
@@ -5,6 +5,7 @@
 #include "reg51.h"
 #include "netdev.h"
 #include "eth.h"
+#include "arp.h"
 #include "ip.h"
 #include "udp.h"
 #include "elp.h"
@@ -54,8 +55,22 @@ void main(void)
         // Vemos que protocolo transporta
         switch (eth_proto)
         {
-            case ETH_ARP: // TODO: implementar ARP!
-                goto drop; // Tiramos el paquete
+            case ETH_ARP:
+                // Obtenemos paquete ARP
+                if (!arp_read_packet) // No es un paquete soportado
+                    goto drop; // Tiramos el paquete
+
+                // Terminamos recepción
+                netdev_recv_end();
+
+                // Respondemos
+                netdev_send_start();
+                eth_write_frame_header();
+                arp_write_packet();
+                netdev_send_end(ETH_HEADER_SIZE + ARP_PACKET_SIZE);
+
+                // Seguimos viaje
+                continue;
 
             case ETH_IP:
                 // Parseamos cabecera IP