www.pudn.com > tcpipstack.rar > ARP.C
/* * SAR: Simple Address Resolution Protocol Implementation * Written by Geoffrey Cooper, September 27, 1983 * * This package implements a very simple version of the Plummer Address * Resolution Protocol (RFC 826). It allows clients to resolve Internet * addresses into Ethernet addresses, and knows how to respond to an * address resolution request (when the transmit buffer is free). * * Routines: * * sar_CheckPacket( pb ) => 1, if ARP packet and processed, 0 otherwise * sar_MapIn2Eth( ina, ethap ) => 1 if did it, 0 if couldn't. * * Copyright (C) 1983, 1986 IMAGEN Corporation * "This code may be duplicated in whole or in part provided that [1] there * is no commercial gain involved in the duplication, and [2] that this * copyright notice is preserved on all copies. Any other duplication * requires written notice of the author." |===================================================================| | The author of this code hereby licenses all duplication and/or | | modification of this code, in whole or in part, consistent with | | the terms of the GNU Library General Public License. | | - Geoffrey H. Cooper 10/29/97 | |===================================================================| |===================================================================| | My changes can be considered public domain. Geof's statement | | will cover everything. | | - Rick Rodman 09/02/97 | |===================================================================| 940424 rr minor changes 940529 rr ditto */ #include "tinytcp.h" #includeextern IP_Address local_IP_address; extern Ethernet_Address local_ethernet_address; extern Ethernet_Address broadcast_ethernet_address; int sar_CheckPacket( ap ) struct arp_Header *ap; { struct arp_Header *op; if( ap->hwType != arp_TypeEther || /* have ethernet hardware, */ ap->protType != 0x800 || /* and internet software, */ ap->opcode != ARP_REQUEST || /* and be a resolution req. */ ap->dstIPAddr != local_IP_address ) /* for my addr. */ return ( 0 ); /* .... or we ignore it. */ /* format response. */ op = ( struct arp_Header * ) sed_FormatPacket( ( Byte * ) ap -> srcEthAddr, 0x806 ); op->hwType = arp_TypeEther; op->protType = 0x800; op->hwProtAddrLen = (sizeof( Ethernet_Address ) << 8 ) + sizeof( IP_Address ); op->opcode = ARP_REPLY; op->srcIPAddr = local_IP_address; Move( ( Byte * ) local_ethernet_address, ( Byte * ) op->srcEthAddr, sizeof( Ethernet_Address )); ap->dstIPAddr = op->srcIPAddr; Move( ( Byte * ) ap->srcEthAddr, ( Byte * ) op->dstEthAddr, sizeof( Ethernet_Address )); sed_Send(sizeof(struct arp_Header)); return ( 1 ); } /* * Do an address resolution bit. */ int sar_MapIn2Eth( ina, ethap ) Longword ina; Ethernet_Address *ethap; { struct arp_Header * op; Longword endTime; Longword rxMitTime; sed_Receive( ( Byte * ) 0 ); endTime = MsecClock() + 2000; while ( endTime > MsecClock() ) { op = (struct arp_Header *) sed_FormatPacket( ( Byte * ) &broadcast_ethernet_address[ 0 ], 0x806 ); op->hwType = arp_TypeEther; op->protType = 0x800; op->hwProtAddrLen = (sizeof(Ethernet_Address) << 8) + sizeof( IP_Address ); op->opcode = ARP_REQUEST; op->srcIPAddr = local_IP_address; Move( ( Byte * ) local_ethernet_address, ( Byte * ) op->srcEthAddr, sizeof(Ethernet_Address)); op->dstIPAddr = ina; /* ...and send the packet */ sed_Send( sizeof(struct arp_Header) ); rxMitTime = MsecClock() + 250; while ( rxMitTime > MsecClock() ) { op = (struct arp_Header *)sed_IsPacket(); if ( op ) { if ( sed_CheckPacket( ( Word * ) op, 0x806 ) == 1 && op->protType == 0x800 && op->srcIPAddr == ina && op->opcode == ARP_REPLY ) { Move( ( Byte * ) op->srcEthAddr, ( Byte * ) ethap, sizeof(Ethernet_Address)); return ( 1 ); } sed_Receive( ( Byte * ) op ); } } } return ( 0 ); } /* end of arp.c */