📄 arp.c
字号:
/* Was an entry found? */
if(ar_entry)
{
switch (ar_entry->ar_pkt_type)
{
case ARPREQ :
/* We will send at most 5 ARP requests. After sending the 5th
timeout, and restart the pending task. */
if (ar_entry->ar_send_count < 5)
{
/* Send the ARP request. */
ARP_Request(ar_entry->ar_device, &ar_entry->ar_dest,
(UINT8 *)"\0\0\0\0\0\0", EARP, ARPREQ);
/* Setup a timer event to send the next one. */
UTL_Timerset(ARPRESOLVE, (UNSIGNED)id, ARPTO, (INT32)0);
/* Increment the number of tries. */
ar_entry->ar_send_count++;
}
else
{
/* After 5 tries we have not received a response. Cleanup. */
/* Save off the hosts IP addresss */
arp_host_ip = ar_entry->ar_dest;
/* Free all ARPs for this host */
do
{
/* Deallocate this buffer. */
MEM_One_Buffer_Chain_Free (ar_entry->ar_buf_ptr,
ar_entry->ar_buf_ptr->mem_dlist);
/* Deallocate the structure. */
DLL_Remove((tqe_t *)&ARP_Res_List, (tqe_t *)ar_entry);
NU_Deallocate_Memory(ar_entry);
/* There may be more entries for this host. We need to free
those buffers too. */
for(ar_entry = ARP_Res_List.ar_head;
ar_entry != NU_NULL;
ar_entry = ar_entry->ar_next)
{
if (ar_entry->ar_dest == arp_host_ip)
break;
}
} while (ar_entry);
}
break;
#if (INCLUDE_RARP == NU_TRUE)
case RARPQ :
if (ar_entry->ar_send_count < 5)
{
/* At this point the device is DV_RUNNING (It has been
initialized) but not DV_UP (There is no IP address attached.
In order to send a packet the device must be up and running.
So temporarily set the device to up so the RARP request can
be sent. */
ar_entry->ar_device->dev_flags |= DV_UP;
/* Send the RARP request. */
ARP_Request(ar_entry->ar_device, (UINT32 *)IP_Null,
ar_entry->ar_device->dev_mac_addr,
ERARP, RARPQ);
/* Clear the DV_UP flag. */
ar_entry->ar_device->dev_flags &= (~DV_UP);
/* Setup a timer event to send the next one in one second. */
UTL_Timerset(ARPRESOLVE, id, SCK_Ticks_Per_Second, (INT32)0);
/* Increment the number of tries. */
ar_entry->ar_send_count++;
}
else
{
/* Start the pending task. */
NU_Resume_Task(ar_entry->ar_task);
/* Deallocate the structure. */
DLL_Remove((tqe_t *)&ARP_Res_List, (tqe_t *)ar_entry);
NU_Deallocate_Memory(ar_entry);
}
break;
#endif /* INCLUDE_RARP == NU_TRUE */
/* This should never be possible, but is here to appease the
compiler. */
default :
;
} /* switch */
}
} /* ARP_Event */
#if (INCLUDE_RARP == NU_TRUE)
/*************************************************************************
*
* FUNCTION
*
* ARP_Rarp
*
* DESCRIPTION
*
* This function is responsible for resolving the IP address of
* this host. It is the entry point for applications that need to
* use RARP (Reverse Address Resolution Protocol). RARP is
* typically required by disk-less workstations. Such workstations
* have no means to store their IP address locally.
*
* INPUTS
*
* *device_name Name of device to resolve.
*
* OUTPUTS
*
* NU_MEM_ALLOC Memory allocation failure.
* NU_NO_BUFFERS No buffers a re available to build the
* pkt in.
* NU_RARP_INIT_FAILED A response was not received to the
* request.
* NU_SUCCESS The IP was successfully resolved.
* NU_INVALID_PARM Device name is invalid.
* NU_HOST_UNREACHABLE Device is not initialized.
*
*************************************************************************/
STATUS ARP_Rarp(CHAR *device_name)
{
ARP_RESOLVE_ENTRY *ar_entry;
DV_DEVICE_ENTRY *device;
UINT8 mask[IP_ADDR_LEN];
UINT8 dev_ip_addr[IP_ADDR_LEN];
NU_SUPERV_USER_VARIABLES
/* Switch to supervisor mode. */
NU_SUPERVISOR_MODE();
/* Don't let any other users in until we are done. */
NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
/* Look up the device for which an IP address needs to be resolved. */
if ( (device = DEV_Get_Dev_By_Name(device_name)) == NU_NULL )
{
NU_Release_Semaphore(&TCP_Resource);
/* Switch back to user mode. */
NU_USER_MODE();
return (NU_INVALID_PARM);
}
/* At this point the device is not completely up yet because there is no IP
address attached to the device. However, the device must have been
initialized before Rarp is called. */
if ( !(device->dev_flags & DV_RUNNING) )
{
NU_Release_Semaphore(&TCP_Resource);
/* Switch back to user mode. */
NU_USER_MODE();
return (NU_HOST_UNREACHABLE);
}
/* At this point the device is DV_RUNNING (It has been intialized) but
not DV_UP (There is no IP address attached. In order to send a
packet the device must be up and running. So temporarily set the
device to up so the RARP request can be sent. */
device->dev_flags |= DV_UP;
/* Send the RARP request. */
if ( ARP_Request(device, (UINT32 *)IP_Null, device->dev_mac_addr, ERARP,
RARPQ) != NU_SUCCESS)
{
NU_Release_Semaphore(&TCP_Resource);
/* Switch back to user mode. */
NU_USER_MODE();
return (NU_NO_BUFFERS);
}
/* Clear the DV_UP flag. */
device->dev_flags &= (~DV_UP);
/* Allocate memory for an ARP resolve entry. This structure is used to keep
track of this resolution attempt. */
if (NU_Allocate_Memory(&System_Memory, (VOID **)&ar_entry,
sizeof(*ar_entry),
(UNSIGNED)NU_NO_SUSPEND) != NU_SUCCESS)
{
NU_Release_Semaphore(&TCP_Resource);
/* Switch back to user mode. */
NU_USER_MODE();
return (NU_MEM_ALLOC);
}
/* Initialize the entry structure. */
ar_entry->ar_id = ARP_Res_Count++;
ar_entry->ar_device = device;
ar_entry->ar_dest = 0xfffffffful;
ar_entry->ar_send_count = 1; /* Already sent once above. */
ar_entry->ar_task = NU_Current_Task_Pointer();
ar_entry->ar_buf_ptr = NU_NULL;
ar_entry->ar_pkt_type = RARPQ;
/* Order is not important. Simply add the new entry to the end of the
list. */
DLL_Enqueue((tqe_t *)&ARP_Res_List, (tqe_t *)ar_entry);
/* Transmit the next one in a second. */
UTL_Timerset (RARP_REQUEST, ar_entry->ar_id, SCK_Ticks_Per_Second, 0);
/* Suspend this task pending the resolution of our IP address or a
timeout. */
SCK_Suspend_Task(NU_Current_Task_Pointer());
if (device->dev_addr.dev_ip_addr != NU_NULL)
{
/* Get the address into a local array. */
PUT32(dev_ip_addr, 0, device->dev_addr.dev_ip_addr);
/* Get the mask associated with an address of this type. */
IP_Get_Net_Mask(dev_ip_addr, mask);
DEV_Attach_IP_To_Device(device_name, dev_ip_addr, mask);
}
/* Deallocate the ARP resolve entry structure. */
DLL_Remove((tqe_t *)&ARP_Res_List, (tqe_t *)ar_entry);
NU_Deallocate_Memory(ar_entry);
NU_Release_Semaphore(&TCP_Resource);
/* Did we find the IP address. */
if (device->dev_addr.dev_ip_addr)
{
/* Switch back to user mode. */
NU_USER_MODE();
return (NU_SUCCESS);
}
else
{
/* Switch back to user mode. */
NU_USER_MODE();
return (NU_RARP_INIT_FAILED);
}
} /* end ARP_Rarp */
#endif /* INCLUDE_RARP == NU_TRUE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -