winpcap, отправка пакетов
От: Аноним  
Дата: 09.06.13 08:39
Оценка:
Всем доброго времени суток.
Шлю udp пакеты используя winsock, с помощью winpcap перехватываю их. Как только пакет будет захвачен, перестаю посылать пакеты используя winsock, а пытаюсь через winpcap, собственно посылка через winpcap и не удается. Точнее снифер wireshark (написан на winpcap) их все же видит, но другой снифер их не ловит и на целевую машину они не доходят.

Пакеты шлются на тот же интерфейс где и были "пойманы"
Пробовал отсылать чистые копии, с измененной контрольной суммой в ноль, даже изменял ip идентификатор, не помогает...

прикладываю код, он основан на рабочих примерах с офф сайта и при простой посылке (даже идентичных) udp пакетов работает, но с добавление прослушки перестает работать.


#include <winsock2.h>
#include <process.h>

#define HAVE_REMOTE
#include <pcap.h>
#include "raw.h"
#include "adapter.h"

class FAKEPACKET;
void ifprint(pcap_if_t *d);

int DevCount = 0; //network devices count
int DevSelected = 0; //number of selected network device
pcap_t *SnifDev; //interface for packet snif
char ErrBuf[PCAP_ERRBUF_SIZE];
pcap_if_t *Interface; //Selected interface
pcap_if_t *Alldevs; //all interface
bool TestPacketFlag = true;
int Error;
FAKEPACKET *PacketDump = NULL;

class FAKEPACKET
{
public:
    u_char *Data;
    int Size;

    FAKEPACKET()
    {
        Data = NULL;
        Size = 0;
    }
    ~FAKEPACKET()
    {
        if (Data != NULL)
        {
            delete[] Data;
            Data = NULL;
        }
    }
};

void Thread_recv_c( void* pParams)
{
    int res;
    struct pcap_pkthdr *header;
    const u_char *pkt_data;

    if ((SnifDev= pcap_open_live(Interface->name, // name of the device
        65536,     // portion of the packet to capture.
        // 65536 grants that the whole packet will be captured on all the MACs.
        1,         // promiscuous mode
        1000,      // read timeout
        ErrBuf     // error buffer
        ) ) == NULL)
    {
        fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n");
        /* Free the device list */
        pcap_freealldevs(Alldevs);
    }
    else
    {
        printf("\nlistening on %s...\n", Interface->description);
        /* Retrieve the packets */
        while((res = pcap_next_ex(SnifDev, &header, &pkt_data)) >= 0){

            if(res == 0)
                /* Timeout elapsed */
                continue;
            int T = header->len;
            if (pkt_data[T-4]=='x' &&
                pkt_data[T-3]=='x' &&
                pkt_data[T-2]=='x' &&
                pkt_data[T-1]=='x')
            {

                PacketDump = new FAKEPACKET;
                PacketDump->Data = new u_char[T];
                PacketDump->Size = T;
                for(int i=0;i<T;i++)
                {
                    PacketDump->Data[i] = pkt_data[i];
                }
                TestPacketFlag = false;
                break;
            }
        }

        if(res == -1){
            printf("Error reading the packets: %s\n", pcap_geterr(SnifDev));
            system("PAUSE");
        }
    }
}

bool SendTestPacket(const char *Ip, USHORT dstport, USHORT srcport)
{
    SOCKET Socket;
    sockaddr_in Targer;
    sockaddr_in Local;

    Local.sin_addr.s_addr = htonl(INADDR_ANY);
    Local.sin_family = AF_INET;
    Local.sin_port = htons(srcport);

    Targer.sin_family = AF_INET;
    Targer.sin_port = htons(dstport);
    Targer.sin_addr.s_addr = inet_addr(Ip);

    Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (Socket == INVALID_SOCKET)
    {
        printf("Can`t create socket!\n");
        return false;
    }
    if (bind(Socket, (struct sockaddr *)&Local, sizeof(Local)) == SOCKET_ERROR)
    {
        printf("Can`t bind socket Socket!\n");
        closesocket (Socket);
        return false;
    }

    sendto(Socket, "xxxx", 4, 0, (struct sockaddr *)&Targer, sizeof(Targer));

    closesocket (Socket);
    return true;
}

int main(int argc, char *argv[])
{
    pcap_t *fp;
    char errbuf[PCAP_ERRBUF_SIZE+1];

    loadiphlpapi();

    //--- вывод всех сетевых интерфейсов ---
    if (pcap_findalldevs_ex("rpcap://", NULL, &Alldevs, errbuf) == -1)
    {
        fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
        exit(1);
    }
      for(Interface = Alldevs ; Interface != NULL ; Interface = Interface->next)    //Print the devices
    {
        DevCount++;
        printf("%d)\n",DevCount);
        ifprint(Interface);
    }
    if (DevCount==0)
    {
        printf("ERROR. Interfaces not found!");
        return 0;
    }

    //--- выбор сетевого интерфейса ---
    printf("Enter the device number you want to use : ");
    scanf("%d",&DevSelected);
    if ((DevSelected < 1) || (DevSelected > DevCount))
    {
        printf("ERROR. Invalid device number.\n");
        return 0;
    }
    Interface = Alldevs;
    for(int i=1; i<DevSelected;i++) Interface = Interface->next; //select needed interface

    //запускаю снифер в новом потоке
    _beginthread( Thread_recv_c, 0, NULL);

    //шлю пакеты (используя winsock) на целевую машину
    while (TestPacketFlag)
    {
        Sleep(100);
        if (!SendTestPacket("1.2.3.4",30000,40000))
        {
            printf("ERROR. Can`t send \"TestPacket\".\n");
        }
    }


    pcap_close(SnifDev);
    if ( (fp = pcap_open(Interface->name,        // name of the device
                        100,                        // portion of the packet to capture (only the first 100 bytes)
                        PCAP_OPENFLAG_PROMISCUOUS,  // promiscuous mode
                        1000,                        // read timeout
                        NULL,                        // authentication on the remote machine
                        errbuf                        // error buffer
                        ) ) == NULL)
    {
        fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", Interface->name);
        return 1;
    }
    pcap_freealldevs(Alldevs);
    //отправка пакетов
    while (1)
    {
        pcap_sendpacket(fp , PacketDump->Data , PacketDump->Size);
        Sleep(1000);
    }

    delete PacketDump;
    system("PAUSE");
    return EXIT_SUCCESS;
}


/*
    Print all the available information about a winpcap device like lo , eth0
*/
void ifprint(pcap_if_t *d)
{
    pcap_addr_t *a;

    printf("%s\n",d->name);    //Name

    if (d->description)
    {
        printf("Description: %s\n",d->description);    //Description
    }

    // Loopback Address
    printf("Loopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"Yes":"No");

      for(a = d->addresses ; a ; a=a->next)    //Now print the IP addresses etc of each device
    {
        printf("Address Family: #%d\n",a->addr->sa_family);

        switch(a->addr->sa_family)
        {
            case AF_INET:
                printf("Address Family Name: AF_INET\n");

                if (a->addr)
                {
                    printf("Address: %s\n",inet_ntoa(((struct sockaddr_in *)a->addr)->sin_addr));
                }

                if (a->netmask)
                {
                    //If a valid netmask has been detected
                    printf("Netmask: %s\n",inet_ntoa(((struct sockaddr_in *)a->netmask)->sin_addr));
                }

                if (a->broadaddr)
                {
                    //If a valid Broadcast Address is detected
                    printf("Broadcast Address: %s\n",inet_ntoa(((struct sockaddr_in *)a->broadaddr)->sin_addr));
                }

                if (a->dstaddr)
                {
                    printf("Destination Address: %s\n",inet_ntoa(((struct sockaddr_in *)a->dstaddr)->sin_addr));
                }
            break;

            default:
                printf("Address Family Name: Unknown\n");
                break;
        }
    }
    printf("\n");
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.