2013-11-21 25 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); 
相关问题