📄 tcp.c
字号:
{
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 + -