Do bounds checking and length checking.

Don't run past the end of the captured data, and don't run past the end
of the packet (i.e., don't make the length variable go negative).
Do more bounds checking and length checking.

Don't run past the end of the captured data, and don't run past the end
of the packet (i.e., don't make the length variable go negative).

Also, stop dissecting if the message length isn't valid.
Add initial bounds check, get rid of union aodv.

Fetch the type field without using a structure, and check to make sure
it's not past the end of the packet.

Pass to each dissection routine a pointer to the appropriate message
type structure, rather than a pointer to a union of all the message type
structures.
Clean up error message printing.

Have "struct aodv_rerr" just be the header, not including the actual
destinations.

Simplify the logic somewhat, and make it similar in the print routines
for the three types of error messages.
Further cleanups.

Use ND_TCHECK() rather than home-brew bounds checks.  Do simpler length
checks.

Let i be the length of the actual remaining packet data; use ND_TCHECK()
inside loops that iterate over the remaining data.

Let the printers for particular message types cast the raw data pointer
to a pointer of the appropriate type, rather than passing two pointers,
with different types, to the same data.
Not using offsetof() any more, so no need for <stddef.h>.
Report a too-long unreachable destination list.

Running out of packet length before running out of unreachable
destinations is an error; report it as such.

Don't worry about leftover data past the end of the list of unreachable
destinations.