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 */
|