Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Не могу перевести сокет в режим promiscuous (https://forum.antichat.xyz/showthread.php?t=97717)

xismyname 24.12.2008 12:59

Не могу перевести сокет в режим promiscuous
 
Нужна помощь, не могу перевести сокет в режим promiscuous,функция ioctlsocket() возвращает -1,то же самое когда хочу настроит сокет на режим IP_HDRINL,функция setsockopt() возвращает -1.

Администраторские права есть,Windows Home Edition,SP3.

Буду благодарен за любую помощь.

xismyname 24.12.2008 14:01

С setsockopt() уже разобрался,остаеться только ioctlsocket().

criz 24.12.2008 17:18

Покажи фрагмент кода, где ты с ioctlsocket() работаешь.

xismyname 24.12.2008 17:28

Вот целый код :
Код:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mstcpip.h>
#include <conio.h>

typedef struct{
        unsigned int version        : 4;
        unsigned int h_len          : 4;
        unsigned int tos            : 8;
        unsigned int tot_len        : 16;
        unsigned int ID              : 16;
        unsigned int flags          : 3;
        unsigned int f_offset        : 13;
        unsigned int TTL        : 8;
        unsigned int protocol  : 8;
        unsigned int h_checksum : 16;
        unsigned int srcip      : 32;
        unsigned int dstip      : 32;
}IPHEADER;

int main(void)
{
        SOCKADDR_IN      addr;
        WSADATA          wsd;
        SOCKET          mSocket;
        HOSTENT          *host;
        IPHEADER        *ip;
        unsigned long    mode = 1;
        int              len;
        char            pcname[32];
        char            buf[sizeof(IPHEADER)];


        /* load windows socket interface */
        if(WSAStartup(MAKEWORD(2,2),&wsd) != 0)
        {
                puts("Could not load winsocket api");
                exit(1);
        }

        /* Get computer name */
        len = sizeof(pcname) - 1;
        GetComputerNameA(pcname,&len);
        len = 0;

        /* Get host IP address by name */
        host = gethostbyname(pcname);

        /* Set addr & buf to 0 */
        memset(&addr,0,sizeof(addr));
        memset(buf,0,sizeof(buf));

        /* init. local address & create raw socket */
        addr.sin_addr.s_addr    = ((struct in_addr*)host->h_addr_list[0])->s_addr;
        addr.sin_family        = AF_INET;
        addr.sin_port          = htons(0);
        mSocket                = socket(AF_INET,SOCK_RAW,IPPROTO_IP);

        if(mSocket == INVALID_SOCKET)
        {
                puts("Could not create a RAW socket");
                exit(1);
        }

        /* Bind socket with local address */
        if(bind(mSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR)) != -1)
        {
                /* Convert socket to SIO_RCVALL mode */
                if(ioctlsocket(mSocket,SIO_RCVALL,&mode) != 0)
                {
                        puts("Could not convert socket to SIO_RCVALL mode");
                }

                /*-----------------------------------------------*/
                int x = 1;
                while(!kbhit())
                {
                        len = recv(mSocket,buf,sizeof(buf),0);

                        /* Check received data */
                        if(len >= sizeof(IPHEADER))
                        {
                                ip = (IPHEADER*)buf;
                                printf("\n+--------- %d ------------+\n",x++);

                                printf("| DEST    : %s\n",inet_ntoa(*((struct in_addr*)&ip->dstip)));
                                printf("| SRC    : %s\n",inet_ntoa(*((struct in_addr*)&ip->srcip)));
                                printf("| VERSION : %d\n",ip->version);

                                printf("+------------------------+\n");

                        }
                }
        }
        else
        {
                puts("Could not bind");
        }
}

Походу он только у меня на компе не работает,у друга проверял - все работало.

criz 24.12.2008 17:38

хм...попробуй константу SIO_RCVALL самому определить:
Код:

#define SIO_RCVALL        0x98000001 // желательно с другим именем :)
и глянь что GetLastError() возвращает

xismyname 24.12.2008 17:44

Цитата:

Сообщение от criz
хм...попробуй константу SIO_RCVALL самому определить:
Код:

#define SIO_RCVALL        0x98000001 // желательно с другим именем :)
и глянь что GetLastError() возвращает

GetLastError() возвращает 10022 - был задан неправильный аргумент или что оно там.

Странно то что на другом компе работает и никакой ошибки не выдает.

Дело не в SIO_RCVALL,я посмотрел так как ты написал.

criz 24.12.2008 17:56

Вот, у меня этот вариант работает:
Код:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock.h>
#include <conio.h>

#define PROMISC        0x98000001
#define MAX    10000

#pragma comment(lib, "ws2_32.lib")

typedef struct{
        unsigned int version        : 4;
        unsigned int h_len          : 4;
        unsigned int tos            : 8;
        unsigned int tot_len        : 16;
        unsigned int ID              : 16;
        unsigned int flags          : 3;
        unsigned int f_offset        : 13;
        unsigned int TTL        : 8;
        unsigned int protocol  : 8;
        unsigned int h_checksum : 16;
        unsigned int srcip      : 32;
        unsigned int dstip      : 32;
}IPHEADER;

int main(void)
{
        SOCKADDR_IN      addr;
        WSADATA          wsd;
        SOCKET          mSocket;
        HOSTENT          *host;
        IPHEADER        *ip;
        unsigned long    mode = 1;
        int              len;
        char            pcname[32];
        char            buf[MAX];
        int x;


        /* load windows socket interface */
        if(WSAStartup(MAKEWORD(2,2),&wsd) != 0)
        {
                puts("Could not load winsocket api");
                exit(1);
        }

        /* Get computer name */
        len = sizeof(pcname) - 1;
        GetComputerNameA(pcname,&len);
        len = 0;

        /* Get host IP address by name */
        host = gethostbyname(pcname);

        /* Set addr & buf to 0 */
        memset(&addr,0,sizeof(addr));
        memset(buf,0,sizeof(buf));

        /* init. local address & create raw socket */
        addr.sin_addr.s_addr    = ((struct in_addr*)host->h_addr_list[0])->s_addr;
        addr.sin_family        = AF_INET;
        addr.sin_port          = htons(0);
        mSocket                = socket(AF_INET,SOCK_RAW,IPPROTO_IP);

        if(mSocket == INVALID_SOCKET)
        {
                puts("Could not create a RAW socket");
                exit(1);
        }

        /* Bind socket with local address */
        if(bind(mSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR)) != -1)
        {
                /* Convert socket to SIO_RCVALL mode */
                if(ioctlsocket(mSocket,PROMISC,&mode) != 0)
                {
                        puts("Could not convert socket to SIO_RCVALL mode");
                        printf("Error: %d\n", GetLastError());
                }

                /*-----------------------------------------------*/
                x = 1;
                while(!kbhit())
                {
                        len = recv(mSocket,buf,sizeof(buf),0);

                        /* Check received data */
                        if(len >= sizeof(IPHEADER))
                        {
                                ip = (IPHEADER*)buf;
                                printf("\n+--------- %d ------------+\n",x++);

                                printf("| DEST    : %s\n",inet_ntoa(*((struct in_addr*)&ip->dstip)));
                                printf("| SRC    : %s\n",inet_ntoa(*((struct in_addr*)&ip->srcip)));
                                printf("| VERSION : %d\n",ip->version);

                                printf("+------------------------+\n");

                        }
                }
        }
        else
        {
                puts("Could not bind");
        }
        return 0;
}

Выделил то, что добавил сам.
З.Ы. тестировал на Builder'е, пришлось некоторые либы выкинуть :)

xismyname 24.12.2008 18:08

Цитата:

Сообщение от criz
Вот, у меня этот вариант работает:
.........
Выделил то, что добавил сам.
З.Ы. тестировал на Builder'е, пришлось некоторые либы выкинуть :)

Неа,criz у меня даже этот вариант не работает,RAW сокеты в виндовс включен от версии винсока 2,поэтому header file тоже должен быть winsock2.h
Походу дело с SP3 или с виндовс.

criz 24.12.2008 18:14

ну, если я подключаю winsock2.h, то приходится отключать windows.h...
З.Ы. протестировал на VC++

cash$$$ 24.12.2008 20:18

Попробуй так

Код:

#include <conio.h>
#include <stdio.h>
#include <winsock2.h>

#define MAX_PACKET_SIZE    0x10000
#define SIO_RCVALL        0x98000001
// Буфер для приёма данных
char Buffer[MAX_PACKET_SIZE]; // 64 Kb

//Структура заголовка IP-пакета

typedef struct IPHeader {
  UCHAR  iph_verlen;  // версия и длина заголовка
  UCHAR  iph_tos;      // тип сервиса
  USHORT  iph_length;  // длина всего пакета
  USHORT  iph_id;      // Идентификация
  USHORT  iph_offset;  // флаги и смещения
  UCHAR  iph_ttl;      // время жизни пакета
  UCHAR  iph_protocol; // протокол
  USHORT  iph_xsum;    // контрольная сумма
  ULONG  iph_src;      // IP-адрес отправителя
  ULONG  iph_dest;    // IP-адрес назначения
} IPHeader;

char src[10];
char dest[10];
char ds[15];
unsigned short lowbyte;
unsigned short hibyte;

void main()
{
  WSADATA    wsadata;  // Инициализация WinSock.
  SOCKET      s;        // Cлущающий сокет.
  char        name[128]; // Имя хоста (компьютера).
  HOSTENT*    phe;      // Информация о хосте.
  SOCKADDR_IN sa;        // Адрес хоста
  IN_ADDR sa1;        //
  unsigned long        flag = 1;  // Флаг PROMISC Вкл/выкл.

  // инициализация
  WSAStartup(MAKEWORD(2,2), &wsadata);
  s = socket( AF_INET, SOCK_RAW, IPPROTO_IP );
  gethostname(name, sizeof(name));
  phe = gethostbyname( name );
  ZeroMemory( &sa, sizeof(sa) );
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = ((struct in_addr *)phe->h_addr_list[0])->s_addr;
  bind(s, (SOCKADDR *)&sa, sizeof(SOCKADDR));
 
  // Включение promiscuous mode.
  ioctlsocket(s, SIO_RCVALL, &flag);

  // Бесконечный приём IP-пакетов.
  while( !_kbhit() )
  {
    int count;
    count = recv( s, Buffer, sizeof(Buffer), 0 );
    // обработка IP-пакета
    if( count >= sizeof(IPHeader) )
    {
      IPHeader* hdr = (IPHeader *)Buffer;
      //Начинаем разбор пакета...

        strcpy(src,"Пакет: ");
        CharToOem(src,dest);
        printf(dest);
        // Преобразуем в понятный вид адрес отправителя.
        printf("From ");
        sa1.s_addr = hdr->iph_src;
        printf(inet_ntoa(sa1));

        // Преобразуем в понятный вид адрес.
        printf(" To ");
        sa1.s_addr = hdr->iph_dest;
        printf(inet_ntoa(sa1));

        // Протокол. Полный список этих констант
        // содержится в файле winsock2.h
        printf(" Prot: ");
        if(hdr->iph_protocol == IPPROTO_TCP) printf("TCP ");
        if(hdr->iph_protocol == IPPROTO_UDP) printf("UDP ");

        // Вычисляем размер. Так как в сети принят прямой порядок
        // байтов, а не обратный, то прийдётся поменять байты местами.
        printf("Size: ");
        lowbyte = hdr->iph_length>>8;
        hibyte = hdr->iph_length<<8;
        hibyte = hibyte + lowbyte;
        printf("%s",itoa(hibyte,"",10));

        // Вычисляем время жизни пакета.
        printf(" TTL:%s",itoa(hdr->iph_ttl,"",10));
        printf("\n");

    }
  }

  closesocket( s );
  WSACleanup();
}



Время: 23:39