Predefined size circular list shared between two threads

kami1219's Avatar, Join Date: Jul 2009
Go4Expert Member
Hi, I have to create a ciruclar list that is shared between two threads. One thread extends the list by storing each new packet on a new node and the other thread reads these packets and frees the node and so on. I need to you check flow of this work. Appreciate your swift replies as this is really urgent.

Creation of the circular list with a predefined 100000 nodes in main thread
Code:
  int counter=0;
  emptylist=NULL;
  pktlist=NULL;
  senderlist=NULL;
  
    while(counter <= 100000)
    {
      enode=(struct CaptureBuffer *)malloc(sizeof(struct CaptureBuffer));
      counter++;
      memset(enode,0,4136);
      if(emptylist == NULL)
    {
               senderlist=shead=snode=pnode=emptylist=ehead=ecurr=enode;
     
    }
      else
    {

      ecurr->next=enode;
      ecurr=ecurr->next;
      enode->next= ehead;
     
    }
      
      
    }
  
  etail=ecurr;
  etail->next=ehead;
  ehead->prev=etail;
-----------------------------------------------------------------

Thread-1 that captures the packets and stores each packet on a new node of the list..

Code:
pnode=pktlist; // START OF THE LIST


if(pktlist == NULL)
        {

      
          pktlist=pnode;
          phead=pnode;
          pcurr=pnode;
        }
      else
        {
          
          pcurr->next =pnode;
          pcurr=pcurr->next;

        }
------------------------------------------------

Thread-2 that retrieves the packets and deletes the node after sending the packet.

Code:
snode=scurr=pktlist;
while(scurr->next!=NULL) // FIRST CHECKS FOR THE SMALLEST PACKET.
     {
       if(snode->ts.tv_sec < scurr->ts.tv_sec && snode->ts.tv_usec < scurr->ts.tv_usec)
        {
          TMPNode=snode;
          snode=scurr;
          scurr=TMPNode;
        }
       
       scurr=scurr->next;
     }
   
    
     
       gettimeofday(&curr_time,NULL);      
//SENDS THE PACKET IF THE PACKET TIMESTAMP IS SMALLER THAN THE CURRENT TIME.
       if(curr_time.tv_sec >= snode->ts.tv_sec  && curr_time.tv_usec >= snode->ts.tv_usec)
     {
       
       struct sockaddr_ll destAddr;
       memcpy(buf,&snode->pkt,snode->pkt_len);
       memcpy(&(destAddr.sll_addr),&buf,MAC_ADDR_LEN);
       destAddr.sll_family=PF_PACKET;
       destAddr.sll_protocol=htons(ETH_P_ALL);
       destAddr.sll_ifindex=2;
       destAddr.sll_pkttype=PACKET_OTHERHOST;
       destAddr.sll_halen=ETH_ALEN;
       if(snode2->rFlag==0 && snode2->wFlag==1)
         {
           
           if((retVal=write(Fd,snode->pkt,snode->pkt_len))==-1)
         {
           printf("retVal is %d",retVal);
           printf("sendto() error \n");
         }
           printf("SENDER 1 --- packet number is %d OF length %d Sent \n",snode2->pkt_id,retVal);
           snode2->rFlag=1;
           snode2->wFlag=0;
         }
       
     }
  pthread_mutex_unlock( &mut );
       snode=snode->next;
  }while(snode->next != NULL);
IN SECOND THREAD, I NEED TO FIND OUT THE SMALLEST PACKET IN THE LIST AND RETRIEVING UPON THE PACKET TIME STAMP REACHES THE PLAYOUT TIME (CURRENT CLOCK TIME) AND THEN SENDING THE PACKET AND REMOVING THE NODE SO THAT NEXT TIME AGAIN THE SAME NODE IS NOT READ AS CONTAINING THE SMALLEST PACKET.


I NEED YOUR SWIFT REPLIES. IT'S REALLY URGENT.

Last edited by shabbir; 30Jul2009 at 21:30.. Reason: Code blocks
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
What is the program doing wrong?
You've got a mutex on thread 2 but don't you need one on thread 1 as well? What's to stop threads 1&2 operating on the same bit of memory?
What is the significance of 4136 (in the memset call)? If sizeof(struct CaptureBuffer)==4136, why not use sizeof(struct CaptureBuffer) instead, and if it isn't, what do you think will happen?
4136*100000 = 413 600 000 not counting other memory needed for pointers and such. Does your program have over 394MB to play with?
kami1219's Avatar, Join Date: Jul 2009
Go4Expert Member
Quote:
Originally Posted by xpi0t0s View Post
What is the program doing wrong?
You've got a mutex on thread 2 but don't you need one on thread 1 as well? What's to stop threads 1&2 operating on the same bit of memory?
What is the significance of 4136 (in the memset call)? If sizeof(struct CaptureBuffer)==4136, why not use sizeof(struct CaptureBuffer) instead, and if it isn't, what do you think will happen?
4136*100000 = 413 600 000 not counting other memory needed for pointers and such. Does your program have over 394MB to play with?

Well this program works between two network interfaces. It contains two threads, capture and sender. Capture thread captures packets at first interface and stores in a linked list and the other thread retrieves the packets from the list and sends through the other interface and the linked list node is removed. The thing that i have to do is to apply delay on the captured packet before they are stored using linked list. These packets are sent by reading their play out time that is the time stamp of the packet when it is captured plus the amount of delay time added into the time stamp. Such that a kind of delay is added to the packets.

I guess i had mutex on thread one as well. Here one thing, I am using two different mutex variable. I mean, one for each thread. Where it should be implemented and will it be useful in this application where continuously packet are captured and sent. I have to do it urngently so I can't think of any other solution at this point of time and I am new to C and for the first time I implemented pthreads and linked list stuff.

4136 is size of the CaptureBuffer and sizeof(CaptureBuffer) can be used instead. You are right.

I can't understand the remaining contents of your post. What is the shortfall if 4136 is used. I did not get it. I'll change it with sizeof(CaptureBuffer). This is not the problem. How the two process can be synchronized is the main issue here regardless of the number of packets coming to the interface.

Thanks for the post and appreciate your further replies.
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
> I am using two different mutex variable

That's likely to be the problem. All you're doing by using two mutex variables is preventing thread1 from interfering with itself (which it won't do anyway even without a mutex) and likewise for thread2. To stop thread1 and thread2 interfering with each other you need to use the SAME mutex flag.

> What is the shortfall if 4136 is used
None if 4136 is exactly equal to sizeof(CaptureBuffer). If it isn't and the problem is that you get odd behaviour, it could be that you're getting UB due to corrupted memory. Remember, you didn't say what the actual problem was, you just posted partial code and said "check the flow", so if I failed to guess the problem correctly then I guess my mind reading skills aren't up to your expectations.

Despite me asking, you still haven't said what the actual problem is. Is there one? What are you observing that you didn't expect?
kami1219's Avatar, Join Date: Jul 2009
Go4Expert Member
Quote:
Originally Posted by kami1219 View Post
Well this program works between two network interfaces. It contains two threads, capture and sender. Capture thread captures packets at first interface and stores in a linked list and the other thread retrieves the packets from the list and sends through the other interface and the linked list node is removed. The thing that i have to do is to apply delay on the captured packet before they are stored using linked list. These packets are sent by reading their play out time that is the time stamp of the packet when it is captured plus the amount of delay time added into the time stamp. Such that a kind of delay is added to the packets.

I guess i had mutex on thread one as well. Here one thing, I am using two different mutex variable. I mean, one for each thread. Where it should be implemented and will it be useful in this application where continuously packet are captured and sent. I have to do it urngently so I can't think of any other solution at this point of time and I am new to C and for the first time I implemented pthreads and linked list stuff.

4136 is size of the CaptureBuffer and sizeof(CaptureBuffer) can be used instead. You are right.

I can't understand the remaining contents of your post. What is the shortfall if 4136 is used. I did not get it. I'll change it with sizeof(CaptureBuffer). This is not the problem. How the two process can be synchronized is the main issue here regardless of the number of packets coming to the interface.

Thanks for the post and appreciate your further replies.

Sorry i had another post on the same forum and I have written the synchronization issues in your reply. Other than synchronization issues you can answer the things. This program is not doing anything wrong. I just need you to see the flow of the link list in these two threads and the creation of the list in the main thread. The following can be checked.

1. In main thread: Is the circular list is created correctly.
2. In capture: Is the flow correct in term of extending the list on each new packet. (mutex locks are used. I have omitted some code because I have to see the flow of the list only here)
3. In sender thread: Is smallest packet taken out from the list and sent. Where should I free the node and if I free the node then how can i create new nodes because on each demalloc or each packet sent, one node will be removed and after sometime all the nodes of the list will be removed.

Thanks and regards
kami1219's Avatar, Join Date: Jul 2009
Go4Expert Member
Quote:
Originally Posted by xpi0t0s View Post
> I am using two different mutex variable

That's likely to be the problem. All you're doing by using two mutex variables is preventing thread1 from interfering with itself (which it won't do anyway even without a mutex) and likewise for thread2. To stop thread1 and thread2 interfering with each other you need to use the SAME mutex flag.

> What is the shortfall if 4136 is used
None if 4136 is exactly equal to sizeof(CaptureBuffer). If it isn't and the problem is that you get odd behaviour, it could be that you're getting UB due to corrupted memory. Remember, you didn't say what the actual problem was, you just posted partial code and said "check the flow", so if I failed to guess the problem correctly then I guess my mind reading skills aren't up to your expectations.

Despite me asking, you still haven't said what the actual problem is. Is there one? What are you observing that you didn't expect?

Here is the code of the first thread.
Code:
pthread_mutex_t mutex2=PTHREAD_MUTEX_INITIALIZER;

void* capture(void* ptr)
{
  printf("I am inside the capture thread to capture packets \n");

  struct sockaddr_ll packet_info;
  int packet_info_size = sizeof(packet_info);
  struct timeval time2;
  union semun args;
  capProcess *cProc;
   int sd;
   char* nic;
   extern int semaphore;
   int pktCnt;

   cProc=(capProcess*)ptr;
   sd=cProc->sd;
   nic=cProc->nic;
   semaphore=cProc->semaphore;
   pktCnt=cProc->pktCnt;
  int len1;
  // int pktCnt=1;
  
  printf("CAP1 THREAD--sd is %d \n",sd); 
 
  // wPos=0;
  int  packets_to_sniff=10000000;
  args.val=1;
  unsigned char *pkt=(unsigned char *)malloc(2048*(sizeof(unsigned char *)));
   
  
    while( packets_to_sniff--)
    {

      if((len1=recvfrom(sd,pnode->pkt,2048,0,(struct sockaddr*)&packet_info,&packet_info_size)) == -1)
    {
      perror("Recvfrom() returned -1");
      exit(-1);
    }
      else
    {
      
      ioctl(sd,SIOCGSTAMP,&time2);


      pthread_mutex_lock(&mutex2);

          pnode->pkt_id=pktCnt;
          printf("packet number is %d \n",pnode->pkt_id);
          //      memcpy(&pnode->pkt,&pkt,len1);
          pnode->pkt_len=len1;
          printf("packet of length %d bytes received \n",pnode->pkt_len);
          pnode->ts.tv_sec=time2.tv_sec;
          printf("packet of time seconds are  %ld  \n",pnode->ts.tv_sec);
          pnode->ts.tv_usec=time2.tv_usec;
          printf("packet of time micro seconds are  %ld  \n",pnode->ts.tv_usec);
          pnode->wPos=wPos;
          rPos=wPos-3;
          pnode->rPos=rPos;
          pnode->wFlag=1;
          pnode->rFlag=0;
          char s[20];
          gettimeofday(&time2);      
          wPos++;
          //   }


      /* current system clocke time in hour-min-sec*/
      time_t rawtime;
      struct tm *timeinfo,*timeinfo2;
      char buffer[80],hr[10],min[10],sec[10];
      int str;int cnt;

      time(&rawtime);
      timeinfo=localtime(&rawtime);
      strftime(hr,10,"%I",timeinfo);
      strftime(min,10,"%M",timeinfo);
      strftime(sec,10,"%S",timeinfo);

      if(strcmp(min,"00")==0)
        {
          printf("New Hour starts \n");
          cnt=0;
        }
      else
        {
          int whichsecond;
          int mins, secs;
          mins = atoi(min);
          printf("mins=%d\n",mins);
          secs=atoi(sec);
          printf("secs=%d\n",secs);

          whichsecond= (mins*60)+secs;
          printf("whichsecond is %d",whichsecond);
          cnt=whichsecond;
        




          /* ADD DELAY AMOUNT TAKEN FROM THE ARRAY IN THE TIMESTAMP OF THE PACKETS*/

          struct timeval delay;
          delay.tv_usec=(1000*Shaper[cnt])+time2.tv_usec;
          pnode->ts.tv_usec=delay.tv_usec;
          printf("pnode->ts.tv_usec = %ld.......... \n",pnode->ts.tv_usec);
          cnt++;

        }

                pthread_mutex_unlock(&mutex2);      

    
      int n=0;int m=0;
    

            
      if(pktlist == NULL)
        {

      
          pktlist=pnode;
          phead=pnode;
          pcurr=pnode;
        }
      else
        {
          
          pcurr->next =pnode;
          pcurr=pcurr->next;

        }


      
    }

      pktCnt++;

    }

Last edited by shabbir; 31Jul2009 at 09:25.. Reason: Code blocks
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
Please use code blocks when posting code. It preserves formatting and uses a monospaced font, thus making code easier to read. You did before so I'm not clear why you didn't this time.

From what I've seen of what you've posted (in code blocks, I didn't bother looking at the code that wasn't), I couldn't see any glaringly obvious mistakes.

But the only way I can know if the code is correct is by building and running it. However, I can't do that as I only have partial code. But you can, because you have the complete code.
So I suggest you should answer your own question by building and running the code. If it does what you expect, then yes the flow is correct. If the flow is wrong then the program won't do what you are expecting.

Sorry if this seems unhelpful but it's really difficult to read someone else's code and work out what their intent was from the code itself, particularly if they're a beginner. The best way to check if the code works is to run it. The only way I can check the code works is by running it myself, but (a) you need to provide complete code so that I can do that, and (b) why should I do it when you are perfectly capable of doing it?

Once you've built and run the code (or just attempted to build it if there were errors), cut the code down to the bare minimum, so for example just do the linked list stuff and keep the rest to a minimum, post the complete (stripped down) code, state precisely and in full detail what the problem is (so not "it doesn't work"), then I stand a chance of working out what might be wrong.
kami1219's Avatar, Join Date: Jul 2009
Go4Expert Member
Quote:
Originally Posted by xpi0t0s View Post
Please use code blocks when posting code. It preserves formatting and uses a monospaced font, thus making code easier to read. You did before so I'm not clear why you didn't this time.

From what I've seen of what you've posted (in code blocks, I didn't bother looking at the code that wasn't), I couldn't see any glaringly obvious mistakes.

But the only way I can know if the code is correct is by building and running it. However, I can't do that as I only have partial code. But you can, because you have the complete code.
So I suggest you should answer your own question by building and running the code. If it does what you expect, then yes the flow is correct. If the flow is wrong then the program won't do what you are expecting.

Sorry if this seems unhelpful but it's really difficult to read someone else's code and work out what their intent was from the code itself, particularly if they're a beginner. The best way to check if the code works is to run it. The only way I can check the code works is by running it myself, but (a) you need to provide complete code so that I can do that, and (b) why should I do it when you are perfectly capable of doing it?

Once you've built and run the code (or just attempted to build it if there were errors), cut the code down to the bare minimum, so for example just do the linked list stuff and keep the rest to a minimum, post the complete (stripped down) code, state precisely and in full detail what the problem is (so not "it doesn't work"), then I stand a chance of working out what might be wrong.

List flow in the thread-1 is given below. remaining text is omitted. It is only how each time a new packet comes and is being stored using the link list node and so the list extends.
Code:
pnode=pktlist; // START OF THE LIST

//Here is the data (packet len, original packet and other stuff) added to the node


if(pktlist == NULL)  // pktlist is the start of the list
        {

      
          pktlist=pnode;
          phead=pnode;
          pcurr=pnode;
        }
      else
        {
          
          pcurr->next =pnode;
          pcurr=pcurr->next;
}
Please check the following thread that
1. I have to take out the smallest packet from the list. I have to take it out only when the clock time reaches the smallest packet's time stamp.
2. When the smallest packet is retrieved, it should be sent when the current clock time reaches the time stamp value
3. How to remove the node from the list in the following thread when the packet is sent. Using demalloc() ??
4. How should i create the new nodes as after some time when all the nodes are removed from the list.

Full code of this thread is given ( header files are removed only).
Code:
pthread_mutex_t mutex_send=PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void* sender(void* ptr)
{
  printf("sender1....-4");
  printf("SENDER1 --I am inside the sender1 thread to send packets \n");
  printf("sender1...-3");
  //  rPos=-3;
  printf("sender1... -2");
  sendProcess *mySend;
  int Fd;
  int nics;
  printf("sender 1... -1");
  extern int semaphore;
  struct sembuf sWait={0,-1,0};
  union semun sSet;
  unsigned char destAddr[6];
  char* nic;
  struct timeval curr_time;
  mySend=(sendProcess*)ptr;

  int sentPkts=0;
  // pktCnt=cProc->pktCnt;
  int len1=0;
  int pktCnt=0;

  sSet.val=1;
  semaphore=mySend->semaphore;
  Fd=mySend->Fd;
  //   rPos=-1;
  //  printf("sender1 .. 1");
  unsigned char buf[4092];

  int retVal;
  printf("SENDER1--Fd is %d",Fd);

  printf("sender 1... 1");


  //  printf("sender1 .. 2");
 
  snode=scurr=pktlist;
 
  printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.snode=%d,scurr=%d,pktlist=%d",snode,scurr,pktlist);
do
  {
  pthread_mutex_lock( &mut );


   //     pthread_mutex_lock( &mut );
      while(scurr->next!=NULL);
     {
       if(snode->ts.tv_sec < scurr->ts.tv_sec && snode->ts.tv_usec < scurr->ts.tv_usec)
	    {
	      TMPNode=snode;
	      snode=scurr;
	      scurr=TMPNode;
	    }
       
       scurr=scurr->next;
     }
   
	
	 
       gettimeofday(&curr_time,NULL);	  
       if(curr_time.tv_sec >= snode->ts.tv_sec  && curr_time.tv_usec >= snode->ts.tv_usec)
	 {
	   
	   struct sockaddr_ll destAddr;
	   memcpy(buf,&snode->pkt,snode->pkt_len);
	   memcpy(&(destAddr.sll_addr),&buf,MAC_ADDR_LEN);
	   destAddr.sll_family=PF_PACKET;
	   destAddr.sll_protocol=htons(ETH_P_ALL);
	   destAddr.sll_ifindex=2;
	   destAddr.sll_pkttype=PACKET_OTHERHOST;
	   destAddr.sll_halen=ETH_ALEN;
	   if(snode2->rFlag==0 && snode2->wFlag==1)
	     {
	       
	       if((retVal=write(Fd,snode->pkt,snode->pkt_len))==-1)
		 {
		   printf("retVal is %d",retVal);
		   printf("sendto() error \n");
		 }
	       printf("SENDER 1 --- packet number is %d OF length %d Sent \n",snode2->pkt_id,retVal);
	       snode2->rFlag=1;
	       snode2->wFlag=0;
	     }
	   
	 }
  pthread_mutex_unlock( &mut );
       snode=snode->next;
  }while(snode->next != NULL);
Please don't mind my things as I am new to C and new to forums also and I need to do the task in a short time so that did not follow the rules.
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
Where is main?
kami1219's Avatar, Join Date: Jul 2009
Go4Expert Member
Quote:
Originally Posted by xpi0t0s View Post
Where is main?

Creation of predefined size Link list specific code

Code:
int counter=0;
  emptylist=NULL;
  pktlist=NULL;
  senderlist=NULL;
  //   snode=NULL;
    while(counter <= 100000)
    {
      //      printf("main ... 0.2");
      enode=(struct CaptureBuffer *)malloc(sizeof(struct CaptureBuffer));
      //      printf("sizeof %d enode=%d\n",counter,sizeof(*enode));
      //  printf("address of %d node is %d\n",counter,enode);
      counter++;
      memset(enode,0,4136);
      if(emptylist == NULL)
    {  printf("main ... 0.3");
     
              senderlist=shead=snode=pnode=emptylist=ehead=ecurr=enode;
     
     
    }
      else
    {// printf("main ... 0.4");
      //  enode->prev=ecurr;
      ecurr->next=enode;
      ecurr=ecurr->next;
      enode->next= ehead;
      //printf("main...0.5"); 
    }
      
      
    }
  printf("main... 0.5");

    
  etail=ecurr;
  etail->next=ehead;
  ehead->prev=etail;

Full code of main

Code:
#include"capture.h"
#include<pthread.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<features.h>
#include<linux/if_packet.h>
#include<linux/if_ether.h>
#include<errno.h>
#include<sys/ioctl.h>
#include<net/if.h>
#include<net/if_arp.h>
#include<linux/ip.h>
#include<linux/tcp.h>
#include<errno.h>
#include<sys/ioctl.h>
#include<netinet/in.h>

int filter_flag=0;
struct sockaddr_ll destAddr;
//destAddr=(unsigned char)malloc(sizeof(8));                                                                                                                 
unsigned char proto[2];
unsigned char* data;
int data_len;

typedef unsigned char MacAddress[MAC_ADDR_LEN];
extern int errno;
MacAddress localMac;
MacAddress destMac;


int semaphore;
union semun arg;

wPos=0;
rPos=-3;
int main()
{

  printf("main ... 0");
  printf(" Allocating memory ...please wait\n");
  //  node=(struct CaptureBuffer *)malloc(1000000*sizeof(struct CaptureBuffer *));
  printf("sizeof structis %d\n",sizeof(struct CaptureBuffer));//4136 bytes 

  printf("main ... 0.1");


  /*Allocating memory for eth0->eth1 traffic*/
  int counter=0;
  emptylist=NULL;
  pktlist=NULL;
  senderlist=NULL;
  //   snode=NULL;
    while(counter <= 100000)
    {
      //      printf("main ... 0.2");
      enode=(struct CaptureBuffer *)malloc(sizeof(struct CaptureBuffer));
      //      printf("sizeof %d enode=%d\n",counter,sizeof(*enode));
      //  printf("address of %d node is %d\n",counter,enode);
      counter++;
      memset(enode,0,4136);
      if(emptylist == NULL)
    {  printf("main ... 0.3");
     
              senderlist=shead=snode=pnode=emptylist=ehead=ecurr=enode;
     
     
    }
      else
    {// printf("main ... 0.4");
      //  enode->prev=ecurr;
      ecurr->next=enode;
      ecurr=ecurr->next;
      enode->next= ehead;
      //printf("main...0.5"); 
    }
      
      
    }
  printf("main... 0.5");

    
  etail=ecurr;
  etail->next=ehead;
  ehead->prev=etail;
  

  printf("main ... 1");


  /* Allocating memeory for the eth1->eth0 traffic*/
    
  int counter2 =0;
  emptylist2=NULL;
  pktlist2=NULL;
  senderlist2=NULL;
  //   snode=NULL;
    printf("main ... 1.1");
  //  printf("1");
  while(counter2 <= 100000)
    {
      //      printf("2");

      enode2=(struct CaptureBuffer2 *)malloc(sizeof(struct CaptureBuffer2));
      //      printf("sizeof %d enode=%d\n",counter,sizeof(*enode));
      counter2++;
      memset(enode2,0,4136);
      if(emptylist2 == NULL)
        {    printf("main ... 1.2");
      //    printf("3");
      senderlist2=shead2=snode2=pnode2=emptylist2=ehead2=ecurr2=enode2;
          //emptylist->next=NULL;
          //ecurr->prev=NULL;
        }
      else
        {//    printf("main ... 1.3");
      //        printf("4");

      ecurr2->next2=enode2;
      ecurr2=ecurr2->next2;
      enode2->next2= ehead2;
    }

    }    
  printf("main ... 1.4");
  etail2=ecurr2;
  etail2->next2=ehead2;
  ehead2->prev2=etail2;
  
  //      printf("5");

  printf("main ... 2");  
  
  printf("memory allocated !!!\n");
  

  int i;
  for(i=1;i<=3600;i++)
    {
      Shaper[i]=i;
      //Shaper[i]=i%100;
    }
  for(i=0;i<3600;i++)
    {
      //      printf("%d",Shaper[i]);
    }

  time_t rawtime;
  struct tm *timeinfo;
  char buffer[80],hr[10],min[10],sec[10];
  int str;

  int cnt=0;




  printf("main ... 3");



  
  /*
    Pthread_t cap1;
    pthread_t sendPID;
    pthread_t cap2;
    pthread_t sendPID2;
  */
  capProcess myCap;
  sendProcess mySend;
  
  capProcess myCap2;
  sendProcess mySend2;
  
  
  key_t key=1234;
  int pid;
  // int semid;
  int nsems =0;
  int nsops=2;
  int semflg= IPC_CREAT | 0666;
  struct sembuf *sops = (struct sembuf *)malloc(2*sizeof(struct sembuf));
  
  /*   
       if((semaphore=semget(key,nsems,semflg) == -1))
       {
       perror("semget:semget fialed\n");
       exit(1);
       }else
       {
       fprintf(stderr, "semget:semget succeeded: semaphore=%d\n",semaphore);
       }
  */
  
  int sd;
  sd=CreateRawSocket(ETH_P_ALL);
  printf(">>>sd is %d\n",sd);
  printf("Socket created successfully to capture packets from eth0 \n");
  BindRawSocketToInterface("eth0",sd,ETH_P_ALL);
  printf("socket is bind to eth0 interface \n");
    
  int Fd;
  Fd=CreateRawSocket(ETH_P_ALL);
  printf(">>>Fd is %d\n",Fd);
  printf("Socket created successfully to send packets to eth1 \n");
  BindRawSocketToInterface("eth1",Fd,ETH_P_ALL);
  printf("socket for sender is bind to eth1 interface \n");
  
  
  myCap.sd=sd;
  myCap.nic="eth0";
  myCap.semaphore=semaphore;
  myCap.pktCnt=0;
  

  printf("main ... 4");    

  if(pthread_create(&cap1,NULL,&capture,&myCap))
    {
      fprintf(stderr,"Error creating RAW Capture thread \n");
      abort();
    }
  printf("Raw capture1 thread created \n");

  printf("main...4.1");

  
  
  mySend.Fd=Fd;
  mySend.nic="eth1";
  mySend.semaphore=semaphore;
  
  printf("main....4.2");
  if(pthread_create(&sendPID,NULL,&sender,&mySend))
    {
      fprintf(stderr,"Error creating sender  thread \n");
      abort();
    }
  printf("Sender1 thread created \n");

  printf("main ... 5");  
  
  
  pthread_join(cap1,NULL);
  printf("CAP1 thread joined");
   pthread_join(sendPID,NULL);
  printf("SENDER1 JOIN successful \n");

  
  


  //-----------------------------------------
  /*  
  myCap2.sd=Fd;

  myCap2.nic="eth1";
  myCap2.semaphore=semaphore;
  myCap2.pktCnt=0;

  if(pthread_create(&cap2,NULL,&capture1,&myCap2))
    {
      fprintf(stderr,"Error creating RAW Capture thread \n");
      abort();
    }
  printf("Raw capture2 thread created \n");
  
  mySend2.Fd=sd;
  mySend2.nic="eth0";
  mySend2.semaphore=semaphore;
   
  if(pthread_create(&sendPID2,NULL,&sender1,&mySend2))
    {
      fprintf(stderr,"Error creating sender  thread \n");
      abort();
    }
  printf("Sender2 thread created \n");
  
  
  
  printf("main ... 6"); 
  
  
   
  pthread_join(cap2,NULL);
  printf("CAP2 thread joined");
   pthread_join(sendPID2,NULL);
  printf("SENDER2 join successful \n");
  
  */
  printf("main ... 7"); 
  
  
    }
  

int CreateRawSocket(int protocol_to_sniff)
{
  int rawso;
  if((rawso = socket(PF_PACKET,SOCK_RAW,htons(protocol_to_sniff))) == -1)
    {
      perror("Error creating raw sockets \n");
      exit(-1);
    }
  return rawso;
}

int BindRawSocketToInterface(char *device,int rawsock,int protocol)
{
  struct sockaddr_ll sll;
  struct ifreq ifr;
  bzero(&sll,sizeof(sll));
  bzero(&ifr,sizeof(ifr));
  
  strncpy((char *)ifr.ifr_name,device,IFNAMSIZ);
  if((ioctl(rawsock,SIOCGIFINDEX,&ifr)) == -1)
    {
      printf("Error getting interface index \n");
      exit(-1);
    }
  sll.sll_family = AF_PACKET;
  
  sll.sll_ifindex = ifr.ifr_ifindex;
  sll.sll_protocol = htons(protocol);
  
  if((bind(rawsock, (struct sockaddr *)&sll,sizeof(sll))) == -1)
    {
      perror("Error binding raw sotcket to interface \n");
      exit(-1);
    }
  return 1;
}