📄 tcp.c
字号:
/* We have no unacked data */
soc->send_unacked = soc->send_next;
tcp_newstate(soc, TCP_STATE_CONNECTED);
soc->myflags = TCP_FLAG_ACK;
tcp_sendcontrol(sochandle);
/* Inform application */
soc->event_listener(sochandle, TCP_EVENT_CONNECTED, soc->rem_ip, soc->remport);
return(0);
}
/* Is it ACK? */
if( received_tcp_packet.hlen_flags & TCP_FLAG_ACK ) {
if( received_tcp_packet.ackno != soc->send_next ) {
TCP_DEBUGOUT("ACK received but wrong Ack\n\r");
return(-1);
}
if( received_tcp_packet.seqno != soc->receive_next ) {
TCP_DEBUGOUT("ACK received but Wrong SEQ number\n\r");
return(-1);
}
TCP_DEBUGOUT("ACK received, this side CONNECTED\r\n");
/* We have no unacked data */
soc->send_unacked = soc->send_next;
tcp_newstate(soc, TCP_STATE_CONNECTED);
/* Inform application */
soc->event_listener(sochandle, TCP_EVENT_CONNECTED, soc->rem_ip, soc->remport);
return(0);
}
/* Is it SYN? */
if( received_tcp_packet.hlen_flags & TCP_FLAG_SYN ) {
TCP_DEBUGOUT("Repeated SYN\r\n");
return(0);
}
/* We didn't understood this one, keep on trying but info with RESET */
TCP_DEBUGOUT("Unrecognized packet\n\r");
tcp_sendreset(&received_tcp_packet, frame->sip);
return(-1);
break;
case TCP_STATE_SYN_SENT:
TCP_DEBUGOUT("SYN_SENT State\r\n");
/* Check for RESET */
if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
TCP_DEBUGOUT("ERROR:Reset received\r\n");
/* Inform application */
soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
if(soc->type & TCP_TYPE_SERVER)
tcp_newstate(soc, TCP_STATE_LISTENING);
else
tcp_newstate(soc, TCP_STATE_CLOSED);
return(-1);
}
/* Is it SYN+ACK? */
if( (received_tcp_packet.hlen_flags & TCP_FLAG_SYN) &&
(received_tcp_packet.hlen_flags & TCP_FLAG_ACK) ) {
/* Rigth ACK? */
if( received_tcp_packet.ackno != soc->send_next ) {
TCP_DEBUGOUT("SYN+ACK received but wrong Ack\n\r");
return(-1);
}
TCP_DEBUGOUT("SYN+ACK received, this side established\n\r");
/* Get peer's seq number */
soc->receive_next = received_tcp_packet.seqno;
soc->receive_next++; /* ACK SYN */
/* We have no unacked data */
soc->send_unacked = soc->send_next;
tcp_newstate(soc, TCP_STATE_CONNECTED);
soc->myflags = TCP_FLAG_ACK;
tcp_sendcontrol(sochandle);
/* Inform application */
soc->event_listener(sochandle, TCP_EVENT_CONNECTED, soc->rem_ip, soc->remport);
return(0);
}
/* Is it SYN (simultaneous open) */
if(received_tcp_packet.hlen_flags & TCP_FLAG_SYN) {
TCP_DEBUGOUT("Simultaneous open, next SYN_RECEIVED\r\n");
/* Get peer's seq number */
soc->receive_next = received_tcp_packet.seqno;
soc->receive_next++; /* ACK SYN */
tcp_newstate(soc, TCP_STATE_SYN_RECEIVED);
soc->myflags = TCP_FLAG_SYN | TCP_FLAG_ACK;
tcp_sendcontrol(sochandle);
return(0);
}
/* This is something we didn't understood, maybe the other peer has */
/* still old connection on or something */
TCP_DEBUGOUT("TCP packet out of nowhere received...\r\n");
tcp_sendreset(&received_tcp_packet, frame->sip);
return(-1);
break;
case TCP_STATE_FINW1:
TCP_DEBUGOUT("FINW1 State\r\n");
/* Check for RESET */
if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
TCP_DEBUGOUT("ERROR:Reset received\r\n");
/* Inform application */
soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
if(soc->type & TCP_TYPE_SERVER)
tcp_newstate(soc, TCP_STATE_LISTENING);
else
tcp_newstate(soc, TCP_STATE_CLOSED);
return(-1);
}
/* Is it FIN+ACK? */
if( (received_tcp_packet.hlen_flags & TCP_FLAG_FIN) &&
(received_tcp_packet.hlen_flags & TCP_FLAG_ACK) ) {
/* Rigth ACK? */
if( received_tcp_packet.ackno != soc->send_next ) {
TCP_DEBUGOUT("FIN+ACK received but wrong Ack\n\r");
return(-1);
}
TCP_DEBUGOUT("FIN+ACK received, next TIMED_WAIT\n\r");
/* ACK FIN and all data */
soc->receive_next = received_tcp_packet.seqno;
soc->receive_next++;
soc->receive_next += dlen;
/* We have no unacked data */
soc->send_unacked = soc->send_next;
tcp_newstate(soc, TCP_STATE_TIMED_WAIT);
soc->myflags = TCP_FLAG_ACK;
tcp_sendcontrol(sochandle);
return(0);
}
/* Is it just FIN */
if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN ) {
TCP_DEBUGOUT("Simultaneous close, next CLOSING\n\r");
/* ACK FIN and all data */
soc->receive_next = received_tcp_packet.seqno;
soc->receive_next++;
soc->receive_next += dlen;
tcp_newstate(soc, TCP_STATE_CLOSING);
soc->myflags = TCP_FLAG_ACK;
tcp_sendcontrol(sochandle);
return(0);
}
/* Is it just ACK? */
if( received_tcp_packet.hlen_flags & TCP_FLAG_ACK ) {
/* Rigth ACK? */
if( received_tcp_packet.ackno != soc->send_next ) {
TCP_DEBUGOUT("ACK received but wrong Ack\n\r");
return(-1);
}
TCP_DEBUGOUT("Our FIN is ACKed but peer don't agree to disconnect yet\r\n");
TCP_DEBUGOUT("Next FINW2\r\n");
/* We have no unacked data */
soc->send_unacked = soc->send_next;
tcp_newstate(soc, TCP_STATE_FINW2);
return(0);
}
break;
case TCP_STATE_FINW2:
TCP_DEBUGOUT("FINW2 State\r\n");
/* Check for RESET */
if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
TCP_DEBUGOUT("ERROR:Reset received\r\n");
/* Inform application */
soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
if(soc->type & TCP_TYPE_SERVER)
tcp_newstate(soc, TCP_STATE_LISTENING);
else
tcp_newstate(soc, TCP_STATE_CLOSED);
return(-1);
}
/* Do we finally get FIN? */
if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN ) {
TCP_DEBUGOUT("FIN received, next TIMED_WAIT\n\r");
/* ACK FIN and all data */
soc->receive_next = received_tcp_packet.seqno;
soc->receive_next++;
soc->receive_next += dlen;
tcp_newstate(soc, TCP_STATE_TIMED_WAIT);
soc->myflags = TCP_FLAG_ACK;
tcp_sendcontrol(sochandle);
return(0);
}
break;
case TCP_STATE_CLOSING:
TCP_DEBUGOUT("CLOSING State...\r\n");
/* Check for RESET */
if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
TCP_DEBUGOUT("ERROR:Reset received\r\n");
/* Inform application */
soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
if(soc->type & TCP_TYPE_SERVER)
tcp_newstate(soc, TCP_STATE_LISTENING);
else
tcp_newstate(soc, TCP_STATE_CLOSED);
return(-1);
}
/* Is it ACK? */
if( received_tcp_packet.hlen_flags & TCP_FLAG_ACK ) {
/* Rigth ACK? */
if( received_tcp_packet.ackno != soc->send_next ) {
TCP_DEBUGOUT("ACK received but wrong Ack\n\r");
return(-1);
}
TCP_DEBUGOUT("Our FIN is ACKed and peer wants to close too\r\n");
TCP_DEBUGOUT("Next TIMED_WAIT\r\n");
/* We have no unacked data */
soc->send_unacked = soc->send_next;
tcp_newstate(soc, TCP_STATE_TIMED_WAIT);
return(0);
}
/* Is it repeated FIN? */
if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN ) {
TCP_DEBUGOUT("Repeated FIN, repeat ACK\n\r");
/* ACK FIN and all data */
soc->receive_next = received_tcp_packet.seqno;
soc->receive_next++;
soc->receive_next += dlen;
soc->myflags = TCP_FLAG_ACK;
tcp_sendcontrol(sochandle);
return(0);
}
break;
case TCP_STATE_LAST_ACK:
TCP_DEBUGOUT("LAST_ACK State...\r\n");
/* Check for RESET */
if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
TCP_DEBUGOUT("ERROR:Reset received\r\n");
/* Inform application */
soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
if(soc->type & TCP_TYPE_SERVER)
tcp_newstate(soc, TCP_STATE_LISTENING);
else
tcp_newstate(soc, TCP_STATE_CLOSED);
return(-1);
}
/* Is it ACK? */
if( received_tcp_packet.hlen_flags & TCP_FLAG_ACK ) {
/* Rigth ACK? */
if( received_tcp_packet.ackno != soc->send_next ) {
TCP_DEBUGOUT("ACK received but wrong Ack\n\r");
return(-1);
}
TCP_DEBUGOUT("Last ACK received, next LISTENING or CLOSED\r\n");
/* We have no unacked data */
soc->send_unacked = soc->send_next;
if(soc->type & TCP_TYPE_SERVER)
tcp_newstate(soc, TCP_STATE_LISTENING);
else
tcp_newstate(soc, TCP_STATE_CLOSED);
return(0);
}
/* Is it repeated FIN? */
if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN ) {
TCP_DEBUGOUT("Repeated FIN, repeat ACK\n\r");
/* ACK FIN and all data */
soc->receive_next = received_tcp_packet.seqno;
soc->receive_next++;
soc->receive_next += dlen;
soc->myflags = TCP_FLAG_FIN | TCP_FLAG_ACK;
tcp_sendcontrol(sochandle);
return(0);
}
break;
case TCP_STATE_TIMED_WAIT:
TCP_DEBUGOUT("TIMED_WAIT State...\r\n");
/* Check for RESET */
if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
TCP_DEBUGOUT("ERROR:Reset received\r\n");
/* Inform application */
soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
if(soc->type & TCP_TYPE_SERVER)
tcp_newstate(soc, TCP_STATE_LISTENING);
else
tcp_newstate(soc, TCP_STATE_CLOSED);
return(-1);
}
/* Is it repeated FIN? */
if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN ) {
TCP_DEBUGOUT("Repeated FIN, repeat ACK\n\r");
/* ACK FIN and all data */
soc->receive_next = received_tcp_packet.seqno;
soc->receive_next++;
soc->receive_next += dlen;
soc->myflags = TCP_FLAG_ACK;
tcp_sendcontrol(sochandle);
return(0);
}
break;
default:
TCP_DEBUGOUT("ERROR:TCP State machine in unknown state!!\r\n");
tcp_sendreset(&received_tcp_packet, frame->sip);
RESET_SYSTEM();
}
TCP_DEBUGOUT("Should not be there!\r\n");
return(-1);
}
/** \brief Create and send TCP packet
* \author
* \li Jari Lahti (jari.lahti@violasystems.com)
* \date 16.07.2002
* \param sockethandle handle to processed socket
* \param buf pointer to data buffer (where TCP header will be stored)
* \param blen buffer length in bytes
* \param dlen length of data in bytes
* \return
* \li -1 - Error
* \li >0 - Packet OK
*
* Based on data supplied as function parameters and data stored in
* socket's tcb, TCP header is created in buffer, checksum is calculated
* and packet is forwarded to lower layers (IP).
*
*/
INT16 process_tcp_out (INT8 sockethandle, UINT8* buf, UINT16 blen, UINT16 dlen)
{
struct tcb* soc;
UINT16 cs;
UINT8 cs_cnt;
UINT8* buf_start;
#if defined (IPv6)
UINT16 i;
#endif
TCP_DEBUGOUT("Entering to send TCP packet\r\n");
if( sockethandle < 0 ) {
TCP_DEBUGOUT("ERROR:Socket Handle not valid (<0)\r\n");
return(-1);
}
if( sockethandle > NO_OF_TCPSOCKETS ) {
TCP_DEBUGOUT("ERROR:Socket Handle not valid (>NO_OF_TCPSOCKETS)\r\n");
return(-1);
}
if( (dlen + MIN_TCP_HLEN) > blen ) {
TCP_DEBUGOUT("ERROR:Transmit buffer too small for TCP header\r\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -