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

📄 tinytcp.c

📁 ADAM2 sources (modified by Oleg)
💻 C
📖 第 1 页 / 共 2 页
字号:
          /* do IP */            if ( ip->destination == lfix(sin_lclINAddr) &&                 in_GetProtocol(ip) == 6 &&                 checksum(ip, in_GetHdrlenBytes(ip)) == 0xFFFF )               {              tcp_Handler(ip);              }            }        x = clock_ValueRough() - start;        timeout -= x;        }    return ( 1 );}#else/* busy-wait loop for tcp.  Also calls an "application proc" */int tcp_receive(procref application){    longword timeout, start;    int x;	    timeout = clock_ValueRough() + tcp_RETRANSMITTIME;    while (tcp_allsocs) 	{        start = clock_ValueRough();				if (ip_Handler() == 0) 		{            if ( clock_ValueRough() > timeout ) 			{                tcp_Retransmitter();                timeout = clock_ValueRough() + tcp_RETRANSMITTIME;            }            application();            continue;		}        x = clock_ValueRough() - start;        timeout -= x;	}			return (1);}#endif /* DHCP_SUPPORT */#endif /* FTP_CLIENT_SUPPORT *//* * Write data to a connection. * Returns number of bytes written, == 0 when connection is not in * established state. */int tcp_Write(tcp_Socket *s, byte *dp, int len)  {  int x;  if ( s->state != tcp_StateESTAB )     len = 0;  if ( len > (x = tcp_MaxData - s->dataSize) )     len = x;  if ( len > 0 )     {    Move(dp, &s->data[s->dataSize], len);    s->dataSize += len;    //tcp_Flush(s); /*TODO*/    }  return ( len );  }/* * Send pending data */void tcp_Flush(tcp_Socket *s)  {  if ( s->dataSize > 0 )     {    s->flags |= tcp_FlagPUSH;    tcp_Send(s);    }  }/* * Handler for incoming packets. */void tcp_Handler(in_Header *ip){    tcp_Header *tp;    tcp_PseudoHeader ph;    int len;    int diff;    tcp_Socket *s;    word flags;    len = in_GetHdrlenBytes(ip);    tp = (tcp_Header *)((byte *)ip + len);    len = wfix(ip->length) - len;    /* demux to active sockets */    for ( s = tcp_allsocs; s; s = s->next )        if ( s->hisport != 0 &&             wfix(tp->dstPort) == s->myport &&             wfix(tp->srcPort) == s->hisport &&             lfix(ip->source) == s->hisaddr ) break;    if ( s == NULL ) {        /* demux to passive sockets */        for ( s = tcp_allsocs; s; s = s->next )            if ( s->hisport == 0 && wfix(tp->dstPort) == s->myport ) break;    }    if ( s == NULL ) {        return;    }    /* save his ethernet address */    MoveW(&((((eth_Header *)ip) - 1)->source[0]), &s->hisethaddr[0], sizeof(eth_HwAddress));    ph.src = ip->source;    ph.dst = ip->destination;    ph.mbz = 0;    ph.protocol = TCP_PROTO;    ph.length = wfix(len);    ph.checksum = wfix(checksum(tp, len));    if ( checksum(&ph, sizeof ph) != 0xffff )        {        return;        }    flags = wfix(tp->flags);    if ( flags & tcp_FlagRST ) {        s->state = tcp_StateCLOSED;        s->dataHandler(s, 0, -1,SABORT);        tcp_Unthread(s);        return;    }    switch ( s->state )       {    case tcp_StateLISTEN:        if ( flags & tcp_FlagSYN )           {          s->acknum = lfix(tp->seqnum) + 1;          s->hisport = wfix(tp->srcPort);          s->hisaddr = lfix(ip->source);          s->flags = tcp_FlagSYN | tcp_FlagACK;          tcp_Send(s);          s->state = tcp_StateSYNREC;          s->unhappy = TRUE;          s->timeout = tcp_TIMEOUT;          }        break;    case tcp_StateSYNSENT:        if ( flags & tcp_FlagACK )          {          if (lfix(tp->acknum) != (s->seqnum + 1))            {            s->flags = tcp_FlagRST;            tcp_Send(s);            s->flags = tcp_FlagSYN;            }          }        if ( flags & tcp_FlagSYN )             {            s->acknum++;            s->flags = tcp_FlagACK;            s->timeout = tcp_TIMEOUT;            if ( (flags & tcp_FlagACK) && lfix(tp->acknum) == (s->seqnum + 1) )                 {                s->state = tcp_StateESTAB;                s->seqnum++;                s->acknum = lfix(tp->seqnum) + 1;                s->unhappy = FALSE;                tcp_Send(s);    /*DRB Added*/                s->dataHandler(s, 0, 0,SOPEN);                }                else                 {                s->state = tcp_StateSYNREC;                }            }        break;    case tcp_StateSYNREC:        if ( flags & tcp_FlagSYN )           {          s->flags = tcp_FlagSYN | tcp_FlagACK;          tcp_Send(s);          s->timeout = tcp_TIMEOUT;          }        if ( (flags & tcp_FlagACK) && lfix(tp->acknum) == (s->seqnum + 1) )           {          s->flags = tcp_FlagACK;          s->seqnum++;                 s->unhappy = FALSE;          s->state = tcp_StateESTAB;          s->timeout = tcp_TIMEOUT;          s->dataHandler(s, 0, 0,SOPEN);          }        break;    case tcp_StateESTAB:        if ( (flags & tcp_FlagACK) == 0 ) return;        /* process ack value in packet */        diff = lfix(tp->acknum) - s->seqnum;        if ( diff > 0 ) {            Move(&s->data[diff], &s->data[0], diff);            s->dataSize -= diff;            s->seqnum += diff;        }        s->flags = tcp_FlagACK;        tcp_ProcessData(s, tp, len);        break;    case tcp_StateFINWT1:        if ( (flags & tcp_FlagACK) == 0 ) return;        diff = lfix(tp->acknum) - s->seqnum - 1;        s->flags = tcp_FlagACK | tcp_FlagFIN;        if ( diff == 0 ) {            s->state = tcp_StateFINWT2;            s->flags = tcp_FlagACK;        }#ifdef FTP_SERVER_SUPPORT		else {			Move(&s->data[diff], &s->data[0], diff);            s->dataSize -= diff;            s->seqnum += diff;		}#endif        tcp_ProcessData(s, tp, len);        break;    case tcp_StateFINWT2:        s->flags = tcp_FlagACK;        tcp_ProcessData(s, tp, len);        break;    case tcp_StateCLOSING:        if ( lfix(tp->acknum) == (s->seqnum + 1) ) {            s->state = tcp_StateTIMEWT;            s->timeout = tcp_TIMEOUT;        }        break;    case tcp_StateLASTACK:        if ( lfix(tp->acknum) == (s->seqnum + 1) ) {            s->state = tcp_StateCLOSED;            s->unhappy = FALSE;            s->dataSize = 0;            s->dataHandler(s, 0, 0,SCLOSE);            tcp_Unthread(s);        } else {            s->flags = tcp_FlagACK | tcp_FlagFIN;            tcp_Send(s);            s->timeout = tcp_TIMEOUT;        }        break;    case tcp_StateTIMEWT:        s->flags = tcp_FlagACK;        tcp_Send(s);#ifdef FTP_SERVER_SUPPORT        s->state = tcp_StateCLOSED;        s->dataHandler(s, 0, 0,SCLOSE);        tcp_Unthread(s);#endif    }}/* * Process the data in an incoming packet. * Called from all states where incoming data can be received: established, * fin-wait-1, fin-wait-2 */void tcp_ProcessData(tcp_Socket *s, tcp_Header *tp, int len){    int diff, x;    word flags;    byte *dp;	flags = wfix(tp->flags);    diff = s->acknum - lfix(tp->seqnum);    if ( flags & tcp_FlagSYN ) diff--;    x = tcp_GetDataOffset(tp) << 2;    dp = (byte *)tp + x;    len -= x;    if ( diff >= 0 ) {        dp += diff;        len -= diff;        s->acknum += len;        s->dataHandler(s, dp, len,SDATA);        if ( flags & tcp_FlagFIN ) {            s->acknum++;            switch(s->state) {              case tcp_StateESTAB:                /* note: skip state CLOSEWT by automatically closing conn */                x = tcp_StateLASTACK;                s->flags |= tcp_FlagFIN;                s->unhappy = TRUE;                break;              case tcp_StateFINWT1:                x = tcp_StateCLOSING;                break;              case tcp_StateFINWT2:                x = tcp_StateTIMEWT;                break;            }            s->state = x;        }		tcp_Send(s);    }    s->timeout = tcp_TIMEOUT;}/* * Format and send an outgoing segment */void tcp_Send(tcp_Socket *s){    tcp_PseudoHeader ph;    struct _pkt {        in_Header in;        tcp_Header tcp;        longword maxsegopt;    } *pkt;    byte *dp;    pkt = (struct _pkt *)sed_FormatPacket(&s->hisethaddr[0], 0x800);    dp = (byte *)&pkt->maxsegopt;    pkt->in.length = wfix(sizeof(in_Header) + sizeof(tcp_Header) + s->dataSize);    /* tcp header */    pkt->tcp.srcPort = wfix(s->myport);    pkt->tcp.dstPort = wfix(s->hisport);    pkt->tcp.seqnum = lfix(s->seqnum);    pkt->tcp.acknum = lfix(s->acknum);    pkt->tcp.window = wfix(1024);    pkt->tcp.flags = wfix(s->flags | 0x5000);    pkt->tcp.checksum = 0;    pkt->tcp.urgentPointer = 0;    if ( s->flags & tcp_FlagSYN )       {      pkt->tcp.flags = wfix(0x1000+wfix(pkt->tcp.flags));      pkt->in.length = wfix(4+wfix(pkt->in.length));      pkt->maxsegopt = lfix(0x02040578); /* 1400 bytes */      dp += 4;      }    MoveW(s->data, dp, s->dataSize);    /* internet header */    pkt->in.vht = wfix(0x4500);   /* version 4, hdrlen 5, tos 0 */    pkt->in.identification = wfix(tcp_id++);    pkt->in.frag = 0;    pkt->in.ttlProtocol = wfix((250<<8) + TCP_PROTO);    pkt->in.checksum = 0;    pkt->in.source = lfix(sin_lclINAddr);    pkt->in.destination = lfix(s->hisaddr);    pkt->in.checksum = wfix(~checksum(&pkt->in, sizeof(in_Header)));    /* compute tcp checksum */    ph.src = pkt->in.source;    ph.dst = pkt->in.destination;    ph.mbz = 0;    ph.protocol = TCP_PROTO;    ph.length = wfix(wfix(pkt->in.length) - sizeof(in_Header));    ph.checksum = wfix(checksum(&pkt->tcp, wfix(ph.length)));    pkt->tcp.checksum = wfix(~checksum(&ph, sizeof ph));    sed_Send(wfix(pkt->in.length));}

⌨️ 快捷键说明

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