2013-05-28 4 views
0

Я пытаюсь использовать сокеты для обнюхивания пакетов 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, но я не смог найти группу рассылки.

ответ