📄 arp.c
字号:
/*************************************************************************
*
* Copyright (c) 1993 - 2001 Accelerated Technology, Inc.
*
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the
* subject matter of this material. All manufacturing, reproduction,
* use, and sales rights pertaining to this subject matter are governed
* by the license agreement. The recipient of this software implicitly
* accepts the terms of the license.
*
*************************************************************************/
/* Portions of this program were written by: */
/*************************************************************************
*
* part of:
* TCP/IP kernel for NCSA Telnet
* by Tim Krauskopf
*
* National Center for Supercomputing Applications
* 152 Computing Applications Building
* 605 E. Springfield Ave.
* Champaign, IL 61820
*
*************************************************************************/
/*************************************************************************
*
* FILE NAME VERSION
*
* ARP.C 4.4
*
* DESCRIPTION
*
* This file contains the implementation of ARP (Address Resolution
* Protocol).
*
* DATA STRUCTURES
*
* ARP_Cache An array that contains the ARP cache.
* ARP_Res_List This is a list of packets that are awaitng
* the resolution of an address before they
* can be transmitted.
* ARP_Res_Count Global counter used to assign a unique ID
* to each entry in ARP_Res_List.
*
* FUNCTIONS
*
* ARP_Build_Pkt Construct an ARP packet.
* ARP_Cache_Update Add an entry to the ARP cache.
* ARP_Check_Events Check for pending ARP events.
* ARP_Event Process an ARP timer event.
* ARP_Find_Entry Search the ARP cache.
* ARP_Init Initialize the ARP Module.
* ARP_Interpret Process a received ARP Packet.
* ARP_Reply Send an ARP reply.
* ARP_Request Send an ARP request.
* ARP_Resolve Resolve an Ethernet address.
* ARP_Rarp
*
* DEPENDENCIES
*
* externs.h
* nucleus.h
* tcpdefs.h
* target.h
* externs.h
* net_extr.h
* socketd.h
* nerrs.h
* dev.h
* arp.h
* ip.h
* net.h
* netevent.h
* tcp.h
*
*************************************************************************/
#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "net/inc/net_extr.h"
#include "net/inc/socketd.h"
#include "net/inc/nerrs.h"
#include "net/inc/dev.h"
#include "net/inc/arp.h"
#include "net/inc/ip.h"
#include "net/inc/net.h"
#include "net/inc/netevent.h"
#include "net/inc/tcp.h"
/* This is our ARP cache. */
ARP_ENTRY ARP_Cache[ARP_CACHE_LENGTH];
/* This is the resolve list. An item is placed on this list when a MAC address
needs to be resolved. It is removed once the address has been resolved or
when failure occurs.
*/
ARP_RESOLVE_LIST ARP_Res_List;
UINT16 ARP_Res_Count;
/* Local Prototypes. */
VOID ARP_Check_Events(ARP_LAYER *a_pkt);
/*************************************************************************
*
* FUNCTION
*
* ARP_Build_Pkt
*
* DESCRIPTION
*
* This function will get a free buffer and fill in as much of the
* ARP packet fields as possible. All other fields must be updated
* by the calling function.
*
* INPUTS
*
* *dev The device to transmit the packet on.
* tipnum The target IP number.
* *thardware The target hardware address.
* pkt_type The ARP packet type, reply or request.
*
* OUTPUTS
*
* *NET_BUFFER Pointer to the buffer in which the packet
* was constructed.
*
*************************************************************************/
NET_BUFFER *ARP_Build_Pkt (DV_DEVICE_ENTRY *dev, UINT32 tipnum, const UINT8 *thardware,
INT16 pkt_type)
{
NET_BUFFER *buf_ptr;
UINT8 *arp_pkt;
/* Allocate a buffer to place the arp packet in. */
if ((buf_ptr = MEM_Buffer_Dequeue(&MEM_Buffer_Freelist)) == NU_NULL)
{
return (NU_NULL);
}
/* Initialize each field in the allocated buffer. */
buf_ptr->mem_total_data_len = buf_ptr->data_len = sizeof(ARP_LAYER);
buf_ptr->data_ptr = buf_ptr->mem_parent_packet + (NET_MAX_ARP_HEADER_SIZE
- sizeof (ARP_LAYER));
buf_ptr->mem_seqnum = 0;
buf_ptr->mem_dlist = (NET_BUFFER_HEADER *) &MEM_Buffer_Freelist;
buf_ptr->next = NU_NULL;
buf_ptr->next_buffer = NU_NULL;
/* Set up a pointer to the packet. */
arp_pkt = (UINT8 *)buf_ptr->data_ptr;
PUT16(arp_pkt, ARP_HRD_OFFSET, HARDWARE_TYPE); /* Ether = 1 */
PUT16(arp_pkt, ARP_PRO_OFFSET, ARPPRO); /* IP protocol = 0x0800 */
PUT8(arp_pkt, ARP_HLN_OFFSET, DADDLEN); /* Ethernet hardware length */
PUT8(arp_pkt, ARP_PLN_OFFSET, 4); /* IP length = 4 */
/* sender's hardware addr */
PUT_STRING(arp_pkt, ARP_SHA_OFFSET, dev->dev_mac_addr, DADDLEN);
PUT_STRING(arp_pkt, ARP_THA_OFFSET, thardware, DADDLEN);
/* sender's IP addr */
PUT32(arp_pkt, ARP_SPA_OFFSET, dev->dev_addr.dev_ip_addr);
/* put in IP address we want */
PUT32(arp_pkt, ARP_TPA_OFFSET, tipnum);
/* Set the packet type. Either a request or a response. */
PUT16(arp_pkt, ARP_OP_OFFSET, pkt_type);
return(buf_ptr);
} /* end ARP_Build_Pkt */
/*************************************************************************
*
* FUNCTION
*
* ARP_Reply
*
* DESCRIPTION
*
* This function sends an ARP reply. Called whenever an ARP request
* is received.
*
* INPUTS
*
* *thardware The target hardware address.
* tipnum The target IP number.
* *dev Pointer to the device the reply will be
* sent from.
* OUTPUTS
*
* NU_SUCCESS Indicates successful operation.
* NU_NO_BUFFERS Indicates failure to allocate a buffer.
*
*************************************************************************/
STATUS ARP_Reply(UINT8 *thardware, UINT32 tipnum, DV_DEVICE_ENTRY *dev)
{
NET_BUFFER *buf_ptr;
ARP_MAC_HEADER mh;
if ( (buf_ptr = ARP_Build_Pkt(dev, tipnum, (const UINT8 *)thardware,
ARPREP)) == NU_NULL )
{
return (NU_NO_BUFFERS);
}
UTL_Zero(&mh, sizeof(mh));
/* This is a psuedo MAC hedaer that is passed to the MAC layer send function.
The MAC layer information that is know is filled in. A family of
SK_FAM_UNSPEC lets the MAC layer know that this is not an IP datagram and
it should not try to resolve a hardware address. */
memcpy (mh.ar_mac.ar_mac_ether.dest, thardware, DADDLEN);
mh.ar_mac.ar_mac_ether.type = EARP;
mh.ar_family = SK_FAM_UNSPEC;
mh.ar_len = sizeof(mh);
/* Send the ARP Packet. */
(*dev->dev_output)( buf_ptr, dev, (SCK_SOCKADDR_IP *)&mh, NU_NULL);
return (NU_SUCCESS);
} /* end ARP_Reply */
/*************************************************************************
*
* FUNCTION
*
* ARP_Interpret
*
* DESCRIPTION
*
* Interpret ARP packets.
* Look at incoming ARP packet and make required assessment of
* usefulness, check to see if we requested this packet, clear
* all appropriate flags.
*
* INPUTS
*
* *a_pkt Pointer to the ARP packet to process.
* *device Pointer to the device the packet was received
* on.
*
* OUTPUTS
*
* NU_SUCCESS Indicates successful operation.
* NU_NO_ACTION Indicates that the packet was determined
* to be unacceptable.
*************************************************************************/
STATUS ARP_Interpret(ARP_LAYER *a_pkt, DV_DEVICE_ENTRY *device)
{
UINT32 my_ip;
UINT8 sha[DADDLEN];
UINT32 target_ip_addr;
UINT32 source_ip_addr;
#if (INCLUDE_RARP == NU_TRUE)
ARP_RESOLVE_ENTRY *ar_entry;
#endif
my_ip = device->dev_addr.dev_ip_addr;
target_ip_addr = GET32(a_pkt, ARP_TPA_OFFSET);
source_ip_addr = GET32(a_pkt, ARP_SPA_OFFSET);
/* Check to see if the packet was for me or if it was sent by someone using
my IP address. If neither then return. Most ARP packets should fall
into this category.
*/
if ( (target_ip_addr != my_ip) &&
(source_ip_addr != my_ip) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -