📄 ttcpproxy.cpp
字号:
void TTCP_SetConfigDefaults( PCMD_BLOCK pCmdBlk )
{
memset( pCmdBlk, 0x00, sizeof( CMD_BLOCK ) );
pCmdBlk->m_bTransmit = FALSE;
pCmdBlk->m_Protocol = IPPROTO_TCP;
memset(
&pCmdBlk->m_RemoteAddr,
0x00,
sizeof( IN_ADDR )
);
pCmdBlk->m_Port = IPPORT_TTCP;
pCmdBlk->m_bOptContinuous = FALSE;
pCmdBlk->m_nOptWriteDelay = 0;
pCmdBlk->m_bOptMultiReceiver = FALSE;
pCmdBlk->m_bTouchRecvData = FALSE;
pCmdBlk->m_bSinkMode = TRUE; // FALSE = normal I/O, TRUE = sink/source mode
//
// Setup SinkMode Default
// ----------------------
// SinkMode description:
// TRUE -> A pattern generator is used fill the send buffer. This
// is done only once. Received data is simply counted.
// FALSE -> Data to be sent is read from stdin. Received data is
// written to stdout.
//
// g_nNumBuffersToSend specifies the number of buffers to be sent
// in SinkMode.
//
pCmdBlk->m_bSinkMode = TRUE; // FALSE = normal I/O, TRUE = sink/source mode
pCmdBlk->m_nNumBuffersToSend = 2 * 1024; // number of buffers to send in sinkmode
//
// Setup Size Of Send/Receive Buffer
//
// pCmdBlk->m_pBufBase = NULL;
// pCmdBlk->m_pBuf = NULL;
pCmdBlk->m_nBufferSize = 8 * 1024;
pCmdBlk->m_nBufOffset = 0; // align buffer to this
pCmdBlk->m_nBufAlign = 16*1024; // modulo this
pCmdBlk->m_bUseSockOptBufSize = FALSE; // socket buffer size to use
pCmdBlk->m_nSockOptBufSize = 0; // socket buffer size to use
pCmdBlk->m_nSockOptNoDelay = 0; // set TCP_NODELAY socket option
pCmdBlk->m_bSockOptDebug = FALSE; // TRUE = set SO_DEBUG socket option
}
// Fill Buffer With Printable Characters...
void TTCP_FillPattern( PTEST_BLOCK pTBlk )
{
register char c;
UCHAR PBPreamble[] = "PCAUSA PCATTCP Pattern"; // 22 Bytes
int cnt = pTBlk->m_Cmd.m_nBufferSize;
char *cp = pTBlk->m_pBuf;
c = 0;
//
// Insert "PCAUSA Pattern" Preamble
//
if( cnt > 22 )
{
memcpy( cp, PBPreamble, 22 );
cnt -= 22;
cp += 22;
}
while( cnt-- > 0 )
{
while( !isprint((c&0x7F)) )
{
c++;
}
*cp++ = (c++&0x7F);
}
}
BOOLEAN TTCP_AllocateBuffer( PTEST_BLOCK pTBlk )
{
//
// Setup Buffer Configuration
//
if( (pTBlk->m_pBufBase = (PCHAR )malloc(
pTBlk->m_Cmd.m_nBufferSize + pTBlk->m_Cmd.m_nBufAlign)) == (PCHAR )NULL
)
{
return( FALSE ); // Failed
}
//
// Align The Buffer
//
pTBlk->m_pBuf = pTBlk->m_pBufBase;
if (pTBlk->m_Cmd.m_nBufAlign != 0)
pTBlk->m_pBuf += (
pTBlk->m_Cmd.m_nBufAlign
- ((int )pTBlk->m_pBuf % pTBlk->m_Cmd.m_nBufAlign
) + pTBlk->m_Cmd.m_nBufOffset) % pTBlk->m_Cmd.m_nBufAlign;
TTCP_LogMsg( " Buffer Size : %d; Alignment: %d/%d\n",
pTBlk->m_Cmd.m_nBufferSize,
pTBlk->m_Cmd.m_nBufAlign,
pTBlk->m_Cmd.m_nBufOffset
);
return( TRUE ); // Success
}
/////////////////////////////////////////////////////////////////////////////
//// Primary TTCP Functions
//
/////////////////////////////////////////////////////////////////////////////
//// TTCP_TransmitTCP
//
// Purpose
// TTCP TCP transmitter.
//
// Parameters
// pCmdBlk - Pointer to CMD_BLOCK that contains options and other
// configuration information to be used for the transmit
// test.
// pRemoteHostName - Pointer to null-terminated name of remote host.
// May be IP address or DNS-resolvable name.
//
// Return Value
// Returns zero(0) for normal return. Non-zero otherwise.
//
// Remarks
//
DWORD WINAPI TTCP_TransmitTCP( PCMD_BLOCK pCmdBlk, PCHAR pRemoteHostName )
{
PTEST_BLOCK pTBlk = NULL;
int optlen;
//
// Say Hello
//
TTCP_LogMsg( "TCP Transmit Test\n" );
//
// Allocate Test Instance Data
// ---------------------------
// Allocate a TEST_BLOCK for this specific instance. The TEST_BLOCK
// contains a copy of the calleer's CMD_BLOCK as well as additional
// members that are used to perform this test.
//
pTBlk = TTCP_AllocateTestBlock( pCmdBlk );
if( !pTBlk )
{
TTCP_ExitTestOnCRTError( NULL, "malloc" );
return( 1 );
}
//
// Setup Remote IP Addresses For Test
//
if( atoi( pRemoteHostName ) > 0 )
{
//
// Numeric
//
pTBlk->m_Cmd.m_RemoteAddr.sin_family = AF_INET;
pTBlk->m_Cmd.m_RemoteAddr.sin_addr.s_addr = inet_addr( pRemoteHostName );
}
else
{
struct hostent *addr;
unsigned long addr_tmp;
TTCP_LogMsg( " Remote Host : %s\n", pRemoteHostName );
if ((addr=gethostbyname( pRemoteHostName )) == NULL)
{
TTCP_ExitTestOnWSAError( pTBlk, "gethostbyname" );
}
pTBlk->m_Cmd.m_RemoteAddr.sin_family = addr->h_addrtype;
memcpy((char*)&addr_tmp, addr->h_addr, addr->h_length );
pTBlk->m_Cmd.m_RemoteAddr.sin_addr.s_addr = addr_tmp;
}
pTBlk->m_Cmd.m_RemoteAddr.sin_port = htons( pTBlk->m_Cmd.m_Port );
//
// Setup Local IP Addresses For Test
//
pTBlk->m_Cmd.m_LocalAddress.sin_family = AF_INET;
pTBlk->m_Cmd.m_LocalAddress.sin_port = 0; /* free choice */
TTCP_LogMsg( " Transmit : TCP -> %s:%d\n",
inet_ntoa( pTBlk->m_Cmd.m_RemoteAddr.sin_addr ),
pTBlk->m_Cmd.m_Port
);
//
// Allocate The Buffer Send/Receive Data
//
if( !TTCP_AllocateBuffer( pTBlk ) )
{
TTCP_ExitTestOnCRTError( pTBlk, "malloc" );
}
//
// Open Socket For Test
//
if( ( pTBlk->m_Socket_fd = socket( AF_INET, SOCK_STREAM, 0 ) )
== INVALID_SOCKET
)
{
TTCP_ExitTestOnWSAError( pTBlk, "socket" );
}
//
// Bind Socket With Local Address
//
if( bind(
pTBlk->m_Socket_fd,
(PSOCKADDR )&pTBlk->m_Cmd.m_LocalAddress,
sizeof(pTBlk->m_Cmd.m_LocalAddress)
) == SOCKET_ERROR
)
{
TTCP_ExitTestOnWSAError( pTBlk, "bind" );
}
if( pTBlk->m_Cmd.m_bUseSockOptBufSize )
{
if( setsockopt(
pTBlk->m_Socket_fd,
SOL_SOCKET,
SO_SNDBUF,
(char * )&pTBlk->m_Cmd.m_nSockOptBufSize,
sizeof pTBlk->m_Cmd.m_nSockOptBufSize
) == SOCKET_ERROR
)
{
TTCP_ExitTestOnWSAError( pTBlk, "setsockopt: SO_SNDBUF" );
}
TTCP_LogMsg( " SO_SNDBUF : %d\n", pTBlk->m_Cmd.m_nSockOptBufSize );
}
//
// Start TCP Connections
//
optlen = sizeof( pTBlk->m_Cmd.m_nSockOptNoDelay );
//
// We are the client if transmitting
//
if( pTBlk->m_Cmd.m_bSockOptDebug )
{
if( setsockopt(
pTBlk->m_Socket_fd,
SOL_SOCKET,
SO_DEBUG,
(PCHAR )&one, // Boolean
sizeof(one)
) == SOCKET_ERROR
)
{
TTCP_ExitTestOnWSAError( pTBlk, "setsockopt: SO_DEBUG" );
}
}
//
// Set TCP_NODELAY Send Option
//
if( pTBlk->m_Cmd.m_nSockOptNoDelay )
{
if( setsockopt(
pTBlk->m_Socket_fd,
IPPROTO_TCP,
TCP_NODELAY,
(PCHAR )&one, // Boolean
sizeof(one)
) == SOCKET_ERROR
)
{
int nError = WSAGetLastError();
TTCP_LogMsg( " Error: 0x%8.8X\n", nError );
TTCP_LogMsg("setsockopt: TCP_NODELAY option failed");
}
}
//
// Query And Display TCP_NODELAY Send Option
//
if( getsockopt(
pTBlk->m_Socket_fd,
IPPROTO_TCP,
TCP_NODELAY,
(PCHAR )&pTBlk->m_Cmd.m_nSockOptNoDelay,
&optlen
) != SOCKET_ERROR
)
{
if( pTBlk->m_Cmd.m_nSockOptNoDelay )
{
TTCP_LogMsg( " TCP_NODELAY : ENABLED (%d)\n",
pTBlk->m_Cmd.m_nSockOptNoDelay );
}
else
{
TTCP_LogMsg( " TCP_NODELAY : DISABLED (%d)\n",
pTBlk->m_Cmd.m_nSockOptNoDelay );
}
}
else
{
int nError = WSAGetLastError();
TTCP_LogMsg( " Error: 0x%8.8X\n", nError );
TTCP_LogMsg("getsockopt: TCP_NODELAY option failed\n");
}
//
// Connect To Remote Server
//
if(connect( pTBlk->m_Socket_fd, (PSOCKADDR )&pTBlk->m_Cmd.m_RemoteAddr,
sizeof(pTBlk->m_Cmd.m_RemoteAddr) ) == SOCKET_ERROR)
{
TTCP_ExitTestOnWSAError( pTBlk, "connect" );
}
TTCP_LogMsg( " Connect : Connected to %s:%d\n",
inet_ntoa( pTBlk->m_Cmd.m_RemoteAddr.sin_addr ), pTBlk->m_Cmd.m_Port );
TTCP_InitStatistics( pTBlk );
errno = 0;
if( pTBlk->m_Cmd.m_nOptWriteDelay )
{
TTCP_LogMsg( " Write Delay : %d milliseconds\n",
pTBlk->m_Cmd.m_nOptWriteDelay
);
}
if( pTBlk->m_Cmd.m_bSinkMode )
{
TTCP_FillPattern( pTBlk );
if( pTBlk->m_Cmd.m_bOptContinuous )
{
TTCP_LogMsg( " Send Mode : Sending Pattern CONTINUOUS\n" );
while( TTCP_Nwrite( pTBlk, pTBlk->m_Cmd.m_nBufferSize) == pTBlk->m_Cmd.m_nBufferSize
)
{
pTBlk->m_nbytes += pTBlk->m_Cmd.m_nBufferSize;
}
}
else
{
TTCP_LogMsg( " Send Mode : Send Pattern; Number of Buffers: %d\n",
pTBlk->m_Cmd.m_nNumBuffersToSend
);
while (pTBlk->m_Cmd.m_nNumBuffersToSend--
&& TTCP_Nwrite( pTBlk, pTBlk->m_Cmd.m_nBufferSize) == pTBlk->m_Cmd.m_nBufferSize)
{
pTBlk->m_nbytes += pTBlk->m_Cmd.m_nBufferSize;
}
}
}
else
{
register int cnt;
TTCP_LogMsg( " Send Mode : Read from STDIN\n" );
//
// Read From stdin And Write To Remote
//
while( ( cnt = read(0, pTBlk->m_pBuf,pTBlk->m_Cmd.m_nBufferSize ) ) > 0
&& TTCP_Nwrite( pTBlk, cnt) == cnt
)
{
pTBlk->m_nbytes += cnt;
}
}
if(errno)
TTCP_ExitTestOnCRTError( pTBlk, "IO" );
TTCP_LogStatistics( pTBlk );
TTCP_FreeTestBlock( pTBlk );
return( 0 );
}
/////////////////////////////////////////////////////////////////////////////
//// TTCP_TransmitUDP
//
// Purpose
// TTCP UDP transmitter.
//
// Parameters
// pCmdBlk - Pointer to CMD_BLOCK that contains options and other
// configuration information to be used for the transmit
// test.
// pRemoteHostName - Pointer to null-terminated name of remote host.
// May be IP address or DNS-resolvable name.
//
// Return Value
// Returns zero(0) for normal return. Non-zero otherwise.
//
// Remarks
//
DWORD WINAPI TTCP_TransmitUDP( PCMD_BLOCK pCmdBlk, PCHAR pRemoteHostName )
{
PTEST_BLOCK pTBlk = NULL;
//
// Say Hello
//
TTCP_LogMsg( "UDP Transmit Test\n" );
//
// Allocate Test Instance Data
// ---------------------------
// Allocate a TEST_BLOCK for this specific instance. The TEST_BLOCK
// contains a copy of the calleer's CMD_BLOCK as well as additional
// members that are used to perform this test.
//
pTBlk = TTCP_AllocateTestBlock( pCmdBlk );
if( !pTBlk )
{
TTCP_ExitTestOnCRTError( NULL, "malloc" );
return( 1 );
}
//
// Setup Remote IP Addresses For Test
//
if( atoi( pRemoteHostName ) > 0 )
{
//
// Numeric
//
pTBlk->m_Cmd.m_RemoteAddr.sin_family = AF_INET;
pTBlk->m_Cmd.m_RemoteAddr.sin_addr.s_addr = inet_addr( pRemoteHostName );
}
else
{
struct hostent *addr;
unsigned long addr_tmp;
TTCP_LogMsg( " Remote Host : %s\n", pRemoteHostName );
if ((addr=gethostbyname( pRemoteHostName )) == NULL)
{
TTCP_ExitTestOnWSAError( pTBlk, "gethostbyname" );
}
pTBlk->m_Cmd.m_RemoteAddr.sin_family = addr->h_addrtype;
memcpy((char*)&addr_tmp, addr->h_addr, addr->h_length );
pTBlk->m_Cmd.m_RemoteAddr.sin_addr.s_addr = addr_tmp;
}
pTBlk->m_Cmd.m_RemoteAddr.sin_port = htons( pTBlk->m_Cmd.m_Port );
//
// Setup Local IP Addresses For Test
//
pTBlk->m_Cmd.m_LocalAddress.sin_family = AF_INET;
pTBlk->m_Cmd.m_LocalAddress.sin_port = 0; /* free choice */
TTCP_LogMsg( " Transmit : UDP -> %s:%d\n",
inet_ntoa( pTBlk->m_Cmd.m_RemoteAddr.sin_addr ),
pTBlk->m_Cmd.m_Port );
//
// Setup Buffer Configuration
//
if( pTBlk->m_Cmd.m_nBufferSize <= UDP_GUARD_BUFFER_LENGTH )
{
pTBlk->m_Cmd.m_nBufferSize = UDP_GUARD_BUFFER_LENGTH + 1; // send more than the sentinel size
}
//
// Allocate The Buffer Send/Receive Data
//
if( !TTCP_AllocateBuffer( pTBlk ) )
{
TTCP_ExitTestOnCRTError( pTBlk, "malloc" );
}
//
// Open Socket For Test
//
if( (pTBlk->m_Socket_fd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == INVALID_SOCKET
)
{
TTCP_ExitTestOnWSAError( pTBlk, "socket" );
}
//
// Bind Socket With Local Address
//
if( bind(
pTBlk->m_Socket_fd,
(PSOCKADDR )&pTBlk->m_Cmd.m_LocalAddress,
sizeof(pTBlk->m_Cmd.m_LocalAddress)
) == SOCKET_ERROR
)
{
TTCP_ExitTestOnWSAError( pTBlk, "bind" );
}
if( pTBlk->m_Cmd.m_bUseSockOptBufSize )
{
if( setsockopt(
pTBlk->m_Socket_fd,
SOL_SOCKET,
SO_SNDBUF,
(char * )&pTBlk->m_Cmd.m_nSockOptBufSize,
sizeof pTBlk->m_Cmd.m_nSockOptBufSize
) == SOCKET_ERROR
)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -