1

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);  // getting error message here as mentioned below

   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.

Beginner
  • 286
  • 2
  • 16
  • You realize `strcpy` will stop as soon as it sees a null _byte_? – alexis Nov 21 '13 at 10:20
  • actually i want to know how do i retrieve the data from struct variables .In the data_process code i get warning . I am unable to understand it. – Beginner Nov 21 '13 at 10:22
  • 2
    possible duplicate of [how to serialize a struct in c?](http://stackoverflow.com/questions/15707933/how-to-serialize-a-struct-in-c) – unwind Nov 21 '13 at 10:26
  • nope..My question is completely different! – Beginner Nov 21 '13 at 10:28
  • 2
    You casting int to ptr, then trying deref pointer from struct. This (socklen_t*)saddr_size = data2.ssize; will work, but I'm not sure what you trying to achieve. Agree with @unwind that you need to look about serialization. Because next your question will be - why pointers arrived from socket does not points anywhere. – Sergei Nikulov Nov 21 '13 at 10:44

1 Answers1

0

It is clear from the Error message you have

(socklen_t*)saddr_size=*(data2.ssize) - Here you are trying to store a value which is of integer type into an address "saddr_size"

Make the change as

*(socklen_t*)saddr_size=*(data2.ssize) -> Now both are of same type and size will be copied to saddr_size .

Srikanth
  • 449
  • 2
  • 8
  • i get warning as : cast to pointer from integer of different size [-Wint-to-pointer-cast] – Beginner Nov 22 '13 at 04:45
  • Actually speaking , do you need the size to be of pointer type ? since it is a pointer , you cannot take value of that without declaring pointer to the strcture which hold *ssize . So my advice is to change the ssize as normal integer/character which makes life simple . – Srikanth Nov 22 '13 at 05:02