Анализатор пакетов обнаруживает только отправленные пакеты

Я работал над анализатором пакетов просто для удовольствия / образования, и все шло довольно хорошо. Проблема в том, что единственные пакеты, которые появляются в recvfrom() это отправленные пакеты, то есть пакеты с моим IP в качестве исходного IP-адреса, а не мой WAN-IP, а мой IP-адрес локальной сети (если это имеет смысл).
Я пытался починить его и часами читал все, что мог найти, но мне кажется, что нет решения.
Я на 100% уверен, что код, который я написал, не обнаруживает все пакеты, потому что wireshark обнаруживает намного больше (входящий и исходящий), и очевидно, что с моего компьютера идет не только исходящий трафик.

packetsize = recvfrom(sniffer , Buffer , 65536 , 0 , (SOCKADDR *)&SenderAddr , &SenderAddrSize);
for (int x = 12; x < 16; x++)
{
printf("%c ",Buffer[x]);
}
std::cout << "\n";

iphdr = (IPV4_HDR *)Buffer;

memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = iphdr->ip_srcaddr;
std::cout << inet_ntoa(source.sin_addr) << "\n\n";

В этот момент все сводится к нулю (кода гораздо больше, но это не важно), все структуры правильно определены, поэтому здесь нет ошибок (иначе я не мог бы получать один и тот же IP-адрес снова и снова в каждом отдельном пакете ).
Также есть еще один, несуществующий IP-адрес из моей сети, который отображается как исходный IP-адрес, и очень редко исходный IP-адрес равен 0.0.0.0, что я оба нахожу очень странным.

Буфер объявлен как

char *Buffer = (char *)malloc(65536);

так что это подписанный символ, и я понятия не имею, как я мог вручную «извлечь» отдельные части заголовка из этих значений.

Я надеюсь, что кто-нибудь может объяснить мне, что recvfrom на самом деле не теряет пакеты и что я делаю что-то не так.
Также я хотел бы знать, как интерпретировать вывод recvfromто есть преобразование подписанного в неподписанное или, может быть, каким-то другим способом?

Я надеюсь, что прояснил мою проблему, заранее спасибо.

РЕДАКТИРОВАТЬ. Большой кусок моего кода

int main()
{
SOCKET sniffer;
struct in_addr addr;
int in;

char hostname[100];
struct hostent *local;
WSADATA wsa;// Initialise Winsock

printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2), &wsa) != 0)
{
printf("WSAStartup() failed.\n");
getchar();
return 1;
}
printf("Initialised");

// Create a RAW Socket
printf("\nCreating RAW Socket....");
sniffer = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (sniffer == INVALID_SOCKET)
{
printf("Failed to create raw socket.\n");
printf("WSA throws error code %d\n",WSAGetLastError());
printf("Run as admin to fix\n");
getchar();
return 1;
}
printf("Created.");

// Retrieve the local hostname
if (gethostname(hostname, sizeof(hostname)) == SOCKET_ERROR)
{
printf("WSA throws error code %d\n",WSAGetLastError());
getchar();
return 1;
}
printf("\nHost name : %s \n",hostname);

bool retry = true;
signed int maxnumber = -1;

do
{
// Retrieve the available IPs of the local host
local = gethostbyname(hostname);
printf("\nAvailable Network Interfaces  \n");
if (local == NULL)
{
printf("WSA throws error code %d.\n",WSAGetLastError());
getchar();
return 1;
}

// Available interfaces
for (i = 0; local->h_addr_list[i] != 0; i++) // h_addr_list is null terminated
{
// local is hostent struct in which information about the host is stored
// in_addr represents an IPv4 internet address. inet_ntoa: in_addr to string (ip adress)
memmove(&addr, local->h_addr_list[i], sizeof(struct in_addr));
//memmove(destination, source, number of bytes to copy)
printf("Interface Number : %d Address : %s\n", i, inet_ntoa(addr));
maxnumber = i;
printf("\n");
}

// Choose interface
if (maxnumber > 0)
{
printf("Enter the interface number you would like to sniff : ");
scanf("%d",&in);
printf(" in: %d | maxnumber: %d \n", in, maxnumber);
if (in <= maxnumber)
{
retry = false;
} else {
printf("Interface number %d with adress %d does not exist \n\n", in, local->h_addr_list[in]);
}
}
else
{
printf("Only one interface available");
in = 0;
retry = false;
}
} while (retry);

self = addr;
CreateFolder(self);

memset(&dest, 0, sizeof(dest));
memcpy(&dest.sin_addr.s_addr,local->h_addr_list[in],sizeof(dest.sin_addr.s_addr));
dest.sin_family = AF_INET;
dest.sin_port = htons(source.sin_port);//=0;

printf("\nBinding socket to local system and port 0 ...");
if (bind(sniffer,(struct sockaddr *)&dest,sizeof(dest)) == SOCKET_ERROR)
{
printf("bind(%s) failed.\n", inet_ntoa(addr));
getchar();
return 1;
}
printf("Binding successful");

j=1;
unsigned long nbytesret;
printf("\nSetting socket to sniff...");
if (WSAIoctl(sniffer, SIO_RCVALL, &j, sizeof(j), 0, 0, &nbytesret , 0 , 0) == SOCKET_ERROR)
{
printf("WSAIoctl() failed.\n");
getchar();
return 1;
}
printf("Socket set\n");
printf("Press enter to start\n");
getchar();

printf("Packet Capture Statistics...\n");
StartSniffing(sniffer);

printf("Ending sniffer, press enter to exit \n");
getchar();
closesocket(sniffer);
WSACleanup();

return 0;
}

void StartSniffing(SOCKET sniffer)
{
char *Buffer = (char *)malloc(65536);
int packetsize;

if (Buffer == NULL)
{
printf("malloc() failed.\n");
getchar();
return;
}

do
{
packetsize = recvfrom(sniffer , Buffer , 65536 , 0 , (SOCKADDR *)&SenderAddr , &SenderAddrSize);

if(packetsize > 0)
{
ProcessPacket(Buffer, packetsize);
}
else
{
printf( "recvfrom() failed.\n");
getchar();
}

}
while (packetsize > 0);

free(Buffer);
}

2

Решение

Чтобы прочитать из буфера как без знака, используйте reinterpret_cast вот так, чтобы получить беззнаковый указатель:

unsigned char *uBuffer = reinterpret_cast<unsigned char *>(Buffer);
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]