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

📄 arp.c

📁 mcf5307实验源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    ARP_Res_Count = 0;


}  /* end ARP_Init */

#if RARP_INCLUDED
/******************************************************************************/
/* FUNCTION                                                                   */
/*                                                                            */
/*   NU_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.                                                        */
/*                                                                            */
/* AUTHOR                                                                     */
/*                                                                            */
/*    Glen Johnson,      Accelerated Technology Inc.                          */
/*                                                                            */
/* CALLED BY                                                                  */
/*                                                                            */
/*    Applications                                                            */
/*                                                                            */
/* CALLS                                                                      */
/*                                                                            */
/*    NU_Obtain_Semaphore       Grab the semaphore.                           */
/*    NU_Release_Semaphore      Release the semaphore.                        */
/*    NU_Allocate_Memory        Allocate a block of memory.                   */
/*    NU_Deallocate_Memory      Deallocate a block of memory.                 */
/*    NU_Suspend_Task           Suspend a task.                               */
/*    NU_Current_Task_Pointer   Get a pointer to the current TCB.             */
/*    dll_dequeue               Remove the first item from a list.            */
/*    dll_remove                Remove an item from anywhere in a list.       */
/*    dll_enqueue               Add an item to the tail of a list.            */
/*    NET_Send                  Send a packet.                                */
/*    Stimerset                 Create a timer event.                         */
/*                                                                            */
/* INPUTS                                                                     */
/*                                                                            */
/*                                                                            */
/* 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.             */
/*                                                                            */
/* HISTORY                                                                    */
/*                                                                            */
/*    NAME                DATE        REMARKS                                 */
/*                                                                            */
/*    Glen Johnson      06/04/97    Created initial version.                  */
/*                                                                            */
/******************************************************************************/
STATUS NU_Rarp(VOID)
{
    BUFFER              *buf_ptr;
    ARPKT               *arp_pkt;
    STATUS              stat;
    ARP_RESOLVE_ENTRY   *ar_entry;

    /*  Don't let any other users in until we are done.  */
#ifdef PLUS
    NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
#else
    NU_Request_Resource(TCP_Resource, NU_WAIT_FOREVER);
#endif

    /* Allocate a buffer to place the arp packet in. */
    if ((buf_ptr = (BUFFER *)dll_dequeue((tqe_t *)&buffer_freelist))==NU_NULL)
           return NU_NO_BUFFERS;

    /* Initialize each field in the allocated buffer. */
    buf_ptr->data_len = sizeof(ARPKT);
    buf_ptr->next = (struct pqueue *)NU_NULL;
    buf_ptr->previous = (struct pqueue *)NU_NULL;
    buf_ptr->seqnum = 0;

    /* Set up a pointer to the packet. */
    arp_pkt = (ARPKT *)buf_ptr->packet;

    /* Copy in the dlayer header. */
    memcpy((void *)&arp_pkt->d, (const void *)&blankd, sizeof(DLAYER));

    /* Set up the target hardware address, this will be a broadcast packet. */
    memcpy((void *)arp_pkt->d.dest, (const void *)broadaddr, DADDLEN);

    /* Set the type to an ARP packet. */
    arp_pkt->d.type = intswap (ERARP);

    arp_pkt->hrd = intswap (HARDWARE_TYPE);     /*  Ether = 1 */
    arp_pkt->pro = intswap (ARPPRO);            /* IP protocol = 0x0800 */
    arp_pkt->hln = DADDLEN;                     /* Ethernet hardware length */
    arp_pkt->pln = 4;                           /* IP length = 4 */

    /* For an RARP request both the target and source hardware addresses should
       be set to my own. */
    memcpy((void *)arp_pkt->sha, (const void *)nnmyaddr, DADDLEN);
    memcpy((void *)arp_pkt->tha, (const void *)nnmyaddr, DADDLEN);

    /* Both our own and the server's IP address is unknown.  Set them both to
       the broadcast address. */
    memcpy((void *)arp_pkt->spa, (const void *)nullip, 4);
    memcpy((void *)arp_pkt->tpa, (const void *)nullip, 4);

    /* This is a RARP request. */
    arp_pkt->op = intswap(RARPQ);

    /* 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)
    {
        /* Free the buffer that was allocated above. */
        dll_enqueue((tqe_t *)&buffer_freelist, (tqe_t *)buf_ptr);

        return (NU_MEM_ALLOC);
    }

    /* 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);

    /* Initialize the entry structure. */
    ar_entry->ar_id         = ARP_Res_Count++;
    ar_entry->ar_send_count = 0;
    ar_entry->ar_task       = NU_Current_Task_Pointer();
    ar_entry->ar_buf_ptr    = buf_ptr;
    ar_entry->ar_pkt_type   = RARPQ;

    /* Continue to periodically retransmit the RARP request until either the IP
      address is resolved or until it's time to give up.
     */
    while ( (*(uint32 *)nnipnum == NU_NULL) &&
            (ar_entry->ar_send_count < RARP_MAX_ATTEMPTS) )
    {
        /* Send the RARP Request. */
        /* IMPORTANT:  I know that this is not a TCP_DATA_PKT, but by claiming
           that it is we can reuse the same packet for retransmits.  The
           alternative would be to allocate a new buffer and re-build the packet
           each time.
        */
        NET_Send(buf_ptr, sizeof(ARPKT), TCP_DATA_PKT);

        /* Increment the number of attempts made so far. */
        ar_entry->ar_send_count++;

        /* Transmit the next one in a second. */
        Stimerset (CONCLASS, RARP_REQUEST, ar_entry->ar_id, TICKSPERSEC, 0);

        /* Suspend this task pending the resolution of our IP address or a
           timeout. */
#ifdef PLUS
        NU_Release_Semaphore(&TCP_Resource);
        NU_Suspend_Task(NU_Current_Task_Pointer());
        NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
#else
        NU_Release_Resource(TCP_Resource);
        NU_Stop(NU_Current_Task_ID());
        NU_Request_Resource(TCP_Resource, NU_WAIT_FOREVER);
#endif

    }

    /* Free the buffer that was allocated above. */
    dll_enqueue((tqe_t *)&buffer_freelist, (tqe_t *)buf_ptr);

    /* Deallocate the ARP resolve entry structure. */
    dll_remove((tqe_t *)&ARP_Res_List, (tqe_t *)ar_entry);
    NU_Deallocate_Memory(ar_entry);

#ifdef PLUS
    NU_Release_Semaphore(&TCP_Resource);
#else
    NU_Release_Resource(TCP_Resource);
#endif

    /* Did we find the IP address. */
    if (*(uint32 *)nnipnum)
        return (NU_SUCCESS);
    else
        return (NU_RARP_INIT_FAILED);

}   /* end NU_Rarp */

/******************************************************************************/
/* FUNCTION                                                                   */
/*                                                                            */
/*   ARP_Event                                                                */
/*                                                                            */
/* DESCRIPTION                                                                */
/*                                                                            */
/*    This function is called from the events dispatcher to process events    */
/*    associated with ARP and RARP.                                           */
/*                                                                            */
/* AUTHOR                                                                     */
/*                                                                            */
/*    Glen Johnson,      Accelerated Technology Inc.                          */
/*                                                                            */
/* CALLED BY                                                                  */
/*                                                                            */
/*    NU_EventsDispatcher                                                     */
/*                                                                            */
/* CALLS                                                                      */
/*                                                                            */
/*    NU_Resume_Task            Resume a suspended task.                      */
/*                                                                            */
/* INPUTS                                                                     */
/*                                                                            */
/*    id                        Identifies the ARP entry structure we are     */
/*                                interested in.                              */
/*                                                                            */
/* OUTPUTS                                                                    */
/*                                                                            */
/*                                                                            */
/* HISTORY                                                                    */
/*                                                                            */
/*    NAME                DATE        REMARKS                                 */
/*                                                                            */
/*    Glen Johnson      06/04/97    Created initial version.                  */
/*                                                                            */
/******************************************************************************/
VOID ARP_Event(uint16 id)
{
    ARP_RESOLVE_ENTRY  *ar_entry;

    /* Search the ARP_Res_List for a match. */
    for(ar_entry = ARP_Res_List.ar_head;
        ar_entry != NU_NULL;
        ar_entry = ar_entry->ar_next)
    {
        /* We have a match when the ID's match. */
        if (ar_entry->ar_id == id)
            break;
    }

    /* If a match was found, start the pending task. */
    if (ar_entry)
    {
        NU_Resume_Task(ar_entry->ar_task);
    }

} /* ARP_Event */

#endif /* RARP_INCLUDED */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -