Discussion:
FreeBSD libnet_pblock_find() problem
Victor Lima
2005-03-01 02:30:12 UTC
Permalink
Hello list,

Im trying to build an application that will forge UDP packets based on
information retrieved by libpcap. The box that I'm using is a FreeBSD
5.3-REL with ports retrieved from the instalation CD. The libnet version
is: libnet-devel-1.1.2.1.

The problem lies somewhere in this code ( or maybe its a bug in libnet
itself ) :

-----------------------

void
echo_server ( const unsigned char *packet ) {
int c;
char errbuf[LIBNET_ERRBUF_SIZE], src[15], dst[15],
*payload = NULL;
libnet_t *lnet;
libnet_ptag_t udp, ip;
struct ip *ip_hdr;
struct udphdr *udp_hdr;

ip_hdr = ( struct ip *) ( packet + size_eth );
udp_hdr = ( struct udphdr *) ( packet + size_eth + size_ip );
payload = ( char *) ( packet + size_eth + size_ip + size_udp );

/* the code break somewhere here... */
if( (lnet = libnet_init( LIBNET_RAW4, NULL, errbuf )) == NULL ) {
fprintf( stderr, "%s: libnet_init() failed: %s\n", prefix,
errbuf);
exit( EXIT_FAILURE );
}

udp = libnet_build_udp( ntohs( udp_hdr->uh_dport ),
ntohs( udp_hdr->uh_sport ),
LIBNET_UDP_H + strlen( payload ),
0,
payload,
strlen(payload),
lnet,
udp );

if( udp == -1 ) {
fprintf (stderr, "%s: libnet_build_udp() failed: %s\n",
prefix, libnet_geterror(lnet));
goto bad;
}
/* to here */

ip = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_UDP_H +
strlen( payload ), 0,
ip_hdr->ip_id,
0,
64,
IPPROTO_UDP,
0,
libnet_name2addr4(lnet, (char *)
inet_ntop(AF_INET, &ip_hdr->ip_dst, dst, sizeof(dst)), LIBNET_RESOLVE),
libnet_name2addr4(lnet, (char *)
inet_ntop(AF_INET, &ip_hdr->ip_src, src, sizeof(src)), LIBNET_RESOLVE),
NULL,
0,
lnet,
ip );
if ( ip == -1 ) {
fprintf( stderr, "%s: libnet_build_ipv4() failed: %s\n",
prefix, libnet_geterror(lnet));
goto bad;
}
if( (c = libnet_write(lnet)) == -1 ) {
fprintf(stderr, "%s: libnet_write() failed: %s\n", prefix,
libnet_geterror(lnet));
goto bad;
}
return;
bad:
libnet_destroy( lnet );
exit( EXIT_FAILURE );
}

-----------------------

Whenever I run it, it first blocks on libpcap listening for
packets, after it recieves one it sends the packet to echo_server, where
the appropriate headers are pointed to the correct places in the packet,
so that I can build a response based on the received information. The
code compiles with no problem except that when I run it, libnet_build_udp
returns -1 and the following error message appears:

---
libnet_pblock_find() - couldn't find protocol block
---
Ive googled a bit, and found a few misleading answers none that
solved my problem, so I came here. Hope you guys can help me...

thanks in advance,
--
Victor Lima
Frédéric Raynal
2005-03-01 19:16:23 UTC
Permalink
Post by Victor Lima
void
echo_server ( const unsigned char *packet ) {
...
libnet_t *lnet;
...
udp = libnet_build_udp( ntohs( udp_hdr->uh_dport ),
ntohs( udp_hdr->uh_sport ),
LIBNET_UDP_H + strlen( payload ),
0,
payload,
strlen(payload),
lnet,
udp );
if( udp == -1 ) {
fprintf (stderr, "%s: libnet_build_udp() failed: %s\n",
prefix, libnet_geterror(lnet));
goto bad;
}
-----------------------
Whenever I run it, it first blocks on libpcap listening for
packets, after it recieves one it sends the packet to echo_server, where
the appropriate headers are pointed to the correct places in the packet,
so that I can build a response based on the received information. The
code compiles with no problem except that when I run it, libnet_build_udp
---
libnet_pblock_find() - couldn't find protocol block
---
Ive googled a bit, and found a few misleading answers none that
solved my problem, so I came here. Hope you guys can help me...
Just a try ...

Your udp variable is not initialised. So I guess it is not 0. Hence,
libnet_build_udp() tries to find the pblock referred by this value,
but cant find it.

Try to set udp = 0; during the initialisation, and it should run
properly.

Fred Raynal
Mike Schiffman
2005-03-01 20:53:34 UTC
Permalink
Try initializing the ptag values:

libnet_ptag_t udp, ip;

udp = ip = LIBNET_PTAG_INITIALIZER;
Post by Victor Lima
Hello list,
Im trying to build an application that will forge UDP packets based on
information retrieved by libpcap. The box that I'm using is a FreeBSD
5.3-REL with ports retrieved from the instalation CD. The libnet version
is: libnet-devel-1.1.2.1.
The problem lies somewhere in this code ( or maybe its a bug in libnet
-----------------------
void
echo_server ( const unsigned char *packet ) {
int c;
char errbuf[LIBNET_ERRBUF_SIZE], src[15], dst[15],
*payload = NULL;
libnet_t *lnet;
libnet_ptag_t udp, ip;
struct ip *ip_hdr;
struct udphdr *udp_hdr;
ip_hdr = ( struct ip *) ( packet + size_eth );
udp_hdr = ( struct udphdr *) ( packet + size_eth + size_ip );
payload = ( char *) ( packet + size_eth + size_ip + size_udp );
/* the code break somewhere here... */
if( (lnet = libnet_init( LIBNET_RAW4, NULL, errbuf )) == NULL ) {
fprintf( stderr, "%s: libnet_init() failed: %s\n", prefix,
errbuf);
exit( EXIT_FAILURE );
}
udp = libnet_build_udp( ntohs( udp_hdr->uh_dport ),
ntohs( udp_hdr->uh_sport ),
LIBNET_UDP_H + strlen( payload ),
0,
payload,
strlen(payload),
lnet,
udp );
if( udp == -1 ) {
fprintf (stderr, "%s: libnet_build_udp() failed: %s\n",
prefix, libnet_geterror(lnet));
goto bad;
}
/* to here */
ip = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_UDP_H +
strlen( payload ), 0,
ip_hdr->ip_id,
0,
64,
IPPROTO_UDP,
0,
libnet_name2addr4(lnet, (char *)
inet_ntop(AF_INET, &ip_hdr->ip_dst, dst, sizeof(dst)), LIBNET_RESOLVE),
libnet_name2addr4(lnet, (char *)
inet_ntop(AF_INET, &ip_hdr->ip_src, src, sizeof(src)), LIBNET_RESOLVE),
NULL,
0,
lnet,
ip );
if ( ip == -1 ) {
fprintf( stderr, "%s: libnet_build_ipv4() failed: %s\n",
prefix, libnet_geterror(lnet));
goto bad;
}
if( (c = libnet_write(lnet)) == -1 ) {
fprintf(stderr, "%s: libnet_write() failed: %s\n", prefix,
libnet_geterror(lnet));
goto bad;
}
return;
libnet_destroy( lnet );
exit( EXIT_FAILURE );
}
-----------------------
Whenever I run it, it first blocks on libpcap listening for
packets, after it recieves one it sends the packet to echo_server, where
the appropriate headers are pointed to the correct places in the packet,
so that I can build a response based on the received information. The
code compiles with no problem except that when I run it,
libnet_build_udp
---
libnet_pblock_find() - couldn't find protocol block
---
Ive googled a bit, and found a few misleading answers none that
solved my problem, so I came here. Hope you guys can help me...
thanks in advance,
--
Victor Lima
--
Mike Schiffman, CISSP
http://www.packetfactory.net/schiffman
Doveryay No Proveryay
Mustafa Abu Sedera
2005-03-03 19:21:47 UTC
Permalink
Hi,

I haven't written any code for a long time, but I have some comments, (in
addition to Mike's comments, which solve the cause of the error message you
get). I see some other bugs in the code though.
What I understand here is that you just want so send back the packet to the
originating IP (correct me if i am wrong).

================================================
Post by Victor Lima
udp_hdr = ( struct udphdr *) ( packet + size_eth + size_ip );
are you sure you took the IP header options into consideration in size_ip?

size_ip should not just be 20, it should be size_ip = ip_hdr->ip_hl *4

================================================
Post by Victor Lima
udp = libnet_build_udp( ntohs( udp_hdr->uh_dport ),
ntohs( udp_hdr->uh_sport ),
LIBNET_UDP_H + strlen( payload ), <<<<<
0,
payload,
strlen(payload), <<<<<<<<<<<
lnet,
udp );
You can't just use strlen() here, if there is any byte with the value NULL
before the end of the packet you will not get the real payload length.
Strlen counts the number of chars in a string starting from the first
character in the buffer till the first NULL it sees.

you could get the payload lenght by doing: pkt_length - size_eth - size_ip
- size_udp
pkt_length you get from libpcap hdr structure.

==========================================
Post by Victor Lima
ip = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_UDP_H +
strlen( payload ), 0, <<< agian a
strlen()!!
ip_hdr->ip_id,
0,
64,
IPPROTO_UDP,
0,
libnet_name2addr4(lnet, (char *) <<<<<<
inet_ntop(AF_INET, &ip_hdr->ip_dst, dst, sizeof(dst)), LIBNET_RESOLVE),
libnet_name2addr4(lnet, (char *)
inet_ntop(AF_INET, &ip_hdr->ip_src, src, sizeof(src)), <<<<<<
LIBNET_RESOLVE),
NULL,
0,
lnet,
ip );
if you are just trying to put the src IP of the captured into the dest IP
and vice versa you can grab them directly by acessing the value in the
ip_hdr struct: ip_hdr->ip_src.s_addr.

actually the struct in_addr has no more than a 4 byte unsigned integer as a
member. so u can use it directly withoiut doing this painful turnaround :)

==============================================

I hope I could help a little.

Regards,
Mustaffa
Subject: Re: FreeBSD libnet_pblock_find() problem
Date: Tue, 1 Mar 2005 12:53:34 -0800
libnet_ptag_t udp, ip;
udp = ip = LIBNET_PTAG_INITIALIZER;
Post by Victor Lima
Hello list,
Im trying to build an application that will forge UDP packets based on
information retrieved by libpcap. The box that I'm using is a FreeBSD
5.3-REL with ports retrieved from the instalation CD. The libnet version
is: libnet-devel-1.1.2.1.
The problem lies somewhere in this code ( or maybe its a bug in libnet
Whenever I run it, it first blocks on libpcap listening for
packets, after it recieves one it sends the packet to echo_server, where
the appropriate headers are pointed to the correct places in the packet,
so that I can build a response based on the received information. The
code compiles with no problem except that when I run it,
libnet_build_udp
---
libnet_pblock_find() - couldn't find protocol block
---
Ive googled a bit, and found a few misleading answers none that
solved my problem, so I came here. Hope you guys can help me...
thanks in advance,
--
Victor Lima
--
Mike Schiffman, CISSP
http://www.packetfactory.net/schiffman
Doveryay No Proveryay
Loading...