From: Leandro Lucarella Date: Wed, 14 Dec 2005 05:12:26 +0000 (+0000) Subject: ARP implementado y andando (más pequeños bugfixes)! X-Git-Tag: cliente-1.0~5 X-Git-Url: https://git.llucax.com/z.facultad/66.09/etherled.git/commitdiff_plain/163891ab133ae8e210f3e4493ebbd6875a4e9327 ARP implementado y andando (más pequeños bugfixes)! --- diff --git a/src/Makefile b/src/Makefile index d51639d..b1e25d8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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 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 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_ */ diff --git a/src/dp8390.c b/src/dp8390.c index 76d0c6d..1b48e9b 100644 --- a/src/dp8390.c +++ b/src/dp8390.c @@ -1,6 +1,7 @@ // vim: set et sw=4 sts=4 : #include "debug.h" +#include "leds.h" #include "eth.h" #include "dp8390.h" diff --git a/src/leds.asm b/src/leds.asm index 558f13f..e32ac13 100644 --- a/src/leds.asm +++ b/src/leds.asm @@ -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 diff --git a/src/main.c b/src/main.c index 9714789..0708044 100644 --- a/src/main.c +++ b/src/main.c @@ -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