📄 htelnet.c
字号:
//------------------------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <assert.h>
#include "httport.h"
//------------------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
HMODULE h_httport_dll;
H_Start *h_start;
H_Stop *h_stop;
H_SetOption *h_setoption;
H_CreateMapping *h_createmapping;
H_GetListeningPort *h_getlisteningport;
H_GetMappingStats *h_getmappingstats;
H_GetProxyStats *h_getproxystats;
H_DestroyMapping *h_destroymapping;
TMappingParameters mapping_params;
TMappingStats mapping_stats;
TProxyStats proxy_stats;
char *set_option_params[3];
char buf[128];
long mapping_id;
long saved_connection_mode, connection_mode;
long saved_data_override, data_override;
long local_port;
STARTUPINFO si;
PROCESS_INFORMATION pi;
int retrying_with_override = 0;
//------------------------------------------------------------------------------------------
if (argc != 9)
{
fprintf(stderr, "test.exe proxy_address proxy_port proxy_username proxy_password htthost_address htthost_port remote_server_address remote_server_port");
return 0;
};
// Load library and fetch entry points
// Static linking is another way of doing this
h_httport_dll = LoadLibrary("httport.dll");
h_start = (H_Start *)GetProcAddress(h_httport_dll, "H_Start");
h_stop = (H_Stop *)GetProcAddress(h_httport_dll, "H_Stop");
h_setoption = (H_SetOption *)GetProcAddress(h_httport_dll, "H_SetOption");
h_createmapping = (H_CreateMapping *)GetProcAddress(h_httport_dll, "H_CreateMapping");
h_getlisteningport = (H_GetListeningPort *)GetProcAddress(h_httport_dll, "H_GetListeningPort");
h_getproxystats = (H_GetProxyStats *)GetProcAddress(h_httport_dll, "H_GetProxyStats");
h_getmappingstats = (H_GetMappingStats *)GetProcAddress(h_httport_dll, "H_GetMappingStats");
h_destroymapping = (H_DestroyMapping *)GetProcAddress(h_httport_dll, "H_DestroyMapping");
//------------------------------------------------------------------------------------------
// set global options (the order of options may be different):
//-----------
// 1. load saved proxy config, which includes connection mode and data override parameters
// the following is just a sample (and a reasonable default by the way)
saved_connection_mode = CONN_USE_AUTO; // in real app these should
saved_data_override = 0; // be restored from some storage, like ini file or registry etc.
connection_mode = saved_connection_mode;
data_override = saved_data_override;
retry_with_override:
//-----------
// 2. set data override option
sprintf(buf, "%d", data_override);
set_option_params[0] = buf;
assert(h_setoption(H_OPTION_DATA_OVERRIDE, 1, set_option_params) == H_SUCCESS);
//-----------
// 3. set HTTP proxy address
set_option_params[0] = argv[1]; // proxy host address or IP address
set_option_params[1] = argv[2]; // proxy port, may not be zero
assert(h_setoption(H_OPTION_PROXY, 2, set_option_params) == H_SUCCESS);
//-----------
// 4. set user information as shown to proxy
set_option_params[0] = argv[3]; // proxy username (may be empty, i.e. '\0')
set_option_params[1] = argv[4]; // proxy password (may be empty, i.e. '\0')
set_option_params[2] = "httport/dll"; // user-agent line (may be empty, i.e. '\0')
assert(h_setoption(H_OPTION_USER_INFO, 3, set_option_params) == H_SUCCESS);
//-----------
// 5. set HTTHosts list, must not be empty
sprintf(buf, "%s:%s", argv[5], argv[6]); // line like 'host:port'
set_option_params[0] = buf; // the hosts may be different for sure
set_option_params[1] = buf; // just an example a list of three hosts
set_option_params[2] = buf;
assert(h_setoption(H_OPTION_HOST_LIST, 3, set_option_params) == H_SUCCESS);
//-----------
// after all options have been set, start
assert(h_start() == H_SUCCESS);
//------------------------------------------------------------------------------------------
// now create the mapping
mapping_params.intStrucSize = sizeof(mapping_params);
mapping_params.intAllowLocalOnly = 1;
mapping_params.intMode = saved_connection_mode;
mapping_params.ptrRemoteHost = argv[7];
mapping_params.wRemotePort = (unsigned short)atol(argv[8]);
// important: setting local port to 0 makes the DLL use any
// local port available for listening. You may override it,
// setting wLocalPort to any other value 1..65535
local_port = 0;
mapping_params.wLocalPort = (unsigned short)local_port;
assert(h_createmapping(&mapping_params) == H_SUCCESS);
// store the returned id
mapping_id = mapping_params.intMappingId;
// we don't know the port number yet, wait until it's known
// it's not taking long, as soon as it's a single bind() actually
while (local_port == 0)
{
assert(h_getlisteningport(mapping_id, &local_port) == H_SUCCESS);
if (local_port == 0) Sleep(100);
};
fprintf(stderr, "Mapping local port %d to %s:%s", local_port, argv[7], argv[8]);
// initialization done
//------------------------------------------------------------------------------------------
// launch telnet and wait until it's closed
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
si.cb = sizeof(si);
sprintf(buf, "telnet.exe 127.0.0.1 %d", local_port);
if (CreateProcess(NULL, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
while (WaitForSingleObject(pi.hProcess, 0)) Sleep(100);
}
else fprintf(stderr, "Can't launch telnet.exe: CreateProcess() failed with error %d", GetLastError());
//------------------------------------------------------------------------------------------
// fetch proxy stats, this must be done while mapping(s) exist
proxy_stats.intStrucSize = sizeof(proxy_stats);
assert(h_getproxystats(&proxy_stats) == H_SUCCESS);
connection_mode = proxy_stats.intCurrentMode;
data_override = proxy_stats.intDataOverride;
// in case proxy requires
// data_override and we did not know that before,
// silently retry
if ((proxy_stats.intDataOverride != 0) && (retrying_with_override == 0))
{
retrying_with_override = 1;
assert(h_destroymapping(mapping_id) == H_SUCCESS); // stop the library and go try again
assert(h_stop() == H_SUCCESS);
fprintf(stderr, "Proxy appears to be not fully HTTP compatible. Retrying connection with different library settings.\n");
goto retry_with_override;
};
// the following statistics only makes sense if the mode is "Remote Host"
if (proxy_stats.intCurrentMode == CONN_USE_REMOTE)
{
fprintf(stderr, "%d proxy faults, %d HTTHost faults\n",
proxy_stats.intProxyFaults, proxy_stats.intHostFaults);
};
// fetch mapping statistics
mapping_stats.intStrucSize = sizeof(mapping_stats);
assert(h_getmappingstats(mapping_id, &mapping_stats) == H_SUCCESS);
fprintf(stderr, "\n\n%d connections, %d K transferred, %d fatal network errors, "
"%d Winsock errors, %d CONNECT errors, %d HTTHost errors, "
"%d memory allocation errors, %d other errors, %d protocol errors, "
"%d timeout errors\n",
mapping_stats.intConnections,
mapping_stats.intKBytesTransferred,
mapping_stats.intFatalErrors,
mapping_stats.intSockErrors,
mapping_stats.intConnectErrors,
mapping_stats.intHostErrors,
mapping_stats.intMemoryErrors,
mapping_stats.intOtherErrors,
mapping_stats.intProtocolErrors,
mapping_stats.intTimeoutErrors
);
//------------------------------------------------------------------------------------------
// begin cleanup
// the application is shutting down, save the actual proxy configuration
saved_connection_mode = connection_mode;
saved_data_override = data_override;
//------------------------------------------------------------------------------------------
// destroy the created mappings
assert(h_destroymapping(mapping_id) == H_SUCCESS);
//------------------------------------------------------------------------------------------
// stopping will release all the mappings anyway
assert(h_stop() == H_SUCCESS);
//------------------------------------------------------------------------------------------
// dispose library
FreeLibrary(h_httport_dll);
return 0;
}
//------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -