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

📄 arp.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 4 页
字号:

    /* 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 + -