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

📄 ttcpproxy.cpp

📁 Complete PCAUSA samples including various kernel mode TDI code, TDI filters/redirectors and NDIS fil
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                     htons( pTBlk->m_Cmd.m_RemoteAddr.sin_port ) );

                  bIsFirst = FALSE;
               }

               pTBlk->m_nbytes += cnt;
            }
         }
      }
      else
      {
         register int cnt;

         //
         // Read From Remote And Write To stdout
         //
         while( ( cnt = TTCP_Nread( pTBlk, pTBlk->m_Cmd.m_nBufferSize ) ) > 0
            && write(1, pTBlk->m_pBuf,cnt) == cnt
            )
         {
            pTBlk->m_nbytes += cnt;
         }
      }

       if(errno)
         TTCP_ExitTestOnCRTError( pTBlk, "IO" );

      if( pTBlk->m_nbytes > 0 )
      {
         TTCP_LogStatistics( pTBlk );
      }

      if( !pTBlk->m_Cmd.m_bOptContinuous )
      {
         bContinue = FALSE;
      }
   }

   TTCP_FreeTestBlock( pTBlk );

   return( 0 );
}

//
// Usage Message
//
char Usage[] = "\
Usage: pcattcp -t [-options] host [ < in ]\n\
       pcattcp -r [-options > out]\n\
Common options:\n\
   -l ##  length of bufs read from or written to network (default 8192)\n\
   -u     use UDP instead of TCP\n\
   -p ##  port number to send to or listen at (default 5001)\n\
   -s     toggle sinkmode (enabled by default)\n\
            sinkmode enabled:\n\
               -t: source (transmit) fabricated pattern\n\
               -r: sink (discard) all received data\n\
            sinkmode disabled:\n\
               -t: reads data to be transmitted from stdin\n\
               -r: writes received data to stdout\n\
   -A     align the start of buffers to this modulus (default 16384)\n\
   -O     start buffers at this offset from the modulus (default 0)\n\
   -v     verbose: print more statistics\n\
   -d     set SO_DEBUG socket option\n\
   -b ##  set socket buffer size (if supported)\n\
   -f X   format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga\n\
   -c       -t: send continuously\n\
            -r: accept multiple connections sequentially\n\
   -R     concurrent TCP/UDP multithreaded receiver\n\
Options specific to -t:\n\
   -n ##  number of source bufs written to network (default 2048)\n\
   -D     don't buffer TCP writes (sets TCP_NODELAY socket option)\n\
   -w ##  milliseconds of delay before each write (default 0)\n\
Options specific to -r:\n\
   -B     for -s, only output full blocks as specified by -l (for TAR)\n\
   -T     \"touch\": access each byte as it's read\n\
";


/////////////////////////////////////////////////////////////////////////////
//// TTCP_ParseCommandLine
//
// Purpose
// Parse the console application command-line arguments and setup the
// CMD_BLOCK/
//
// Parameters
//   pCmdBlk - Pointer to CMD_BLOCK to be filled with parsed option
//             information.
//
// Return Value
// Returns zero(0) for normal return. Non-zero otherwise.
//
// Remarks
//

int TTCP_ParseCommandLine( PCMD_BLOCK pCmdBlk, int argc, char **argv )
{
   int   c;

    if (argc < 2)
   {
      fprintf( stderr, Usage );
      return( !0 );
   }

   while (optind != argc)
   {
       c = getopt(argc, argv, "cdrstuvBDRTb:f:l:n:p:A:O:w:" );

        switch (c)
      {
         case EOF:
            optarg = argv[optind];
            optind++;
            break;

         case 'B':
            b_flag = 1;
            break;

         case 't':
            pCmdBlk->m_bTransmit = TRUE;
            break;

         case 'r':
            pCmdBlk->m_bTransmit = FALSE;
            break;

         case 'c':
            pCmdBlk->m_bOptContinuous = TRUE;
            break;

         case 'd':
            pCmdBlk->m_bSockOptDebug = 1;
            break;

         case 'D':
            pCmdBlk->m_nSockOptNoDelay = 1;
            break;

         case 'R':
            pCmdBlk->m_bOptContinuous = TRUE;
            pCmdBlk->m_bTransmit = FALSE;
            pCmdBlk->m_bOptMultiReceiver = TRUE;
            break;

         case 'n':
            pCmdBlk->m_nNumBuffersToSend = atoi(optarg);
            break;

         case 'l':
            pCmdBlk->m_nBufferSize = atoi(optarg);
            break;

         case 's':
            pCmdBlk->m_bSinkMode = !pCmdBlk->m_bSinkMode;
            break;

         case 'p':
            pCmdBlk->m_Port = atoi(optarg);
            break;

         case 'u':
            pCmdBlk->m_Protocol = IPPROTO_UDP;
            break;

         case 'v':
            verbose = 1;
            break;

         case 'A':
            pCmdBlk->m_nBufAlign = atoi(optarg);
            break;

         case 'O':
            pCmdBlk->m_nBufOffset = atoi(optarg);
            break;

         case 'b':
            pCmdBlk->m_bUseSockOptBufSize = TRUE;
            pCmdBlk->m_nSockOptBufSize = atoi(optarg);
            if( pCmdBlk->m_nSockOptBufSize < 0 )
            {
               pCmdBlk->m_nSockOptBufSize = 0;
            }
            break;

         case 'f':
            fmt = *optarg;
            break;

         case 'T':
            pCmdBlk->m_bTouchRecvData = 1;
            break;

         case 'w':
            pCmdBlk->m_nOptWriteDelay = atoi(optarg);
            break;

           default:
            fprintf( stderr, Usage );
            return( !0 );
      }
   }

   return( 0 );
}


/////////////////////////////////////////////////////////////////////////////
//// MAIN Program Entry Point
//

int _tmain(int argc, _TCHAR* argv[])
{
    CMD_BLOCK cmdBlock;

    //
    // Say Hello
    //
    TTCP_LogMsg( "PCAUSA TTCP Proxy V%s\n", PCATTCP_VERSION );

    //
    // Fetch Command/Options For This Test
    //
    TTCP_SetConfigDefaults( &cmdBlock );

    if( TTCP_ParseCommandLine( &cmdBlock, argc, argv ) != 0 )
    {
        return( 0 );
    }

    if (!TcpRedirector_Startup())
    {
        printf( "%s Driver Not Loaded\n", TDIREDIR_BASE_NAME );
        return 0;
    }
    else
        printf( "%s Driver Loaded\n", TDIREDIR_BASE_NAME );

    //
    // Start Winsock 2
    //
    if( WSAStartup( MAKEWORD(0x02,0x00), &g_WsaData ) == SOCKET_ERROR )
    {
        fprintf( stderr, Usage );
        TTCP_ExitTestOnWSAError( NULL, "WSAStartup" );
    }

    PTCP_REDIR_RULE_BUFFER pRuleBuffer = NULL;

    // Allocate the Redirection Rule Buffer
    pRuleBuffer = TcpRedirector_AllocateRuleBuffer();

    if( pRuleBuffer == NULL )
    {
        printf( "Redirection Rule Buffer Allocation Failed\n" );

        // Cleanup
        TcpRedirector_Shutdown();
        WSACleanup();

        return 0;
    }

    // 192.168.1.20 - 192.168.1.100:5001 -> 127.0.0.1:5002
    //    Redirect Any Process Except "TTCPPROXY.EXE"
    pRuleBuffer = TcpRedirector_AddPortRule(
        pRuleBuffer,
        inet_addr( "192.168.1.20" ),    // RemoteAddressRangeStart
        inet_addr( "192.168.1.100" ),   // RemoteAddressRangeEnd
        inet_addr( "255.255.255.0" ),   // RemoteNetMask
        IPPORT_TTCP,                    // RemotePort
        NULL,
        "ttcpproxy.exe",
        (HANDLE )GetCurrentProcessId(),
        inet_addr( "127.0.0.1" ),       // RedirectToAddress
        IPPORT_TTCP_PROXY               // RedirectToPort
        );

    // Crude Rule Dumper for Debug...
    DumpRuleBuffer( pRuleBuffer );

    // Pass Redirection Rules to Driver
    TcpRedirector_SetRedirectRules( pRuleBuffer, pRuleBuffer->TotalBufferSize );

    //
    // Set The Ctrl-C Handler
    //
    SetConsoleCtrlHandler( CtrlHandler, TRUE );

    if( cmdBlock.m_bOptMultiReceiver )
    {
        TTCP_LogMsg( "  Threading   : Multithreaded\n" );
    }

    //
    // Dispatch To Specialized Procedues
    //
    if( cmdBlock.m_bTransmit )
    {
        DWORD nResult;

        if( cmdBlock.m_Protocol == IPPROTO_UDP )
        {
            nResult = TTCP_TransmitUDP( &cmdBlock, argv[argc - 1] );
        }
        else
        {
            nResult = TTCP_TransmitTCP( &cmdBlock, argv[argc - 1] );
        }
    }
    else
    {
        DWORD nResult;

        if( cmdBlock.m_bOptMultiReceiver )
        {
            if( cmdBlock.m_Protocol == IPPROTO_UDP )
            {
                nResult = TTCP_ReceiveUDP( &cmdBlock );
            }
            else
            {
                HANDLE   RxThreadHandles[ 2 ];   // Thread Handles
                DWORD    tid[2];                 // Thread IDs

                //
                // Run TCP Connection Listener In New Thread
                //
                cmdBlock.m_Protocol = IPPROTO_TCP;
                RxThreadHandles[0] = CreateThread(
                    NULL,
                    0,
                    (LPTHREAD_START_ROUTINE )TTCP_ListenTCP,
                    &cmdBlock,
                    0,
                    &tid[0]
                    );

                    //cmdBlock.m_Protocol = IPPROTO_UDP;
                    //nResult = TTCP_ReceiveUDP( &cmdBlock );
            }
        }
        else
        {
            if( cmdBlock.m_Protocol == IPPROTO_UDP )
            {
                nResult = TTCP_ReceiveUDP( &cmdBlock );
            }
            else
            {
                nResult = TTCP_ListenTCP( &cmdBlock );
            }
        }
    }

    // Cleanup
    TcpRedirector_ClearRedirectRules();
    TcpRedirector_Shutdown();
    WSACleanup();

    return( 0 );
}

/*
 *          N R E A D
 */
int TTCP_Nread( PTEST_BLOCK pTBlk, int count )
{
    SOCKADDR_IN from;
    int len = sizeof(from);
    register int cnt;

    if( pTBlk->m_Cmd.m_Protocol == IPPROTO_UDP )
    {
        cnt = recvfrom( pTBlk->m_Socket_fd,
            pTBlk->m_pBuf, count, 0,
            (PSOCKADDR )&from,
            &len
            );

        pTBlk->m_Cmd.m_RemoteAddr.sin_addr.s_addr = from.sin_addr.s_addr;
        pTBlk->m_Cmd.m_RemoteAddr.sin_port = from.sin_port;

        pTBlk->m_numCalls++;
    }
    else
    {
        if( b_flag )
        {
            cnt = TTCP_mread( pTBlk, count );  /* fill buf */
        }
        else
        {
            cnt = recv( pTBlk->m_Socket_fd, pTBlk->m_pBuf, count, 0 );

            if( cnt == SOCKET_ERROR )
            {
                int nError = WSAGetLastError();
            }

            pTBlk->m_numCalls++;
        }
    }

    if( pTBlk->m_Cmd.m_bTouchRecvData && cnt > 0 )
    {
        register int c = cnt, sum;
        register char *b = pTBlk->m_pBuf;
        sum = 0;
        while (c--)
            sum += *b++;
    }

    return(cnt);
}


/*
 *          N W R I T E
 */
int TTCP_Nwrite( PTEST_BLOCK pTBlk, int count )
{
    register int cnt;

    //
    // Introduce Write Delay After First Write Call
    //
    if( pTBlk->m_Cmd.m_nOptWriteDelay && pTBlk->m_numCalls > 0 )
    {
        Sleep( pTBlk->m_Cmd.m_nOptWriteDelay );
    }

    if( pTBlk->m_Cmd.m_Protocol == IPPROTO_UDP )
    {
again:
        cnt = sendto( pTBlk->m_Socket_fd, pTBlk->m_pBuf, count, 0,
            (PSOCKADDR )&pTBlk->m_Cmd.m_RemoteAddr,
            sizeof(pTBlk->m_Cmd.m_RemoteAddr)
            );

        pTBlk->m_numCalls++;

        if( cnt == SOCKET_ERROR && WSAGetLastError() == WSAENOBUFS )
        {
            delay(18000);
            errno = 0;
            goto again;
        }
    }
    else
    {
        cnt = send( pTBlk->m_Socket_fd, pTBlk->m_pBuf, count, 0 );
        pTBlk->m_numCalls++;
    }

    return(cnt);
}

void delay( int us )
{
    struct timeval tv;

    tv.tv_sec = 0;
    tv.tv_usec = us;
    select( 1, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
}

/*
*          M R E A D
*
* This function performs the function of a read(II) but will
* call read(II) multiple times in order to get the requested
* number of characters.  This can be necessary because
* network connections don't deliver data with the same
* grouping as it is written with.  Written by Robert S. Miles, BRL.
*/
int TTCP_mread( PTEST_BLOCK pTBlk, unsigned n)
{
    char *bufp = pTBlk->m_pBuf;
    register unsigned    count = 0;
    register int     nread;

    do
    {
        nread = recv( pTBlk->m_Socket_fd, bufp, n-count, 0);

        pTBlk->m_numCalls++;

        if(nread < 0)  {
            perror("ttcp_mread");
            return(-1);
        }

        if(nread == 0)
            return((int)count);

        count += (unsigned)nread;

        bufp += nread;
    }
    while(count < n);

    return((int)count);
}

#define END(x)  {while(*x) x++;}

char *outfmt( double b )
{
    static char obuf[50];

    switch (fmt) {
    case 'G':
        sprintf(obuf, "%.2f GB", b / 1024.0 / 1024.0 / 1024.0);
        break;
    default:
    case 'K':
        sprintf(obuf, "%.2f KB", b / 1024.0);
        break;
    case 'M':
        sprintf(obuf, "%.2f MB", b / 1024.0 / 1024.0);
        break;
    case 'g':
        sprintf(obuf, "%.2f Gbit", b * 8.0 / 1024.0 / 1024.0 / 1024.0);
        break;
    case 'k':
        sprintf(obuf, "%.2f Kbit", b * 8.0 / 1024.0);
        break;
    case 'm':
        sprintf(obuf, "%.2f Mbit", b * 8.0 / 1024.0 / 1024.0);
        break;
    }

    return obuf;
}



⌨️ 快捷键说明

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