⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arp.c

📁 ADAM2 sources (modified by Oleg)
💻 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 + -