Beginner
Beginner

Reputation: 286

How to copy the struct variables into buffer in c socket program?

In the client side,I need to receive the packets from the network and write it into a file which will be sent to the server for further process.

There was problem in receiving and processing the packets because i used to send just a buffer not 'saddr' and its 'size' in write() api.

Hence i used structure to declare all the members such as buffer, saddr, saddr_size. This is my data_capture code:

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");
}

I used strcpy to copy the values of buffer,sadddr,saddr_size to a variable which can be used in write api. I mean to say i want to copy the whole structure into a buffer and then use it in write().

data process code is :

   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;
}

when i compile this data_process code i get error in the line (socklen_t*)saddr_size=*(data2.ssize); warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] error: lvalue required as left operand of assignment

I had previously posted this question but i dint get the solution . Hence have posted it again by uploading entire modified code. Please somebody help me.

Upvotes: 1

Views: 2728

Answers (3)

kunal
kunal

Reputation: 966

You can do it like this change the struct as

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

and then in the code

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);

Upvotes: 2

user3011768
user3011768

Reputation: 191

by your code it's not fully clear from which variable to which variable you want to copy values. but my little understanding you can do following:

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

try it to see if it works for you

Upvotes: 0

Parthiban
Parthiban

Reputation: 2330

The code has many errors. To answer your question first, you have to use strcpy(data.buffer, (char*)(&data)->saddr);

Other errors in your code are,

  1. Your have defined a structure and never used to update the saddr. Instead you have used separate saddr variable.
  2. "data" is not the pointer which you tried accessing with "->". "saddr" variable inside in your structure is declared as pointer.
  3. Even if you use the structure, you have to allocate memory for the pointers which you have declared inside the structure before using it. Else you will face segmentation fault.
  4. The allocated memory is not freed for "buffer" variable.
  5. This way of reading the network data is not the right way. See "select" system call and async read in socket programming.

If your using the "gcc" compiler, use the option "-Wall -Wextra" which will show all your mistakes.

Upvotes: 1

Related Questions