From: Stefan E. <se...@us...> - 2003-04-01 18:55:23
|
Update of /cvsroot/blob/blob/src/lib In directory sc8-pr-cvs1:/tmp/cvs-serv4059 Modified Files: arp.c ip_bits.c Log Message: - implemented ARP replies, otherwise tftp stalls. Index: arp.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/arp.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- arp.c 18 Mar 2003 16:20:50 -0000 1.2 +++ arp.c 1 Apr 2003 18:55:19 -0000 1.3 @@ -14,6 +14,14 @@ #include <net/ether.h> #include <net/arp.h> +#undef ARP_DEBUG +#ifdef ARP_DEBUG +static int dbg = 1; +# define DBG( x, args... ) if ( dbg>=x ) printf( args ) +#else +# define DBG( x, args... ) ; +#endif + static const unsigned char arp_txpacket[] = { /* destination address */ /* source address */ @@ -73,4 +81,73 @@ } while (--retry); return -1; +} + +int do_arp_reply(unsigned char *rx_pkt, unsigned int size) +{ + struct ether_hdr *eth_request = (struct ether_hdr *)rx_pkt; + struct arp_packet *request = (struct arp_packet *)(rx_pkt+sizeof(struct ether_hdr)); + u8 bcast[6] = { [0 ... 5] 0xff }; + struct arp_packet reply = { + .hw_type = HTON( 0x0001 ), + .proto_type = HTON( 0x0800 ), + .hw_len = 6, + .proto_len = 4, + .opcode = HTON( 0x0002 ) + }; + struct ether_hdr eth_reply; + + DBG( 1, "%s: ETH: %02x:%02x:%02x:%02x:%02x:%02x" + " %02x:%02x:%02x:%02x:%02x:%02x proto 0x%04x\n", __FUNCTION__, + eth_request->dest[0], eth_request->dest[1], eth_request->dest[2], + eth_request->dest[3], eth_request->dest[4], eth_request->dest[5], + eth_request->src[0], eth_request->src[1], eth_request->src[2], + eth_request->src[3], eth_request->src[4], eth_request->src[5], + HTON( eth_request->proto )); + + + /* is it for us or broadcast? */ + if ( !memeq( eth_request->dest, hwaddress, 6 ) && !memeq( eth_request->dest, bcast, 6 )) + return -1; + + DBG( 1, "%s: opcode 0x%04x\n", __FUNCTION__, HTON( request->opcode ) ); + + /* is it an arp request? */ + if ( request->opcode != HTON( 0x0001 ) ) + return -1; + + DBG( 1, "%s: got an arp request from IP %d.%d.%d.%d requesting %d.%d.%d.%d\n", __FUNCTION__, + request->sender.ip[0], + request->sender.ip[1], + request->sender.ip[2], + request->sender.ip[3], + request->target.ip[0], + request->target.ip[1], + request->target.ip[2], + request->target.ip[3] + ); + + /* requesting our IP ? */ + if ( !memeq( request->target.ip, clientipaddress, 4 )) + return -1; + + DBG( 1, "%s: arp request for our IP\n", __FUNCTION__ ); + + /* ethernet header */ + eth_reply.proto = HTON( 0x0806 ); /* ARP */ + memcpy( eth_reply.dest, eth_request->src, 6 ); + memcpy( eth_reply.src, hwaddress, 6 ); + + /* arp reply */ + memcpy(reply.sender.hw, hwaddress, 6); + memcpy(reply.sender.ip, clientipaddress, 4); + memcpy(reply.target.hw, request->sender.hw, 6); + memcpy(reply.target.ip, request->sender.ip, 4); + + memzero(arp_tx, sizeof(arp_tx)); + memcpy(arp_tx, ð_reply, sizeof(struct ether_hdr)); + memcpy(arp_tx + sizeof(struct ether_hdr), &reply, sizeof(struct arp_packet)); + + writeether(arp_tx, sizeof(arp_tx)); + return 0; } Index: ip_bits.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/ip_bits.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- ip_bits.c 18 Mar 2003 16:20:49 -0000 1.2 +++ ip_bits.c 1 Apr 2003 18:55:19 -0000 1.3 @@ -11,6 +11,7 @@ #include <serial.h> #include <net/net.h> #include <net/ether.h> +#include <net/arp.h> #include <net/ip_bits.h> unsigned long ip_sequence = 0; @@ -72,9 +73,21 @@ return writeether (ptr, size + OFF_UDP); } +/* handle broadcast packets. For arp requests */ +int do_bcast( unsigned char *ptr, unsigned int size ) +{ + /* check whether or not ARP proto */ + if (((ptr[OFF_ETHER + 12] << 8) | ptr[OFF_ETHER + 13]) != 0x0806) + return 0; /* not ARP */ + + /* ok, its an arp. handle it. */ + return do_arp_reply( ptr, size ); +} + int ipbits_rcv (unsigned char *ptr, unsigned int size, unsigned int *dsz, int sport, int dport) { unsigned int cksum, hdrlen, off_udp; + u8 bcast[6] = { [0 ... 5] 0xff }; size = readether(ptr, size); if (!size) @@ -82,6 +95,10 @@ if (size < MIN_UDPPKTSIZE) /* must be at least this size for UDP */ return 0; + + if (memeq (ptr + OFF_ETHER, bcast, 6)) { + return do_bcast( ptr, size ); + } if (!memeq (ptr + OFF_ETHER, hwaddress, 6)) return 0; /* not for us */ |