|
Packit |
03b34a |
===============================================================================
|
|
Packit |
03b34a |
$Id: MIGRATION,v 1.2 2004/01/03 20:31:00 mike Exp $
|
|
Packit |
03b34a |
LIBNET 1.1 (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
|
|
Packit |
03b34a |
http://www.packetfactory.net/libnet
|
|
Packit |
03b34a |
===============================================================================
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
MIGRATING YOUR CODE AND QUICKSTART
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
Using Libnet 1.1 you will find it MUCH simpler to build and write packets
|
|
Packit |
03b34a |
than before. Instead of the previous five steps (initialize memory,
|
|
Packit |
03b34a |
initialize network, build packet, do checksums, write packet) there are
|
|
Packit |
03b34a |
now only three steps (initialize library, build packet, write packet).
|
|
Packit |
03b34a |
In order to port your existing code, you will mainly be REMOVING
|
|
Packit |
03b34a |
function calls and variables.
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
1) Start with code removal:
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
- Remove all calls to libnet_init_packet() / packet malloc()ing and
|
|
Packit |
03b34a |
all associated variables.
|
|
Packit |
03b34a |
- Remove all calls to libnet_open_raw_sock() / libnet_open_link_layer()
|
|
Packit |
03b34a |
and all associated variables.
|
|
Packit |
03b34a |
- Remove all calls to libnet_do_checksum() and all associated
|
|
Packit |
03b34a |
variables.
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
2) Continue with code addition and modification:
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
- You will need a single "libnet_t *l" which is your libnet file
|
|
Packit |
03b34a |
context and an error buffer:
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
libnet_t *l
|
|
Packit |
03b34a |
char errbuf[LIBNET_ERRBUF_SIZE];
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
l = libnet_init(
|
|
Packit |
03b34a |
LIBNET_RAW4, /* or LIBNET_LINK or LIBNET_RAW6 */
|
|
Packit |
03b34a |
NULL, /* or device if you using LIBNET_LINK */
|
|
Packit |
03b34a |
errbuf);
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
- The libnet_build functions are largely unchanged with a few
|
|
Packit |
03b34a |
important differences:
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
1) Packets headers MUST be stacked IN ORDER. This is
|
|
Packit |
03b34a |
intuitive and shouldn't be a problem. Due to the way
|
|
Packit |
03b34a |
individual packet header memory is allocated and how
|
|
Packit |
03b34a |
packet pieces are combined to build a packet they HAVE to
|
|
Packit |
03b34a |
be built IN ORDER, from the high end of the protocol stack
|
|
Packit |
03b34a |
on down. ie: using the raw interface to build a NTP
|
|
Packit |
03b34a |
packet, you would:
|
|
Packit |
03b34a |
libnet_build_ntp(...)
|
|
Packit |
03b34a |
libnet_build_udp(...)
|
|
Packit |
03b34a |
libnet_build_ipv4(...)
|
|
Packit |
03b34a |
To build the same packet using the LINK interface on
|
|
Packit |
03b34a |
top of ethernet you would:
|
|
Packit |
03b34a |
libnet_build_ntp(...)
|
|
Packit |
03b34a |
libnet_build_udp(...)
|
|
Packit |
03b34a |
libnet_build_ipv4(...)
|
|
Packit |
03b34a |
libnet_build_ethernet(...)
|
|
Packit |
03b34a |
1a) There is the option now of using libnet_autobuild_ipv4()
|
|
Packit |
03b34a |
and libnet_autobuild_ethernet() which have fewer
|
|
Packit |
03b34a |
arguments and smaller stack frames and are a bit more
|
|
Packit |
03b34a |
convenient.
|
|
Packit |
03b34a |
2) The libnet_build functions return a libnet_ptag_t datatype
|
|
Packit |
03b34a |
on success or -1 on error. This ptag is your
|
|
Packit |
03b34a |
"protocol/packet tag" so you can find this header again
|
|
Packit |
03b34a |
if you needed to modify it later on. If you don't need
|
|
Packit |
03b34a |
to modify the packet header you can throw this value
|
|
Packit |
03b34a |
away. You should definitely check for error now on
|
|
Packit |
03b34a |
your build functions. Alot's going on down there fellas.
|
|
Packit |
03b34a |
2a) NOTE that after packets are built, they may accessed
|
|
Packit |
03b34a |
independently of construction order via the saved ptag.
|
|
Packit |
03b34a |
3) They NO LONGER ACCEPT BUFFER ARGUMENTS. This is ALL
|
|
Packit |
03b34a |
done internally. The last TWO arguments are the libnet
|
|
Packit |
03b34a |
context you created in your call to libnet_init() and
|
|
Packit |
03b34a |
an OPTIONAL ptag argument. The ptag argument, if non-zero,
|
|
Packit |
03b34a |
specifes a packet tag to an ALREADY EXISTING packet header
|
|
Packit |
03b34a |
that will be OVERWRITTEN with the values specified in
|
|
Packit |
03b34a |
this libnet_build function call. This is how you modify
|
|
Packit |
03b34a |
existing packet header pieces. If this ptag is 0,
|
|
Packit |
03b34a |
a new protocol block is allocated and the packet is
|
|
Packit |
03b34a |
pushed down on the "protocol stack".
|
|
Packit |
03b34a |
4) For the functions that build headers that have checksums
|
|
Packit |
03b34a |
these are NOW SPECIFIED AS AN ARGUMENT. This adds more
|
|
Packit |
03b34a |
flexibility in how checksums are done (you can leave the
|
|
Packit |
03b34a |
field 0, put in a random value, precompute it on your own,
|
|
Packit |
03b34a |
or let the library do it). By default, when you build
|
|
Packit |
03b34a |
a header, a "DO_CHECKSUM" flag will be set. This means
|
|
Packit |
03b34a |
the library will compute the checksum for the header
|
|
Packit |
03b34a |
and possibly over the data before the packet is written.
|
|
Packit |
03b34a |
To clear this flag, there is a special macro you
|
|
Packit |
03b34a |
can call on the ptag refering to that header.
|
|
Packit |
03b34a |
5) For the functions that have a length, it now specifies
|
|
Packit |
03b34a |
the TOTAL packet length from that protocol unit on down.
|
|
Packit |
03b34a |
For IP, that would be the entire packet length. For
|
|
Packit |
03b34a |
TCP, that would be TCP and any possible data.
|
|
Packit |
03b34a |
6) Nomenclature support for the eventual support of ipv6
|
|
Packit |
03b34a |
has been added.
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
libnet_ptag_t ip_tag;
|
|
Packit |
03b34a |
libnet_ptag_t tcp_tag;
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
tcp_tag = libnet_build_tcp(
|
|
Packit |
03b34a |
src_prt, /* source TCP port */
|
|
Packit |
03b34a |
dst_prt, /* destination TCP port */
|
|
Packit |
03b34a |
0xffff, /* sequence number */
|
|
Packit |
03b34a |
0x53, /* acknowledgement number */
|
|
Packit |
03b34a |
TH_SYN, /* control flags */
|
|
Packit |
03b34a |
1024, /* window size */
|
|
Packit |
03b34a |
0xd00d, /* checksum */
|
|
Packit |
03b34a |
0, /* urgent pointer */
|
|
Packit |
03b34a |
LIBNET_TCP_H /* TCP packet size */
|
|
Packit |
03b34a |
NULL, /* payload (none) */
|
|
Packit |
03b34a |
0, /* payload length */
|
|
Packit |
03b34a |
l, /* libnet context */
|
|
Packit |
03b34a |
0); /* ptag */
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
ip_tag = libnet_build_ipv4(
|
|
Packit |
03b34a |
LIBNET_TCP_H + LIBNET_IPV4_H,/* total packet len */
|
|
Packit |
03b34a |
IPTOS_LOWDELAY, /* tos */
|
|
Packit |
03b34a |
ip_id, /* IP ID */
|
|
Packit |
03b34a |
0, /* IP Frag */
|
|
Packit |
03b34a |
64, /* TTL */
|
|
Packit |
03b34a |
IPPROTO_TCP, /* protocol */
|
|
Packit |
03b34a |
0, /* checksum */
|
|
Packit |
03b34a |
src_ip, /* source ip */
|
|
Packit |
03b34a |
dst_ip, /* dest ip */
|
|
Packit |
03b34a |
NULL, /* payload (none) */
|
|
Packit |
03b34a |
0, /* payload size */
|
|
Packit |
03b34a |
l, /* libnet context */
|
|
Packit |
03b34a |
0); /* ptag */
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
Now, if you wanted to modify one of these headers in a loop
|
|
Packit |
03b34a |
somewhere you would:
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
int i;
|
|
Packit |
03b34a |
for (ip_tag, tcp_tag = LIBNET_PTAG_INITIALIZER, i = 0; i < 10; i++)
|
|
Packit |
03b34a |
{
|
|
Packit |
03b34a |
tcp_tag = libnet_build_tcp(++src_prt, ..., l, tcp_tag);
|
|
Packit |
03b34a |
ip_tag = libnet_build_ipv4(..., ++ip_id, ..., l, ip_tag);
|
|
Packit |
03b34a |
/* do something */
|
|
Packit |
03b34a |
}
|
|
Packit |
03b34a |
Since we are specifying a ptag for an existing header, the
|
|
Packit |
03b34a |
build function will NOT create a new header and append it to
|
|
Packit |
03b34a |
the list, it will FIND the one referenced by the ptag and UPDATE
|
|
Packit |
03b34a |
it. Since there is nothing new being created, order is NOT
|
|
Packit |
03b34a |
important here.
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
Also note that it's perfectly fine to wrap the loop around the
|
|
Packit |
03b34a |
initial building of the packets. Since we're initializing the
|
|
Packit |
03b34a |
ptags (to be zero), the first call into the builder functions
|
|
Packit |
03b34a |
will allocate the memory and create the packet blocks. These
|
|
Packit |
03b34a |
calls will return ptag values. The next calls will modify
|
|
Packit |
03b34a |
these headers since the ptags will not be NULL.
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
- Finally, we write the packet. Checksums are computed, by default
|
|
Packit |
03b34a |
for each protocol header that requires one. If the user specifies
|
|
Packit |
03b34a |
a non-zero value, by default, this will be used INSTEAD of a
|
|
Packit |
03b34a |
libnet computed checksum. This behavior is overridable with:
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
Turn ON checksums for header referenced by ptag:
|
|
Packit |
03b34a |
libnet_toggle_checksum(l, ptag, 1)
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
Turn OFF checksums for header referenced by ptag:
|
|
Packit |
03b34a |
libnet_toggle_checksum(l, ptag, 0)
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
Note, the packet header MUST exist before you can toggle this setting.
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
int c;
|
|
Packit |
03b34a |
c = libnet_write(l);
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
Boom. You're done. Now go read the sample code.
|
|
Packit |
03b34a |
|
|
Packit |
03b34a |
EOF
|