source: lib/libtrace.h @ 5bbe424

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 5bbe424 was 5bbe424, checked in by Daniel Lawson <dlawson@…>, 15 years ago

added vlan support

  • Property mode set to 100644
File size: 20.4 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2004 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *         
8 * All rights reserved.
9 *
10 * This code has been developed by the University of Waikato WAND
11 * research group. For further information please see http://www.wand.net.nz/
12 *
13 * libtrace is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * libtrace is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with libtrace; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 * $Id$
28 *
29 */
30
31#ifndef LIBTRACE_H
32#define LIBTRACE_H
33
34#include <sys/types.h>
35#include <netinet/in.h>
36
37/** API version as 3 byte hex digits, eg 0xXXYYZZ */
38#define LIBTRACE_API_VERSION 0x100014
39
40#ifdef __cplusplus
41extern "C" { 
42#endif
43/** @file
44 *
45 * @brief Trace file processing library header
46 *
47 * @author Daniel Lawson
48 * @author Perry Lorier
49 *
50 * @version $Id$
51 *
52 * This library provides a per packet interface into a trace file, or a live
53 * captures.  It supports ERF, DAG cards, WAG cards, WAG's event format,
54 * pcap etc.
55 *
56 * @par Usage
57 * <ol>
58 * <li> include "libtrace.h"
59 * <li> call create_trace with the uri of the trace you're interested in.<br>
60 * This is usually passed in as argv[1] to your program.
61 * <li> call libtrace_read_packet(), passing in the libtrace_t returned from
62 * create trace and a buffer (and the buffer length)
63 * <li> call getIP() on the buffer, and do whatever you need
64 * <li> loop back to step 3, until libtrace_read_packet() returns -1
65 * </ol>
66 * @par Linking
67 * To use this library you need to link against libtrace by passing -ltrace
68 * to your linker. You may also need to link against a version of libpcap
69 * and of zlib which are compiled for largefile support (if you wish to access
70 * traces larger than 2 GB). This is left as an exercise for the reader. Debian
71 * Woody, at least, does not support large file offsets.
72 *
73 */
74
75#define COLLECTOR_PORT 3435
76
77       
78/** Opaque structure holding information about an output trace */
79struct libtrace_out_t;
80       
81/** Opaque structure holding information about a trace */
82struct libtrace_t;
83       
84/** Opaque structure holding information about a bpf filter */
85struct libtrace_filter_t;
86
87/** Opaque structure holding information about a packet */
88#define LIBTRACE_PACKET_BUFSIZE 65536
89struct libtrace_packet_t {
90        struct libtrace_t *trace;
91        //void *buffer;
92        char buffer[LIBTRACE_PACKET_BUFSIZE];
93        size_t size;
94        uint8_t status;
95};
96
97/** Enumeration of error codes */
98enum {E_NOERROR, E_BAD_FORMAT, E_NO_INIT, E_NO_INIT_OUT, E_URI_LONG, E_URI_NOCOLON, E_INIT_FAILED };
99
100/** Structure for dealing with IP packets */
101struct libtrace_ip
102  {
103#if BYTE_ORDER == LITTLE_ENDIAN
104    unsigned int ip_hl:4;               /**< header length */
105    unsigned int ip_v:4;                /**< version */
106#elif BYTE_ORDER == BIG_ENDIAN
107    unsigned int ip_v:4;                /**< version */
108    unsigned int ip_hl:4;               /**< header length */
109#else
110#   error "Adjust your <bits/endian.h> defines"
111#endif
112    u_int8_t ip_tos;                    /**< type of service */
113    u_short ip_len;                     /**< total length */
114    u_short ip_id;                      /**< identification */
115    u_short ip_off;                     /**< fragment offset field */
116#define IP_RF 0x8000                    /**< reserved fragment flag */
117#define IP_DF 0x4000                    /**< dont fragment flag */
118#define IP_MF 0x2000                    /**< more fragments flag */
119#define IP_OFFMASK 0x1fff               /**< mask for fragmenting bits */
120    u_int8_t ip_ttl;                    /**< time to live */
121    u_int8_t ip_p;                      /**< protocol */
122    u_short ip_sum;                     /**< checksum */
123    struct in_addr ip_src;              /**< source address */
124    struct in_addr ip_dst;              /**< dest address */
125  };
126
127/** Structure for dealing with TCP packets */
128struct libtrace_tcp
129  {
130    u_int16_t source;           /**< Source Port */
131    u_int16_t dest;             /**< Destination port */
132    u_int32_t seq;              /**< Sequence number */
133    u_int32_t ack_seq;          /**< Acknowledgement Number */
134#  if BYTE_ORDER == LITTLE_ENDIAN
135    u_int16_t res1:4;           /**< Reserved bits */
136    u_int16_t doff:4;           
137    u_int16_t fin:1;            /**< FIN */
138    u_int16_t syn:1;            /**< SYN flag */
139    u_int16_t rst:1;            /**< RST flag */
140    u_int16_t psh:1;            /**< PuSH flag */
141    u_int16_t ack:1;            /**< ACK flag */
142    u_int16_t urg:1;            /**< URG flag */
143    u_int16_t res2:2;           /**< Reserved */
144#  elif BYTE_ORDER == BIG_ENDIAN
145    u_int16_t doff:4;           
146    u_int16_t res1:4;           /**< Reserved bits */
147    u_int16_t res2:2;           /**< Reserved */
148    u_int16_t urg:1;            /**< URG flag */
149    u_int16_t ack:1;            /**< ACK flag */
150    u_int16_t psh:1;            /**< PuSH flag */
151    u_int16_t rst:1;            /**< RST flag */
152    u_int16_t syn:1;            /**< SYN flag */
153    u_int16_t fin:1;            /**< FIN flag */
154#  else
155#   error "Adjust your <bits/endian.h> defines"
156#  endif
157    u_int16_t window;           /**< Window Size */
158    u_int16_t check;            /**< Checksum */
159    u_int16_t urg_ptr;          /**< Urgent Pointer */
160};
161
162/** UDP Header for dealing with UDP packets */
163struct libtrace_udp {
164  u_int16_t     source;         /**< Source port */
165  u_int16_t     dest;           /**< Destination port */
166  u_int16_t     len;            /**< Length */
167  u_int16_t     check;          /**< Checksum */
168};
169
170/** ICMP Header for dealing with icmp packets */
171struct libtrace_icmp
172{
173  u_int8_t type;                /**< message type */
174  u_int8_t code;                /**< type sub-code */
175  u_int16_t checksum;           /**< checksum */
176  union
177  {
178    struct
179    {
180      u_int16_t id;
181      u_int16_t sequence;
182    } echo;                     /**< echo datagram */
183    u_int32_t   gateway;        /**< gateway address */
184    struct
185    {
186      u_int16_t unused;
187      u_int16_t mtu;
188    } frag;                     /**< path mtu discovery */
189  } un;
190};
191
192/** 802.1Q frame */
193struct libtrace_8021q
194{
195  u_int8_t  ether_dhost[6];      /* destination eth addr */
196  u_int8_t  ether_shost[6];      /* source ether addr    */
197  u_int16_t ether_type;                 /* packet type ID field , 0x8100 for VLAN */
198  u_int16_t vlan_pri:3;                 /* vlan user priority */
199  u_int16_t vlan_cfi:1;                 /* vlan format indicator, 0 for ethernet, 1 for token ring */
200  u_int16_t vlan_id:12;                 /* vlan id */
201  u_int16_t vlan_ether_type;            /* vlan sub-packet type ID field (next-header)*/
202} __attribute__ ((__packed__));
203
204/** Prints help information for libtrace
205 *
206 * Function prints out some basic help information regarding libtrace,
207 * and then prints out the help() function registered with each input module
208 */
209void trace_help();
210
211/** Gets the output format for a given output trace
212 *
213 */
214char *trace_get_output_format(struct libtrace_out_t *libtrace);
215
216/** Prints error information
217 *
218 * Prints out a descriptive error message for the currently set trace_err value
219 */
220void trace_perror(char *caller);
221
222/** Create a trace file from a URI
223 *
224 * @returns opaque pointer to a libtrace_t
225 *
226 * Valid URI's are:
227 *  - erf:/path/to/erf/file
228 *  - erf:/path/to/erf/file.gz
229 *  - erf:/path/to/rtclient/socket
230 *  - erf:-  (stdin)
231 *  - dag:/dev/dagcard                  (implementd?)
232 *  - pcapint:pcapinterface                (eg: pcap:eth0)
233 *  - pcap:/path/to/pcap/file
234 *  - pcap:/path/to/pcap/file.gz
235 *  - pcap:/path/to/pcap/socket         (implemented?)
236 *  - pcap:-
237 *  - rtclient:hostname
238 *  - rtclient:hostname:port
239 *  - wag:/path/to/wag/file
240 *  - wag:/path/to/wag/file.gz
241 *  - wag:/path/to/wag/socket
242 *  - wag:/dev/device
243 *
244 *  If an error occured when attempting to open the trace file, NULL is returned
245 *  and an error is output to stdout.
246 */
247struct libtrace_t *trace_create(char *uri);
248
249/** Creates a "dummy" trace file that has only the format type set.
250 *
251 * @returns opaque pointer to a (sparsely initialised) libtrace_t
252 *
253 * IMPORTANT: Do not attempt to call trace_read_packet or other such functions with
254 * the dummy trace. Its intended purpose is to act as a packet->trace for libtrace_packet_t's
255 * that are not associated with a libtrace_t structure.
256 */
257struct libtrace_t *trace_create_dead(char *uri);
258
259/** Creates a trace output file from a URI.
260 *
261 * @returns opaque pointer to a libtrace_output_t
262 *
263 * Valid URI's are:
264 *  - gzerf:/path/to/erf/file.gz
265 *  - gzerf:/path/to/erf/file
266 *  - rtserver:hostname
267 *  - rtserver:hostname:port
268 *
269 *  If an error occured when attempting to open the output trace, NULL is returned and
270 *  an error is output to stdout.
271 */
272struct libtrace_out_t *trace_output_create(char *uri);
273
274/** Configures a trace output file as specified by an option string in getopt() format
275 *
276 * @param libtrace      the output trace file to be configured
277 * @param options       the string containing the configuration options
278 * @returns -1 if configuration fails, 0 if successful
279 */
280int trace_output_config(struct libtrace_out_t *libtrace, char *options);
281
282/** Close a trace file, freeing up any resources it may have been using
283 *
284 */
285void trace_destroy(struct libtrace_t *trace);
286
287void trace_destroy_dead(struct libtrace_t *trace);
288
289/** Close a trace output file, freeing up any resources it may have been using
290 *
291 */
292void trace_output_destroy(struct libtrace_out_t *trace);
293
294/** Read one packet from the trace into buffer
295 *
296 * @param trace         the libtrace opaque pointer
297 * @param packet        the packet opaque pointer
298 * @returns false if it failed to read a packet
299 *
300 */
301int trace_read_packet(struct libtrace_t *trace, struct libtrace_packet_t *packet);
302
303/** Write one packet out to the output trace
304 *
305 * @param trace         the libtrace_out opaque pointer
306 * @param packet        the packet opaque pointer
307 * @returns the number of bytes written out, if zero or negative then an error has occured.
308 */
309int trace_write_packet(struct libtrace_out_t *trace, struct libtrace_packet_t *packet);
310
311/** get a pointer to the link layer
312 * @param packet        the packet opaque pointer
313 *
314 * @returns a pointer to the link layer, or NULL if there is no link layer
315 *
316 * @note you should call getLinkType() to find out what type of link layer
317 * this is
318 */
319void *trace_get_link(const struct libtrace_packet_t *packet);
320
321/** get a pointer to the IP header (if any)
322 * @param packet        the packet opaque pointer
323 *
324 * @returns a pointer to the IP header, or NULL if there is not an IP packet
325 */
326struct libtrace_ip *trace_get_ip(const struct libtrace_packet_t *packet);
327
328/** get a pointer to the TCP header (if any)
329 * @param packet        the packet opaque pointer
330 *
331 * @returns a pointer to the TCP header, or NULL if there is not a TCP packet
332 */
333struct libtrace_tcp *trace_get_tcp(const struct libtrace_packet_t *packet);
334
335/** get a pointer to the TCP header (if any) given a pointer to the IP header
336 * @param ip            The IP header
337 * @param[out] skipped  An output variable of the number of bytes skipped
338 *
339 * @returns a pointer to the TCP header, or NULL if this is not a TCP packet
340 *
341 * Skipped can be NULL, in which case it will be ignored by the program.
342 *
343 * @author Perry Lorier
344 */
345struct libtrace_tcp *trace_get_tcp_from_ip(struct libtrace_ip *ip,int *skipped);
346
347/** get a pointer to the UDP header (if any)
348 * @param packet        the packet opaque pointer
349 *
350 * @returns a pointer to the UDP header, or NULL if this is not a UDP packet
351 */
352struct libtrace_udp *trace_get_udp(const struct libtrace_packet_t *packet);
353
354/** get a pointer to the UDP header (if any) given a pointer to the IP header
355 * @param       ip      The IP header
356 * @param[out]  skipped An output variable of the number of bytes skipped
357 *
358 * @returns a pointer to the UDP header, or NULL if this is not an UDP packet
359 *
360 * Skipped may be NULL, in which case it will be ignored by this function.
361 */
362struct libtrace_udp *trace_get_udp_from_ip(struct libtrace_ip *ip,int *skipped);
363
364/** get a pointer to the ICMP header (if any)
365 * @param packet        the packet opaque pointer
366 *
367 * @returns a pointer to the ICMP header, or NULL if this is not a ICMP packet
368 */
369struct libtrace_icmp *trace_get_icmp(const struct libtrace_packet_t *packet);
370
371/** get a pointer to the ICMP header (if any) given a pointer to the IP header
372 * @param ip            The IP header
373 * @param[out] skipped  An output variable of the number of bytes skipped
374 *
375 * @returns a pointer to the ICMP header, or NULL if this is not an ICMP packet
376 *
377 * Skipped may be NULL, in which case it will be ignored by this function
378 */
379struct libtrace_icmp *trace_get_icmp_from_ip(struct libtrace_ip *ip,int *skipped);
380
381/** parse an ip or tcp option
382 * @param[in,out] ptr   the pointer to the current option
383 * @param[in,out] len   the length of the remaining buffer
384 * @param[out] type     the type of the option
385 * @param[out] optlen   the length of the option
386 * @param[out] data     the data of the option
387 *
388 * @returns bool true if there is another option (and the fields are filled in)
389 *               or false if this was the last option.
390 *
391 * This updates ptr to point to the next option after this one, and updates
392 * len to be the number of bytes remaining in the options area.  Type is updated
393 * to be the code of this option, and data points to the data of this option,
394 * with optlen saying how many bytes there are.
395 *
396 * @note Beware of fragmented packets.
397 */
398int trace_get_next_option(unsigned char **ptr,int *len,
399                        unsigned char *type,
400                        unsigned char *optlen,
401                        unsigned char **data);
402
403
404/** Get the current time in DAG time format
405 * @param packet        the packet opaque pointer
406 *
407 * @returns a 64 bit timestamp in DAG ERF format (upper 32 bits are the seconds
408 * past 1970-01-01, the lower 32bits are partial seconds)
409 * @author Daniel Lawson
410 */
411uint64_t trace_get_erf_timestamp(const struct libtrace_packet_t *packet);
412
413/** Get the current time in struct timeval
414 * @param packet        the packet opaque pointer
415 *
416 * @returns time that this packet was seen in a struct timeval
417 * @author Daniel Lawson
418 * @author Perry Lorier
419 */ 
420struct timeval trace_get_timeval(const struct libtrace_packet_t *packet);
421
422/** Get the current time in floating point seconds
423 * @param packet        the packet opaque pointer
424 *
425 * @returns time that this packet was seen in 64bit floating point seconds
426 * @author Perry Lorier
427 */
428double trace_get_seconds(const struct libtrace_packet_t *packet);
429
430/** Get the size of the packet in the trace
431 * @param packet        the packet opaque pointer
432 * @returns the size of the packet in the trace
433 * @author Perry Lorier
434 * @note Due to this being a header capture, or anonymisation, this may not
435 * be the same size as the original packet.  See get_wire_length() for the original
436 * size of the packet.
437 * @note This can (and often is) different for different packets in a trace!
438 * @par
439 *  This is sometimes called the "snaplen".
440 */
441
442int trace_get_capture_length(const struct libtrace_packet_t *packet);
443
444/** Get the size of the packet as it was seen on the wire.
445 * @param packet        the packet opaque pointer
446 * @returns the size of the packet as it was on the wire.
447 * @author Perry Lorier
448 * @author Daniel Lawson
449 * @note Due to the trace being a header capture, or anonymisation this may
450 * not be the same as the Capture Len.
451 */ 
452
453int trace_get_wire_length(const struct libtrace_packet_t *packet);
454
455/** Link layer types
456 */
457typedef enum { 
458       TRACE_TYPE_LEGACY, 
459       TRACE_TYPE_HDLC_POS, 
460       TRACE_TYPE_ETH,
461       TRACE_TYPE_ATM,
462       TRACE_TYPE_80211,
463       TRACE_TYPE_NONE,
464       TRACE_TYPE_LINUX_SLL,
465       TRACE_TYPE_PFLOG
466     } libtrace_linktype_t;
467
468/** Get the type of the link layer
469 * @param packet        the packet opaque pointer
470 * @returns libtrace_linktype_t
471 * @author Perry Lorier
472 * @author Daniel Lawson
473 */
474
475inline libtrace_linktype_t trace_get_link_type(const struct libtrace_packet_t *packet);
476
477/** Get the destination MAC addres
478 * @param packet        the packet opaque pointer
479 * @returns a pointer to the destination mac, (or NULL if there is no
480 * destination MAC)
481 * @author Perry Lorier
482 */
483uint8_t *trace_get_destination_mac(const struct libtrace_packet_t *packet);
484
485/** Get the source MAC addres
486 * @param packet        the packet opaque pointer
487 * @returns a pointer to the source mac, (or NULL if there is no source MAC)
488 * @author Perry Lorier
489 */
490uint8_t *trace_get_source_mac(const struct libtrace_packet_t *packet);
491
492/** Truncate the packet at the suggested length
493 * @param packet        the packet opaque pointer
494 * @param len           the new length of the packet
495 * @returns the new length of the packet, or the original length of the
496 * packet if unchanged
497 * @author Daniel Lawson
498 */
499size_t trace_set_capture_length(struct libtrace_packet_t *packet, size_t size);
500
501/** Set the direction flag, if it has one
502 * @param packet        the packet opaque pointer
503 * @param direction     the new direction (0,1,2,3)
504 * @returns a signed value containing the direction flag, or -1 if this is not supported
505 * @author Daniel Lawson
506 */
507int8_t trace_set_direction(struct libtrace_packet_t *packet, int8_t direction);
508
509/** Get the direction flag, if it has one
510 * @param packet        the packet opaque pointer
511 * @returns a signed value containing the direction flag, or -1 if this is not supported
512 * The direction is defined as 0 for packets originating locally (ie, outbound)
513 * and 1 for packets originating remotely (ie, inbound).
514 * Other values are possible, which might be overloaded to mean special things
515 * for a special trace.
516 * @author Daniel Lawson
517 */
518int8_t trace_get_direction(const struct libtrace_packet_t *packet);
519
520/** Event types */
521typedef enum {
522        TRACE_EVENT_IOWAIT,
523        TRACE_EVENT_SLEEP,
524        TRACE_EVENT_PACKET,
525        TRACE_EVENT_TERMINATE
526} libtrace_event_t;
527
528/** structure returned by libtrace_event explaining what the current event is */
529struct libtrace_eventobj_t {
530        libtrace_event_t type; /**< event type (iowait,sleep,packet */
531        int fd;                /**< if IOWAIT, the fd to sleep on */
532        double seconds;        /**< if SLEEP, the amount of time to sleep for */
533        int size;              /**< if PACKET, the value returned from trace_read_packet */
534};
535
536/** process a libtrace event
537 * @param trace the libtrace opaque pointer
538 * @param packet the libtrace_packet opaque pointer
539 * @param fd a pointer to a file descriptor to listen on
540 * @param seconds a pointer the time in seconds since to the next event
541 * @returns libtrace_event struct containing the type, and potential
542 *      fd or seconds to sleep on
543 *
544 * Type can be:
545 *  TRACE_EVENT_IOWAIT  Waiting on I/O on <fd>
546 *  TRACE_EVENT_SLEEP   Next event in <seconds>
547 *  TRACE_EVENT_PACKET  Packet arrived in <buffer> with size <size>
548 *  TRACE_EVENT_TERMINATE Trace terminated (perhaps with an error condition)
549 */
550struct libtrace_eventobj_t trace_event(struct libtrace_t *trace,
551                struct libtrace_packet_t *packet);
552
553/** setup a BPF filter
554 * @param filterstring a char * containing the bpf filter string
555 * @returns opaque pointer pointer to a libtrace_filter_t object
556 * @author Daniel Lawson
557 */
558struct libtrace_filter_t *trace_bpf_setfilter(const char *filterstring);
559
560/** apply a BPF filter
561 * @param filter        the filter opaque pointer
562 * @param packet        the packet opaque pointer
563 * @returns 0 if the filter fails, 1 if it succeeds
564 * @author Daniel Lawson
565 */
566int trace_bpf_filter(struct libtrace_filter_t *filter,
567                const struct libtrace_packet_t *packet);
568
569
570typedef enum {USE_DEST, USE_SOURCE} serverport_t;
571
572/** Get the source port
573 * @param packet        the packet to read from
574 * @returns a port in \em HOST byte order, or equivilent to ports for this
575 * protocol, or 0 if this protocol has no ports.
576 * @author Perry Lorier
577 */
578uint16_t trace_get_source_port(const struct libtrace_packet_t *packet);
579
580/** Get the destination port
581 * @param packet        the packet to read from
582 * @returns a port in \em HOST byte order, or equivilent to ports for this
583 * protocol, or 0 if this protocol has no ports.
584 * @author Perry Lorier
585 */
586uint16_t trace_get_destination_port(const struct libtrace_packet_t *packet);
587
588/** hint at the server port in specified protocol
589 * @param protocol      the IP layer protocol, eg 6 (tcp), 17 (udp)
590 * @param source        the source port from the packet
591 * @param dest          the destination port from the packet
592 * @returns one of USE_SOURCE or USE_DEST depending on which one you should use
593 * @note ports must be in \em host byte order!
594 * @author Daniel Lawson
595 */
596int8_t trace_get_server_port(uint8_t protocol, uint16_t source, uint16_t dest);
597
598/** Takes a uri and splits it into a format and uridata component.
599 * Primarily for internal use but made available for external use.
600 * @param uri           the uri to be parsed
601 * @param format        destination location for the format component of the uri
602 * @returns 0 if an error occured, otherwise returns the uridata component
603 * @author Shane Alcock
604 */
605char *trace_parse_uri(char *uri, char **format);
606#ifdef __cplusplus
607} // extern "C"
608#endif // #ifdef __cplusplus
609#endif // LIBTRACE_H_
Note: See TracBrowser for help on using the repository browser.