Всем доброго времени суток.
Шлю 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");
}