1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

raw socket

Discussion in 'Userland Programming and Scripting' started by dursino, Feb 21, 2011.

  1. dursino

    dursino New Member

    Messages:
    11
    Thanks Received:
    0
    I'm writing code about raw sockets. In linux this code is ok:

    Code:
    void spoofa(smurfina *p,smurfina *q)
    {	const int PKT_LEN=9999;
    	int sd;
    	char buffer[PKT_LEN];
    	struct iphdr *ip = (struct iphdr *) buffer;
    	struct udphdr *udp = (struct udphdr *) (buffer + sizeof(struct iphdr));
    	struct sockaddr_in sin;
    	int one = 1;
    	const int *val = &one;
    	memset(buffer, 0, PKT_LEN);
    	
    	sd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);  //Pacchetto UDP
    	if (sd < 0)
    		{	 perror("Errore inoltro Disconnect");
    		  	 return ;
    		}
    	sin.sin_family = AF_INET;
    	sin.sin_port = htons(p->porta);
    	sin.sin_addr.s_addr = p->ip_addr.s_addr;	//indirizzo IP destinazione 
    	ip->ihl = 5;		//pacchetto IP
    	ip->version = 4;         //IPV4
    	ip->tos = 16;		//Mi pare minimize delay
    	ip->tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) + 5;  //5 il mex hola+'\0'
    	ip->id = htons(52407);   //
    	ip->ttl = 64;          //Quanto mi resta da vivere?
    	ip->protocol = 17;        //UDP
    	ip->saddr = p->ip_addr.s_addr;	//indirizzo IP destinazione 
    	ip->daddr = q->ip_addr.s_addr;	//indirizzo IP destinazione 
    		
    	//pacchetto UDP
    	udp->source = htons(9999);	//porta UDP sorgente 
    	udp->dest = htons(p->porta);	//porta UDP destinazione
    	udp->len = htons(sizeof(struct udphdr)+5);
    	strcpy(buffer+sizeof(struct iphdr)+(sizeof(struct udphdr)) ,"hola");
    	ip->check = csum((unsigned short *) buffer, sizeof(struct iphdr) + sizeof(struct udphdr));	//calcolo checksum
    	
    	if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)	//informo il sistema operativo che l'intestazione IP è già presente
    		perror("Errore setsockopt()");
    
    	if (sendto(sd, buffer, ip->tot_len, 0, (struct sockaddr *) &sin, sizeof(sin)) < 0)	//invio pacchetto
    		perror("Errore sendto()");
    }
    	


    But under FreeBSD I have these errors:

    Code:
    In file included from main_server.c:4:
    ./server.h: In function `spoofa':
    ./server.h:388: error: invalid application of `sizeof' to incomplete type `iphdr' 
    ./server.h:402: error: dereferencing pointer to incomplete type
    ./server.h:403: error: dereferencing pointer to incomplete type
    ./server.h:404: error: dereferencing pointer to incomplete type
    ./server.h:405: error: dereferencing pointer to incomplete type
    ./server.h:405: error: invalid application of `sizeof' to incomplete type `iphdr' 
    ./server.h:406: error: dereferencing pointer to incomplete type
    ./server.h:407: error: dereferencing pointer to incomplete type
    ./server.h:408: error: dereferencing pointer to incomplete type
    ./server.h:409: error: dereferencing pointer to incomplete type
    ./server.h:410: error: dereferencing pointer to incomplete type
    ./server.h:413: error: structure has no member named `source'
    ./server.h:414: error: structure has no member named `dest'
    ./server.h:415: error: structure has no member named `len'
    ./server.h:416: error: invalid application of `sizeof' to incomplete type `iphdr' 
    ./server.h:417: error: dereferencing pointer to incomplete type
    ./server.h:417: error: invalid application of `sizeof' to incomplete type `iphdr' 
    ./server.h:422: error: dereferencing pointer to incomplete type
    


    Can you help me?

    Thanks a lot
     
  2. rambetter

    rambetter New Member

    Messages:
    89
    Thanks Received:
    5
    My guess is that iphdr and udphdr are not defined on FreeBSD.

    I had a look at /usr/include/netinet/ip.h on a Linux machine and sure enough these structs are defined.
    I had a look at /usr/include/netinet/ip.h on a FreeBSD machine and they are missing.

    I guess the answer is don't use these structs? I wrote a UDP server without them using just the bare sockets API. Why do you need them?
     
  3. expl

    expl New Member

    Messages:
    664
    Thanks Received:
    121
    struct iphdr is a linux style definition of IP header, it holds same data structure as BSD struct ip. So you should rewrite the code and apply struct ip instead.
     
  4. dursino

    dursino New Member

    Messages:
    11
    Thanks Received:
    0
    Sorry but I'm not sure that I have understood! I should replace iphdr with ip, simply? So the code was not portable from BSD machine and linux machine, true?
     
  5. Alt

    Alt New Member

    Messages:
    726
    Thanks Received:
    79
    True, this code is not portable. You can check with grep -r iphdr /usr/include/ -- there is no "iphdr" struct.
    Btw, this code is really em.. strange... At least first 5 lines...
     
  6. expl

    expl New Member

    Messages:
    664
    Thanks Received:
    121
    Yes you need to replace, ip structure points to same bit fields but the entries have different names so you will have to change the names in the code. Look at netinet/ip.h for reference and compare to linux/ip.h.
     
  7. expl

    expl New Member

    Messages:
    664
    Thanks Received:
    121
    From a quick look at the code, it seems like it tries to create a custom UDP packet and push it via raw socket.
     
  8. dursino

    dursino New Member

    Messages:
    11
    Thanks Received:
    0
    Thanks, I have changed that fields but I receive error too:
    Code:
    ./server.h:402: error: dereferencing pointer to incomplete type
    ./server.h:403: error: dereferencing pointer to incomplete type
    ./server.h:404: error: dereferencing pointer to incomplete type
    ./server.h:405: error: dereferencing pointer to incomplete type
    


    Why in your opinion?
     
  9. dursino

    dursino New Member

    Messages:
    11
    Thanks Received:
    0
    Boyssssssss.
    Thanks a lot, followed your suggestions, I have corrected code and now it's ok!
    Code:
    void spoofa(smurfina *p,smurfina *q)
    {	const int PKT_LEN=9999;
    	int sd;
    	char buffer[PKT_LEN];
    	struct ip *ip = (struct ip *) buffer;
    	struct udphdr *udp = (struct udphdr *) (buffer + sizeof(struct ip));
    	struct sockaddr_in sin;
    	int one = 1;
    	const int *val = &one;
    	memset(buffer, 0, PKT_LEN);
    	
    	sd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);  //Pacchetto UDP
    	if (sd < 0)
    		{	 perror("Errore inoltro Disconnect");
    		  	 return ;
    		}
    	sin.sin_family = AF_INET;
    	sin.sin_port = htons(p->porta);
    	sin.sin_addr.s_addr = p->ip_addr.s_addr;	//indirizzo IP destinazione 
    	ip->ip_hl = 5;		//pacchetto IP
    	ip->ip_v = 4;         //IPV4
    	ip->ip_tos = 16;		//Mi pare minimize delay
    	ip->ip_len = sizeof(struct ip) + sizeof(struct udphdr) + 5;  //5 il mex hola+'\0'
    	ip->ip_id = htons(52407);   //
    	ip->ip_ttl = 64;          //Quanto mi resta da vivere?
    	ip->ip_p = 17;        //UDP
    	ip->ip_src = p->ip_addr;	//indirizzo IP destinazione 
    	ip->ip_dst = q->ip_addr;	//indirizzo IP destinazione 
    		
    	//pacchetto UDP
    	udp->uh_sport = htons(9999);	//porta UDP sorgente 
    	udp->uh_dport = htons(p->porta);	//porta UDP destinazione
    	udp->uh_ulen = htons(sizeof(struct udphdr)+5);
    	strcpy(buffer+sizeof(struct ip)+(sizeof(struct udphdr)) ,"hola");
    	ip->ip_sum = csum((unsigned short *) buffer, sizeof(struct ip) + sizeof(struct udphdr));	//calcolo checksum
    	
    	if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)	//informo il sistema operativo che l'intestazione IP è già presente
    		perror("Errore setsockopt()");
    
    	if (sendto(sd, buffer, ip->ip_len, 0, (struct sockaddr *) &sin, sizeof(sin)) < 0)	//invio pacchetto
    		perror("Errore sendto()");
    }
    	

    Now i can put this function in an other file and then write:
    Code:
    #ifdef __USE_BSD
    ..
    ..
    #endif /* __USE_BSD */

    So compiler understand if use this version or that in first post..
    no?
     
  10. expl

    expl New Member

    Messages:
    664
    Thanks Received:
    121
    I am pretty sure that linux has struct ip defined aswell so it should compile on both systems.
     
  11. dursino

    dursino New Member

    Messages:
    11
    Thanks Received:
    0
    Solved:
    Code:
    #ifndef __linux__
    void spoofa(smurfina *p,smurfina *q)
    {	const int PKT_LEN=9999;
    	int sd;
    	char buffer[PKT_LEN];
    	struct ip *ip = (struct ip *) buffer;
    	struct udphdr *udp = (struct udphdr *) (buffer + sizeof(struct ip));
    	struct sockaddr_in sin;
    	int one = 1;
    	const int *val = &one;
    	memset(buffer, 0, PKT_LEN);
    	
    	sd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);  //Pacchetto UDP
    	if (sd < 0)
    		{	 perror("Errore inoltro Disconnect");
    		  	 return ;
    		}
    	sin.sin_family = AF_INET;
    	sin.sin_port = htons(p->porta);
    	sin.sin_addr.s_addr = p->ip_addr.s_addr;	//indirizzo IP destinazione 
    	ip->ip_hl = 5;		//pacchetto IP
    	ip->ip_v = 4;         //IPV4
    	ip->ip_tos = 16;		//Mi pare minimize delay
    	ip->ip_len = sizeof(struct ip) + sizeof(struct udphdr) + 5;  //5 il mex hola+'\0'
    	ip->ip_id = htons(52407);   //
    	ip->ip_ttl = 64;          //Quanto mi resta da vivere?
    	ip->ip_p = 17;        //UDP
    	ip->ip_src = p->ip_addr;	//indirizzo IP destinazione 
    	ip->ip_dst = q->ip_addr;	//indirizzo IP destinazione 
    		
    	//pacchetto UDP
    	udp->uh_sport = htons(9999);	//porta UDP sorgente 
    	udp->uh_dport = htons(p->porta);	//porta UDP destinazione
    	udp->uh_ulen = htons(sizeof(struct udphdr)+5);
    	strcpy(buffer+sizeof(struct ip)+(sizeof(struct udphdr)) ,"hola");
    	ip->ip_sum = csum((unsigned short *) buffer, sizeof(struct ip) + sizeof(struct udphdr));	//calcolo checksum
    	
    	if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)	//informo il sistema operativo che l'intestazione IP è già presente
    		perror("Errore setsockopt()");
    
    	if (sendto(sd, buffer, ip->ip_len, 0, (struct sockaddr *) &sin, sizeof(sin)) < 0)	//invio pacchetto
    		perror("Errore sendto()");
    }
    	
    #endif 
    #ifdef __linux__
    void spoofa(smurfina *p,smurfina *q)
    {	const int PKT_LEN=9999;
    	int sd;
    	char buffer[PKT_LEN];
    	struct iphdr *ip = (struct iphdr *) buffer;
    	struct udphdr *udp = (struct udphdr *) (buffer + sizeof(struct iphdr));
    	struct sockaddr_in sin;
    	int one = 1;
    	const int *val = &one;
    	memset(buffer, 0, PKT_LEN);
    	
    	sd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);  //Pacchetto UDP
    	if (sd < 0)
    		{	 perror("Errore inoltro Disconnect");
    		  	 return ;
    		}
    	sin.sin_family = AF_INET;
    	sin.sin_port = htons(p->porta);
    	sin.sin_addr.s_addr = p->ip_addr.s_addr;	//indirizzo IP destinazione 
    	ip->ihl = 5;		//pacchetto IP
    	ip->version = 4;         //IPV4
    	ip->tos = 16;		//Mi pare minimize delay
    	ip->tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) + 5;  //5 il mex hola+'\0'
    	ip->id = htons(52407);   //
    	ip->ttl = 64;          //Quanto mi resta da vivere?
    	ip->protocol = 17;        //UDP
    	ip->saddr = p->ip_addr.s_addr;	//indirizzo IP destinazione 
    	ip->daddr = q->ip_addr.s_addr;	//indirizzo IP destinazione 
    		
    	//pacchetto UDP
    	udp->source = htons(9999);	//porta UDP sorgente 
    	udp->dest = htons(p->porta);	//porta UDP destinazione
    	udp->len = htons(sizeof(struct udphdr)+5);
    	strcpy(buffer+sizeof(struct iphdr)+(sizeof(struct udphdr)) ,"hola");
    	ip->check = csum((unsigned short *) buffer, sizeof(struct iphdr) + sizeof(struct udphdr));	//calcolo checksum
    	
    	if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)	//informo il sistema operativo che l'intestazione IP è già presente
    		perror("Errore setsockopt()");
    
    	if (sendto(sd, buffer, ip->tot_len, 0, (struct sockaddr *) &sin, sizeof(sin)) < 0)	//invio pacchetto
    		perror("Errore sendto()");
    }
    #endif /* __USE_GNU!!*/	
     
  12. dursino

    dursino New Member

    Messages:
    11
    Thanks Received:
    0
    Sorry, but I have a new problem. If I compile the code above, with an old version of FreeBSD I receive this error :
    Code:
    /usr/include/netinet/ip.h:160: error: syntax error before "n_long"
    /usr/include/netinet/ip.h:163: error: syntax error before "n_long"
    


    Why?