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>