Annotation of embedaddon/libnet/doc/DESIGN_NOTES, revision 1.1
1.1 ! misho 1: ===============================================================================
! 2: $Id: DESIGN_NOTES,v 1.3 2004/01/17 07:51:19 mike Exp $
! 3: LIBNET 1.1 (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
! 4: http://www.packetfactory.net/libnet
! 5: ===============================================================================
! 6:
! 7:
! 8: DESIGN NOTES
! 9:
! 10: In order to remove most of the decisions a user had to make (how much
! 11: memory to allocate for a packet, where to build the packet headers, where
! 12: to do the checksums, how to inject the packet, etc) I decided to move ALL
! 13: of that logic into the library, behind the scenes. To initialize
! 14: things and get an initial libnet context, the applications programmer
! 15: calls:
! 16:
! 17: libnet_t *l;
! 18: l = libnet_init(INJECTION_TYPE, PROTOCOL, DEVICE, ERRBUFFER);
! 19:
! 20: where:
! 21:
! 22: INJECTION_TYPE = LIBNET_RAW4 (ipv4 raw socket)
! 23: LIBNET_RAW6 (ipv6 raw socket)
! 24: LIBNET_LINK (link-layer socket)
! 25: LIBNET_RAW4_ADV (advanced mode)
! 26: LIBNET_RAW6_ADV (advanced mode)
! 27: LIBNET_LINK_ADV (advanced mode)
! 28:
! 29: PROTOCOL = IP protocol to be used for the raw socket. This is
! 30: ignored for the link-layer, and almost always
! 31: IPPROTO_RAW for ipv4.
! 32:
! 33: DEVICE = The canoical name of the device, used only with the link
! 34: layer stuff. For ipv4 raw socket, you can leave this
! 35: NULL. If it's NULL with the link-layer, libnet will try
! 36: to find a suitable device.
! 37:
! 38: ERRBUFFER = Until we have our libnet context l, this is where
! 39: errors will be.
! 40:
! 41: Inside of this newly created context we have a ton of stuff including a
! 42: file descriptor for the packet device the injection type, the device name
! 43: (if applicable) a pointer to the libnet protocol block structure and some
! 44: other ancillary data.
! 45:
! 46: Additionally, we will soon be supporting context manipulation functions
! 47: that will allow the user to set certain flags inside the context. This
! 48: interface will be akin to libnet_toggle_checksum() for those of you who
! 49: care.
! 50:
! 51: When a packet is first constructed, the protocol block (pblock) stuff comes
! 52: into play. On the outside, to an applications programmer, a packet is
! 53: constructed more or less like normal (with a few notable exceptions):
! 54:
! 55: libnet_ptag_t ip_tag;
! 56: ip_tag = libnet_build_ipv4(
! 57: LIBNET_UDP_H,
! 58: 0,
! 59: 242,
! 60: 0,
! 61: 64,
! 62: IPPROTO_UDP,
! 63: 0, /* NEW: checksum */
! 64: src_ip,
! 65: dst_ip,
! 66: NULL,
! 67: 0,
! 68: l, /* NEW: libnet context */
! 69: 0 /* NEW: libnet ptag */
! 70: );
! 71:
! 72: The checksum allows an applications programmer to decide if he wants to
! 73: specify his own random value (useful in NIDS fooling) or precompute the
! 74: sum elsewhere, or leave it zero and by default libnet will take care of it
! 75: (although this is over-ridable). The libnet context is the opague
! 76: pointer we allocated earlier and will show up in just about every libnet
! 77: function call from here on out. The libnet ptag is a way to reference an
! 78: ALREADY BUILT protocol block. This is necessary if you want to change
! 79: some values of a header inside of a packet injection loop.
! 80:
! 81: So, when you call a build function, internally, it's a completely new
! 82: system. If the item you're constructing is NEW, a new pblock will be
! 83: allocated and linked onto the end of the list. It may be helpful to think
! 84: of this as a "protocol stack" because you MUST build your packets IN
! 85: ORDER, from the top of the protocol stack on down (i.e.: tcp -> ip ->
! 86: ethernet). Once you build a new protocol block, it's "pushed down on the
! 87: stack" and you move on to the next. However, this analogy breaks down
! 88: because you can modify any one of these items and when they're assembled
! 89: for the final packet, libnet starts at the head of the list. It may be
! 90: MORE helpful to think of the pblock chain as a doubly linked FIFO
! 91: queue, because that's what it is. :)
! 92:
! 93: For example:
! 94:
! 95: libnet_ptag_t 1;
! 96: libnet_ptag_t 2;
! 97: libnet_ptag_t 3;
! 98:
! 99: 1 = libnet_build_data(blah, l, 0);
! 100: 2 = libnet_build_tcp(blah, l, 0);
! 101: 3 = libnet_build_ipv4(blah, l, 0);
! 102:
! 103: Will result in:
! 104: ---------- ---------- ----------
! 105: l->protocol_blocks--->| data |----->| tcp |----->| ip |
! 106: | pblock |<-----| pblock |<-----| pblock |----|
! 107: --| ptag: 1| | ptag: 2| | ptag: 3| |
! 108: | ---------- ---------- ---------- v
! 109: | -----
! 110: |-------------------------------------------> ---
! 111: -
! 112:
! 113: To access and change the ip header, an additional call to libnet_build_ipv4
! 114: with the ptag argument would be made:
! 115:
! 116: libnet_build_ipv4(blah..., l, 3);
! 117:
! 118: Note that the ptag DOES NOT CHANGE. Once a pblock is built, its tag is
! 119: set in stone.
! 120:
! 121: When it comes time to write the packet to the wire,
! 122: libnet_pblock_coalesce() is called to assemble the packet fragments.
! 123:
! 124: 1) Gather up all of the pblock sizes in order to allocate one
! 125: contiguous block of memory.
! 126: 2) Copy over the packet fragments.
! 127: 3) Check each pblock to see which items need checksums, then perform
! 128: that checksum over each portion (the entire packet is needed for
! 129: some checksums).
! 130:
! 131: So that's a quick description of what's going on under the hood. There's
! 132: more, but this should be enough to get you started.
! 133:
! 134: EOF
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>