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

📄 hdlc.c

📁 PPP协议C语言源程序
💻 C
📖 第 1 页 / 共 4 页
字号:

                if (link_layer->received < PPP_MAX_RX_SIZE)
                {
                    link_layer->rx_ring[link_layer->rx_ring_write].buffer[link_layer->received++]
                                                = PPP_HDLC_CONTROL_ESCAPE;


#ifdef DEBUG_PKT_TRACE
                    if (debug_rx_index == PKT_TRACE_SIZE)
                        debug_rx_index = 0;

                    debug_rx_buf[debug_rx_index++] = PPP_HDLC_CONTROL_ESCAPE;
#endif
                }

                break;

            default:

                if (link_layer->received < PPP_MAX_RX_SIZE)
                {
                    link_layer->rx_ring[link_layer->rx_ring_write].buffer[link_layer->received++]
                                                = ( c ^PPP_HDLC_TRANSPARENCY);


#ifdef DEBUG_PKT_TRACE
                    if (debug_rx_index == PKT_TRACE_SIZE)
                        debug_rx_index = 0;

                    debug_rx_buf[debug_rx_index++] = (c ^ PPP_HDLC_TRANSPARENCY);
#endif
                }

                break;
        }

        /* Reset the escape received flag. */
        link_layer->esc_received = NU_FALSE;
    }

    /* This is either just another character or its the end of the
       frame. */

    else
    {
        switch (c)
        {
            /* If it's an END character, then we're done with the packet. */

            case PPP_HDLC_FRAME:

                /* A minor optimization:  If there is no data in the packet,
                   ignore it.  This is meant to avoid bothering IP with all the
                   empty packets generated by the duplicate END characters which
                   are in Serial Line IP.
                */

                if(link_layer->received)
                {
                    /* Store the length of this packet and a pointer to it for
                       the HISR */

                    /*  Store the device for this interrupt. */
                    link_layer->rx_ring[link_layer->rx_ring_write].device = device;

                    /* Update the length of current buffer. */
                    link_layer->rx_ring[link_layer->rx_ring_write].size = link_layer->received;

                    /* Add this packet to the HISR's packet pointer list. Make
                       sure there is room first. We must also check for looping
                       of the write pointer. */
                    if ((_ppp_rx_queue_write + 1) >= HDLC_MAX_HOLDING_PACKETS_PTR)
                    {
                        /* This is the case if it does wrap. */
                        if (_ppp_rx_queue_read != 0)
                        {
                            _ppp_rx_queue[_ppp_rx_queue_write] =
                                            &link_layer->rx_ring[link_layer->rx_ring_write++];

                            /* Wrap the HISR write pointer. */
                            _ppp_rx_queue_write = 0;

                            /* Activate the HISR.  The HISR will inform the upper layer
                               protocols that a packet has arrived. */
                            NU_Activate_HISR (&PPP_RX_HISR);

                        }
                        else
                            NERRS_Log_Error (TCP_SEVERE, __FILE__, __LINE__);

                    }
                    else
                    {
                        /* This is the case if it doesn't wrap */
                        if ((_ppp_rx_queue_write + 1) != _ppp_rx_queue_read)
                        {
                            _ppp_rx_queue[_ppp_rx_queue_write++] =
                                        &link_layer->rx_ring[link_layer->rx_ring_write++];

                            /* Activate the HISR.  The HISR will inform the upper layer
                               protocols that a packet has arrived. */
                            NU_Activate_HISR (&PPP_RX_HISR);

                        }
                        else
                            NERRS_Log_Error (TCP_SEVERE, __FILE__, __LINE__);

                    }

                    /* Make sure the LISR index wraps around if needed. */
                    link_layer->rx_ring_write %= (UINT8) HDLC_MAX_HOLDING_PACKETS;

                    /* Reset the number of bytes received. */
                    link_layer->received = 0;

                }

                break;

            case PPP_HDLC_CONTROL_ESCAPE:

                /* Set the escape received flag. */
                link_layer->esc_received = NU_TRUE;

                break;

            default:

                if (link_layer->received < PPP_MAX_RX_SIZE)
                {
                    /* Store the char if we are under our MTU and if the char
                       is not one that is supposed to be control escaped. */
                    if (c < PPP_MAX_ACCM)
                    {
                        if (!(PPP_Two_To_Power(c) & (((LINK_LAYER *)device->link_layer)
                            ->lcp.local_options.accm)))
                        {
#ifdef DEBUG_PKT_TRACE
                            if (debug_rx_index == PKT_TRACE_SIZE)
                                debug_rx_index = 0;

                            debug_rx_buf [debug_rx_index++] = c;
#endif

                        link_layer->rx_ring[link_layer->rx_ring_write].buffer[link_layer->received++] = c;

                        }
                    }
                    else
                    {
                        link_layer->rx_ring[link_layer->rx_ring_write].buffer[link_layer->received++] = c;
                    }
                }
                break;
        }

    }

    return (NU_SUCCESS);

}  /* end PPP_Receive */





/************************************************************************
* FUNCTION
*
*     PPP_TX_Packet
*
* DESCRIPTION
*
*     This function will send the PPP packet. This includes adding the
*     correct PPP header and computing the Frame Check Sequence over the
*     packet.
*
* AUTHOR
*
*     Uriah Pollock
*
* INPUTS
*
*     DEV_DEVICE_ENTRY  *device         Pointer to device structure for
*                                        the device to send the packet
*                                        over.
*     NET_BUFFER        *buf_ptr        Pointer to the buffer that
*                                        holds the packet to be sent.
*
* OUTPUTS
*
*     STATUS                            NU_SUCCESS is always returned
*
************************************************************************/
STATUS HDLC_TX_Packet (DV_DEVICE_ENTRY *device, NET_BUFFER *buf_ptr)
{
    NET_BUFFER          *tmp_buf_ptr = buf_ptr;
    URT_LAYER           *uart;
    LCP_LAYER           *lcp;
    IPCP_LAYER          *ipcp;
    UINT16              frame_check, pkt_type;
    UINT8       HUGE    *ppp_header_ptr;
    INT16               length;
    UINT8               more_to_send = NU_TRUE;

    /* Get the uart stucture for this device. */
    uart = &((LINK_LAYER *)device->link_layer)->uart;

    /* Get the LCP stucture for this device. */
    lcp = &((LINK_LAYER *)device->link_layer)->lcp;

    /* Get the IPCP stucture for this device. */
    ipcp = &((LINK_LAYER *)device->link_layer)->ipcp;

    /* Get the type of packet we are encapsulating. */
    if (buf_ptr->mem_flags & NET_IP)
        pkt_type = PPP_IP_PROTOCOL;
    else
        if (buf_ptr->mem_flags & NET_LCP)
            pkt_type = PPP_LINK_CONTROL_PROTOCOL;
        else
            if (buf_ptr->mem_flags & NET_IPCP)
                pkt_type = PPP_IP_CONTROL_PROTOCOL;
            else
                if (buf_ptr->mem_flags & NET_PAP)
                    pkt_type = PPP_PAP_PROTOCOL;
                else
                    if (buf_ptr->mem_flags & NET_CHAP)
                        pkt_type = PPP_CHAP_PROTOCOL;
                    else
                        return NU_PPP_INVALID_PROTOCOL;

    /* Add the PPP protocol header. */
    if ((lcp->state == OPENED) && (ipcp->state == OPENED)
        && (buf_ptr->mem_flags & NET_IP) &&
        (lcp->foreign_options.protocol_field_compression == NU_TRUE))
    {
        /* Make room for the PPP header and adjust the lengths */
        buf_ptr->data_ptr           -= PPP_COMPRESS_HEADER;
        buf_ptr->data_len           += PPP_COMPRESS_HEADER;
        buf_ptr->mem_total_data_len += PPP_COMPRESS_HEADER;

        /* Add the packet type in MSB LSB order. */
        buf_ptr->data_ptr[0] = (UINT8)pkt_type;
    }
    else
    {
        /* Since we are not in the opened state we must be sending
           configure pkts, none of these are compressed. */
        buf_ptr->data_ptr           -= PPP_MAX_PROTOCOL_SIZE;
        buf_ptr->data_len           += PPP_MAX_PROTOCOL_SIZE;
        buf_ptr->mem_total_data_len += PPP_MAX_PROTOCOL_SIZE;

        /* Add the packet type in MSB LSB order. */
        PUT16 (buf_ptr->data_ptr, 0, pkt_type);
    }

    /* Add the PPP address and control field header. */
    if (!((lcp->state == OPENED) && (ipcp->state == OPENED)
        && (buf_ptr->mem_flags & NET_IP) &&
        (lcp->foreign_options.address_field_compression == NU_TRUE)))
        {
            /* Make room for the HDLC header and adjust the lengths */
            buf_ptr->data_ptr           -= PPP_MAX_PROTOCOL_SIZE;
            buf_ptr->data_len           += PPP_MAX_PROTOCOL_SIZE;
            buf_ptr->mem_total_data_len += PPP_MAX_PROTOCOL_SIZE;

            /* Add the HDLC header info. */
            buf_ptr->data_ptr[0] = PPP_HDLC_ADDRESS;
            buf_ptr->data_ptr[1] = PPP_HDLC_CONTROL;
        }

    /* Now compute the FCS. */
    frame_check = HDLC_Compute_TX_FCS (PPP_INIT_FCS16, buf_ptr);
    frame_check ^= 0xffff;                  /* get the complement */

#ifdef PPP_POLLED_TX

    /* Send a FLAG character to flush out any characters the remote host might
       have received because of line noise and to mark the begining of this
       PPP HDLC frame. */

    URT_Put_Char (PPP_HDLC_FRAME, uart);

#endif

    /* Loop through all the buffers in the chain and send out each byte. */
    while (more_to_send)
    {
        /* Get the length so that we can loop through the packet and send out
           each byte. */
        length = (UINT16) tmp_buf_ptr->data_len;

        /* Get a pointer to the data. */
        ppp_header_ptr = tmp_buf_ptr->data_ptr;

        /* Now loop through the encapsulated packet and send it out */
        while(length-- > 0)
        {
            switch((CHAR)*ppp_header_ptr)
            {
                /* If it's the same code as a FRAME character, then send the special
                   two character code so that the receiver does not think we sent
                   a FRAME.
                */
                case PPP_HDLC_FRAME:
#ifdef DEBUG_PKT_TRACE
                    if (debug_tx_index == PKT_TRACE_SIZE)
                        debug_tx_index = 0;

                    debug_tx_buf [debug_tx_index++] = (PPP_HDLC_FRAME);

#endif

#ifdef PPP_POLLED_TX
                    URT_Put_Char(PPP_HDLC_CONTROL_ESCAPE, uart);
                    URT_Put_Char(PPP_HDLC_FRAME ^ PPP_HDLC_TRANSPARENCY, uart);
#else
                    /* Store the byte. */
                    uart->tx_buffer[uart->tx_buffer_write++] = PPP_HDLC_CONTROL_ESCAPE;

                    /* Check for wrapping of the write pointer. */
                    uart->tx_buffer_write %= (UINT16) URT_TX_BUFFER_SIZE;

                    /* Store the byte. */
                    uart->tx_buffer[uart->tx_buffer_write++] = (PPP_HDLC_FRAME ^ PPP_HDLC_TRANSPARENCY);

                    /* Check for wrapping of the write pointer. */
                    uart->tx_buffer_write %= (UINT16) URT_TX_BUFFER_SIZE;
#endif

                    break;

                /* If it's the same code as an ESC character, then send the special
                   two character code so that the receiver does not think we sent
                   an ESC.
                */
            case PPP_HDLC_CONTROL_ESCAPE:
#ifdef DEBUG_PKT_TRACE
                    if (debug_tx_index == PKT_TRACE_SIZE)
                        debug_tx_index = 0;

                    debug_tx_buf [debug_tx_index++] = PPP_HDLC_CONTROL_ESCAPE;

#endif

#ifdef PPP_POLLED_TX
                    URT_Put_Char(PPP_HDLC_CONTROL_ESCAPE, uart);
                    URT_Put_Char(PPP_HDLC_CONTROL_ESCAPE ^ PPP_HDLC_TRANSPARENCY, uart);
#else
                    /* Store the byte. */
                    uart->tx_buffer[uart->tx_buffer_write++] = PPP_HDLC_CONTROL_ESCAPE;

                    /* Check for wrapping of the write pointer. */

⌨️ 快捷键说明

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