亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? tcp.c

?? arm環境下開發以太網的程序
?? C
?? 第 1 頁 / 共 3 頁
字號:

	if ( flags & SYN )
	{
		len += sizeof(options);
		options.Kind = TCP_OPTIONS_MAX_SEG_SIZE;
		options.Length = 0x04;

		// Load MSS in already swapped order.
		options.MaxSegSize.v[0]  = (MAC_RX_BUFFER_SIZE >> 8); // 0x05;
		options.MaxSegSize.v[1]  = (MAC_RX_BUFFER_SIZE & 0xff); // 0xb4;

		header.DataOffset.Val   = (sizeof(header) + sizeof(options)) >> 2;
	}
	else
		header.DataOffset.Val   = sizeof(header) >> 2;


	// Calculate IP pseudoheader checksum.
	pseudoHeader.SourceAddress	= AppConfig.MyIPAddr;
	pseudoHeader.DestAddress    = remote->IPAddr;
	pseudoHeader.Zero           = 0x0;
	pseudoHeader.Protocol       = IP_PROT_TCP;
	pseudoHeader.TCPLength      = len;

	SwapPseudoTCPHeader(pseudoHeader);

	header.Checksum = ~CalcIPChecksum((BYTE*)&pseudoHeader,
		sizeof(pseudoHeader));
	checkSum.Val = header.Checksum;

	// Write IP header.
	IPPutHeader(remote, IP_PROT_TCP, len);
	IPPutArray((BYTE*)&header, sizeof(header));

	if ( flags & SYN )
		IPPutArray((BYTE*)&options, sizeof(options));

	IPSetTxBuffer(buffer, 0);

	checkSum.Val = CalcIPBufferChecksum(len);

	// Update the checksum.
	IPSetTxBuffer(buffer, 16);
	MACPut(checkSum.v[1]);
	MACPut(checkSum.v[0]);
	MACSetTxBuffer(buffer, 0);

	MACFlush();

#if !defined(TCP_NO_WAIT_FOR_ACK) && !defined(DEBUG)
	// If we send the packet again, the remote node might think that we timed 
	// out and retransmitted.  It could thus immediately send back an ACK and 
	// dramatically improve throuput.
	while(!IPIsTxReady(TRUE));
	MACFlush();
#endif
}



/*********************************************************************
* Function:        static TCP_SOCKET FindMatchingSocket(TCP_HEADER *h,
*                                      NODE_INFO* remote)
*
* PreCondition:    TCPInit() is already called
*
* Input:           h           - TCP Header to be matched against.
*                  remote      - Node who sent this header.
*
* Output:          A socket that matches with given header and remote
*                  node is searched.
*                  If such socket is found, its index is returned
*                  else INVALID_SOCKET is returned.
*
* Side Effects:    None
*
* Overview:        None
*
* Note:            None
********************************************************************/
static TCP_SOCKET FindMatchingSocket(TCP_HEADER *h, NODE_INFO *remote)
{
	SOCKET_INFO *ps;
	TCP_SOCKET s;
	TCP_SOCKET partialMatch;

	partialMatch = INVALID_SOCKET;

	for ( s = 0; s < MAX_SOCKETS; s++ )
	{
		ps = &TCB[s];

		if ( ps->smState != TCP_CLOSED )
		{
			if ( ps->localPort == h->DestPort )
			{
				if ( ps->smState == TCP_LISTEN )
					partialMatch = s;

				if ( ps->remotePort == h->SourcePort &&
					ps->remote.IPAddr.Val == remote->IPAddr.Val )
				{
					return s;
				}
			}
		}
	}

	// We are not listening on this port
	if(partialMatch == INVALID_SOCKET)
		return INVALID_SOCKET;

	// Copy the remote node IP/MAC address and source TCP port 
	// number into our TCB and return this socket to the caller
	ps = &TCB[partialMatch];
	memcpy((void*)&ps->remote, (void*)remote, sizeof(*remote));
	ps->remotePort          = h->SourcePort;
	ps->Flags.bIsGetReady   = FALSE;
	if(ps->TxBuffer != INVALID_BUFFER)
	{
		MACDiscardTx(ps->TxBuffer);
		ps->TxBuffer        = INVALID_BUFFER;
	}
	ps->Flags.bIsPutReady   = TRUE;
	
	return partialMatch;
}






/*********************************************************************
* Function:        static void SwapTCPHeader(TCP_HEADER* header)
*
* PreCondition:    None
*
* Input:           header      - TCP Header to be swapped.
*
* Output:          Given header is swapped.
*
* Side Effects:    None
*
* Overview:        None
*
* Note:            None
********************************************************************/
static void SwapTCPHeader(TCP_HEADER* header)
{
	header->SourcePort      = swaps(header->SourcePort);
	header->DestPort        = swaps(header->DestPort);
	header->SeqNumber       = swapl(header->SeqNumber);
	header->AckNumber       = swapl(header->AckNumber);
	header->Window          = swaps(header->Window);
	header->Checksum        = swaps(header->Checksum);
	header->UrgentPointer   = swaps(header->UrgentPointer);
}



/*********************************************************************
* Function:        static void CloseSocket(SOCKET_INFO* ps)
*
* PreCondition:    TCPInit() is already called
*
* Input:           ps  - Pointer to a socket info that is to be
*                          closed.
*
* Output:          Given socket information is reset and any
*                  buffer held by this socket is discarded.
*
* Side Effects:    None
*
* Overview:        None
*
* Note:            None
********************************************************************/
static void CloseSocket(SOCKET_INFO* ps)
{
	if(ps->TxBuffer != INVALID_BUFFER)
	{
		MACDiscardTx(ps->TxBuffer);
		ps->TxBuffer            = INVALID_BUFFER;
		ps->Flags.bIsPutReady   = TRUE;
	}

	ps->remote.IPAddr.Val = 0x00;
	ps->remotePort = 0x00;
	if(ps->Flags.bIsGetReady)
	{
		MACDiscardRx();
	}
	ps->Flags.bIsGetReady       = FALSE;
	ps->TimeOut                 = TCP_START_TIMEOUT_VAL;

	ps->Flags.bIsTxInProgress   = FALSE;

	if(ps->Flags.bServer)
	{
		ps->smState = TCP_LISTEN;
	}
	else
	{
		ps->smState = TCP_CLOSED;
	}

	ps->TxCount = 0;

	return;
}



/*********************************************************************
* Function:        static void HandleTCPSeg(TCP_SOCKET s,
*                                      NODE_INFO *remote,
*                                      TCP_HEADER* h,
*                                      WORD len)
*
* PreCondition:    TCPInit() is already called     AND
*                  TCPProcess() is the caller.
*
* Input:           s           - Socket that owns this segment
*                  remote      - Remote node info
*                  h           - TCP Header
*                  len         - Total buffer length.
*
* Output:          TCP FSM is executed on given socket with
*                  given TCP segment.
*
* Side Effects:    None
*
* Overview:        None
*
* Note:            None
********************************************************************/
static void HandleTCPSeg(TCP_SOCKET s,
						 NODE_INFO *remote,
						 TCP_HEADER *h,
						 WORD len)
{
	DWORD ack;
	DWORD seq;
	DWORD prevAck, prevSeq;
	SOCKET_INFO *ps;
	BYTE flags;

	ps = &TCB[s];

	flags = 0x00;

	// Clear timeout info
	ps->RetryCount  = 0;
	ps->startTick   = TickGet();
	ps->TimeOut = TCP_START_TIMEOUT_VAL;

	// Reset FSM, if RST is received.
	if(h->Flags.bits.flagRST)
	{
		MACDiscardRx();
		ps->smState = ps->Flags.bServer ? TCP_LISTEN : TCP_SYN_SENT;
		return;
	}

	seq = ps->SND_SEQ;
	
	// ack is just a temporary variable
	ack = h->Window - (seq - h->AckNumber) - ps->TxCount;
	if((signed long)ack < 0)
		ps->RemoteWindow = 0;
	else
		ps->RemoteWindow = ack;


#ifdef STACK_CLIENT_MODE
	// Handle TCP_SYN_SENT state
	// The TCP_SYN_SENT state occurs when an application 
	// calls TCPConnect().  After an initial SYN is sent,
	// we expect a SYN + ACK before establishing the 
	// connection.
	if(ps->smState == TCP_SYN_SENT)
	{
		// Check if this is a SYN packet.  Unsynchronized, we cannot
		// handle any other packet types.
		if(!h->Flags.bits.flagSYN)
		{
			MACDiscardRx();

			// Send out a RESET if the remote node thinks a connection is already established
		    if(h->Flags.bits.flagACK)
		    {
				flags = RST;
				goto SendTCPControlPacket;
	        }

			return;
		}

		// We now have a sequence number for the remote node
		ps->SND_ACK = h->SeqNumber + len + 1;
		ack = ps->SND_ACK;

		// If there is no ACK, we must go to TCP_SYN_RECEIVED.  With an ACK, 
		// we can establish the connection now.
		if(!h->Flags.bits.flagACK)
		{
			ps->smState = TCP_SYN_RECEIVED;
			MACDiscardRx();
			// Send out a SYN+ACK for simultaneous connection open
			flags = SYN | ACK;
			goto SendTCPControlPacket;
		}

		// We received SYN+ACK, establish the connection now
		ps->smState = TCP_ESTABLISHED;
		// Send out an ACK
		flags = ACK;

		ps->RemoteWindow = h->Window;

		// Check for application data and make it 
		// available, if present
		if(len)
		{
			ps->Flags.bIsGetReady   = TRUE;
			ps->RxCount             = len;
			ps->Flags.bFirstRead    = TRUE;
		}
		else	// No application data in this packet
		{
			MACDiscardRx();
		}
		goto SendTCPControlPacket;
	}
#endif

	// Handle TCP_LISTEN state
	if(ps->smState == TCP_LISTEN )
	{
		MACDiscardRx();

		// Send a RST if this isn't a SYN packet
		if(!h->Flags.bits.flagSYN)
		{
			flags = RST;
			goto SendTCPControlPacket;
		}

		ps->SND_ACK = h->SeqNumber + len + 1;
		ps->RemoteWindow = h->Window;

		// This socket has received connection request (SYN).
		// Remember calling node, assign next segment seq. number
		// for this potential connection.
		memcpy((void*)&ps->remote, (const void*)remote, sizeof(*remote));
		ps->remotePort = h->SourcePort;

		// Grant connection request.
		ps->smState = TCP_SYN_RECEIVED;
		seq = ps->SND_SEQ++;
		ack =  ps->SND_ACK;
		flags = SYN | ACK;
		goto SendTCPControlPacket;
	}


	// Remember current seq and ack for our connection so that if
	// we have to silently discard this packet, we can go back to
	// previous ack and seq numbers.
	prevAck = ps->SND_ACK;
	prevSeq = ps->SND_SEQ;

	ack = h->SeqNumber;
	ack += (DWORD)len;
	seq = ps->SND_SEQ;

	// State is something other than TCP_LISTEN, handle it.
	{
		// Check to see if the incomming sequence number is what 
		// we expect (last transmitted ACK value).  Throw this packet 
		// away if it is wrong.
		if(h->SeqNumber == prevAck)
		{
			// After receiving a SYNchronization request, we expect an 
			// ACK to our transmitted SYN
			if(ps->smState == TCP_SYN_RECEIVED)
			{
				if(h->Flags.bits.flagACK)
				{
					// ACK received as expected, this connection is 
					// now established
					ps->SND_ACK = ack;
					ps->smState = TCP_ESTABLISHED;

					// Check if this first packet has application data 
					// in it.  Make it available if so.
					if(len)
					{
						ps->Flags.bIsGetReady   = TRUE;
						ps->RxCount             = len;
						ps->Flags.bFirstRead    = TRUE;
					}
					else
						MACDiscardRx();
				}
				else	// No ACK to our SYN
				{
					MACDiscardRx();
				}
			}
			// Connection is established, closing, or otherwise
			else
			{

				// Save the seq+len value of the packet for our future 
				// ACK transmission, and so out of sequence packets 
				// can be detected in the future.
				ps->SND_ACK = ack;

				// Handle packets received while connection established.
				if(ps->smState == TCP_ESTABLISHED)
				{
					// If this packet has the ACK set, mark all 
					// previous TX packets as no longer needed for 
					// possible retransmission.
					// TODO: Make this more sophisticated so that partial ACKs due to fragmentation are handled correctly.  i.e. Keep a real output stream buffer with slidable window capability.
					if(h->Flags.bits.flagACK && !ps->Flags.bIsPutReady)
					{
						if(ps->TxBuffer != INVALID_BUFFER)
						{
							MACDiscardTx(ps->TxBuffer);
							ps->TxBuffer            = INVALID_BUFFER;
							ps->Flags.bIsPutReady   = TRUE;
						}
					}

					// Check if the remote node is closing the connection
					if(h->Flags.bits.flagFIN)
					{
						DebugPrint("|");
						flags = FIN | ACK;
						seq = ps->SND_SEQ++;
						ack = ++ps->SND_ACK;
						ps->smState = TCP_LAST_ACK;
					}

					// Check if there is any application data in 
					// this packet.
					if(len)
					{
						// There is data.  Make it available if we 
						// don't already have data available.
						if(!ps->Flags.bIsGetReady)
						{
							ps->Flags.bIsGetReady   = TRUE;
							ps->RxCount             = len;
							ps->Flags.bFirstRead    = TRUE;

							// 4/1/02
							flags |= ACK;
						}
						// There is data, but we cannot handle it at this time.
						else
						{
							DebugPrint("D");
							// Since we cannot accept this packet,
							// restore to previous seq and ack.
							// and do not send anything back.
							// Host has to resend this packet when
							// we are ready.
							ps->SND_SEQ = prevSeq;
							ps->SND_ACK = prevAck;

							MACDiscardRx();
						}
					}
					// There is no data in this packet, and thus it 
					// can be thrown away.
					else
					{
						MACDiscardRx();
					}
				}
				// Connection is not established; check if we've sent 
				// a FIN and expect our last ACK
				else if(ps->smState == TCP_LAST_ACK)
				{
					MACDiscardRx();

					if(h->Flags.bits.flagACK)
					{
						CloseSocket(ps);
					}
				}
				else if(ps->smState == TCP_FIN_WAIT_1)
				{
					MACDiscardRx();

					if(h->Flags.bits.flagFIN)
					{
						flags = ACK;
						ack = ++ps->SND_ACK;
						if(h->Flags.bits.flagACK)
						{
							CloseSocket(ps);
						}
						else
						{
							ps->smState = TCP_CLOSING;
						}
					}
					else if(h->Flags.bits.flagACK)
					{
						ps->smState = TCP_FIN_WAIT_2;
					}
				}
				else if(ps->smState == TCP_FIN_WAIT_2)
				{
					MACDiscardRx();

					if(h->Flags.bits.flagFIN)
					{
						flags = ACK;
						ack = ++ps->SND_ACK;
						CloseSocket(ps);
					}
				}
				else if ( ps->smState == TCP_CLOSING )
				{
					MACDiscardRx();

					if ( h->Flags.bits.flagACK )
					{
						CloseSocket(ps);
					}
				}
			}
		}
		// This packet's sequence number does not match what we were 
		// expecting (the last value we ACKed).  Throw this packet 
		// away.  This may happen if packets are delivered out of order.
		// Not enough memory is available on our PIC or Ethernet 
		// controller to implement a robust stream reconstruction 
		// buffer.  As a result, the remote node will just have to 
		// retransmit its packets starting with the proper sequence number.
		else
		{
			MACDiscardRx();

			// Send a new ACK out in case if the previous one was lost 
			// (ACKs aren't ACKed).  This is required to prevent an 
			// unlikely but possible situation which would cause the 
			// connection to time out if the ACK was lost and the 
			// remote node keeps sending us older data than we are 
			// expecting.
			flags = ACK;	
			ack = prevAck;
		}
	}

SendTCPControlPacket:
	if(flags)
	{
		SendTCP(remote,
			h->DestPort,
			h->SourcePort,
			seq,
			ack,
			flags);
	}
}


#endif //#if defined(STACK_USE_TCP)

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
免费在线看一区| 国产一区二区女| 久久久久久电影| 欧美色综合影院| 国产成人在线视频免费播放| 亚洲成av人**亚洲成av**| 国产精品人人做人人爽人人添| 欧美日韩精品是欧美日韩精品| 国产99精品在线观看| 日韩国产欧美视频| 亚洲精品日韩综合观看成人91| 精品国产免费人成电影在线观看四季| 91浏览器在线视频| 国产成人av一区二区三区在线| 午夜不卡av免费| 亚洲综合偷拍欧美一区色| 国产女同性恋一区二区| 欧美成人女星排名| 欧美一区二区三区影视| 欧美午夜电影网| 色综合久久88色综合天天6| 成人午夜av在线| 国产美女精品人人做人人爽| 久久成人久久爱| 老司机精品视频导航| 免费一级片91| 免费成人在线播放| 五月开心婷婷久久| 午夜日韩在线电影| 日韩专区在线视频| 天堂蜜桃91精品| 视频一区国产视频| 天涯成人国产亚洲精品一区av| 一区二区三区四区五区视频在线观看| 国产精品亲子乱子伦xxxx裸| 国产亚洲一区二区三区四区| 久久奇米777| 国产视频911| 中文字幕一区av| 亚洲天堂免费看| 亚洲乱码中文字幕综合| 亚洲女人的天堂| 亚洲综合在线免费观看| 夜夜操天天操亚洲| 性做久久久久久久免费看| 五月天激情小说综合| 日本sm残虐另类| 久久国产人妖系列| 国产毛片一区二区| 成人av网站免费| 色婷婷av一区二区三区gif| 在线视频观看一区| 制服丝袜一区二区三区| 精品卡一卡二卡三卡四在线| 久久亚洲综合色| 国产精品视频麻豆| 综合av第一页| 香蕉久久一区二区不卡无毒影院 | 天天免费综合色| 日韩中文字幕不卡| 激情综合色综合久久综合| 高潮精品一区videoshd| 91丝袜国产在线播放| 欧美天堂亚洲电影院在线播放| 欧美精品亚洲二区| 久久精品欧美一区二区三区不卡| 中文字幕一区二| 丝袜亚洲另类欧美| 国产乱理伦片在线观看夜一区| 成人综合在线网站| 欧美日韩一区二区在线视频| 欧美videos大乳护士334| 久久精品综合网| 一区二区三区日韩欧美精品| 免费在线一区观看| 波多野结衣亚洲| 欧美精品丝袜中出| 国产精品情趣视频| 日韩黄色免费网站| 成人丝袜18视频在线观看| 欧美日韩综合不卡| 久久久99精品久久| 亚洲午夜精品网| 国产成人av一区二区三区在线| 在线欧美日韩精品| 久久久久久久久久久99999| 中文字幕在线一区二区三区| 日韩精品成人一区二区在线| 丰满亚洲少妇av| 这里只有精品电影| 亚洲天堂久久久久久久| 激情国产一区二区| 欧美性xxxxxx少妇| 国产精品入口麻豆九色| 三级欧美在线一区| 91免费版在线| 久久久久久免费毛片精品| 亚洲小说欧美激情另类| 成人av网站在线观看| 日韩欧美一二三区| 亚洲综合色区另类av| 成人夜色视频网站在线观看| 欧美一级在线观看| 一区二区三区四区在线免费观看 | 欧美日韩国产成人在线免费| 国产精品乱人伦| 精品一二三四在线| 欧美乱妇15p| 亚洲精品va在线观看| 高清国产午夜精品久久久久久| 欧美一区二区二区| 五月婷婷综合网| 色狠狠综合天天综合综合| 欧美经典一区二区| 黑人巨大精品欧美一区| 日韩欧美一级精品久久| 亚洲成在人线在线播放| 一本大道久久a久久综合| 国产精品久久久久久久久晋中 | 91高清视频免费看| 中文字幕一区二区三区av| 粉嫩aⅴ一区二区三区四区| 精品国产成人在线影院| 蜜臀av在线播放一区二区三区| 在线观看日韩电影| 一区二区三区四区亚洲| 91精品办公室少妇高潮对白| 中文字幕一区在线观看视频| 丰满亚洲少妇av| 国产精品乱码一区二三区小蝌蚪| 国产成人精品亚洲777人妖| 久久久国产一区二区三区四区小说| 蜜臀av一区二区在线观看| 日韩亚洲国产中文字幕欧美| 日韩国产精品大片| 欧美一区二区免费| 久久精品二区亚洲w码| 精品国产成人在线影院| 国产剧情av麻豆香蕉精品| 久久久夜色精品亚洲| 国产精品77777| 国产精品乱码一区二区三区软件| 成熟亚洲日本毛茸茸凸凹| 中文字幕制服丝袜成人av| 91蜜桃网址入口| 亚洲国产中文字幕| 在线不卡中文字幕播放| 免费成人美女在线观看.| 精品国产乱码久久久久久影片| 久久精品久久综合| 中文字幕欧美区| 一本色道久久综合亚洲91| 亚洲国产欧美在线人成| 337p亚洲精品色噜噜噜| 精品中文字幕一区二区小辣椒| 久久视频一区二区| 波多野结衣亚洲一区| 一区二区三区精品视频| 777欧美精品| 高清视频一区二区| 亚洲一区二区三区中文字幕| 7777精品伊人久久久大香线蕉的| 久久精品99国产国产精| 中文字幕va一区二区三区| 91久久久免费一区二区| 美日韩一区二区三区| 日本一区二区视频在线| 欧美三级日本三级少妇99| 国模少妇一区二区三区| 亚洲日本乱码在线观看| 91精品国产综合久久小美女| 国精产品一区一区三区mba桃花| 国产精品久久久久一区二区三区 | 中文字幕一区二区三区不卡| 欧美日韩极品在线观看一区| 国产专区欧美精品| 最新日韩在线视频| 91精品国产高清一区二区三区| 国产99久久久精品| 无吗不卡中文字幕| 日本视频免费一区| 久久久午夜电影| 欧美视频在线一区二区三区 | 大陆成人av片| 丝袜脚交一区二区| 国产精品第五页| 精品久久一区二区| 色哦色哦哦色天天综合| 国产一区久久久| 五月天欧美精品| 日韩理论片中文av| 久久久久久毛片| 91精品国产黑色紧身裤美女| 91丝袜美女网| 国产91在线观看丝袜| 日韩在线一区二区三区| 亚洲男人的天堂网| 久久精品视频免费观看| 91麻豆精品国产91| 在线精品视频一区二区三四 |