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

Тема в разделе "MS Visual C++", создана пользователем Antonim, 3 июл 2012.

  1. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    Всем привет!​

    Я хочу реализовать некую программку, которая бы туннелировала трафик приложений, запущенных на машине, через 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
     
  2. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    :) можно закрывать
     
  3. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    а почему? - все вопросы решены?
     
  4. Antonim

    Antonim Member

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

Поделиться этой страницей