tcp.c
来自「mcf5307实验源代码」· C语言 代码 · 共 1,562 行 · 第 1/5 页
C
1,562 行
dll_update_lists(&buffer_list, &buffer_freelist);
break;
case SCWAIT:
ackcheck (prt, p);
if (!prt->in.contain)
{
prt->tcpout.t.flags = TFIN | TACK;
Send_SYN_FIN(prt, 0);
prt->state = SLAST;
} /* end if */
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
break;
case SLAST: /* check ack of FIN, or reset to see if we are done */
if (ackcheck (prt, p) == NU_SUCCESS)
{
prt->state = SCLOSED;
#if SNMP_INCLUDED
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, prt->tcpout.i.ipsource,
prt->in.port, prt->tcpout.i.ipdest,
prt->out.port);
#endif
// sprintf(buffer,"closed 3:%u-%u",syntimes,++syntimes_add);
// __TextOut(10,300,12,buffer);
netputevent (CONCLASS, CONCLOSE, pnum);
dll_update_lists(&buffer_list, &buffer_freelist);
break;
}
if ((p->t.flags & TRESET)
|| ((uint32)longswap (p->t.ack) == (prt->out.nxt + 1)))
{
// sprintf(buffer,"closed 4:%u-%u",syntimes,++syntimes_add);
// __TextOut(10,300,12,buffer);
netputevent (CONCLASS, CONCLOSE, pnum);
prt->state = SCLOSED;
#if SNMP_INCLUDED
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, prt->tcpout.i.ipsource,
prt->in.port, prt->tcpout.i.ipdest,
prt->out.port);
#endif
}
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
break;
case SFW1: /* waiting for ACK of FIN */
/* throw away data */
ackcheck (prt, p);
prt->in.nxt = longswap (p->t.seq) + tlen - hlen;
if (p->t.flags & TRESET)
{
// sprintf(buffer,"closed 5:%u-%u",syntimes,++syntimes_add);
// __TextOut(10,300,12,buffer);
netputevent (CONCLASS, CONCLOSE, pnum);
prt->state = SCLOSED;
#if SNMP_INCLUDED
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, prt->tcpout.i.ipsource,
prt->in.port, prt->tcpout.i.ipdest,
prt->out.port);
#endif
}
else
if ((uint32)longswap (p->t.ack) != (prt->out.nxt + 1))
{
if (p->t.flags & TFIN) /* got FIN, no ACK for mine */
{
prt->in.nxt++; /* account for FIN byte */
prt->tcpout.t.ack = longswap (prt->in.nxt);
prt->tcpout.t.flags = TACK; /* final byte has no FIN flag */
tcp_sendack (prt, 0);
prt->state = SCLOSING;
/* Free up any buffers that were received but not processed. */
dll_cleanup(&prt->in.packet_list);
} /* end if */
else
{
prt->tcpout.t.ack = longswap (prt->in.nxt);
prt->tcpout.t.flags = TACK | TFIN;
/* Since we are already in SFW1 a FIN has already been sent. So
don't call Send_SYN_FIN here. That would create another packet
containing a FIN that would have a retransmit event associated
with it. */
tcp_sendack (prt, 0);
} /* end else */
} /* end if */
else
if (p->t.flags & TFIN) /* ACK and FIN */
{
prt->in.nxt++; /* account for his FIN flag */
prt->out.nxt++; /* account for my FIN */
prt->tcpout.t.ack = longswap (prt->in.nxt);
prt->tcpout.t.flags = TACK; /* final byte has no FIN flag */
tcp_sendack (prt, 0);
// sprintf(buffer,"closed 6:%u-%u",syntimes,++syntimes_add);
// __TextOut(10,300,12,buffer);
netputevent (CONCLASS, CONCLOSE, pnum);
prt->state = STWAIT; /* we are done */
#if SNMP_INCLUDED
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, prt->tcpout.i.ipsource,
prt->in.port, prt->tcpout.i.ipdest,
prt->out.port);
#endif
/* Free up any buffers that were received but not processed. */
dll_cleanup(&prt->in.packet_list);
} /* end if */
else
{ /* got ACK, no FIN */
prt->out.nxt++; /* account for my FIN byte */
prt->tcpout.t.flags = TACK; /* final pkt has no FIN flag */
prt->state = SFW2;
} /* end else */
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
break;
case SFW2:
/* want FIN */
ackcheck (prt, p);
prt->in.nxt=longswap(p->t.seq)+tlen-hlen;
if(p->t.flags&TRESET)
{
// sprintf(buffer,"closed 7:%u-%u",syntimes,++syntimes_add);
// __TextOut(10,300,12,buffer);
netputevent (CONCLASS, CONCLOSE, pnum);
prt->state=SCLOSED;
#if SNMP_INCLUDED
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, prt->tcpout.i.ipsource,
prt->in.port, prt->tcpout.i.ipdest,
prt->out.port);
#endif
}
else
if(p->t.flags&TFIN) /* we got FIN */
{
prt->in.nxt++; /* count his FIN byte */
prt->tcpout.t.ack=longswap(prt->in.nxt);
tcp_sendack (prt, 0);
// sprintf(buffer,"closed 8:%u-%u",syntimes,++syntimes_add);
// __TextOut(10,300,12,buffer);
netputevent(CONCLASS, CONCLOSE, pnum);
prt->state=STWAIT;
#if SNMP_INCLUDED
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, prt->tcpout.i.ipsource,
prt->in.port, prt->tcpout.i.ipdest,
prt->out.port);
#endif
/* Free up any buffers that were received but not processed. */
dll_cleanup(&prt->in.packet_list);
} /* end if */
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
break;
case SCLOSING: /* want ACK of FIN */
if(p->t.flags&TRESET)
{
// sprintf(buffer,"closed 9:%u-%u",syntimes,++syntimes_add);
// __TextOut(10,300,12,buffer);
netputevent (CONCLASS, CONCLOSE, pnum);
prt->state = SCLOSED;
#if SNMP_INCLUDED
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, prt->tcpout.i.ipsource,
prt->in.port, prt->tcpout.i.ipdest,
prt->out.port);
#endif
}
else if(!ackcheck(prt,p))
{
prt->out.nxt++; /* account for my FIN byte */
// sprintf(buffer,"closed 10:%u-%u",syntimes,++syntimes_add);
// __TextOut(10,300,12,buffer);
netputevent(CONCLASS, CONCLOSE, pnum);
prt->state = STWAIT; /* time-wait state next */
#if SNMP_INCLUDED
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, prt->tcpout.i.ipsource,
prt->in.port, prt->tcpout.i.ipdest,
prt->out.port);
#endif
} /* end if */
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
break;
case STWAIT: /* ack FIN again? */
if(p->t.flags&TRESET)
{
// sprintf(buffer,"closed 11:%u-%u",syntimes,++syntimes_add);
// __TextOut(10,300,12,buffer);
netputevent (CONCLASS, CONCLOSE, pnum);
prt->state = SCLOSED;
#if SNMP_INCLUDED
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, prt->tcpout.i.ipsource,
prt->in.port, prt->tcpout.i.ipdest,
prt->out.port);
#endif
}
if(prt->out.lasttime &&
(INT32_CMP(prt->out.lasttime+WAITTIME, n_clicks()) < 0)
|| p->t.flags&TFIN) /* only if he wants it */
{
tcp_sendack (prt, 0);
prt->state = SCLOSED;
#if SNMP_INCLUDED
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, prt->tcpout.i.ipsource,
prt->in.port, prt->tcpout.i.ipdest,
prt->out.port);
#endif
}
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
break;
case SCLOSED:
prt->in.port = prt->out.port = 0;
for(ii = 0; ii < 4; ii++)
prt->tcpout.i.ipdest[ii] = 0;
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
break;
default:
NU_Tcp_Log_Error (TCP_UNKOWN_STATE, TCP_RECOVERABLE,
__FILE__, __LINE__);
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
break;
} /* end switch */
return(0);
} /* end tcpdo() */
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* checkmss */
/* */
/* 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. */
/* */
/* CALLED BY */
/* tcpdo */
/* */
/* CALLS */
/* */
/* intswap */
/* */
/*************************************************************************/
static void checkmss(struct port *prt,TCPKT *p, uint16 hlen)
{
uint16 i;
/* Check header for maximum segment size option. */
if(hlen > 20 && p->x.options[0] == 2 && p->x.options[1] == 4)
{
/* Copy the sender's negotiated value. */
memcpy ( (void *)&i, (const void *)&p->x.options[2], 2);
/* swapped value of maxseg */
i=intswap(i);
/* we have our own limits too */
if(i < (uint16) (prt->sendsize))
prt->sendsize=i;
} /* end if */
} /* end checkmss() */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?