Thread: Sending Structs pointers through pipes

  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    192

    Sending Structs pointers through pipes

    I'm having a problem with pipes. And i think I'm not sure how to send pointers to a struct through pipes. Since most examples online using pipes are usually just a char[]. But this doesn't work. Does anyone know who to send a pointer to a struct through pipes.

    Code:
    struct Ethfrm_t
    {
    	struct FCfrm_t* ptr;
    	unsigned char DestEthAdr[6];
    	unsigned char SrcEthAdr[6];
    	UINT32  VLAN_HdrSave;
    	UINT32  reserved;
    	UINT32  pad;
    	unsigned char Ethbuffer[BUF_SIZE];
    }  __attribute__ ((packed));
    
    Ethfrm_t* FCoe = malloc(sizeof(*FCoe));
    Ethfrm_t* Ethfrm =malloc(sizeof(*Ethfrm));
    
    int FCoepipe[2];
    
    if (pipe( FCoepipe ) ) {
    		fprintf(stderr,"Pipe error!\n");
    		exit(1);
    }
    #define BUF_SIZE 1500
    
    write(FCoepipe[1],Ethfrm,BUF_SIZE);
    read(FCoepipe[0],FCoe,BUF_SIZE);

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Are you sending this pointer to another application? Pointers can not be shared among different applications like this because the applications have a different address space. In other words, a pointer value of 0xDEADBEEF in one application will pointer to something different than the pointer with the same value in another application.

    So you need to send the actual data through the pipe -- not a pointer to the data.

    Also the read and write calls in your code make no sense. You are sending BUF_SIZE bytes, but your structure is larger than BUF_SIZE...
    bit∙hub [bit-huhb] n. A source and destination for information.

  3. #3
    Registered User
    Join Date
    Aug 2009
    Posts
    192
    So should i have a pointer pointing to the top of the struct like
    unsigned char* Etho = Ethfrm
    and then
    unsigned char bugger[BUF_SIZE+200]
    write(FCoepipe[1],Etho,BUF_SIZE+200);
    read(FCoepipe[0],bugger,BUF_SIZE+200);
    So taht all the data in Ethfrm will be transfered through the pipe?

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Quote Originally Posted by kiros88 View Post
    So should i have a pointer pointing to the top of the struct like
    unsigned char* Etho = Ethfrm
    and then
    unsigned char bugger[BUF_SIZE+200]
    write(FCoepipe[1],Etho,BUF_SIZE+200);
    read(FCoepipe[0],bugger,BUF_SIZE+200);
    So taht all the data in Ethfrm will be transfered through the pipe?
    No. If you want to send a generic structure, then you should do something like:
    Code:
    write(fd, my_struct_pointer, sizeof(*my_struct_pointer));
    But remember what I said about pointers. If your struct contains pointers, those pointer values will not be valid to the application which receives this structure.
    bit∙hub [bit-huhb] n. A source and destination for information.

  5. #5
    Registered User
    Join Date
    Aug 2009
    Posts
    192
    Sorry dont want to be a douche but how do u do the read actually thats one of the confusing parts since its needs i think its own seperate pointer struct to do things? would it look like this.
    Ethfrm_t* FCoe = malloc(sizeof(*FCoe));
    read(FCoepipe[0],FCoe,sizeof(*FCoe));

  6. #6
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    >> would it look like this
    yes.
    bit∙hub [bit-huhb] n. A source and destination for information.

  7. #7
    Registered User
    Join Date
    Aug 2009
    Posts
    192
    Im having a problem

    Code:
    Ethfrm->reserved = 0x0202;
    write(FCoepipe[1],Ethfrm,BUF_SIZE);
    
    thread(){
    read(FCoepipe[0],FCoe,BUF_SIZE);
    printf(      "        %02X   \n",FCoe->reserved);
    }
    Okay so i know thread isn't looking right but yea so im sending in the pipe Fcoe but right before i write i change the reserved for Ethfrm but when i read and do a printf it doesnt change the reserved in FCoe?
    }

  8. #8
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    For some reason you are sending and receiving BUF_SIZE bytes again...
    I already pointed out how that is wrong.
    bit∙hub [bit-huhb] n. A source and destination for information.

  9. #9
    Registered User
    Join Date
    Aug 2009
    Posts
    192
    o my bad I just copied some of hte code on top i changed that already but yea There both sizeof(Ethfrm) or sizeof(FCoe) But im still not understanding why the reserved isn't being processed through the pipe.

  10. #10
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    There's probably a problem somewhere else in your code. Can you post a complete program?
    bit∙hub [bit-huhb] n. A source and destination for information.

  11. #11
    Registered User
    Join Date
    Aug 2009
    Posts
    192
    Code:
    #include <sys/socket.h> 
    
    #include <sys/ioctl.h>
    
    #include <sys/time.h>
    
    
    #include <asm/types.h>
    
    #include "server.h"
    
    #include "util.h"
    
    
    
    #include <math.h>
    
    #include <string.h>
    
    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <unistd.h>
    
    #include <signal.h>
    
    #include <pthread.h>
    
    #include "machdeps.h"
    #include "fcframe.h"
    
    
    #include <linux/if_packet.h>
    
    #include <linux/if_ether.h>
    
    #include <linux/if_arp.h>
    
    
    
    #define BUF_SIZE ETH_FRAME_TOTALLEN
    
    
    void * thread2(void*);			/*Functions for the Threads*/
    void * thread1(void*);
    
    int	FCoepipe[2];			/*The two pipes for the threads*/
    int	FIPpipe[2];
    
    
    #define NUM_THREADS 2
    pthread_t tid[NUM_THREADS];      /* array of thread IDs */
    
    
    int s = 0; /*Socketdescriptor*/
    
    
    
    long total_packets = 0;
    
    long answered_packets = 0;
    int typerror;
    #define CFI 0x10
    unsigned char test[4] = {0x00, 0x19, 0xB9, 0x3D};
    unsigned char VLAN[2] = {0x81,0x00};
    unsigned char FCoe[2] = {0x89,0x06};
    unsigned char FIP[2] = {0x89,0x14};
    void* buffer;
    int readint;
    
    /* The Ethernet Frame structure*/
    
    struct Ethfrm_t
    {
    	struct FCfrm_t* ptr;
    	unsigned char DestEthAdr[6];
    	unsigned char SrcEthAdr[6];
    	UINT32  VLAN_HdrSave;
    	UINT32  reserved;
    	UINT32  pad;
    	unsigned char Ethbuffer[BUF_SIZE];
    }  __attribute__ ((packed));
    	
    Ethfrm_t* FCoethread;			/* pointers to the Ethernetframe for the pipes read() call */
    Ethfrm_t* FIPthread; 
    
    void printEthfrm(Ethfrm_t * Ethfrm);    /* prints out the error Frame*/
    void deleteEthfrm(Ethfrm_t * Ethfrm);   /* Freeing the Struct*/
    Ethfrm_t * CopyEthfrm(Ethfrm_t * Ethfrm);
    unsigned char bugger[BUF_SIZE+200];
    
    
    
    int main(void) {
    	unsigned char* etherhead;
    	struct ethhdr *eh;
    	unsigned char* Etho;
    
    	unsigned char src_mac[6];		/*our MAC address*/
    	FCoethread = malloc(sizeof(*FCoethread));			
    	FIPthread = malloc(sizeof(*FIPthread));
    	//Ethfrm_t Etherframe = malloc(sizeof(Etherframe)); 
    
    	Ethfrm_t* Ethfrm;// = Etherframe;
    	Ethfrm = malloc(sizeof(*Ethfrm));              
    
    	etherhead = Ethfrm->Ethbuffer;	/*Pointer to Ethenet Header*/
    
    	eh = (struct ethhdr *)etherhead; /*Another pointer to ethernet header*/
    	buffer = Ethfrm->Ethbuffer;                    /*Buffer for Ethernet Frame*/
    
    
    
    
    	struct ifreq ifr;
    
    	struct sockaddr_ll socket_address;
    
    	int ifindex = 0;			/*Ethernet Interface index*/
    
    	int i;
    
    	int length;				/*length of received packet*/
    
    	int sent;
    	
    	/* Creating the two Ethernet thread Pipes*/
    	if (pipe( FCoepipe ) ) {
    		fprintf(stderr,"Pipe error!\n");
    		exit(1);
    	}
    	if (pipe( FIPpipe ) ) {
    		fprintf(stderr,"Pipe error!\n");
    		exit(1);
    	}
    
    
    
    
    	printf("Server started, entering initialiation phase...\n");
    
    
    
    	/*open socket*/
    
    	s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    
    	if (s == -1) {
    
    		perror("socket():");
    
    	        exit(1);
    
    	}
    
    	printf("Successfully opened socket: %i\n", s);
    
    	
    
    	/*retrieve ethernet interface index*/
    
    	strncpy(ifr.ifr_name, DEVICE, IFNAMSIZ);
    
    	if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) {
    
    		perror("SIOCGIFINDEX");
    
    		exit(1);
    
    	}
    
    	ifindex = ifr.ifr_ifindex;
    
    	printf("Successfully got interface index: %i\n", ifindex);
    
    	
    
    	/*retrieve corresponding MAC*/
    
    	if (ioctl(s, SIOCGIFHWADDR, &ifr) == -1) {
    
    		perror("SIOCGIFINDEX");
    
    		exit(1);
    
    	}
    
            for (i = 0; i < 6; i++) {
    
    		src_mac[i] = ifr.ifr_hwaddr.sa_data[i];
    
    	}
    
    	printf("Successfully got our MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n", 
    
    			src_mac[0],src_mac[1],src_mac[2],src_mac[3],src_mac[4],src_mac[5]);
    
    
    
    	/*prepare sockaddr_ll*/
    
    	socket_address.sll_family   = PF_PACKET;
    
    	socket_address.sll_protocol = htons(ETH_P_IP);
    
    	socket_address.sll_ifindex  = ifindex;
    
    	socket_address.sll_hatype   = ARPHRD_ETHER;
    
    	socket_address.sll_pkttype  = PACKET_OTHERHOST;
    
    	socket_address.sll_halen    = ETH_ALEN;
    
    	socket_address.sll_addr[6]  = 0x00; 
    
    	socket_address.sll_addr[7]  = 0x00;
    
    														
    
    
    	/*establish signal handler*/
    
    	signal(SIGINT, sigint);
    
    	printf("Successfully established signal handler for SIGINT\n");
    
    		
    
    	printf("We are in production state, waiting for incoming packets....\n");
    	pthread_create(&tid[1], NULL, thread1, NULL);
    	pthread_create(&tid[0], NULL, thread2, NULL);
    
    
    
    	while (1) {
    
    
    		/*Wait for incoming packet...*/	
    
    		length = recvfrom(s, buffer, BUF_SIZE, 0, NULL, NULL);
    
    		if (length == -1) {
    
    			perror("recvfrom():");
    
    			exit(1);
    
    		}
    
    		 
    
    		/*See if we should answer (Ethertype == 0x0 && destination address == our MAC)*/
    
    		if (eh->h_proto == ETH_P_NULL && memcmp( (const void*)eh->h_dest, (const void*)src_mac, ETH_MAC_LEN) == 0 ) {
    
    
    			
    			/* Comparing the Ethertype*/
    			if(memcmp((void*)(etherhead+14), FCoe,2) == 0 || memcmp((void*)(etherhead+14),FIP,2) == 0){
    				Ethfrm->ptr = (struct FCfrm_t *)(&Ethfrm->pad);  // Ethfrm pointer 
    			} else if(memcmp((void*)(etherhead+14), VLAN,2) == 0){
    				Ethfrm->ptr = (struct FCfrm_t *)(&Ethfrm->reserved);
    				printf("VLAN HEADER\n");
    				if((etherhead[16]& CFI) == CFI){
    					printf("CFI is set:\n");
    					printEthfrm(Ethfrm);
    					continue;
    				}
    			} else {
    				printf("Not FCoe or FIP EtherType:\n");
    				printEthfrm(Ethfrm);
    				continue;
    			}
    		
    			/* Setting the FCframe_t StructureStart Pointer to the EthernetFrame*/
    			Ethfrm->ptr->StructureStart = Ethfrm;
    
    			//printf("%02lX VLAN\n", Ethfrm->ptr->StructureStart);
    
    			/* Storing the Ethernet Destination/Source address*/
    			memcpy(Ethfrm->DestEthAdr, (void*)etherhead, ETH_MAC_LEN);			
    			memcpy(Ethfrm->SrcEthAdr, (void*)(etherhead+ETH_MAC_LEN), ETH_MAC_LEN);
    			memcpy((unsigned char *)&Ethfrm->VLAN_HdrSave, (void*)(etherhead+(ETH_MAC_LEN*2)), 4);
    			
    			/* Sending the Frames to either FCoe or FIP Threads*/
    			if(memcmp((void*)(etherhead+14), FCoe,2) == 0 || memcmp((void*)(etherhead+18), FCoe,2) == 0){
    					//Ethfrm_t* FCoeframe = CopyEthfrm(Ethfrm);
    					Ethfrm_t* FCoeframe = malloc(sizeof(*FCoeframe));
    					*FCoeframe = *Ethfrm;				
    					write(FCoepipe[1],FCoeframe->ptr->StructureStart,sizeof(Ethfrm->ptr->StructureStart));
    			} 
    			if(memcmp((void*)(etherhead+14),FIP,2) == 0 || memcmp((void*)(etherhead+18),FIP,2) == 0){
    					//Ethfrm_t* FIPframe = CopyEthfrm(Ethfrm);
    					Ethfrm_t* FIPframe = malloc(sizeof(*FIPframe));
    					*FIPframe = *Ethfrm;
    					FIPframe->ptr = (struct FCfrm_t *)(&FIPframe->pad);
    					FIPframe->reserved = 0x2020;
    					printf("Ethfrm %02X \n", Ethfrm->reserved);
    					printf("FIP %02X \n", FIPframe->reserved);
    
    					write(FIPpipe[1],FIPframe,sizeof(FIPframe));
    			}
    
    
    
    			
    
    			/*exchange addresses in buffer*/
    
    			memcpy( (void*)etherhead, (const void*)(etherhead+ETH_MAC_LEN), ETH_MAC_LEN);
    
    			memcpy( (void*)(etherhead+ETH_MAC_LEN), (const void*)src_mac, ETH_MAC_LEN);
    			
    			
    
    			
    
    			/*prepare sockaddr_ll*/
    
    			socket_address.sll_addr[0]  = eh->h_dest[0];
    
    			socket_address.sll_addr[1]  = eh->h_dest[1];
    
    			socket_address.sll_addr[2]  = eh->h_dest[2];
    
    			socket_address.sll_addr[3]  = eh->h_dest[3];
    
    			socket_address.sll_addr[4]  = eh->h_dest[4];
    
    			socket_address.sll_addr[5]  = eh->h_dest[5];
    
    
    
    			/*send answer*/
    
    			sent = sendto(s, buffer, length-4, 0, (struct sockaddr*)&socket_address, sizeof(socket_address));
    
    			if (sent == -1) {
    
    				perror("sendto():");
    
    				exit(1);
    
    			}
    
    			
    
    			answered_packets++;
    			
    
    		}
    
    		
    
    		total_packets++;
    		
    
    	}
    
    }
    
    
    void * thread1(void* parm){
    	int i;
    	while(1){
    		readint = read(FIPpipe[0], FIPthread, sizeof(FIPthread));
    		//for(i = 0; i <500000000; i++);
    		printf("FIP thread1   %02X\n", FIPthread->reserved);	
    		//printf("read int %d\n", readint);
    		//deleteEthfrm(FIPthread);	
    	}
    
    }
    
    void* thread2(void* parm){
    	while(1){
    		read(FCoepipe[0], FCoethread, sizeof(FCoethread));
    		printf("FCoe thread2   %02X\n", FCoethread->ptr->fr_ref);
    		//deleteEthfrm(FCoethread);
    	}
    }
    
    void printEthfrm(Ethfrm_t * Ethfrm){
    	unsigned char* etherhead = Ethfrm->Ethbuffer;
    	printf("EtherType error ");
    	for(typerror = 0; typerror<1; typerror++){
    		printf("%02X:",etherhead[typerror]);
    	}
    	printf("\n");
    }
    
    Ethfrm_t * CopyEthfrm(Ethfrm_t * Ethfrm){
    	int i;
    	Ethfrm_t * EthfrmTmp = malloc(sizeof(*EthfrmTmp));
    
    	EthfrmTmp->ptr= Ethfrm->ptr;
    	for(i = 0; i < 6; i++){
    		EthfrmTmp->DestEthAdr[i] = Ethfrm->DestEthAdr[i];
    		EthfrmTmp->SrcEthAdr[i] = Ethfrm->SrcEthAdr[i];
    	}
    	EthfrmTmp->VLAN_HdrSave = Ethfrm->VLAN_HdrSave;
    	EthfrmTmp->reserved = Ethfrm->reserved;
    	EthfrmTmp->pad = Ethfrm->pad;
    	for(i = 0; i < BUF_SIZE; i++){
    		EthfrmTmp->Ethbuffer[i] = Ethfrm->Ethbuffer[i];
    	}
    	return EthfrmTmp;
    }
    	
    
    void deleteEthfrm(Ethfrm_t * Ethfrm){
    	/*
    	free(Ethfrm->ptr);
    	free(Ethfrm->DestEthAdr);
    	free(Ethfrm->SrcEthAdr);
    	free(Ethfrm->VLAN_HdrSave);
    	free(Ethfrm->reserved);
    	free(Ethfrm->pad);
    	free(Ethfrm->Ethbuffer);
    	free(Ethfrm);
    	*/
    	free(Ethfrm);
    }
    
    
    
    void sigint(int signum) {
    
    	/*Clean up.......*/
    
    
    
    	struct ifreq ifr;
    
    
    
            if (s == -1)
    
            	return;
    
    	
    
    	strncpy(ifr.ifr_name, DEVICE, IFNAMSIZ);
    
    	ioctl(s, SIOCGIFFLAGS, &ifr);
    
    	ifr.ifr_flags &= ~IFF_PROMISC;
    
    	ioctl(s, SIOCSIFFLAGS, &ifr);
    
    	close(s);
    
    
    
    	free(FCoethread->Ethbuffer);
    
    	
    
    	printf("Server terminating....\n");
    
    
    
    	printf("Totally received: %d packets\n", total_packets);
    
    	printf("Answered %d packets\n", answered_packets);
    
    	exit(0);
    
    }

  12. #12
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    You need to break this down into a much smaller problem, and solve that. Start with a simple program that sends a structure through a pipe, and receives it on the other end. Once you have that working (and have tested that it works completely), you can start adding on to it. Right now you have a giant mess of code that is buggy, and you don't even know where to start in fixing the problems.

    Start with a small application that works, and then slowly add on to it.
    bit∙hub [bit-huhb] n. A source and destination for information.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Passing pointers to two-dimensional arrays of structs
    By dr.neil.stewart in forum C Programming
    Replies: 2
    Last Post: 09-07-2007, 10:25 AM
  2. A question on Pointers & Structs
    By FJ8II in forum C++ Programming
    Replies: 4
    Last Post: 05-28-2007, 10:56 PM
  3. Sending array's to functions by reference or pointers
    By homeyg in forum C++ Programming
    Replies: 16
    Last Post: 12-27-2004, 02:55 PM
  4. Replies: 5
    Last Post: 02-20-2004, 09:36 AM
  5. Segmentation fault with structs and char pointers
    By Keybone in forum C++ Programming
    Replies: 20
    Last Post: 01-17-2004, 01:36 PM