3ef3 [Solved] raw socket [Archive] - The FreeBSD Forums

PDA

View Full Version : [Solved] raw socket


dursino
February 21st, 2011, 15:10
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
February 21st, 2011, 15:52
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
February 21st, 2011, 16:16
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
February 21st, 2011, 16:34
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
February 21st, 2011, 16:51
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...

expl
February 21st, 2011, 17:41
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 (http://www.cse.scu.edu/~dclark/am_256_graph_theory/linux_2_6_stack/linux_2ip_8h-source.html).

expl
February 21st, 2011, 17:53
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...

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
February 21st, 2011, 18:47
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
February 21st, 2011, 19:37
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
February 21st, 2011, 21:32
I am pretty sure that linux has struct ip defined aswell so it should compile on both systems.

dursino
February 21st, 2011, 22:09
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
February 22nd, 2011, 22:01
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?

0