📄 arp.c
字号:
/*------------------------------------------------------------------------------*/
/* */
/* Copyright (C) 2000-2003 by Texas Instruments, Inc. All rights reserved. */
/* Copyright (C) 2001-2003 Telogy Networks. */
/* */
/* NOTE: THIS VERSION OF CODE IS MAINTAINED BY TELOGY NETWORKS AND NOT TI! */
/*------------------------------------------------------------------------------*/
/* */
/* 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." */
/* */
/* */
/*------------------------------------------------------------------------------*/
#include "_stdio.h"
#include "tinyip.h"
#define MAX_ARP_ENTRIES 5
typedef struct _arpEntry
{
int valid;
eth_HwAddress ethAddr;
in_HwAddress ipAddr;
}arpEntry;
static arpEntry arpTable[MAX_ARP_ENTRIES];
int sar_CheckPacket(arp_Header *ap)
{
register arp_Header *op;
if ( ap->hwType != wfix(arp_TypeEther) || /* have ethernet hardware, */
ap->protType != wfix(0x800) || /* and internet software, */
ap->opcode != wfix(ARP_REQUEST) || /* and be a resolution req. */
ap->dstIPAddr != lfix(sin_lclINAddr) /* for my addr. */
)
return ( 0 ); /* .... or we ignore it. */
/* format response. */
op = (arp_Header *)sed_FormatPacket(ap->srcEthAddr, 0x806);
op->hwType = wfix(arp_TypeEther);
op->protType = wfix(0x800);
op->hwProtAddrLen = wfix((sizeof(eth_HwAddress) << 8) + sizeof(in_HwAddress));
op->opcode = wfix(ARP_REPLY);
op->srcIPAddr = lfix(sin_lclINAddr);
MoveW(sed_lclEthAddr, op->srcEthAddr, sizeof(eth_HwAddress));
op->dstIPAddr = ap->srcIPAddr;
MoveW(ap->srcEthAddr, op->dstEthAddr, sizeof(eth_HwAddress));
sed_Send(sizeof(arp_Header));
return ( 1 );
}
/*
* Do an address resolution bit.
*/
int sar_MapIn2Eth(longword ina, eth_HwAddress *ethap)
{
register arp_Header *op;
extern in_HwAddress sin_lclINAddr;
longword endTime;
longword rxMitTime;
if (sar_FindEntry(ina, ethap))
return 1;
endTime = clock_ValueRough() + 2000;
while ( endTime > clock_ValueRough() )
{
op = (arp_Header *)sed_FormatPacket(&sed_ethBcastAddr[0], 0x806);
op->hwType = wfix(arp_TypeEther);
op->protType = wfix(0x800);
op->hwProtAddrLen = wfix((sizeof(eth_HwAddress) << 8) + sizeof(in_HwAddress));
op->opcode = wfix(ARP_REQUEST);
op->srcIPAddr = lfix(sin_lclINAddr);
MoveW(sed_lclEthAddr, op->srcEthAddr, sizeof(eth_HwAddress));
if ((ina&net_IpMask)!=(sin_lclINAddr&net_IpMask))
ina=net_Gateway;
op->dstIPAddr = lfix(ina);
/* ...and send the packet */
sed_Send( sizeof(arp_Header) );
rxMitTime = clock_ValueRough() + 500;
while ( rxMitTime > clock_ValueRough() )
{
op = (arp_Header *)sed_IsPacket();
if ( op )
{
if ((sed_CheckPacket(op, 0x806) == 1) &&
(op->protType == wfix(0x800)) &&
(op->srcIPAddr == lfix(ina)) &&
(op->opcode == wfix(ARP_REPLY)) )
{
MoveW(op->srcEthAddr, ethap, sizeof(eth_HwAddress));
return ( 1 );
}
}
}
}
return ( 0 );
}
/*
* Do a one's complement checksum
*/
int checksum(void *vdp, int length)
{
int len;
longword sum;
word *dp=vdp;
len = length >> 1;
sum = 0;
while ( len-- > 0 )
{
sum += wfix(*dp);
dp++;
}
if ( length & 1 ) sum += (wfix(*dp) & 0xFF00);
sum = (sum & 0xFFFF) + ((sum >> 16) & 0xFFFF);
sum = (sum & 0xFFFF) + ((sum >> 16) & 0xFFFF);
return ( sum );
}
/*
* Move bytes from hither to yon
*/
void Move( void *vsrc, void *vdest, int numbytes )
{
byte *src=vsrc;
byte *dest=vdest;
if ( numbytes <= 0 ) return;
if ( src < dest ) {
src += numbytes;
dest += numbytes;
do {
*--dest = *--src;
} while ( --numbytes > 0 );
} else
do {
*dest++ = *src++;
} while ( --numbytes > 0 );
}
void sar_initTable(void)
{
sys_memset(&arpTable[0], 0, (MAX_ARP_ENTRIES*sizeof(arpEntry)));
}
int sar_addEntry(in_HwAddress ip, eth_HwAddress eth)
{
int i;
for (i = 0; i < MAX_ARP_ENTRIES; i++)
{
if ((arpTable[i].valid == FALSE) ||
((arpTable[i].valid == TRUE) && (arpTable[i].ipAddr == ip)))
{
arpTable[i].valid = TRUE;
arpTable[i].ipAddr = ip;
MoveW(eth, arpTable[i].ethAddr, sizeof(eth_HwAddress));
return 1;
}
}
return 0;
}
int sar_FindEntry(in_HwAddress ip, eth_HwAddress *eth)
{
int i;
for (i = 0; i < MAX_ARP_ENTRIES; i++)
{
if (arpTable[i].ipAddr == ip)
{
MoveW(arpTable[i].ethAddr, eth, sizeof(eth_HwAddress));
return 1;
}
}
return 0;
}
#if 0
int sar_deleteEntry(in_HwAddress ip)
{
int i;
for (i = 0; i < MAX_ARP_ENTRIES; i++)
{
if (arpTable[i].ipAddr == ip)
{
sys_memset(arpTable[i], 0, sizeof(arpEntry));
return 1;
}
}
return 0;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -