2013-11-21 34 views
1

在客戶端,我需要接收來自網絡的數據包並將其寫入一個文件,該文件將被髮送到服務器進行進一步處理。如何將結構變量複製到c socket程序中的緩衝區中?

接收和處理數據包時出現問題,因爲我用write()api發送了一個不是'saddr'和'size'的緩衝區。

因此,我用結構聲明所有的成員,如緩衝區,saddr,saddr_size。 這是我的data_capture代碼:

int logfile; 
struct sockaddr_in source, dest; 

struct fields{    //edited 
    void* b; 
    struct sockaddr *s; 
    socklen_t *ssize; 
}data; 

int main() 
{ 
    int saddr_size, data_size; 
    struct fields data; 
    struct sockaddr saddr; 

    gopromiscous(); 

    unsigned char *buffer = (unsigned char *) malloc(1024); 

    logfile = open("sniff_data.bin", O_CREAT | O_WRONLY | O_APPEND, 0777); 
    if (logfile == -1) 
    { 
    printf("Unable to create sniff_data file."); 
    } 
    printf("\n Client Receiving the Packets...\n"); 

    int sock_raw = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 
    setsockopt(sock_raw, SOL_SOCKET, SO_BINDTODEVICE, "eth0", strlen("eth0") + 1); 

    if (sock_raw < 0) 
    { 
    perror("Socket Error"); 
    return 1; 
    } 

    int count = 10; 
    while (count >= 0) 
    { 
    count--; 
    saddr_size = sizeof saddr; 
    //Receive a packet  
    data_size = recvfrom(sock_raw, buffer, 1024, 0, &saddr, 
     (socklen_t*) &saddr_size); 

    // i have created struct to buffer,saddr and saddr_size above 
    if (data_size < 0) 
    { 
     printf("Recvfrom error , failed to get packets\n"); 
     return 1; 
    } 

    //i need to copy the values of buffer, saddr and sddr_size into a variable and  
    //then use that variable in write api 

    strcpy(data.b,buffer);   //edited 
    data.s=&saddr; 
    data.ssize=(socklen_t*)&saddr_size; 

    int cont = write(logfile, &data, data_size); 

    } 
    printf("\n Done\n"); 
    close(logfile); 
    close(sock_raw); 
    return 0; 
} 

int gopromiscous() 
{ 
    int fd; 
    struct ifreq eth; 

    fd = socket(AF_INET, SOCK_PACKET, htons(0x800)); 

    strcpy(eth.ifr_name, "eth0"); 

    ioctl(fd, SIOCGIFFLAGS, &eth); 

    eth.ifr_flags |= IFF_PROMISC; 

    ioctl(fd, SIOCSIFFLAGS, &eth); 

    printf("\n Entered Promiscuous Mode Successfully\n"); 
} 

我以前的strcpy到緩衝器,sadddr,saddr_size的值複製到可在寫入API一起使用的變量。我的意思是說我想將整個結構複製到緩衝區中,然後在write()中使用它。

數據處理代碼是:

void ProcessPacket(unsigned char* , int); 
    void print_ip_header(unsigned char* , int); 
    void print_tcp_packet(unsigned char * , int); 
    void print_udp_packet(unsigned char * , int); 
    void print_icmp_packet(unsigned char* , int); 
    void PrintData (unsigned char* , int); 

    FILE *logfile; 
    int infile; 
    struct sockaddr_in source,dest; 
    int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j; 


    int main() 
    { 
    int saddr_size , data_size; 
    struct sockaddr saddr; 

    struct fields{ 
     void* b; 
     struct sockaddr *s; 
     socklen_t *ssize; 
    }data2; 


    unsigned char *buffer3 = (unsigned char *) malloc(1024); 
    char *fname = "/home/shishira/Desktop/packet_capture/info_agent_report_processed.txt"; 


    infile=open("info_agent_report.txt",O_RDONLY); 
    logfile=fopen(fname,"w"); 

    printf("\n Starting..\n"); 
    saddr_size = sizeof saddr; 

    //Now process the packet 
    int totl=1; 
    do 
    { 
    printf("iteration %d of processing at taskagent\n",totl++); 
    data_size=read(infile,&data2,3024); 
//the value which was read by struct variables should be copied to buffer3 . 
    strcpy(buffer3,data2.b); 
    saddr=*(data2.s); 
    (socklen_t*)saddr_size=*(data2.ssize); 

    ProcessPacket(buffer3 , data_size); 

    } 
    while(data_size>0); 

    fclose(logfile); 
    close(infile); 
    printf("\n"); 
    printf(" Finished\n\n"); 
    return 0; 
} 

當我編譯此data_process代碼i的行 (socklen_t的*)saddr_size = *(data2.ssize)得到誤差; 警告:投以指針不同大小的整數[-Wint到指針鑄造] 錯誤:因分配

的左操作數左值我以前張貼了這個問題,但我不力得到解決。因此,通過上傳整個修改過的代碼再次發佈它。請有人幫助我。

+0

我同意Parthiban..Your問題不只是寫入日誌文件。事實上,當你糾正你的代碼中的其他錯誤時很簡單。 –

+0

'(socklen_t *)&saddr_size);'在int的大小與socklen_t不相同的系統上,這會失敗。 – alk

回答

1

該代碼有很多錯誤。要首先回答你的問題,你必須使用strcpy(data.buffer,(char *)(& data) - > saddr);

代碼中的其他錯誤,

  1. 您已經定義了一個結構,從不用於更新SADDR。相反,您使用了單獨的saddr變量。
  2. 「數據」不是您嘗試使用「 - >」訪問的指針。結構中的「saddr」變量被聲明爲指針。
  3. 即使使用該結構,也必須爲使用它之前在結構中聲明的指針分配內存。否則你將面臨分段錯誤。
  4. 分配的內存不會釋放「緩衝區」變量。
  5. 這種讀取網絡數據的方式並不正確。請參閱「選擇」系統調用和異步讀入套接字編程。

如果您使用「gcc」編譯器,請使用選項「-Wall -Wextra」來顯示您的所有錯誤。

+0

好的我修改了我的代碼.sir現在可以告訴我是否有任何錯誤? – Beginner

0

通過您的代碼,它不完全清楚您想要將哪個變量複製到哪個變量值。但我有點了解你可以做到以下幾點:

strcpy(data.buffer,buffer); //i guess you need to copy data that you received from socket to the variable buffer in data(a variable of fields struct) 
//i guess you need to copy received saddr to the saddr(in data variable) and as it's a pointer then you can simply assign the saddr to that pointer. 
data->saddr = &saddr; 
//and same assignment should work for size variable 

嘗試一下,看看它是否適合你

2

你能做到這樣 改變結構作爲

struct fields{ 
     char buffer[1024]; 
     struct sockaddr saddr; 
     socklen_t saddr_size; 
}data; 

,然後在代碼

memcpy(data.buffer,buffer,sizeof buffer); 
memcpy(&data.saddr,&saddr,sizeof saddr); 
memcpy(&data.saddr_size,&saddr_size,sizeof(saddr_size)); 
int cont = write(logfile, &data, data_size); 
相關問題