raw socket

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
 
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?
 
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.
 
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?
 
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...
 
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.
 
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.
 
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?
 
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?
 
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!!*/
 
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?
 
Back
Top