# raw socket



## dursino (Feb 21, 2011)

I'm writing code about raw sockets. In linux this code is ok:


```
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:


```
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


----------



## rambetter (Feb 21, 2011)

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?


----------



## expl (Feb 21, 2011)

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.


----------



## dursino (Feb 21, 2011)

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?


----------



## Alt (Feb 21, 2011)

True, this code is not portable. You can check with [cmd=]grep -r iphdr /usr/include/[/cmd] -- there is no "iphdr" struct.
Btw, this code is really em.. strange... At least first 5 lines...


----------



## expl (Feb 21, 2011)

dursino said:
			
		

> 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?



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.


----------



## expl (Feb 21, 2011)

Alt said:
			
		

> True, this code is not portable. You can check with [cmd=]grep -r iphdr /usr/include/[/cmd] -- there is no "iphdr" struct.
> Btw, this code is really em.. strange... At least first 5 lines...



From a quick look at the code, it seems like it tries to create a custom UDP packet and push it via raw socket.


----------



## dursino (Feb 21, 2011)

Thanks, I have changed that fields but I receive error too:

```
./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?


----------



## dursino (Feb 21, 2011)

Boyssssssss.
Thanks a lot, followed your suggestions, I have corrected code and now it's ok!

```
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:

```
#ifdef __USE_BSD
..
..
#endif /* __USE_BSD */
```
So compiler understand if use this version or that in first post..
no?


----------



## expl (Feb 21, 2011)

I am pretty sure that linux has struct ip defined aswell so it should compile on both systems.


----------



## dursino (Feb 21, 2011)

Solved:

```
#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!!*/
```


----------



## dursino (Feb 22, 2011)

Sorry, but I have a new problem. If I compile the code above, with an old version of FreeBSD I receive this error :

```
/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?


----------

