Annotation of embedaddon/libnet/doc/MIGRATION.md, revision 1.1
1.1 ! misho 1: Migrating Your Code to libnet 1.1 or Later
! 2: ==========================================
! 3: by Mike D. Schiffman <mike@infonexus.com>
! 4:
! 5: Using Libnet 1.1 you will find it MUCH simpler to build and write packets than
! 6: before. Instead of the previous five steps (initialize memory, initialize
! 7: network, build packet, do checksums, write packet) there are now only three
! 8: steps (initialize library, build packet, write packet).
! 9:
! 10: In order to port your existing code, you will mainly be *removing* function
! 11: calls and variables.
! 12:
! 13:
! 14: Cleanup
! 15: -------
! 16:
! 17: Start with code removal:
! 18:
! 19: - Remove all calls to `libnet_init_packet()` packet `malloc()`ing, and all
! 20: associated variables
! 21: - Remove all calls to `libnet_open_raw_sock()`, `libnet_open_link_layer()`,
! 22: and all associated variables
! 23: - Remove all calls to `libnet_do_checksum()` and all associated variables
! 24:
! 25:
! 26: Code Changes
! 27: ------------
! 28:
! 29: Continue with code addition and modification.
! 30:
! 31: You will need a single `libnet_t *l` which is your libnet file context and an
! 32: error buffer:
! 33:
! 34: libnet_t *l
! 35: char errbuf[LIBNET_ERRBUF_SIZE];
! 36:
! 37: l = libnet_init(
! 38: LIBNET_RAW4, /* or LIBNET_LINK or LIBNET_RAW6 */
! 39: NULL, /* or device if you using LIBNET_LINK */
! 40: errbuf);
! 41:
! 42: The `libnet_build_*()` functions are largely unchanged with a few important
! 43: differences:
! 44:
! 45: 1. Packets headers *MUST* be stacked *IN ORDER*. This is intuitive and
! 46: shouldn't be a problem. Due to the way individual packet header memory is
! 47: allocated and how packet pieces are combined to build a packet they *HAVE*
! 48: to be built *IN ORDER*, from the high end of the protocol stack on down.
! 49: i.e.: using the raw interface to build a NTP packet, you would:
! 50:
! 51: libnet_build_ntp(...)
! 52: libnet_build_udp(...)
! 53: libnet_build_ipv4(...)
! 54:
! 55: To build the same packet using the LINK interface on top of ethernet you
! 56: would:
! 57:
! 58: libnet_build_ntp(...)
! 59: libnet_build_udp(...)
! 60: libnet_build_ipv4(...)
! 61: libnet_build_ethernet(...)
! 62:
! 63: > **Note:** There is the option now of using `libnet_autobuild_ipv4()` and
! 64: > `libnet_autobuild_ethernet()` which have fewer arguments and smaller
! 65: > stack frames, and are a bit more convenient.
! 66:
! 67: 2. The `libnet_build_*()` functions return a `libnet_ptag_t` datatype on
! 68: success or -1 on error. This ptag is your "protocol/packet tag" so you can
! 69: find this header again if you needed to modify it later on. If you don't
! 70: need to modify the packet header you can throw this value away. You should
! 71: definitely check for error now on your build functions. A lot's going on
! 72: down there fellas.
! 73:
! 74: > **Note:** that after packets are built, they may be accessed
! 75: > independently of construction order via the saved ptag.
! 76:
! 77: 3. They *NO LONGER ACCEPT BUFFER ARGUMENTS*. This is *ALL* done internally.
! 78: The last *TWO* arguments are the libnet context you created in your call to
! 79: `libnet_init()` and an *OPTIONAL* ptag argument. The ptag argument, if
! 80: non-zero, specifes a packet tag to an *ALREADY EXISTING* packet header that
! 81: will be *OVERWRITTEN* with the values specified in this `libnet_build_*()`
! 82: function call. This is how you modify existing packet header pieces. If
! 83: this ptag is 0, a new protocol block is allocated and the packet is pushed
! 84: down on the "protocol stack".
! 85: 4. For the functions that build headers that have checksums these are *NOW
! 86: SPECIFIED AS AN ARGUMENT*. This adds more flexibility in how checksums are
! 87: done (you can leave the field 0, put in a random value, precompute it on
! 88: your own, or let the library do it). By default, when you build a header,
! 89: a `DO_CHECKSUM` flag will be set. This means the library will compute the
! 90: checksum for the header and possibly over the data before the packet is
! 91: written. To clear this flag, there is a special macro you can call on the
! 92: ptag refering to that header.
! 93: 5. For the functions that have a length, it now specifies the *TOTAL* packet
! 94: length from that protocol unit on down. For IP, that would be the entire
! 95: packet length. For TCP, that would be TCP and any possible data.
! 96: 6. Nomenclature support for the eventual support of ipv6 has been added.
! 97:
! 98: ### Example
! 99:
! 100: libnet_ptag_t ip_tag;
! 101: libnet_ptag_t tcp_tag;
! 102:
! 103: tcp_tag = libnet_build_tcp(
! 104: src_prt, /* source TCP port */
! 105: dst_prt, /* destination TCP port */
! 106: 0xffff, /* sequence number */
! 107: 0x53, /* acknowledgement number */
! 108: TH_SYN, /* control flags */
! 109: 1024, /* window size */
! 110: 0xd00d, /* checksum */
! 111: 0, /* urgent pointer */
! 112: LIBNET_TCP_H /* TCP packet size */
! 113: NULL, /* payload (none) */
! 114: 0, /* payload length */
! 115: l, /* libnet context */
! 116: 0); /* ptag */
! 117:
! 118: ip_tag = libnet_build_ipv4(
! 119: LIBNET_TCP_H + LIBNET_IPV4_H,/* total packet len */
! 120: IPTOS_LOWDELAY, /* tos */
! 121: ip_id, /* IP ID */
! 122: 0, /* IP Frag */
! 123: 64, /* TTL */
! 124: IPPROTO_TCP, /* protocol */
! 125: 0, /* checksum */
! 126: src_ip, /* source ip */
! 127: dst_ip, /* dest ip */
! 128: NULL, /* payload (none) */
! 129: 0, /* payload size */
! 130: l, /* libnet context */
! 131: 0); /* ptag */
! 132:
! 133: Now, if you wanted to modify one of these headers in a loop somewhere you
! 134: would:
! 135:
! 136: int i;
! 137: for (ip_tag, tcp_tag = LIBNET_PTAG_INITIALIZER, i = 0; i < 10; i++)
! 138: {
! 139: tcp_tag = libnet_build_tcp(++src_prt, ..., l, tcp_tag);
! 140: ip_tag = libnet_build_ipv4(..., ++ip_id, ..., l, ip_tag);
! 141: /* do something */
! 142: }
! 143:
! 144: Since we are specifying a ptag for an existing header, the build function will
! 145: NOT create a new header and append it to the list, it will FIND the one
! 146: referenced by the ptag and *UPDATE* it. Since there is nothing new being
! 147: created, order is NOT important here.
! 148:
! 149: Also note that it's perfectly fine to wrap the loop around the initial
! 150: building of the packets. Since we're initializing the ptags (to be zero), the
! 151: first call into the builder functions will allocate the memory and create the
! 152: packet blocks. These calls will return ptag values. The next calls will
! 153: modify these headers since the ptags will not be NULL.
! 154:
! 155: ### Writing the Packet
! 156:
! 157: Finally, we write the packet. Checksums are computed, by default for each
! 158: protocol header that requires one. If the user specifies a non-zero value, by
! 159: default, this will be used *INSTEAD* of a libnet computed checksum. This
! 160: behavior is possible to override with:
! 161:
! 162: Turn ON checksums for header referenced by ptag:
! 163:
! 164: libnet_toggle_checksum(l, ptag, 1)
! 165:
! 166: Turn OFF checksums for header referenced by ptag:
! 167:
! 168: libnet_toggle_checksum(l, ptag, 0)
! 169:
! 170: Note, the packet header MUST exist before you can toggle this setting.
! 171:
! 172: int c;
! 173: c = libnet_write(l);
! 174:
! 175: Boom. You're done. Now go read the sample code.
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>