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

📄 tcp.cpp

📁 使用VC++开发的很棒的上网拨号工具的程序的源码,可以选择PING,UDP,TCP/IP等等方式,功能比较全面.Using Visual C + + development of the great
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    char* tempstr;
	switch ( s->state ) {

    case tcp_StateLISTEN:
        if ( flags & tcp_FlagSYN ) {
            s->acknum = tp->seqnum + 1;
            s->hisport = tp->srcPort;
            s->hisaddr = ip->source;
            s->flags = tcp_FlagSYN | tcp_FlagACK;
            tcp_Send(s);
            s->state = tcp_StateSYNREC;
            s->unhappy = true;
            s->timeout = tcp_TIMEOUT;
            sprintf(tempstr,"Syn from 0x%x#%d (seq 0x%x)", s->hisaddr, s->hisport, tp->seqnum);
			writelog(tempstr);
		}
        break;

    case tcp_StateSYNSENT:
        if ( flags & tcp_FlagSYN ) {
            s->acknum++;
            s->flags = tcp_FlagACK;
            s->timeout = tcp_TIMEOUT;
            if ( (flags & tcp_FlagACK) && tp->acknum == (s->seqnum + 1) ) {
                sprintf(tempstr,"Open");
				writelog(tempstr);
                s->state = tcp_StateESTAB;
                s->seqnum++;
                s->acknum = tp->seqnum + 1;
                s->unhappy = false;
            } 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;
            sprintf(tempstr," retransmit of original syn");
			writelog(tempstr);
        }
        if ( (flags & tcp_FlagACK) && tp->acknum == (s->seqnum + 1) ) {
            s->flags = tcp_FlagACK;
            tcp_Send(s);
            s->seqnum++;
            s->unhappy = false;
            s->state = tcp_StateESTAB;
            s->timeout = tcp_TIMEOUT;
            printf("Synack received - connection established");
			writelog(tempstr);
        }
        break;

    case tcp_StateESTAB:
        if ( (flags & tcp_FlagACK) == 0 ) return;
        /* process ack value in packet */
        diff = 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 = tp->acknum - s->seqnum - 1;
        s->flags = tcp_FlagACK | tcp_FlagFIN;
        if ( diff == 0 ) {
            s->state = tcp_StateFINWT2;
            s->flags = tcp_FlagACK;
            sprintf(tempstr,"finack received.");
			writelog(tempstr);
        }
        tcp_ProcessData(s, tp, len);
        break;

    case tcp_StateFINWT2:
        s->flags = tcp_FlagACK;
        tcp_ProcessData(s, tp, len);
        break;

    case tcp_StateCLOSING:
        if ( tp->acknum == (s->seqnum + 1) ) {
            s->state = tcp_StateTIMEWT;
            s->timeout = tcp_TIMEOUT;
        }
        break;

    case tcp_StateLASTACK:
        if ( tp->acknum == (s->seqnum + 1) ) {
            s->state = tcp_StateCLOSED;
            s->unhappy = false;
            s->dataSize = 0;
            s->dataHandler(s, 0, 0);
            tcp_Unthread(s);
            sprintf(tempstr,"Closed. ");
			writelog(tempstr);
        } else {
            s->flags = tcp_FlagACK | tcp_FlagFIN;
            tcp_Send(s);
            s->timeout = tcp_TIMEOUT;
            sprintf(tempstr,"retransmitting FIN");
			writelog(tempstr);
        }
        break;

    case tcp_StateTIMEWT:
        s->flags = tcp_FlagACK;
        tcp_Send(s);
    }
}

/*
 * 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 CTcp::tcp_ProcessData(tcp_Socket *s,tcp_Header * tp,int len)
{
    int diff, x;
    word flags;
    byte *dp;

    flags = tp->flags;
    diff = s->acknum - 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);
        if ( flags & tcp_FlagFIN ) {
            s->acknum++;
#ifdef DEBUG
            writelog("consumed fin.");
#endif
            switch(s->state) {
              case tcp_StateESTAB:
                /* note: skip state CLOSEWT by automatically closing conn */
                x = tcp_StateLASTACK;
                s->flags |= tcp_FlagFIN;
                s->unhappy = true;
#ifdef DEBUG
                writelog("sending fin.");
#endif
                break;
              case tcp_StateFINWT1:
                x = tcp_StateCLOSING;
                break;
              case tcp_StateFINWT2:
                x = tcp_StateTIMEWT;
                break;
            }
            s->state = x;
        }
    }
    s->timeout = tcp_TIMEOUT;
    tcp_Send(s);
}

/*
 * Format and send an outgoing segment
 */
void CTcp::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);//Format an ethernet header in the transmit buffer
 //   dp = &pkt->maxsegopt;

    pkt->in.length = sizeof(in_Header) + sizeof(tcp_Header) + s->dataSize;

    /* tcp header */
    pkt->tcp.srcPort = s->myport;
    pkt->tcp.dstPort = s->hisport;
    pkt->tcp.seqnum = s->seqnum;
    pkt->tcp.acknum = s->acknum;
    pkt->tcp.window = 1024;
    pkt->tcp.flags = s->flags | 0x5000;
    pkt->tcp.checksum = 0;
    pkt->tcp.urgentPointer = 0;
    if ( s->flags & tcp_FlagSYN ) {
        pkt->tcp.flags += 0x1000;
        pkt->in.length += 4;
        pkt->maxsegopt = 0x02040578; /* 1400 bytes */
        dp += 4;
    }
    Move(s->data, dp, s->dataSize);

    /* internet header */
    pkt->in.vht = 0x4500;   /* version 4, hdrlen 5, tos 0 */
    pkt->in.identification = tcp_id++;
    pkt->in.frag = 0;
    pkt->in.ttlProtocol = (250<<8) + 6;
    pkt->in.checksum = 0;
    pkt->in.source = sin_lclINAddr;
    pkt->in.destination = s->hisaddr;
    pkt->in.checksum = ~checksum((word*)&pkt->in, sizeof(in_Header));

    /* compute tcp checksum */
    ph.src = pkt->in.source;//ph:tcp_PseudoHeader
    ph.dst = pkt->in.destination;
    ph.mbz = 0;
    ph.protocol = 6;
    ph.length = pkt->in.length - sizeof(in_Header);
    ph.checksum = checksum((word*)&pkt->tcp, ph.length);
    pkt->tcp.checksum = ~checksum((word*)&ph, sizeof ph);

#ifdef DEBUG
    if ( tcp_logState & tcp_LOGPACKETS )
        tcp_DumpHeader(&pkt->in, &pkt->tcp, "Sending");
#endif

  //  sed_Send(pkt->in.length);//发送
}

/*
 * Do a one's complement checksum
 */
longword CTcp::checksum(word *dp,int length)
{
    int len;
    longword sum;

    len = length >> 1;
    sum = 0;
    while ( len-- > 0 ) sum += *dp++;
    if ( length & 1 ) sum += (*dp & 0xFF00);
    sum = (sum & 0xFFFF) + ((sum >> 16) & 0xFFFF);
    sum = (sum & 0xFFFF) + ((sum >> 16) & 0xFFFF);

    return ( sum );
}

/*
 * Dump the tcp protocol header of a packet
 */
void CTcp::tcp_DumpHeader(in_Header * ip,tcp_Header *tp, char *mesg )
{
    
    static char *flags[] = { "FIN", "SYN", "RST", "PUSH", "ACK", "URG" };
    int len;
    word f;
	char* tempstr;
	
	tp = (tcp_Header *)((byte *)ip + in_GetHdrlenBytes(ip));
    len =  ip->length - ((tcp_GetDataOffset(tp) + in_GetHdrlen(ip)) << 2);
    sprintf(tempstr,"TCP: %s packet:\nS: %x; D: %x; SN=%x ACK=%x W=%d DLen=%d\n",
           mesg, tp->srcPort, tp->dstPort, tp->seqnum, tp->acknum,
           tp->window, len);
	writelog(tempstr);
    printf(tempstr,"DO=%d, C=%x U=%d",
           tcp_GetDataOffset(tp), tp->checksum, tp->urgentPointer);
	writelog(tempstr);
    /* output flags */
    f = tp->flags;
    for ( len = 0; len < 6; len++ )
        if ( f & (1 << len) ) writelog(flags[len]);
    //printf("\n");
}

/*
 * Move bytes from hither(here) to yon(there)
 */
void CTcp::Move(byte *src,byte * dest,int numbytes )
{
    if ( numbytes <= 0 ) return;
    if ( src < dest ) {
        src += numbytes;
        dest += numbytes;
        do {
            *--dest = *--src;
        } while ( --numbytes > 0 );
    } else
        do {
             *dest++ = *src++;
        } while ( --numbytes > 0 );
}

void CTcp::writelog(CString temp)
{
	CStdioFile file;
	CString filename;
	CTime time;
	time=CTime::GetCurrentTime();
	filename=time.Format("%Y%m%d");
	file.Open(filename+".tcp",CFile::modeNoTruncate|CFile::modeCreate|CFile::modeWrite|CFile::typeText);
	file.SeekToEnd();
	temp=time.Format("%Y.%m.%d %H:%M:%S  ")+temp+"\r\n";
	file.Write(temp,temp.GetLength());
	file.Close();
}

⌨️ 快捷键说明

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