Пример #1
0
/*--#+func----------------------------------------------------------------
    FUNCTION: AX25Level2()
     PURPOSE: This routine is the level 2 upcall
      SYNTAX: void AX25Level2(AX25_LEVEL1 *p)
 DESCRIPTION: Called once for each received level1 packet
              This routine handles logging packets in the debugging log,
              dumping packets packets on screen,
              updating the heard stations list.
     RETURNS: Nothing
     HISTORY: 940223 V0.2
    SEE ALSO: Heard LogPacket
--#-func----------------------------------------------------------------*/
void AX25Level2(AX25_LEVEL1 *p)
{
  AX25_PACKET *p2 = NULL;

  if((p2 = ax25rec(p)) == NULL)     /* Convert AX.25 Level 1 to Level 2  */
      return;                       /* bad packet */

  if (CRCcheck(p))  {
    RXCount++;                      /* Increment good frames counter */
    wn_printf(w_mon,"%s\n",DumpAX25(p2,DUMP_HEADER|DUMP_INFO));
    LogPacket(p);                   /* log packets    */
    Heard(p2);                      /* log nodes heard */
  }
  else {
    RXCRCErr++;                     /* Increment CRC error counter */
    /*
    wn_printf(w_mon,"%s\n",DumpAX25(p2,DUMP_HEADER|DUMP_INFO));
    */
    wn_printf(w_mon,"packet CRC failed\n");
  }

  /*-----/ Show heard list and status /-----*/
  DoHeard();
  DumpStatus();


  /*-----/ Free memory, allocated by level2 packet  /-----*/
  free(p2);
  /* p2 = NULL; /*       /* Not neccessary, but useful for later */
}
Пример #2
0
/*-#+func----------------------------------------------------------
    FUNCTION: DumpLog()
     PURPOSE: Dumps all of the log entries to logfile
      SYNTAX: void DumpLog(void);
 DESCRIPTION:
     RETURNS:
     HISTORY:
------------------------------------------------------------------*/
void DumpLog(void)
{
    char    fname[80];
    int i;

    if(nlogs) {
      /*
      printf("\n\nFilename for trace log (RETURN for no logfile) --> ");
      gets(fname);
      */
      strcpy(fname,"packmon.log");
      if(*fname) {
        if((outfile = fopen(fname,"w")) == NULL) {
          perror("Can't open output file");
          return;
        }
        fprintf(outfile,"Version:  Packmon %s compiled %s\n\n",VERSION,__DATE__);
        for(i = 0; i<nlogs; i++)
          DumpEntry(log[i]);
        DumpStatus();
        printf("\n%d packets written to logfile %s.\n",nlogs,strupr(fname));
        fclose(outfile);
      }
    }
}
Пример #3
0
BOOL CService::SendStatusToServiceControlManager( DWORD current_state, 
                                                  DWORD win32_exit_code,
                                                  DWORD check_point,
                                                  DWORD wait_hint,
                                                  DWORD service_specific_code )
{
   BOOL return_value = FALSE;

   SERVICE_STATUS service_status;

   ::ZeroMemory( &service_status, sizeof( service_status ) );

   // initialize service_status and send it to SCM

   if ( current_state == SERVICE_START_PENDING )
   {
      service_status.dwControlsAccepted = 0;
   }
   else
   {
      service_status.dwControlsAccepted = m_ControlsAccepted;
   }

   if ( service_specific_code == 0 )
   {
      service_status.dwWin32ExitCode = win32_exit_code;
   }
   else
   {
      service_status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
   }

   service_status.dwServiceType             = SERVICE_WIN32_OWN_PROCESS;
   service_status.dwCurrentState            = current_state;
   service_status.dwServiceSpecificExitCode = service_specific_code;
   service_status.dwCheckPoint              = check_point;
   service_status.dwWaitHint                = wait_hint;

#if defined( _DEBUG )
   DumpStatus( &service_status );
#endif

   return_value = ::SetServiceStatus( m_ServiceStatusHandle, &service_status );

   if ( return_value == FALSE )
   {
      m_ErrorCode = ::GetLastError();
      LogEvent();
      Exit();
   }

   return( return_value );
}
Пример #4
0
void BaczekKPAI::Update()
{
	boost::timer total;
	int frame=cb->GetCurrentFrame();

	int unitids[MAX_UNITS];
	int num = cb->GetFriendlyUnits(unitids);
	friends.clear();
	std::copy(unitids, unitids+num, inserter(friends, friends.begin()));

	num = cheatcb->GetEnemyUnits(unitids);
	oldEnemies.clear();
	oldEnemies.resize(allEnemies.size());
	std::copy(allEnemies.begin(), allEnemies.end(), oldEnemies.begin());
	allEnemies.clear();
	allEnemies.resize(num);
	std::copy(unitids, unitids+num, allEnemies.begin());

	if (frame == 1) {
		// XXX this will fail if used with prespawned units, e.g. missions
		std::copy(unitids, unitids+num, std::inserter(enemyBases, enemyBases.end()));
	}

	if ((frame % 30) == 0) {
		DumpStatus();
	}
	influence->Update(friends, allEnemies);
	python->GameFrame(frame);
	// enable dynamic switching of debug info
	debugLines = python->GetIntValue("debugDrawLines", false);
	debugMsgs = python->GetIntValue("debugMessages", false);


	toplevel->Update();

	ailog->info() << "frame " << frame << " in " << total.elapsed() << std::endl;
}
Пример #5
0
int CTCPConnection::PacketReceived (const void	*pPacket,
				    unsigned	 nLength,
				    CIPAddress	&rSenderIP,
				    int		 nProtocol)
{
	if (nProtocol != IPPROTO_TCP)
	{
		return 0;
	}

	if (nLength < sizeof (TTCPHeader))
	{
		return -1;
	}

	assert (pPacket != 0);
	TTCPHeader *pHeader = (TTCPHeader *) pPacket;

	if (m_nOwnPort != be2le16 (pHeader->nDestPort))
	{
		return 0;
	}
	
	if (m_State != TCPStateListen)
	{
		if (   m_ForeignIP != rSenderIP
		    || m_nForeignPort != be2le16 (pHeader->nSourcePort))
		{
			return 0;
		}
	}
	else
	{
		if (!(pHeader->nDataOffsetFlags & TCP_FLAG_SYN))
		{
			return 0;
		}

		m_Checksum.SetDestinationAddress (rSenderIP);
	}

	if (m_Checksum.Calculate (pPacket, nLength) != CHECKSUM_OK)
	{
		return 0;
	}

	u16 nFlags = pHeader->nDataOffsetFlags;
	u32 nDataOffset = TCP_DATA_OFFSET (pHeader->nDataOffsetFlags)*4;
	u32 nDataLength = nLength-nDataOffset;

	// Current Segment Variables
	u32 nSEG_SEQ = be2le32 (pHeader->nSequenceNumber);
	u32 nSEG_ACK = be2le32 (pHeader->nAcknowledgmentNumber);

	u32 nSEG_LEN = nDataLength;
	if (nFlags & TCP_FLAG_SYN)
	{
		nSEG_LEN++;
	}
	if (nFlags & TCP_FLAG_FIN)
	{
		nSEG_LEN++;
	}
	
	u32 nSEG_WND = be2le16 (pHeader->nWindow);
	//u16 nSEG_UP  = be2le16 (pHeader->nUrgentPointer);
	//u32 nSEG_PRC;	// segment precedence value

	ScanOptions (pHeader);

#ifdef TCP_DEBUG
	CLogger::Get ()->Write (FromTCP, LogDebug,
				"rx %c%c%c%c%c%c, seq %u, ack %u, win %u, len %u",
				nFlags & TCP_FLAG_URGENT ? 'U' : '-',
				nFlags & TCP_FLAG_ACK    ? 'A' : '-',
				nFlags & TCP_FLAG_PUSH   ? 'P' : '-',
				nFlags & TCP_FLAG_RESET  ? 'R' : '-',
				nFlags & TCP_FLAG_SYN    ? 'S' : '-',
				nFlags & TCP_FLAG_FIN    ? 'F' : '-',
				nSEG_SEQ-m_nIRS,
				nFlags & TCP_FLAG_ACK ? nSEG_ACK-m_nISS : 0,
				nSEG_WND,
				nDataLength);

	DumpStatus ();
#endif

	boolean bAcceptable = FALSE;

	// RFC 793 section 3.9 "SEGMENT ARRIVES"
	switch (m_State)
	{
	case TCPStateClosed:
		if (nFlags & TCP_FLAG_RESET)
		{
			// ignore
		}
		else if (!(nFlags & TCP_FLAG_ACK))
		{
			m_ForeignIP.Set (rSenderIP);
			m_nForeignPort = be2le16 (pHeader->nSourcePort);
			m_Checksum.SetDestinationAddress (rSenderIP);

			SendSegment (TCP_FLAG_RESET | TCP_FLAG_ACK, 0, nSEG_SEQ+nSEG_LEN);
		}
		else
		{
			m_ForeignIP.Set (rSenderIP);
			m_nForeignPort = be2le16 (pHeader->nSourcePort);
			m_Checksum.SetDestinationAddress (rSenderIP);

			SendSegment (TCP_FLAG_RESET, nSEG_ACK);
		}
		break;

	case TCPStateListen:
		if (nFlags & TCP_FLAG_RESET)
		{
			// ignore
		}
		else if (nFlags & TCP_FLAG_ACK)
		{
			m_ForeignIP.Set (rSenderIP);
			m_nForeignPort = be2le16 (pHeader->nSourcePort);
			m_Checksum.SetDestinationAddress (rSenderIP);

			SendSegment (TCP_FLAG_RESET, nSEG_ACK);
		}
		else if (nFlags & TCP_FLAG_SYN)
		{
			m_nRCV_NXT = nSEG_SEQ+1;
			m_nIRS = nSEG_SEQ;

			m_nSND_WND = nSEG_WND;
			m_nSND_WL1 = nSEG_SEQ;
			m_nSND_WL2 = nSEG_ACK;
	
			assert (nSEG_LEN > 0);

			if (nDataLength > 0)
			{
				m_RxQueue.Enqueue ((u8 *) pPacket+nDataOffset, nDataLength);
			}

			m_nISS = CalculateISN ();
			m_RTOCalculator.Initialize (m_nISS);

			m_ForeignIP.Set (rSenderIP);
			m_nForeignPort = be2le16 (pHeader->nSourcePort);
			m_Checksum.SetDestinationAddress (rSenderIP);

			SendSegment (TCP_FLAG_SYN | TCP_FLAG_ACK, m_nISS, m_nRCV_NXT);
			m_RTOCalculator.SegmentSent (m_nISS);

			m_nSND_NXT = m_nISS+1;
			m_nSND_UNA = m_nISS;
			
			NEW_STATE (TCPStateSynReceived);

			m_Event.Set ();
		}
		break;

	case TCPStateSynSent:
		if (nFlags & TCP_FLAG_ACK)
		{
			if (!bwh (m_nISS, nSEG_ACK, m_nSND_NXT))
			{
				if (!(nFlags & TCP_FLAG_RESET))
				{
					SendSegment (TCP_FLAG_RESET, nSEG_ACK);
				}

				return 1;
			}
			else if (bwlh (m_nSND_UNA, nSEG_ACK, m_nSND_NXT))
			{
				bAcceptable = TRUE;
			}
		}

		if (nFlags & TCP_FLAG_RESET)
		{
			if (bAcceptable)
			{
				NEW_STATE (TCPStateClosed);
				m_bSendSYN = FALSE;
				m_nErrno = -1;

				m_Event.Set ();
			}
			
			break;
		}
		
		if (   (nFlags & TCP_FLAG_ACK)
		    && !bAcceptable)
		{
			break;
		}

		if (nFlags & TCP_FLAG_SYN)
		{
			m_nRCV_NXT = nSEG_SEQ+1;
			m_nIRS = nSEG_SEQ;

			if (nFlags & TCP_FLAG_ACK)
			{
				m_RTOCalculator.SegmentAcknowledged (nSEG_ACK);

				if (nSEG_ACK-m_nSND_UNA > 1)
				{
					m_RetransmissionQueue.Advance (nSEG_ACK-m_nSND_UNA-1);
				}

				m_nSND_UNA = nSEG_ACK;
			}

			if (gt (m_nSND_UNA, m_nISS))
			{
				NEW_STATE (TCPStateEstablished);
				m_bSendSYN = FALSE;

				StopTimer (TCPTimerRetransmission);

				// next transmission starts with this count
				m_nRetransmissionCount = MAX_RETRANSMISSIONS;

				m_Event.Set ();

				// RFC 1122 section 4.2.2.20 (c)
				m_nSND_WND = nSEG_WND;
				m_nSND_WL1 = nSEG_SEQ;
				m_nSND_WL2 = nSEG_ACK;
	
				SendSegment (TCP_FLAG_ACK, m_nSND_NXT, m_nRCV_NXT);
				
				if (   (nFlags & TCP_FLAG_FIN)		// other controls?
				    || nDataLength > 0)
				{
					goto StepSix;
				}

				break;
			}
			else
			{
				NEW_STATE (TCPStateSynReceived);
				m_bSendSYN = FALSE;
				SendSegment (TCP_FLAG_SYN | TCP_FLAG_ACK, m_nISS, m_nRCV_NXT);
				m_RTOCalculator.SegmentSent (m_nISS);
				m_nRetransmissionCount = MAX_RETRANSMISSIONS;
				StartTimer (TCPTimerRetransmission, m_RTOCalculator.GetRTO ());

				if (   (nFlags & TCP_FLAG_FIN)		// other controls?
				    || nDataLength > 0)
				{
					if (nFlags & TCP_FLAG_FIN)
					{
						SendSegment (TCP_FLAG_RESET, m_nSND_NXT);
						NEW_STATE (TCPStateClosed);
					}

					if (nDataLength > 0)
					{
						m_RxQueue.Enqueue ((u8 *) pPacket+nDataOffset, nDataLength);
					}

					break;
				}
			}
		}
		break;

	case TCPStateSynReceived:
	case TCPStateEstablished:
	case TCPStateFinWait1:
	case TCPStateFinWait2:
	case TCPStateCloseWait:
	case TCPStateClosing:
	case TCPStateLastAck:
	case TCPStateTimeWait:
		// step 1 ( check sequence number)
		if (m_nRCV_WND > 0)
		{
			if (nSEG_LEN == 0)
			{
				if (bwl (m_nRCV_NXT, nSEG_SEQ, m_nRCV_NXT+m_nRCV_WND))
				{
					bAcceptable = TRUE;
				}
			}
			else
			{
				if (   bwl (m_nRCV_NXT, nSEG_SEQ, m_nRCV_NXT+m_nRCV_WND)
				    || bwl (m_nRCV_NXT, nSEG_SEQ+nSEG_LEN-1, m_nRCV_NXT+m_nRCV_WND))
				{
					bAcceptable = TRUE;
				}
			}
		}
		else
		{
			if (nSEG_LEN == 0)
			{
				if (nSEG_SEQ == m_nRCV_NXT)
				{
					bAcceptable = TRUE;
				}
			}
		}

		if (   !bAcceptable
		    && m_State != TCPStateSynReceived)
		{
			SendSegment (TCP_FLAG_ACK, m_nSND_NXT, m_nRCV_NXT);
			break;
		}

		// step 2 (check RST bit)
		if (nFlags & TCP_FLAG_RESET)
		{
			switch (m_State)
			{
			case TCPStateSynReceived:
				m_RetransmissionQueue.Flush ();
				if (!m_bActiveOpen)
				{
					NEW_STATE (TCPStateListen);
					return 1;
				}
				else
				{
					m_nErrno = -1;
					NEW_STATE (TCPStateClosed);
					m_Event.Set ();
					return 1;
					
				}
				break;

			case TCPStateEstablished:
			case TCPStateFinWait1:
			case TCPStateFinWait2:
			case TCPStateCloseWait:
				m_nErrno = -1;
				m_RetransmissionQueue.Flush ();
				m_TxQueue.Flush ();
				m_RxQueue.Flush ();
				NEW_STATE (TCPStateClosed);
				m_Event.Set ();
				return 1;

			case TCPStateClosing:
			case TCPStateLastAck:
			case TCPStateTimeWait:
				NEW_STATE (TCPStateClosed);
				m_Event.Set ();
				return 1;

			default:
				UNEXPECTED_STATE ();
				return 1;
			}
		}

		// step 3 (check security and precedence, not supported)
		
		// step 4 (check SYN bit)
		if (nFlags & TCP_FLAG_SYN)
		{
			// RFC 1122 section 4.2.2.20 (e)
			if (   m_State == TCPStateSynReceived
			    && !m_bActiveOpen)
			{
				NEW_STATE (TCPStateListen);
				return 1;
			}
			
			SendSegment (TCP_FLAG_RESET, m_nSND_NXT);
			m_nErrno = -1;
			m_RetransmissionQueue.Flush ();
			m_TxQueue.Flush ();
			m_RxQueue.Flush ();
			NEW_STATE (TCPStateClosed);
			m_Event.Set ();
			return 1;
		}

		// step 5 (check ACK field)
		if (!(nFlags & TCP_FLAG_ACK))
		{
			return 1;
		}

		switch (m_State)
		{
		case TCPStateSynReceived:
			if (bwlh (m_nSND_UNA, nSEG_ACK, m_nSND_NXT))
			{
				// RFC 1122 section 4.2.2.20 (f)
				m_nSND_WND = nSEG_WND;
				m_nSND_WL1 = nSEG_SEQ;
				m_nSND_WL2 = nSEG_ACK;

				m_nSND_UNA = nSEG_ACK;		// got ACK for SYN

				m_RTOCalculator.SegmentAcknowledged (nSEG_ACK);

				NEW_STATE (TCPStateEstablished);

				// next transmission starts with this count
				m_nRetransmissionCount = MAX_RETRANSMISSIONS;
			}
			else
			{
				SendSegment (TCP_FLAG_RESET, nSEG_ACK);
			}
			break;

		case TCPStateEstablished:
		case TCPStateFinWait1:
		case TCPStateFinWait2:
		case TCPStateCloseWait:
		case TCPStateClosing:
			if (bwh (m_nSND_UNA, nSEG_ACK, m_nSND_NXT))
			{
				m_RTOCalculator.SegmentAcknowledged (nSEG_ACK);

				unsigned nBytesAck = nSEG_ACK-m_nSND_UNA;
				m_nSND_UNA = nSEG_ACK;

				if (nSEG_ACK == m_nSND_NXT)	// all segments are acknowledged
				{
					StopTimer (TCPTimerRetransmission);

					// next transmission starts with this count
					m_nRetransmissionCount = MAX_RETRANSMISSIONS;

					m_Event.Set ();
				}

				if (   m_State == TCPStateFinWait1
				    || m_State == TCPStateClosing)
				{
					nBytesAck--;		// acknowledged FIN does not count
					m_bFINQueued = FALSE;
				}

				if (   m_State == TCPStateEstablished
				    && nBytesAck == 1)
				{
					nBytesAck--;
				}
				
				if (nBytesAck > 0)
				{
					m_RetransmissionQueue.Advance (nBytesAck);
				}

				// update send window
				if (   lt (m_nSND_WL1, nSEG_SEQ)
				    || (   m_nSND_WL1 == nSEG_SEQ
				        && le (m_nSND_WL2, nSEG_ACK)))
				{
					m_nSND_WND = nSEG_WND;
					m_nSND_WL1 = nSEG_SEQ;
					m_nSND_WL2 = nSEG_ACK;
				}
			}
			else if (le (nSEG_ACK, m_nSND_UNA))	// RFC 1122 section 4.2.2.20 (g)
			{
				// ignore duplicate ACK ...
				
				// RFC 1122 section 4.2.2.20 (g)
				if (bwlh (m_nSND_UNA, nSEG_ACK, m_nSND_NXT))
				{
					// ... but update send window
					if (   lt (m_nSND_WL1, nSEG_SEQ)
					    || (   m_nSND_WL1 == nSEG_SEQ
						&& le (m_nSND_WL2, nSEG_ACK)))
					{
						m_nSND_WND = nSEG_WND;
						m_nSND_WL1 = nSEG_SEQ;
						m_nSND_WL2 = nSEG_ACK;
					}
				}
			}
			else if (gt (nSEG_ACK, m_nSND_NXT))
			{
				SendSegment (TCP_FLAG_ACK, m_nSND_NXT, m_nRCV_NXT);
				return 1;
			}
			
			switch (m_State)
			{
			case TCPStateEstablished:
			case TCPStateCloseWait:
				break;

			case TCPStateFinWait1:
				if (nSEG_ACK == m_nSND_NXT)	// if our FIN is now acknowledged
				{
					m_RTOCalculator.SegmentAcknowledged (nSEG_ACK);

					m_bFINQueued = FALSE;
					StopTimer (TCPTimerRetransmission);
					NEW_STATE (TCPStateFinWait2);
				}
				else
				{
					break;
				}
				// fall through

			case TCPStateFinWait2:
				if (m_RetransmissionQueue.IsEmpty ())
				{
					m_Event.Set ();
				}
				break;
				
			case TCPStateClosing:
				if (nSEG_ACK == m_nSND_NXT)	// if our FIN is now acknowledged
				{
					m_RTOCalculator.SegmentAcknowledged (nSEG_ACK);

					m_bFINQueued = FALSE;
					StopTimer (TCPTimerRetransmission);
					NEW_STATE (TCPStateTimeWait);
					StartTimer (TCPTimerTimeWait, HZ_TIMEWAIT);
				}
				break;

			default:
				UNEXPECTED_STATE ();
				break;
			}
			break;
			
		case TCPStateLastAck:
			if (nSEG_ACK == m_nSND_NXT)	// if our FIN is now acknowledged
			{
				m_bFINQueued = FALSE;
				NEW_STATE (TCPStateClosed);
				m_Event.Set ();
				return 1;
			}
			break;

		case TCPStateTimeWait:
			if (nSEG_ACK == m_nSND_NXT)	// if our FIN is now acknowledged
			{
				m_bFINQueued = FALSE;
				SendSegment (TCP_FLAG_ACK, m_nSND_NXT, m_nRCV_NXT);
				StartTimer (TCPTimerTimeWait, HZ_TIMEWAIT);
			}
			break;

		default:
			UNEXPECTED_STATE ();
			break;
		}

		// step 6 (check URG bit, not supported)
	StepSix:

		// step 7 (process text segment)
		if (nSEG_LEN == 0)
		{
			return 1;
		}
		
		switch (m_State)
		{
		case TCPStateEstablished:
		case TCPStateFinWait1:
		case TCPStateFinWait2:
			if (nSEG_SEQ == m_nRCV_NXT)
			{
				if (nDataLength > 0)
				{
					m_RxQueue.Enqueue ((u8 *) pPacket+nDataOffset, nDataLength);

					m_nRCV_NXT += nDataLength;

					// m_nRCV_WND should be adjusted here (section 3.7)

					// following ACK could be piggybacked with data
					SendSegment (TCP_FLAG_ACK, m_nSND_NXT, m_nRCV_NXT);

					if (nFlags & TCP_FLAG_PUSH)
					{
						m_Event.Set ();
					}
				}
			}
			else
			{
				SendSegment (TCP_FLAG_ACK, m_nSND_NXT, m_nRCV_NXT);
			}
			break;

		case TCPStateCloseWait:
		case TCPStateClosing:
		case TCPStateLastAck:
		case TCPStateTimeWait:
			break;

		default:
			UNEXPECTED_STATE ();
			break;
		}

		// step 8 (check FIN bit)
		if (   m_State == TCPStateClosed
		    || m_State == TCPStateListen
		    || m_State == TCPStateSynSent)
		{
			return 1;
		}
			
		if (!(nFlags & TCP_FLAG_FIN))
		{
			return 1;
		}

		// connection is closing
		m_nRCV_NXT++;
		SendSegment (TCP_FLAG_ACK, m_nSND_NXT, m_nRCV_NXT);
		
		switch (m_State)
		{
		case TCPStateSynReceived:
		case TCPStateEstablished:
			NEW_STATE (TCPStateCloseWait);
			m_Event.Set ();
			break;

		case TCPStateFinWait1:
			if (nSEG_ACK == m_nSND_NXT)	// if our FIN is now acknowledged
			{
				m_bFINQueued = FALSE;
				StopTimer (TCPTimerRetransmission);
				StopTimer (TCPTimerUser);
				NEW_STATE (TCPStateTimeWait);
				StartTimer (TCPTimerTimeWait, HZ_TIMEWAIT);
			}
			else
			{
				NEW_STATE (TCPStateClosing);
			}
			break;

		case TCPStateFinWait2:
			StopTimer (TCPTimerRetransmission);
			StopTimer (TCPTimerUser);
			NEW_STATE (TCPStateTimeWait);
			StartTimer (TCPTimerTimeWait, HZ_TIMEWAIT);
			break;

		case TCPStateCloseWait:
		case TCPStateClosing:
		case TCPStateLastAck:
			break;
			
		case TCPStateTimeWait:
			StartTimer (TCPTimerTimeWait, HZ_TIMEWAIT);
			break;

		default:
			UNEXPECTED_STATE ();
			break;
		}
		break;
	}

	return 1;
}