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

📄 tcp.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
            {
                if (SCK_Sockets[prt->p_socketd]->s_RXTask != NU_NULL)
                    NU_Resume_Task(SCK_Sockets[prt->p_socketd]->s_RXTask);

                if (SCK_Sockets[prt->p_socketd]->s_TXTask != NU_NULL)
                    NU_Resume_Task(SCK_Sockets[prt->p_socketd]->s_TXTask);

                if (SCK_Sockets[prt->p_socketd]->s_CLSTask != NU_NULL)
                    NU_Resume_Task(SCK_Sockets[prt->p_socketd]->s_CLSTask);
            }

            UTL_Timerset(TCPTIMEWAIT, (UNSIGNED)prt->pindex, WAITTIME, (INT32)0);

            prt->state=STWAIT;

#if (INCLUDE_SNMP == NU_TRUE)

            PUT32(tcp_laddr, 0, prt->tcp_laddr);
            PUT32(tcp_faddr, 0, prt->tcp_faddr);

            SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, tcp_laddr, (UNSIGNED)(prt->in.port), 
                                    tcp_faddr, (UNSIGNED)(prt->out.port));
#endif

        } /* end if */

        /* Drop the packet by placing it back on the buffer_freelist. */
        MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
      
        break;

    case SCLOSING:                          /* want ACK of FIN */

        if(flags & TRESET)
        {
            /* Return to the closed state */
            prt->state = SCLOSED;

#if (INCLUDE_SNMP == NU_TRUE)

            PUT32(tcp_laddr, 0, prt->tcp_laddr);
            PUT32(tcp_faddr, 0, prt->tcp_faddr);

            SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, tcp_laddr, (UNSIGNED)(prt->in.port), 
                                    tcp_faddr, (UNSIGNED)(prt->out.port));
#endif
            
            TCP_Cleanup(prt);
        }
                /* The SYN flag should no be set. */
        else if(flags & TSYN)        
        {
            /* Send a FIN and a RESET. */
            prt->out.tcp_flags = TFIN | TRESET;
            TCP_ACK_It(prt, 1);

            /* Return to the closed state */
            prt->state = SCLOSED;

            /* Clean up the port. */
            TCP_Cleanup(prt);

            /* Drop the packet by placing it back on the buffer_freelist. */
            MEM_Buffer_Chain_Free(&MEM_Buffer_List, &MEM_Buffer_Freelist);

            return(1);
        }

        else if(!TCP_ACK_Check(prt, p))
        {
            /* If the socket has not been deallocated, restart any tasks
               pending on this port. */
            if ( (prt->p_socketd >= 0) && (SCK_Sockets[prt->p_socketd] != NU_NULL) )
            {
                /* Restart any tasks pending on this port. */
                if (SCK_Sockets[prt->p_socketd]->s_RXTask != NU_NULL)
                    NU_Resume_Task(SCK_Sockets[prt->p_socketd]->s_RXTask);

                if (SCK_Sockets[prt->p_socketd]->s_TXTask != NU_NULL)
                    NU_Resume_Task(SCK_Sockets[prt->p_socketd]->s_TXTask);

                if (SCK_Sockets[prt->p_socketd]->s_CLSTask != NU_NULL)
                    NU_Resume_Task(SCK_Sockets[prt->p_socketd]->s_CLSTask);
            }

            UTL_Timerset(TCPTIMEWAIT, (UNSIGNED)prt->pindex, WAITTIME, (INT32)0);

            prt->state = STWAIT;            /* time-wait state next */

#if (INCLUDE_SNMP == NU_TRUE)

            PUT32(tcp_laddr, 0, prt->tcp_laddr);
            PUT32(tcp_faddr, 0, prt->tcp_faddr);

            SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, tcp_laddr, (UNSIGNED)(prt->in.port), 
                                    tcp_faddr, (UNSIGNED)(prt->out.port));
#endif
        } /* end if */
      
        /* Drop the packet by placing it back on the buffer_freelist. */
        MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
      
        break;

    case STWAIT:                            /* ack FIN again? */
      
        if(flags & TRESET)
        {
            /* Return to the closed state */
            prt->state = SCLOSED;

#if (INCLUDE_SNMP == NU_TRUE)

            PUT32(tcp_laddr, 0, prt->tcp_laddr);
            PUT32(tcp_faddr, 0, prt->tcp_faddr);

            SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, tcp_laddr, (UNSIGNED)(prt->in.port), 
                                    tcp_faddr, (UNSIGNED)(prt->out.port));
#endif

            TCP_Cleanup(prt);
        }

        /* The SYN flag should no be set. */
        if(flags & TSYN)        
        {
            /* Send a FIN and a RESET. */
            prt->out.tcp_flags = TFIN | TRESET;
            TCP_ACK_It(prt, 1);

            /* Return to the closed state */
            prt->state = SCLOSED;

            /* Clean up the port. */
            TCP_Cleanup(prt);

            /* Drop the packet by placing it back on the buffer_freelist. */
            MEM_Buffer_Chain_Free(&MEM_Buffer_List, &MEM_Buffer_Freelist);

            return(1);
        }

        if((prt->out.lasttime &&
            (INT32_CMP(prt->out.lasttime+WAITTIME, NU_Retrieve_Clock()) < 0))
            || (flags & TFIN))               /* only if he wants it */
        {
            TCP_ACK_It (prt, 1);

#if (INCLUDE_SNMP == NU_TRUE)

            PUT32(tcp_laddr, 0, prt->tcp_laddr);
            PUT32(tcp_faddr, 0, prt->tcp_faddr);

            SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, tcp_laddr, (UNSIGNED)(prt->in.port), 
                                    tcp_faddr, (UNSIGNED)(prt->out.port));
#endif
        }

        /* Drop the packet by placing it back on the buffer_freelist. */
        MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
      
        break;

    case SCLOSED:

        prt->in.port = prt->out.port = 0;
        
        prt->tcp_faddr = 0;

        /* Drop the packet by placing it back on the buffer_freelist. */
        MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
        
        break;

    default:

        NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);

        /* Drop the packet by placing it back on the buffer_freelist. */
        MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);

        break;
  } /* end switch */

  return(0);

}   /* end TCP_Do() */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TCP_Check_MSS                                                    
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Look at incoming SYN,ACK packet and check for the options field   
*       containing a TCP Maximum segment size option.  If it has one,     
*       then set the port's internal value to make sure that it never     
*       exceeds that segment size.                                        
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *prt                                                              
*       *p                                                                
*       hlen                                                             
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       None.                                                            
*                                                                       
*************************************************************************/
static void TCP_Check_MSS(TCP_PORT *prt,TCPLAYER *p, UINT16 hlen)
{
    UINT16 i;
    UINT8  *data_ptr;
    
    
    /* Get a pointer to data past the TCP header. */
    data_ptr = (UINT8 *)(p + sizeof (TCPLAYER));

    /*  Check header for maximum segment size option.  */
    if(hlen > 20 && data_ptr[0] == 2 && data_ptr[1] == 4)
    {

        /* Extract the MSS */
        i = INTSWAP(*(UINT16 *)&data_ptr[2]);

        /* we have our own limits too */
        if(i < (UINT16) (prt->sendsize))
            prt->sendsize=i;

    } /* end if */

}   /* end TCP_Check_MSS() */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TCP_Reset_FIN                                                    
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Send a reset packet back to sender                                
*       Use the packet which just came in as a template to return to      
*       sender.  Fill in all of the fields necessary and send it back.    
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *t                                                                
*       *tcp_chk                                                          
*       dlen                                                             
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       INT16                   0                                        
*                               1                                        
*                               NU_NULL                                  
*                                                                       
*************************************************************************/
static INT16 TCP_Reset_FIN(TCPLAYER *t, struct pseudotcp *tcp_chk, INT16 dlen)
{
    UINT16      tport;
    NET_BUFFER  *buf_ptr;
    TCPLAYER    *out_tcp;
    STATUS      stat;
    UINT8       flags;

    flags = GET8(t, TCP_FLAGS_OFFSET);
      
    if(flags & TRESET)                     /* don't reset a reset */
        return(1);

    /* We need to build a new packet to transmit this reset back to the
       sender.  Therefore, we must get the packet itself and we must acquire
       a header packet for the transmit operation (see below).  */

    /* Allocate a buffer to place the arp packet in. */
    buf_ptr = MEM_Buffer_Dequeue(&MEM_Buffer_Freelist);

    if(buf_ptr == NU_NULL)
    {
        return (NU_NULL);
    }

    /* Initialize each field in the allocated buffer. */
    buf_ptr->data_len   = buf_ptr->mem_total_data_len = sizeof (TCPLAYER);
    buf_ptr->data_ptr   = buf_ptr->mem_parent_packet +
        (NET_MAX_TCP_HEADER_SIZE - sizeof (TCPLAYER));
    buf_ptr->mem_seqnum = 0;
    buf_ptr->mem_dlist  = &MEM_Buffer_Freelist;

    /* Set up a pointer to the packet. */
    out_tcp = (TCPLAYER *)(buf_ptr->data_ptr);

    /*  Now we start building the packet itself.  We move the data from
        the TCP packet that we received into our newly allocated packet.  */

    /*  Swap TCP layer portions for sending back. */
    if(flags & TACK)
    {
        PUT32(out_tcp, TCP_SEQ_OFFSET, GET32(t, TCP_ACK_OFFSET)); /* ack becomes next sequence # */
        PUT32(out_tcp, TCP_ACK_OFFSET, 0L);               /* ack # is 0 */
        PUT8(out_tcp, TCP_FLAGS_OFFSET, TRESET|TFIN);
    } /* end if */
    else
    {
        PUT32(out_tcp, TCP_SEQ_OFFSET, 0L);
        
        if(flags & TSYN)
            PUT32(out_tcp, TCP_ACK_OFFSET, GET32(t, TCP_SEQ_OFFSET) + dlen + 1);
        else
            PUT32(out_tcp, TCP_ACK_OFFSET, GET32(t, TCP_SEQ_OFFSET) + dlen);

        PUT8(out_tcp, TCP_FLAGS_OFFSET, TRESET | TACK | TFIN);
    } /* end else */

    /* swap port #'s */
    tport               = GET16(t, TCP_SRC_OFFSET);  
    PUT16(out_tcp, TCP_SRC_OFFSET, GET16(t, TCP_DEST_OFFSET));
    PUT16(out_tcp, TCP_DEST_OFFSET, tport);
    PUT8(out_tcp, TCP_HLEN_OFFSET, sizeof (TCPLAYER) << 2); /* header len */
    PUT16(out_tcp, TCP_WINDOW_OFFSET, 0);
    PUT16(out_tcp, TCP_URGENT_OFFSET, GET16(t, TCP_URGENT_OFFSET));
    PUT16(out_tcp, TCP_CHECK_OFFSET, 0);

    /* Note that the source and destination IP addresses in tcp_chk need to be 
       reversed. The destination is our source and the source is our 
       destination. */
    PUT16(out_tcp, TCP_CHECK_OFFSET, 

⌨️ 快捷键说明

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