Туннелирование

15.12.2010
15
0
#1
Всем привет!​

Я хочу реализовать некую программку, которая бы туннелировала трафик приложений, запущенных на машине, через SOCKS v4/v5...
Получая адрес и порт назначения(куда, кто из приложений желает попасть) из функций GetExtendedTcpTable и GetExtendedUdpTable, желаю перенаправить все запросы приложений/ия через прокси, а точнее через цепь прокси серверов.
Позаимствовав небольшой пример подобного соксирования, из журнала Хакер ( bY Николай (G)) , начал реализацию и столкнулся с проблемой коннекта ко второй и последующим соксЯм.
Для начала приведу часть кода(сам туннель):
C++:
///////////////////структуры и константы
#define CONNECT_ERROR 1
#define REQUEST_ERROR 2
#define SOCKS_*цензура* 0xFF

typedef struct _server {
DWORD ip;
u_short port;
}	server;

typedef struct _req {
BYTE ver;
BYTE cmd; 
BYTE rsv;
BYTE type;
DWORD addr;
u_short port;
} req;

//////////////////////////////////////////////////

int connectbysocks(server *socks, int socksnum, SOCKET s, server dest)
{
SOCKADDR_IN addr;
int nrecv = 0;
char* request = "\x05\x01\x00"; //запрос к проксе
BYTE request_ans[3]; //ответ прокси
req temp;

addr.sin_addr.S_un.S_addr = socks[0].ip;
addr.sin_port = socks[0].port;
addr.sin_family = AF_INET;

if(connect(s, (struct sockaddr *)&addr,sizeof(SOCKADDR_IN))) // к первой прокси
{	
return CONNECT_ERROR;
}

for (int i = 1; i <= socksnum; i++) // запросы на 2,3... прокси
{

send(s,(char*)request,3,0);
nrecv = recv(s,(char*)request_ans,3,0);

if (nrecv == SOCKET_ERROR)	
{
return REQUEST_ERROR; //ошибка сокета
}

if (request_ans[1]==0xFF)		
{
return SOCKS_ERROR; //сервер не ответил или нельзя подключиться
}

if (request_ans[0]!=0x05)		
{
return REQUEST_ERROR; // сокси не 5й версии
}

temp.ver = 0x05; //новый запрос - версия и т.д.
temp.cmd = 0x01; 
temp.rsv = 0x00;
temp.type = 0x01;

if (i == socksnum) //если дошли до конца то теперь коннект к адресу назначения
{
temp.addr = dest.ip;
temp.port = dest.port;
}
else //иначе след. прокси
{
temp.addr = socks[i].ip;
temp.port = socks[i].port;
}
//		printf("Iteration - %d\nsocksaddr - %s\nsockport - %d",i,gi_ntoa(temp.addr),temp.port);
if (!temp.addr) //проблемы с адресом прокси... пропускать
{
continue;
}

send(s,(char*)&temp,sizeof(temp),0);				//отправка нового запроса на след прокси
nrecv = recv(s, (char*)&temp,sizeof(temp),0);

if (nrecv == SOCKET_ERROR)		// аналогичные проверки
{
return REQUEST_ERROR;
}
if (temp.rsv != 0)		
{
return REQUEST_ERROR;
}
if( temp.cmd != 0) 
{
return SOCKS_ERROR;
}
}

return 0;
}
в main():
C++:
#define SOCKSNUM 3 //пусть проксей будет 3

int main(int argc, char *argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);

server socks[SOCKSNUM];
server dest;

socks[0].ip = resolve("85.169.47.254");
socks[0].port = htons(28777);
socks[1].ip = resolve("86.101.58.87");
socks[1].port = htons(45957);
socks[2].ip = resolve("94.213.100.187");
socks[2].port = htons(55247);

dest.ip = resolve("ya.ru");
dest.port = htons(80);

SOCKET s = socket (AF_INET,SOCK_STREAM,0);

if (connectbysocks((server*)&socks[0], SOCKSNUM, s, dest))
{
return 0;
}

/// тут блок не по теме


closesocket(s);
WSACleanup();

/*	if(_CrtDumpMemoryLeaks())
gprintf(FOREGROUND_RED|FOREGROUND_INTENSITY,
" !!!Îáíàðóæåíû óòå÷êè ïàìÿòè!!! \n");
*/	return 0;
}
...Мне кажется проблема в том что структуру SOCKADDR_IN надо тоже менять на айпи 2ой и следующих прокси, или нет(не получится ли в таком случае просто коннект от моей машины проксе №2 и т.д., а не по цепи)??
P.S.: Скорее всего вопрос избит донЕльзя, но кому не лень посоветуйте как правильнее реализовать такую задачу.

добавил окно с логом...
fail.jpg
 

Вложения

15.12.2010
15
0
#4
а почему? - все вопросы решены?
Почему? - Потому что, теме сто лет в обед, а коммент был один... и тот мой.
Все ли вопросы решены? - Нет, не все. Данный пример уже переработан, и доведён до адекватного состояния.
Пишу TDI фильтр, под семёрку.