Я пытаюсь использовать сокеты для обнюхивания пакетов OpenFlow. У меня есть код, который пытается собрать OF-пакеты и распечатать информацию заголовка, однако, похоже, не печатает правильную информацию. Я установил среду в mininet и указал ее на удаленный контроллер. В wirehark я вижу стандартный эхо-запрос/ответ, который в openflow - это типы 2 и 3, определенные в части заголовка. Когда я смотрю на пакетные данные, которые я собираю в своей программе, я, кажется, печатаю нечетный пакет типа 2 и ничего другого, из-за чего я считаю, что мой код неверен, а напечатанные пакеты типа 2 не являются пакетами типа 2.Sniffing for OpenFlow Пакеты неожиданные данные напечатаны
Я играл с этим некоторое время, поэтому мне жаль, если он немного грязный/несовершенный. Я попытался сделать его читаемым для всех:
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <openflow/openflow.h>
#include "openflow/lib/ofpbuf.h"
int sock_raw;
void DieWithError(char *errorMessage);
void handlePacket(unsigned char *, int);
void printOFHeader(struct ofp_header *);
int main()
{
int saddr_size , data_size;
struct sockaddr saddr;
unsigned char *buffer = (unsigned char *)malloc(65536); //Its Big! -- Malloc allocates a block of size bytes of memory, returning a pointer to the beginning of the block
printf("Starting...\n");
//Create a raw socket that shall sniff
sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
printf("socket: %d\n",sock_raw);
if(sock_raw < 0)
{
printf("Socket Error\n");
return 1;
}
while(1)
{
saddr_size = sizeof saddr;
//Receive a packet
data_size = recvfrom(sock_raw, buffer, 65536, 0 , &saddr , (socklen_t*)&saddr_size);
if(data_size <0)
{
printf("Recvfrom error , failed to get packets\n");
return 1;
}
//Now process the packet
handlePacket(buffer, data_size);
}
close(sock_raw);
printf("Finished");
return 0;
}
void DieWithError(char *errorMessage)
{
perror(errorMessage);
exit(1);
}
void handlePacket(unsigned char *buff, int data_size)
{
//first get IP header length
struct iphdr *iph = (struct iphdr *)buff;
unsigned short iphdrlen = iph->ihl*4;
//get tcp header length
struct tcphdr *tcph = (struct tcphdr*)(buff + iphdrlen);
unsigned int ofph_offset = (iphdrlen+(unsigned int)tcph->doff*4);
//add total length of ip and tcp headers to the buffer to get the start of the OF Header
struct ofp_header *oh = (struct ofp_header*)(buff + ofph_offset);
//Check it is an OF Header -- Not sure this is right
if(oh->version == OFP_VERSION)
{
printOFHeader(oh);
}
else
{
printf("This is not an openflow packet\n");
}
}
void printOFHeader(struct ofp_header * oh)
{
printf("OPENFLOW PACKET HEADER\n");
printf(" |-OF Version %d\n", oh->version);
printf(" |-Type: %d\n", oh->type);
printf(" |-Transaction ID: %d\n", oh->xid);
printf(" |-Length: %d\n", oh->length);
printf("----------------------------------------------------");
printf("\n");
}
Я проверял данные для следующего:
//first get IP header length
struct iphdr *iph = (struct iphdr *)buff;
unsigned short iphdrlen = iph->ihl*4;
//get tcp header length
struct tcphdr *tcph = (struct tcphdr*)(buff + iphdrlen);
Этих печатать правильные адреса портов и IP-адрес для пакетов, так что я думаю мой недостаток заключается в том, как я назначаю структуру thep_header. Этот вопрос может быть лучше размещен на веб-сайте openflow.org, но я не смог найти группу рассылки.