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

📄 lcp.c

📁 PPP协议C语言源程序
💻 C
📖 第 1 页 / 共 5 页
字号:
                    (LCP_CLEAR_HIGH & (*(lcp_pkt_ptr + LCP_CONFIG_OPTS + 3)));

                /* Make sure they are not the same. Note :
                   lcp->local_options.magic_number is stored in the endien order
                   of the processor. Therefore the longswap on it is needed.
                   lcp->foreign_options.magic_number is stored from the incomming
                   pkt and will always be in the correct order, so no swapping
                   is needed. */
                if (lcp->foreign_options.magic_number ==
                                        LONGSWAP (lcp->local_options.magic_number))
                {
                    /* Since they are we must NAK with a new number */

                    /* Put it in the nak packet */
                    memcpy (lcp_nak_ptr, lcp_pkt_ptr,
                                                  LCP_MAGIC_NUMBER_LENGTH);

                    /* Get a new number */
                    lcp->local_options.magic_number = LCP_Random_Number32();

                    /* Move the pointer to the spot where the number goes. */
                    lcp_nak_ptr += LCP_CONFIG_OPTS;

                    /* Fill in the new number */
                    PUT32 (lcp_nak_ptr, 0, lcp->local_options.magic_number);

                    /* Update the pkt ptr and length */
                    nak_length += LCP_MAGIC_NUMBER_LENGTH;
                    lcp_nak_ptr += LCP_MAGIC_NUMBER_LENGTH - LCP_CONFIG_OPTS;

                    /* Set the status that all options are not ok */
                    options_ok = NU_FALSE;
                }

                /* Update the pkt pointer and the packet size */
                lcp_pkt_ptr += LCP_MAGIC_NUMBER_LENGTH;
                length -= LCP_MAGIC_NUMBER_LENGTH;

                break;

            case LCP_PROTOCOL_FIELD_COMPRESS :

                /* See if we are going to use protocol compression */
                if (lcp->local_options.protocol_field_compression)
                    lcp->foreign_options.protocol_field_compression = NU_TRUE;
                else
                {
                    /* We need to reject this option since it is a boolean
                       option */

                    /* Put it in the reject packet */
                    memcpy (lcp_reject_ptr, lcp_pkt_ptr,
                                                LCP_PROTOCOL_COMPRESS_LENGTH);

                    /* Update the length and the ptr */
                    lcp_reject_ptr += LCP_PROTOCOL_COMPRESS_LENGTH;
                    reject_length += LCP_PROTOCOL_COMPRESS_LENGTH;

                    /* Mark that we need to reject something */
                    dont_need_to_reject = NU_FALSE;
                }

                /* Update the pkt pointer and the packet size */
                lcp_pkt_ptr += LCP_PROTOCOL_COMPRESS_LENGTH;
                length -= LCP_PROTOCOL_COMPRESS_LENGTH;

                break;

            case LCP_ADDRESS_FIELD_COMPRESS :

                /* See if we are going to use address compression */
                if (lcp->local_options.address_field_compression)
                    lcp->foreign_options.address_field_compression = NU_TRUE;
                else
                {
                    /* We need to reject this option since it is a boolean
                       option */

                    /* Put it in the reject packet */
                    memcpy (lcp_reject_ptr, lcp_pkt_ptr,
                                                LCP_ADDRESS_COMPRESS_LENGTH);

                    /* Update the length and the ptr */
                    lcp_reject_ptr += LCP_ADDRESS_COMPRESS_LENGTH;
                    reject_length += LCP_ADDRESS_COMPRESS_LENGTH;

                    /* Mark that we need to reject something */
                    dont_need_to_reject = NU_FALSE;
                }


                /* Update the pkt pointer and the packet size */
                lcp_pkt_ptr += LCP_ADDRESS_COMPRESS_LENGTH;
                length -= LCP_ADDRESS_COMPRESS_LENGTH;

                break;

            default                         :

                /* If we make it here then there is a protocol that we
                   do not understand, send a reject. */

                /* Put it in the reject packet */
                memcpy (lcp_reject_ptr, lcp_pkt_ptr,
                          (unsigned int)lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET]);

                /* Update the length and the ptr */
                lcp_reject_ptr += lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET];
                reject_length += lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET];

                /* Mark that we need to reject something */
                dont_need_to_reject = NU_FALSE;

                /* The length is usually the second field in the protocol,
                   so minus it off and look at the reset of the pkt. */
                length -= lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET];
                lcp_pkt_ptr += lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET];

                break;

        } /* switch */
    } /* while */


    /* See if all the options are ok, if so send an ack */
    if (options_ok && dont_need_to_reject)
    {
#ifdef NU_DEBUG_PPP
        _PRINT ("acking ");
#endif

        /* Every option is ok. The ack pkt is the same as the config pkt.
           The only difference is that the pkt code is now config ack. */

        /* Change the pkt code and put in the same ID */
        lcp_ack_pkt->code = LCP_CONFIGURE_ACK;
        lcp_ack_pkt->identifier = identifier;

        /* Copy the pkt data over */
        memcpy (&lcp_ack_pkt->data, lcp_pkt + LCP_DATA_OFFSET,
                                           ((unsigned int)INTSWAP(lcp_ack_pkt->length)));

        /* Update the lengths for the buffer. */
        ack_buf_ptr->data_len = ack_buf_ptr->mem_total_data_len =
                INTSWAP(lcp_ack_pkt->length);

        /* Set the packet type. */
        ack_buf_ptr->mem_flags = NET_LCP;

        /* Set the dlist for this buffer. */
        ack_buf_ptr->mem_dlist = &MEM_Buffer_Freelist;

        /* Send it */
        buf_ptr->mem_buf_device->dev_output (ack_buf_ptr,
                        buf_ptr->mem_buf_device, NU_NULL, NU_NULL);

        /* Release the buffer for the NAK packet since it was not sent. */
        MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, nak_buf_ptr);

        /* Release the buffer for the reject packet since it was not sent. */
        MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, reject_buf_ptr);

    }
    else
    {
        /* Release the buffer for the ACK packet since it was not sent. */
        MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, ack_buf_ptr);

        /* One or more options were not ok. We must nak or reject them. */

        /* See if we need to nak something. Only NAK if we do not have to
           reject. */
        if ((!options_ok) && (dont_need_to_reject))
        {
#ifdef NU_DEBUG_PPP
            _PRINT ("naking ");
#endif

            /* Put in the pkt indentifier and type */
            lcp_nak_pkt->identifier = identifier;
            lcp_nak_pkt->code = LCP_CONFIGURE_NAK;
            lcp_nak_pkt->length = INTSWAP(nak_length);

            /* Update the lengths for the buffer. */
            nak_buf_ptr->data_len = nak_buf_ptr->mem_total_data_len =
                nak_length;

            /* Set the packet type. */
            nak_buf_ptr->mem_flags = NET_LCP;

            /* Set the dlist for this buffer. */
            nak_buf_ptr->mem_dlist = &MEM_Buffer_Freelist;

            /* Send the pkt */
            buf_ptr->mem_buf_device->dev_output (nak_buf_ptr,
                            buf_ptr->mem_buf_device, NU_NULL, NU_NULL);
        }
        else
            /* Release the buffer for the NAK packet since it was not sent. */
            MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, nak_buf_ptr);


        /* See if we need to reject something */
        if (!dont_need_to_reject)
        {
#ifdef NU_DEBUG_PPP
            _PRINT ("rejecting ");
#endif
            /* Put in the pkt indentifier and type */
            lcp_reject_pkt->identifier = identifier;
            lcp_reject_pkt->code = LCP_CONFIGURE_REJECT;
            lcp_reject_pkt->length = INTSWAP(reject_length);

            /* Update the lengths for the buffer. */
            reject_buf_ptr->data_len = reject_buf_ptr->mem_total_data_len =
                reject_length;

            /* Set the packet type. */
            reject_buf_ptr->mem_flags = NET_LCP;

            /* Set the dlist for this buffer. */
            reject_buf_ptr->mem_dlist = &MEM_Buffer_Freelist;

            /* Send the pkt */
            buf_ptr->mem_buf_device->dev_output (reject_buf_ptr,
                                    buf_ptr->mem_buf_device, NU_NULL, NU_NULL);
        }
        else
            /* Release the buffer for the reject packet since it was not sent. */
            MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, reject_buf_ptr);

    }

    return (options_ok && dont_need_to_reject);
}

/***************************************************************************
*
*   FUNCTION
*
*       LCP_Send_Terminate_Ack
*
*   DESCRIPTION
*
*       Sends a terminate ack packet to the peer.
*
*   INPUTS
*
*       UINT8       *in_buf_ptr     Pointer to the packet that
*                                   requested termination
*       UINT16      protocol_type   Which protocol, LCP or NCP, is
*                                   sending the ack
*
*   OUTPUTS
*
*       None
*
****************************************************************************/
VOID LCP_Send_Terminate_Ack(NET_BUFFER *in_buf_ptr, UINT16 protocol_type)
{
    NET_BUFFER          *buf_ptr;
    UINT16              length;
    UINT8   HUGE        *lcp_pkt = in_buf_ptr->data_ptr;
    LINK_LAYER  *link_layer;

    link_layer = (LINK_LAYER*)in_buf_ptr->mem_buf_device->link_layer;

#ifdef NU_DEBUG_PPP
    _PRINT ("\nsend term ack ");
#endif

    /* Is there a negotiation packet that can be reused? */
    if (link_layer->lcp.negotiation_pkt != NU_NULL)
        buf_ptr = link_layer->lcp.negotiation_pkt;
    else
        /* Allocate a buffer for the LCP packet. */
        link_layer->lcp.negotiation_pkt
                    = buf_ptr = MEM_Buffer_Dequeue (&MEM_Buffer_Freelist);

    /* Make sure a buffer was available */
    if (buf_ptr == NU_NULL)
    {
        NERRS_Log_Error (TCP_SEVERE, __FILE__, __LINE__);

        /* Get out */
        return;
    }

    /* Set the data ptr */
    buf_ptr->data_ptr = (buf_ptr->mem_parent_packet + in_buf_ptr->mem_buf_device->dev_hdrlen);

    /* The pkt to be sent is the same as the one RX except the code field is
       changed to ACK. */

    /* Put in the pkt type */
    lcp_pkt [LCP_CODE_OFFSET] = LCP_TERMINATE_ACK;

    /* Get the length */
    length      = (UINT16) ( (*(lcp_pkt + LCP_LENGTH_OFFSET)) << 8 );
    length      =  length | *(lcp_pkt + LCP_LENGTH_OFFSET + 1);

    /* Save a copy of this packet for retransmission, if needed. */
    memcpy (buf_ptr->data_ptr, lcp_pkt, (unsigned int)length);

    /* Set the protocol type */
    if (protocol_type == PPP_LINK_CONTROL_PROTOCOL)
        buf_ptr->mem_flags = NET_LCP;
    else
        if (protocol_type == PPP_IP_CONTROL_PROTOCOL)
            buf_ptr->mem_flags = NET_IPCP;

    /* Set the length */
    buf_ptr->data_len = buf_ptr->mem_total_data_len = length;

    /* Set the dlist to NULL so this buffer will not be
       put on the free list. */
    buf_ptr->mem_dlist = NU_NULL;

    /* Send the pkt */
    in_buf_ptr->mem_buf_device->dev_output (buf_ptr, in_buf_ptr->mem_buf_device, NU_NULL, NU_NULL);

}

/***************************************************************************
*
*   FUNCTION
*
*       LCP_Send_Terminate_Req
*
*   DESCRIPTION
*
*       Sends a terminate req packet to the peer.
*
*   INPUTS
*
*       *dev_ptr
*
*   OUTPUTS
*
*       None
*
****************************************************************************/
VOID LCP_Send_Terminate_Req (DV_DEVICE_ENTRY *dev_ptr)
{
    NET_BUFFER  *buf_ptr;
    LCP_HEADER   *lcp_pkt;
    UINT16  len;
    LINK_LAYER   *link_layer;

    link_layer = (LINK_LAYER*)dev_ptr->dev_ppp_layer;

#ifdef NU_DEBUG_PPP
    _PRINT ("send term req ");
#endif

    len = 0;

    /* Is there a negotiation packet that can be reused? */
    if (link_layer->lcp.negotiation_pkt != NU_NULL)
        buf_ptr = link_layer->lcp.negotiation_pkt;
    else
        /* Allocate a buffer for the LCP packet. */
        link_layer->lcp.negotiation_pkt =
                        buf_ptr = MEM_Buffer_Dequeue (&MEM_Buffer_Freelist);

    /* Make sure a buffer was available */
    if (buf_ptr == NU_NULL)
    {
        NERRS_Log_Error (TCP_SEVERE, __FILE__, __LINE__);

        /* Get out */
        return;
    }

    /* Set the data pointer for the buffer */
    buf_ptr->data_ptr = (buf_ptr->mem_parent_packet + dev_ptr->dev_hdrlen);

    /* Point the LCP structure to the data part of the outgoing buffer */
    lcp_pkt = (LCP_HEADER *) buf_ptr->data_ptr;

    /* Set up the terminate pkt. */
    lcp_pkt->code        = LCP_TERMINATE_REQUEST;
    lcp_pkt->identifier  = LCP_Random_Number();

    /* Fill in the length for the lcp packet. */
    len                 += LCP_HEADER_LENGTH;
    lcp_pkt->length      = INTSWAP (len);

    /* Set the type of packet to be TX*/

⌨️ 快捷键说明

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