1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML
><HEAD
><TITLE
>Introduction</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="libpcapnav Manual"
HREF="index.html"><LINK
REL="PREVIOUS"
TITLE="libpcapnav Manual"
HREF="index.html"><LINK
REL="NEXT"
TITLE="Using libpcapnav"
HREF="c61.html"><LINK
REL="STYLESHEET"
TYPE="text/css"
HREF="stylesheet.css"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
><CODE
CLASS="FUNCTION"
>libpcapnav</CODE
> Manual</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="index.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c61.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="AEN17"
></A
>Introduction</H1
><DIV
CLASS="TOC"
><DL
><DT
><B
>Table of Contents</B
></DT
><DT
><A
HREF="c17.html#AEN21"
>What is <CODE
CLASS="FUNCTION"
>libpcapnav</CODE
>?</A
></DT
><DT
><A
HREF="c17.html#AEN30"
>How does it work?</A
></DT
></DL
></DIV
><P
> Welcome! You're looking at the manual for <CODE
CLASS="FUNCTION"
>libpcapnav</CODE
>. Thanks for reading this.
</P
><BR
CLEAR="all"><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="AEN21"
>What is <CODE
CLASS="FUNCTION"
>libpcapnav</CODE
>?</A
></H1
><P
> <CODE
CLASS="FUNCTION"
>libpcapnav</CODE
> is a <CODE
CLASS="FUNCTION"
>libpcap</CODE
> wrapper library that allows navigation to
arbitrary locations in a <CODE
CLASS="FUNCTION"
>tcpdump</CODE
> trace file between reads.
The API is intentionally much like that of the pcap library.
You can navigate in trace files both in time and space: you
can jump to a packet which is at appr. 2/3 of the trace, or
you can jump as closely as possible to a packet with a given
timestamp, and then read packets from there. In addition, the
API provides convenience functions for manipulating timeval
structures.
</P
><P
> Like <CODE
CLASS="FUNCTION"
>libpcap</CODE
>, this library handles things through an opaque
handle struct. For trace file navigation and reading packets,
this handle is enough. If you need to apply BPF filters or
write packets to disk, you can access the familiar pcap
handle that is used internally.
</P
></DIV
><BR
CLEAR="all"><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="AEN30"
>How does it work?</A
></H1
><P
> At the core of <CODE
CLASS="FUNCTION"
>libpcapnav</CODE
> is the ability to resynchronize to
the sequence of packets contained in a <CODE
CLASS="FUNCTION"
>tcpdump</CODE
> trace file
at arbitrary location of the file position indicator. The
algorithm is based on Vern Paxson's method from the the <CODE
CLASS="FUNCTION"
>tcpslice</CODE
>
tool, that basically works as follows: the point near which the
file position indicator is to be synchronized with the packet
sequence is undershot a little bit, as it is much easier to
scan forwards to the desired location, once the packet sequence
has been detected. The file is scanned from that initial
offset in single-byte steps, at each step assuming a <CODE
CLASS="FUNCTION"
>libpcap</CODE
>
packet header is present and sanity-checking the values read.
Several checks analyze this potential header for sane timestamps,
capture lengths etc. If the header appears valid, the next
packet header is examined in a similar function, based upon
the offset that the checked header provides. If a sequence
of three packets seems valid, the algorithm considers the
file position pointer to be synchronized with the packet flow
and scans as closely as possible to the desired location.
If the synchronization point is supposed to be a packet with
a given timestamp, some interpolation is done and the process
repeated, until the packet closest to the desired timestamp
has been found.
</P
><P
> <CODE
CLASS="FUNCTION"
>libpcapnav</CODE
>'s algorithm contains a few modifications that are explained
in gory detail in the Netdude
<A
HREF="http://netdude.sourceforge.net/doco/netdude-freenix2004/index.html"
TARGET="_top"
>Freenix paper</A
>,
and briefly listed here:
</P
><P
></P
><UL
><LI
><P
> <CODE
CLASS="FUNCTION"
>libpcapnav</CODE
> doesn't use Vern's state-machine approach to determine
definitive header matches. I've done a lot of my
testing with a trace that was captured while NFS-copying
another trace file, thus containing lots of "bogus" headers
to make things fun, and I've seen a number of problems in
this case. This data causes a number of nasty problems, such as
large snaplens in the captured data (where a single packet
may contain many smaller packets) or payload packets that
have a caplen that causes the next packet to be read
directly from the next valid header.
Much of this should be handled through invalid timestamps,
but this is not 100% reliable.
</P
><P
> To rectify this, pcapnav uses a different approach: once
a header is found that does not instantly appear to be
invalid, the chain of packets that it starts is followed, up
to a maximum number of packets or until we're out of buffer
space.
</P
><P
> For this, buffers already containing data loaded from disk
are used as much as possible, but when this buffer doesn't
suffice, more data is loaded from disk. The hope is that
most attempts will point to invalid headers anyway so that
this additional load never happens unless we have good
reason to believe we've actually found a good header. The
difference between <CODE
CLASS="CONSTANT"
>PCAPNAV_PERHAPS</CODE
> and
<CODE
CLASS="CONSTANT"
>PCAPNAV_DEFINITELY</CODE
> (explained in detail
later in this document)
is then based on the length of the chain found.
</P
><P
> While checking headers, the best valid header (ie the one
with the longest chain) is remembered, as well as the offset
in the trace that'll be the successor of this packet,
so that it isn't confused with a "new" good header.
</P
><P
> The fun part without doubt are header clashes. A clash in
this new system occurs when two headers have the same,
maximum, chain length and the same level of reliability
of the chain lengths (eg, the chain search could have been
stopped because we were out of buffer space or because we
have hit the limit of packets we check — the latter is
considered more reliable).
</P
><P
> If we hit a clash, we simply forget the old best match and
keep looking after the clash packet. If we cannot find any
better headers afterwards, we return a clash, otherwise the
best match found afterwards.
</P
></LI
><LI
><P
> I've seen traces with rather strange final packet headers,
containing invalid caplen/len field values and packet data.
To make sure we don't miss the last few correct packet
headers, I've added some padding space and thus start
looking for the last packet in the trace a bit earlier
in the file. As the last-packet timestamp and offset is
buffered in the pcapnav_t handle anyway, this performance
hit is probably negligible.
</P
></LI
><LI
><P
> To find the last packet in a trace, we now go back a lot
more from the end of a trace, then find a packet more
reliably by using the chain approach described above,
and then use pcap to iterate to the last valid packet.
Slower, but safer.
</P
></LI
><LI
><P
> A buffer abstraction was introduced to help reduce the
number of local variables and parameters to functions.
See <TT
CLASS="FILENAME"
>pcapnav_buf.h</TT
>.
</P
></LI
><LI
><P
> The original tcpslice version used the <CODE
CLASS="CONSTANT"
>PACKET_HDR_LEN</CODE
> macro,
yielding the size of a struct pcap_pkthdr, even when the
trace file at hand actually uses the extended, larger
patched headers.
</P
></LI
></UL
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c61.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><CODE
CLASS="FUNCTION"
>libpcapnav</CODE
> Manual</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
> </TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Using <CODE
CLASS="FUNCTION"
>libpcapnav</CODE
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>
|