/*
*
* Copyright (c) 2007-2016 The University of Waikato, Hamilton, New Zealand.
* All rights reserved.
*
* This file is part of libtrace.
*
* This code has been developed by the University of Waikato WAND
* research group. For further information please see http://www.wand.net.nz/
*
* libtrace is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* libtrace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
*
*/
/** @file
*
* @brief Header file containing definitions for structures and functions that
* are internal
*
* @author Daniel Lawson
* @author Perry Lorier
* @author Shane Alcock
*
* @version $Id$
*
* All of the structures and functions defined in this header file are intended
* for internal use within Libtrace only. They should not be exported as part
* of the library API as we don't want users accessing things like the
* contents of the libtrace packet structure directly!
*/
#ifndef LIBTRACE_INT_H
#define LIBTRACE_INT_H
#ifdef __cplusplus
extern "C" {
#endif
#include "config.h"
#include "common.h"
#include "libtrace_parallel.h"
#include "wandio.h"
#include "lt_bswap.h"
#ifdef _MSC_VER
// warning: deprecated function
#pragma warning(disable:4996)
// warning: benign redefinitions of types
#pragma warning(disable:4142)
#endif
#ifdef HAVE_INTTYPES_H
# include
#else
# include "lt_inttypes.h"
#endif
#ifdef HAVE_STDDEF_H
# include
#else
#ifndef WIN32
# error "Can't find stddev.h -- do you define ptrdiff_t elsewhere?"
#endif
#endif
#include "rt_protocol.h"
/* Prefer net/bpf.h over pcap-bpf.h for format_bpf.c on MacOS */
#ifdef HAVE_NET_BPF_H
# include
# define HAVE_BPF 1
#else
#ifdef HAVE_PCAP_BPF_H
# include
# define HAVE_BPF 1
#endif
#endif
#ifdef HAVE_PCAP_H
# include
# ifdef HAVE_PCAP_INT_H
# include
# endif
#endif
#ifdef HAVE_ZLIB_H
# include
#endif
#ifndef HAVE_STRNDUP
char *strndup(const char *s, size_t size);
#endif
#ifndef HAVE_STRNCASECMP
# ifndef HAVE__STRNICMP
/** A local implementation of strncasecmp (as some systems do not have it) */
int strncasecmp(const char *str1, const char *str2, size_t n);
# else
# define strncasecmp _strnicmp
# endif
#endif
#ifndef HAVE_SNPRINTF
# ifndef HAVE_SPRINTF_S
/** A local implementation of snprintf (as some systems do not have it) */
int snprintf(char *str, size_t size, const char *format, ...);
# else
# define snprintf sprintf_s
# endif
#endif
#include "daglegacy.h"
#ifdef HAVE_DAG_API
# include "dagnew.h"
# include "dagapi.h"
# if DAG_VERSION == 24
# include
# else
# include
# endif
# include "erftypes.h"
#else
# include "dagformat.h"
#endif
#ifdef HAVE_LLVM
#include "bpf-jit/bpf-jit.h"
#endif
#include "data-struct/ring_buffer.h"
#include "data-struct/object_cache.h"
#include "data-struct/vector.h"
#include "data-struct/message_queue.h"
#include "data-struct/deque.h"
#include "data-struct/linked_list.h"
#include "data-struct/sliding_window.h"
#include "data-struct/buckets.h"
#include "pthread_spinlock.h"
//#define RP_BUFSIZE 65536U
#define LIBTRACE_MAX_REPLAY_SPEEDUP 1000
/** Data about the most recent event from a trace file */
struct libtrace_event_status_t {
/** A libtrace packet to store the packet when a PACKET event occurs */
libtrace_packet_t *packet;
/* The walltime when we processed the first packet from the trace */
double first_now;
/* The tracetime of the first packet in the trace */
double first_ts;
/** The size of the current PACKET event */
int psize;
/** Whether there is a packet stored in *packet above waiting for an
* event to occur */
bool waiting;
};
enum thread_types {
THREAD_EMPTY,
THREAD_HASHER,
THREAD_PERPKT,
THREAD_REPORTER,
THREAD_KEEPALIVE
};
enum thread_states {
THREAD_RUNNING,
THREAD_FINISHING,
THREAD_FINISHED,
THREAD_PAUSED,
THREAD_STATE_MAX
};
enum hash_owner {
HASH_OWNED_LIBTRACE,
HASH_OWNED_EXTERNAL,
};
/**
* Information of this thread
*/
struct libtrace_thread_t {
uint64_t accepted_packets; // The number of packets accepted only used if pread
uint64_t filtered_packets;
// is retreving packets
// Set to true once the first packet has been stored
bool recorded_first;
// For thread safety reason we actually must store this here
int64_t tracetime_offset_usec;
void* user_data; // TLS for the user to use
void* format_data; // TLS for the format to use
libtrace_message_queue_t messages; // Message handling
libtrace_ringbuffer_t rbuffer; // Input
libtrace_t * trace;
void* ret;
enum thread_types type;
enum thread_states state;
pthread_t tid;
int perpkt_num; // A number from 0-X that represents this perpkt threads number
// in the table, intended to quickly identify this thread
// -1 represents NA (such as the case this is not a perpkt thread)
} ALIGN_STRUCT(CACHE_LINE_SIZE);
/**
* Storage to note time value against each.
* Used both internally to do trace time playback
* and can be used externally to assist applications which need
* a trace starting time such as tracertstats.
*/
struct first_packets {
pthread_spinlock_t lock;
size_t count; // If == perpkt_thread_count threads we have all
size_t first; // Valid if count != 0
struct {
libtrace_packet_t * packet;
struct timeval tv;
} * packets;
};
#define TRACE_STATES \
X(STATE_NEW) \
X(STATE_RUNNING) \
X(STATE_PAUSING) \
X(STATE_PAUSED) \
X(STATE_FINISHED) \
X(STATE_FINISHING) \
X(STATE_DESTROYED) \
X(STATE_JOINED) \
X(STATE_ERROR)
#define X(a) a,
enum trace_state {
TRACE_STATES
};
#undef X
#define X(a) case a: return #a;
static inline char *get_trace_state_name(enum trace_state ts){
switch(ts) {
TRACE_STATES
default:
return "UNKNOWN";
}
}
#undef X
#define READ_EOF 0
#define READ_ERROR -1
#define READ_MESSAGE -2
// Used for inband tick message
#define READ_TICK -3
/**
* Tuning the parallel sizes
* See the user documentation trace_set_x
*/
struct user_configuration {
size_t cache_size;
size_t thread_cache_size;
bool fixed_count;
size_t burst_size;
size_t tick_interval;
size_t tick_count;
size_t perpkt_threads;
size_t hasher_queue_size;
bool hasher_polling;
bool reporter_polling;
size_t reporter_thold;
bool debug_state;
};
#define ZERO_USER_CONFIG(config) memset(&config, 0, sizeof(struct user_configuration));
struct callback_set {
fn_cb_starting message_starting;
fn_cb_dataless message_stopping;
fn_cb_dataless message_resuming;
fn_cb_dataless message_pausing;
fn_cb_packet message_packet;
fn_cb_result message_result;
fn_cb_first_packet message_first_packet;
fn_cb_tick message_tick_count;
fn_cb_tick message_tick_interval;
fn_cb_usermessage message_user;
};
/** A libtrace input trace
* @internal
*/
struct libtrace_t {
/** The capture format for the input trace */
struct libtrace_format_t *format;
/** Details of the most recent PACKET event reported by the trace */
struct libtrace_event_status_t event;
/** Pointer to the "global" data for the capture format module */
void *format_data;
/** A BPF filter to be applied to all packets read by the trace -
* used only if the capture format does not support filters natively */
struct libtrace_filter_t *filter;
/** The snap length to be applied to all packets read by the trace -
* used only if the capture format does not support snapping natively */
size_t snaplen;
/** Speed up the packet rate when using trace_event() to process trace
* files by this factor. */
int replayspeedup;
/** Count of the number of packets returned to the libtrace user */
uint64_t accepted_packets;
/** Count of the number of packets filtered by libtrace */
uint64_t filtered_packets;
/** The sequence is like accepted_packets but we don't reset this after a pause. */
uint64_t sequence_number;
/** The packet read out by the trace, backwards compatibility to allow us to finalise
* a packet when the trace is destroyed */
libtrace_packet_t *last_packet;
/** The filename from the uri for the trace */
char *uridata;
/** The libtrace IO reader for this trace (if applicable) */
io_t *io;
/** Error information for the trace */
libtrace_err_t err;
/** Boolean flag indicating whether the trace has been started */
bool started;
/** Synchronise writes/reads across this format object and attached threads etc */
pthread_mutex_t libtrace_lock;
/** Packet read lock, seperate from libtrace_lock as to not block while reading a burst */
pthread_mutex_t read_packet_lock;
/** State */
enum trace_state state;
/** Use to control pausing threads and finishing threads etc always used with libtrace_lock */
pthread_cond_t perpkt_cond;
/** Keeps track of counts of threads in any given state */
int perpkt_thread_states[THREAD_STATE_MAX];
/** Set to indicate a perpkt's queue is full as such the writing perpkt cannot proceed */
bool perpkt_queue_full;
/** Global storage for this trace, shared among all the threads */
void* global_blob;
/** The actual freelist */
libtrace_ocache_t packet_freelist;
/** The hasher function */
enum hasher_types hasher_type;
/** The hasher function - NULL implies they don't care or balance */
fn_hasher hasher;
void *hasher_data;
enum hash_owner hasher_owner;
/** The pread_packet choosen path for the configuration */
int (*pread)(libtrace_t *, libtrace_thread_t *, libtrace_packet_t **, size_t);
libtrace_thread_t hasher_thread;
libtrace_thread_t reporter_thread;
libtrace_thread_t keepalive_thread;
int perpkt_thread_count;
libtrace_thread_t * perpkt_threads; // All our perpkt threads
// Used to keep track of the first packet seen on each thread
struct first_packets first_packets;
int tracetime;
/*
* Caches statistic counters in the case that our trace is
* paused or stopped before this counter is taken
*/
libtrace_stat_t *stats;
struct user_configuration config;
libtrace_combine_t combiner;
/* Set of callbacks to be executed by per packet threads in response
* to various messages. */
struct callback_set *perpkt_cbs;
/* Set of callbacks to be executed by the reporter thread in response
* to various messages. */
struct callback_set *reporter_cbs;
};
#define LIBTRACE_STAT_MAGIC 0x41
void trace_fin_packet(libtrace_packet_t *packet);
void libtrace_zero_thread(libtrace_thread_t * t);
void store_first_packet(libtrace_t *libtrace, libtrace_packet_t *packet, libtrace_thread_t *t);
libtrace_thread_t * get_thread_table(libtrace_t *libtrace);
void send_message(libtrace_t *trace, libtrace_thread_t *target,
const enum libtrace_messages type,
libtrace_generic_t data, libtrace_thread_t *sender);
/** A libtrace output trace
* @internal
*/
struct libtrace_out_t {
/** The capture format for the output trace */
struct libtrace_format_t *format;
/** Pointer to the "global" data for the capture format module */
void *format_data;
/** The filename for the uri for the output trace */
char *uridata;
/** Error information for the output trace */
libtrace_err_t err;
/** Boolean flag indicating whether the trace has been started */
bool started;
};
/** Sets the error status on an input trace
*
* @param trace The input trace to set the error status for
* @param errcode The code for the error - can be a libtrace error code or a regular errno value
* @param msg A message to print when reporting the error
*/
void trace_set_err(libtrace_t *trace, int errcode,const char *msg,...)
PRINTF(3,4);
/** Sets the error status on an output trace
*
* @param trace The output trace to set the error status for
* @param errcode The code for the error - can be a libtrace error code or a regular errno value
* @param msg A message to print when reporting the error
*/
void trace_set_err_out(libtrace_out_t *trace, int errcode, const char *msg,...)
PRINTF(3,4);
/** Clears the cached values for a libtrace packet
*
* @param packet The libtrace packet that requires a cache reset
*/
void trace_clear_cache(libtrace_packet_t *packet);
#ifndef PF_RULESET_NAME_SIZE
#define PF_RULESET_NAME_SIZE 16
#endif
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif
/** A local definition of a PFLOG header */
typedef struct libtrace_pflog_header_t {
uint8_t length;
sa_family_t af;
uint8_t action;
uint8_t reason;
char ifname[IFNAMSIZ];
char ruleset[PF_RULESET_NAME_SIZE];
uint32_t rulenr;
uint32_t subrulenr;
uint8_t dir;
uint8_t pad[3];
} PACKED libtrace_pflog_header_t;
/** A libtrace capture format module */
/* All functions should return -1, or NULL on failure */
struct libtrace_format_t {
/** The name of this module, used in the libtrace URI to identify the
* capture format */
const char *name;
/** The version of this module */
const char *version;
/** The RT protocol type of this module */
enum base_format_t type;
/** Given a filename, return if this is the most likely capture format
* (used for devices). Used to "guess" the capture format when the
* URI is not fully specified.
*
* @param fname The name of the device or file to examine
* @return 1 if the name matches the capture format, 0 otherwise
*/
int (*probe_filename)(const char *fname);
/** Given a file, looks at the start of the file to determine if this
* is the capture format. Used to "guess" the capture format when the
* URI is not fully specified.
*
* @param io An open libtrace IO reader for the file to check
* @return 1 if the file matches the capture format, 0 otherwise
*/
int (*probe_magic)(io_t *io);
/** Initialises an input trace using the capture format.
*
* @param libtrace The input trace to be initialised
* @return 0 if successful, -1 in the event of error
*/
int (*init_input)(libtrace_t *libtrace);
/** Applies a configuration option to an input trace.
*
* @param libtrace The input trace to apply the option to
* @param option The option that is being configured
* @param value A pointer to the value that the option is to be
* set to
* @return 0 if successful, -1 if the option is unsupported or an error
* occurs
*/
int (*config_input)(libtrace_t *libtrace,trace_option_t option,void *value);
/** Starts or unpauses an input trace - note that this function is
* often the one that opens the file or device for reading.
*
* @param libtrace The input trace to be started or unpaused
* @return 0 if successful, -1 in the event of error */
int (*start_input)(libtrace_t *libtrace);
/** Pauses an input trace - this function should close or detach the
* file or device that is being read from.
*
* @param libtrace The input trace to be paused
* @return 0 if successful, -1 in the event of error
*/
int (*pause_input)(libtrace_t *libtrace);
/** Initialises an output trace using the capture format.
*
* @param libtrace The output trace to be initialised
* @return 0 if successful, -1 in the event of error
*/
int (*init_output)(libtrace_out_t *libtrace);
/** Applies a configuration option to an output trace.
*
* @param libtrace The output trace to apply the option to
* @param option The option that is being configured
* @param value A pointer to the value that the option is to be
* set to
* @return 0 if successful, -1 if the option is unsupported or an error
* occurs
* */
int (*config_output)(libtrace_out_t *libtrace, trace_option_output_t option, void *value);
/** Starts an output trace - note that this function is often the one
* that opens the file or device for writing.
*
* @param libtrace The output trace to be started
* @return 0 if successful, -1 if an error occurs
*
* There is no pause for output traces, as writing is not performed
* asynchronously.
*/
int (*start_output)(libtrace_out_t *libtrace);
/** Concludes an input trace and cleans up the capture format data.
*
* @param libtrace The input trace to be concluded
* @return 0 if successful, -1 if an error occurs
*
* Libtrace will call the pause_input function if the input trace is
* currently active prior to calling this function.
*/
int (*fin_input)(libtrace_t *libtrace);
/** Concludes an output trace and cleans up the capture format data.
*
* @param libtrace The output trace to be concluded
* @return 0 if successful, -1 if an error occurs
*/
int (*fin_output)(libtrace_out_t *libtrace);
/** Reads the next packet from an input trace into the provided packet
* structure.
*
* @param libtrace The input trace to read from
* @param packet The libtrace packet to read into
* @return The size of the packet read (in bytes) including the capture
* framing header, or -1 if an error occurs. 0 is returned in the
* event of an EOF or -2 in the case of interrupting the parallel API.
*
* If no packets are available for reading, this function should block
* until one appears or return 0 if the end of a trace file has been
* reached.
*/
int (*read_packet)(libtrace_t *libtrace, libtrace_packet_t *packet);
/** Converts a buffer containing a packet record into a libtrace packet
*
* @param libtrace An input trace in the capture format for the
* packet
* @param packet A libtrace packet to put the prepared packet
* into
* @param buffer The buffer containing the packet record
* (including the capture format header)
* @param rt_type The RT type for the packet
* @param flags Flags describing properties that should be
* applied to the new packet
* @return 0 if successful, -1 if an error occurs.
*
* Updates internal trace and packet details, such as payload pointers,
* loss counters and packet types to match the packet record provided
* in the buffer. This is a zero-copy function.
*
* Intended (at this stage) only for internal use, particularly by
* RT which needs to decapsulate RT packets */
int (*prepare_packet)(libtrace_t *libtrace, libtrace_packet_t *packet,
void *buffer, libtrace_rt_types_t rt_type,
uint32_t flags);
/** Frees any resources allocated by the capture format module for a
* libtrace packet.
*
* @param The packet to be finalised
* */
void (*fin_packet)(libtrace_packet_t *packet);
/** Write a libtrace packet to an output trace.
*
* @param libtrace The output trace to write the packet to
* @param packet The packet to be written out
* @return The number of bytes written, or -1 if an error occurs
*/
int (*write_packet)(libtrace_out_t *libtrace, libtrace_packet_t *packet);
/** Flush any buffered output for an output trace.
*
* @param libtrace The output trace to be flushed
*/
int (*flush_output)(libtrace_out_t *libtrace);
/** Returns the libtrace link type for a packet.
*
* @param packet The packet to get the link type for
* @return The libtrace link type, or -1 if this link type is unknown
*/
libtrace_linktype_t (*get_link_type)(const libtrace_packet_t *packet);
/** Returns the direction of a packet.
*
* @param packet The packet to get the direction for
* @return The direction of the packet, or -1 if no direction tag is
* present or an error occurs
*/
libtrace_direction_t (*get_direction)(const libtrace_packet_t *packet);
/** Sets the direction of a packet.
*
* @param packet The packet to set the direction for
* @param direction The direction to assign to the packet
* @return The updated direction for the packet, or -1 if an error
* occurs
*
* @note Some capture formats do not feature direction tagging, so it
* will not make sense to implement a set_direction function for them.
*/
libtrace_direction_t (*set_direction)(libtrace_packet_t *packet, libtrace_direction_t direction);
/** Returns the timestamp for a packet in the ERF timestamp format.
*
* @param packet The packet to get the timestamp from
* @return The 64-bit ERF timestamp
*
* @note Each format must implement at least one of the four "get
* timestamp" functions.
*
* If not implemented, libtrace will convert the result of one of the
* other timestamp functions into the appropriate format instead.
* This means each capture format only needs to implement the most
* sensible of the four and let libtrace handle any conversions.
*
*/
uint64_t (*get_erf_timestamp)(const libtrace_packet_t *packet);
/** Returns the timestamp for a packet in the timeval format
*
* @param packet The packet to get the timestamp from
* @return The timestamp from the packet as a timeval
*
* @note Each format must implement at least one of the four "get
* timestamp" functions.
*
* If not implemented, libtrace will convert the result of one of the
* other timestamp functions into the appropriate format instead.
* This means each capture format only needs to implement the most
* sensible of the four and let libtrace handle any conversions.
*/
struct timeval (*get_timeval)(const libtrace_packet_t *packet);
/** Returns the timestamp for a packet in the timespec format.
*
* @param packet The packet to get the timestamp from
* @return The timestamp from the packet as a timespec
*
* @note Each format must implement at least one of the four "get
* timestamp" functions.
*
* If not implemented, libtrace will convert the result of one of the
* other timestamp functions into the appropriate format instead.
* This means each capture format only needs to implement the most
* sensible of the four and let libtrace handle any conversions.
*/
struct timespec (*get_timespec)(const libtrace_packet_t *packet);
/** Returns the timestamp for a packet in floating point seconds.
*
* @param packet The packet to get the timestamp from
* @return The timestamp from the packet as a floating point number of
* seconds since 1970-01-01 00:00:00 UTC
*
* @note Each format must implement at least one of the four "get
* timestamp" functions.
*
* If not implemented, libtrace will convert the result of one of the
* other timestamp functions into the appropriate format instead.
* This means each capture format only needs to implement the most
* sensible of the four and let libtrace handle any conversions.
*/
double (*get_seconds)(const libtrace_packet_t *packet);
/** Moves the read pointer to a certain ERF timestamp within an input
* trace file.
*
* @param trace The input trace to seek within
* @param timestamp The timestamp to seek to, as an ERF timestamp
*
* @return 0 on success, -1 on failure.
*
* The next packet read from this trace will now be the first packet
* to have a timestamp equal to or greater than the provided timestamp.
*
* @note Each format that supports seeking must implement at least one
* of the seek functions.
*
* If not implemented, libtrace will convert the timestamp into the
* appropriate format to use a seek function that has been implemented.
* This means each capture format only needs to implement the seek
* function that matches the native timestamp format for that capture.
*
*/
int (*seek_erf)(libtrace_t *trace, uint64_t timestamp);
/** Moves the read pointer to a certain timestamp represented using a
* timeval within an input trace file.
*
* @param trace The input trace to seek within
* @param timestamp The timestamp to seek to, as a timeval
*
* @return 0 on success, -1 on failure.
*
* The next packet read from this trace will now be the first packet
* to have a timestamp equal to or greater than the provided timestamp.
*
* @note Each format that supports seeking must implement at least one
* of the seek functions.
*
* If not implemented, libtrace will convert the timestamp into the
* appropriate format to use a seek function that has been implemented.
* This means each capture format only needs to implement the seek
* function that matches the native timestamp format for that capture.
*
*/
int (*seek_timeval)(libtrace_t *trace, struct timeval tv);
/** Moves the read pointer to a certain timestamp represented using
* floating point seconds within an input trace file.
*
* @param trace The input trace to seek within
* @param timestamp The timestamp to seek to, as floating point
* seconds since 1970-01-01 00:00:00 UTC
*
* @return 0 on success, -1 on failure.
*
* The next packet read from this trace will now be the first packet
* to have a timestamp equal to or greater than the provided timestamp.
*
* @note Each format that supports seeking must implement at least one
* of the seek functions.
*
* If not implemented, libtrace will convert the timestamp into the
* appropriate format to use a seek function that has been implemented.
* This means each capture format only needs to implement the seek
* function that matches the native timestamp format for that capture.
*
*/
int (*seek_seconds)(libtrace_t *trace, double seconds);
/** Returns the payload length of the captured packet record.
*
* @param packet The packet to get the capture length from
* @return The capture length for the packet, or -1 if an error occurs
*
* Capture length is the current size of the packet record itself,
* following any truncation that may have occurred during the capture
* process. This length does not include the capture format framing
* header.
*/
int (*get_capture_length)(const libtrace_packet_t *packet);
/** Returns the original length of the packet as it was on the wire.
*
* @param packet The packet to get the wire length from
* @return The length of the packet on the wire at the time of capture,
* or -1 if an error occurs
*
* Wire length is the original size of the packet prior to any
* truncation that may have occurred as part of the capture process.
* This length does not include the capture format framing header.
*/
int (*get_wire_length)(const libtrace_packet_t *packet);
/** Returns the length of the capture format framing header
*
* @param packet The packet to get the framing length from
* @return The length of the framing header, or -1 if an error occurs
*
* The framing header is the extra metadata that the capture process
* records about a packet. The framing length does not include any
* of the packet payload itself. The total size of the packet record
* can be calculated be adding this value with the capture length.
*/
int (*get_framing_length)(const libtrace_packet_t *packet);
/** Sets the capture length for a packet.
*
* @param packet The packet to adjust the capture length for.
* @param size The new capture length
* @return The new capture length of the packet, or -1 if an error
* occurs
*
* @note This function should only reduce the capture length. If the
* provided length is larger than the current capture length, -1 should
* be returned.
*/
size_t (*set_capture_length)(struct libtrace_packet_t *packet,size_t size);
/** Returns the number of packets observed by an input trace.
*
* @param trace The input trace to get the packet count for
* @return The number of packets observed by an input trace, or
* UINT64_MAX if the number is unknown
*
* This count includes packets that have been filtered and dropped.
*/
uint64_t (*get_received_packets)(libtrace_t *trace);
/** Returns the number of packets filtered by an input trace.
*
* @param trace The input trace to get the filtered count for
* @return The number of packets filtered by the input trace, or
* UINT64_MAX if the number is unknown
*
*/
uint64_t (*get_filtered_packets)(libtrace_t *trace);
/** Returns the number of packets dropped by an input trace.
*
* @param trace The input trace to get the dropped count for
* @return The number of packets dropped by the input trace, or
* UINT64_MAX if the number is unknown
*
*/
uint64_t (*get_dropped_packets)(libtrace_t *trace);
/** Returns statistics about a trace.
*
* @param trace The libtrace object
* @param stat [in,out] A statistics structure ready to be filled
*
* The filtered and accepted statistics will be set to the values
* stored in the library. All other statistics are not set.
*
* @note If filtering of packets is performed by a trace and the number
* of filtered packets is unknown this should be marked as invalid by
* the format.
*/
void (*get_statistics)(libtrace_t *trace, libtrace_stat_t *stat);
/** Returns the file descriptor used by the input trace.
*
* @param trace The input trace to get the file descriptor for
* @return The file descriptor used by the input trace to read packets
*
*/
int (*get_fd)(const libtrace_t *trace);
/** Returns the next libtrace event for the input trace.
*
* @param trace The input trace to get the next event from
* @param packet A libtrace packet to read a packet into
* @return A libtrace event describing the event that occured
*
* The event API allows for non-blocking reading of packets from an
* input trace. If a packet is available and ready to be read, a packet
* event should be returned. Otherwise a sleep or fd event should be
* returned to indicate that the caller needs to wait. If the input
* trace has an error or reaches EOF, a terminate event should be
* returned.
*/
struct libtrace_eventobj_t (*trace_event)(libtrace_t *trace, libtrace_packet_t *packet);
/** Prints some useful help information to standard output. */
void (*help)(void);
/** Next pointer, should always be NULL - used by the format module
* manager. */
struct libtrace_format_t *next;
/** Holds information about the trace format */
struct libtrace_info_t info;
/**
* Starts or unpauses an input trace in parallel mode - note that
* this function is often the one that opens the file or device for
* reading.
*
* @param libtrace The input trace to be started or unpaused
* @return 0 upon success.
* Otherwise in event of an error -1 is returned.
*
*/
int (*pstart_input)(libtrace_t *trace);
/**
* Read a batch of packets from the input stream related to thread.
* At most read nb_packets, however should return with less if packets
* are not waiting. However still must return at least 1, 0 still indicates
* EOF.
*
* @param libtrace The input trace
* @param t The thread
* @param packets An array of packets
* @param nb_packets The number of packets in the array (the maximum to read)
* @return The number of packets read, or 0 in the case of EOF or -1 in error or -2 to represent
* interrupted due to message waiting before packets had been read.
*/
int (*pread_packets)(libtrace_t *trace, libtrace_thread_t *t, libtrace_packet_t **packets, size_t nb_packets);
/** Pause a parallel trace
*
* @param libtrace The input trace to be paused
*/
int (*ppause_input)(libtrace_t *trace);
/** Called after all threads have been paused, Finish (close) a parallel trace
*
* @param libtrace The input trace to be stopped
*/
int (*pfin_input)(libtrace_t *trace);
/**
* Register a thread for use with the format or using the packets produced
* by it. This is NOT only used for threads reading packets in fact all
* threads use this.
*
* The libtrace lock is not held by this format but can be aquired
* by the format.
*
* Some use cases include setting up any thread local storage required for
* to read packets and free packets. For DPDK we require any thread that
* may release or read a packet to have have an internal number associated
* with it.
*
* The thread type can be used to see if this thread is going to be used
* to read packets or otherwise.
*
* @return 0 if successful, -1 if the option is unsupported or an error
* occurs (such as a maximum of threads being reached)
*/
int (*pregister_thread)(libtrace_t *libtrace, libtrace_thread_t *t, bool reader);
/**
* If needed any memory allocated with pregister_thread can be released
* in this function. The thread will be destroyed directly after this
* function is called.
*/
void (*punregister_thread)(libtrace_t *libtrace, libtrace_thread_t *t);
/** Returns statistics for a single thread.
*
* @param trace The libtrace object
* @param t The thread to return statistics for
* @param stat [in,out] A statistics structure ready to be filled
*
* The filtered and accepted statistics will be set to the values
* stored in the library. All other statistics are not set.
*
* @note If filtering of packets is performed by a trace and the number
* of filtered packets is unknown this should be marked as invalid by
* the format.
*/
void (*get_thread_statistics)(libtrace_t *libtrace,
libtrace_thread_t *t,
libtrace_stat_t *stat);
};
/** Macro to zero out a single thread format */
#define NON_PARALLEL(live) \
{live, 1}, /* trace info */ \
NULL, /* pstart_input */ \
NULL, /* pread_packet */ \
NULL, /* ppause_input */ \
NULL, /* pfin_input */ \
NULL, /* pregister_thread */ \
NULL, /* punregister_thread */ \
NULL, /* get_thread_statistics */
/** The list of registered capture formats */
//extern struct libtrace_format_t *form;
/** Specifies whether any blocking packet readers should cease reading
* immediately
*/
extern volatile int libtrace_halt;
/**
* Used by a format to check if trace_interrupt or if a trace_pause/stop has
* been called. Provides backwards compatibility with traditional read
* functions when trace_read_packet() is used by the parallel API.
*
* Returns -1 if not halting otherwise returns the code that the read
* operation should pass on.
*/
static inline int is_halted(libtrace_t *trace) {
if (!(libtrace_halt || trace->state == STATE_PAUSING)) {
return -1;
} else if (libtrace_halt) {
return READ_EOF;
} else {
return READ_MESSAGE;
}
}
/** Registers a new capture format module.
*
* @param format The format module to be registered
*/
void register_format(struct libtrace_format_t *format);
/** Converts a timeval into a timestamp in microseconds since the epoch.
*
* @param tv The timeval to be converted.
* @return A 64 bit timestamp in microseconds since the epoch.
*/
uint64_t tv_to_usec(const struct timeval *tv);
/** Converts a PCAP DLT into a libtrace link type.
*
* @param linktype The PCAP DLT to be converted
* @return The libtrace link type that is equivalent to the provided DLT, or
* -1 if the DLT is unknown
*/
libtrace_linktype_t pcap_linktype_to_libtrace(libtrace_dlt_t linktype);
/** Converts a PCAP DLT into an RT protocol type.
*
* @param linktype The PCAP DLT to be converted
* @return The RT type that is equivalent to the provided DLT
*/
libtrace_rt_types_t pcap_linktype_to_rt(libtrace_dlt_t linktype);
/** Converts a PCAP-NG DLT into an RT protocol type.
*
* @param linktype The PCAP DLT to be converted
* @return The RT type that is equivalent to the provided DLT
*/
libtrace_rt_types_t pcapng_linktype_to_rt(libtrace_dlt_t linktype);
/** Converts a libtrace link type into a PCAP linktype.
*
* @param type The libtrace link type to be converted
* @return The PCAP linktype that is equivalent to the provided libtrace link
* type, or -1 if the link type is unknown
*/
libtrace_dlt_t libtrace_to_pcap_linktype(libtrace_linktype_t type);
/** Converts a libtrace link type into a PCAP DLT.
*
* @param type The libtrace link type to be converted
* @return The PCAP DLT that is equivalent to the provided libtrace link
* type, or -1 if the link type is unknown
*/
libtrace_dlt_t libtrace_to_pcap_dlt(libtrace_linktype_t type);
/** Converts an RT protocol type into a PCAP DLT.
*
* @param rt_type The RT type to be converted
* @return The PCAP DLT that is equivalent to the provided RT protocol
*/
libtrace_dlt_t rt_to_pcap_linktype(libtrace_rt_types_t rt_type);
/** Converts a PCAP DLT into an RT protocol type for the BPF format.
*
* @param linktype The PCAP DLT to be converted
* @return The RT type that is equivalent to the provided DLT for BPF
*/
libtrace_rt_types_t bpf_linktype_to_rt(libtrace_dlt_t linktype);
/** Converts an ERF type into a libtrace link type.
*
* @param erf The ERF type to be converted
* @return The libtrace link type that is equivalent to the provided ERF type,
* or -1 if the ERF type is unknown
*/
libtrace_linktype_t erf_type_to_libtrace(uint8_t erf);
/** Converts a libtrace link type into an ERF type.
*
* @param linktype The libtrace link type to be converted
* @return The ERF type that is equivalent to the provided libtrace link type,
* or -1 if the link type cannot be matched to an ERF type.
*/
uint8_t libtrace_to_erf_type(libtrace_linktype_t linktype);
/** Converts an ARPHRD type into a libtrace link type.
*
* @param arphrd The ARPHRD type to be converted
* @return The libtrace link type that is equivalent to the provided ARPHRD
* type, or -1 if the ARPHRD type is unknown
*/
libtrace_linktype_t arphrd_type_to_libtrace(unsigned int arphrd);
/** Converts a libtrace link type into an ARPHRD type.
*
* @param type The libtrace link type to be converted
* @return The ARPHRD type that is equivalent to the provided libtrace link
* type, or -1 if the link type cannot be matched to an ARPHRD type
*/
unsigned int libtrace_to_arphrd_type(libtrace_linktype_t type);
/** Converts a libtrace packet to the Linux SLL type.
*
* @param packet The packet to be promoted
*
* @note This will involve memcpy() so use sparingly.
*
* This function prepends a Linux SLL header to a packet so that we can store
* direction tagging information.
*/
void promote_packet(libtrace_packet_t *packet);
/** Attempts to demote a packet by removing the first header.
*
* @param packet The packet to be demoted
* @return True if the packet was demoted, false otherwise.
*
* Essentially the opposite of promote_packet, except that it will also remove
* an ATM header as well as Linux SLL.
*
*/
bool demote_packet(libtrace_packet_t *packet);
/** Returns a pointer to the header following a Linux SLL header.
*
* @param link A pointer to the Linux SLL header to be skipped
* @param[out] arphrd_type The arp hardware type of the packet
* @param[out] next_header The ethertype of the next header
* @param[in,out] remaining Updated with the number of captured bytes
* remaining
* @return A pointer to the header following the Linux SLL header, or NULL if
* no subsequent header is present.
*
* Remaining must point to the number of bytes captured from the Linux SLL
* header and beyond. It will be decremented by the number of bytes skipped
* to find the payload.
*
* If the Linux SLL header is complete but there are zero bytes of payload
* after the end of the header, a pointer to where the payload would be is
* returned and remaining will be set to zero. If the Linux SLL header is
* incomplete (truncated), then NULL is returned and remaining will be set to
* 0. Therefore, it is very important to check the value of remaining after
* calling this function.
*/
void *trace_get_payload_from_linux_sll(const void *link,
uint16_t *arphrd_type,
uint16_t *next_header,
uint32_t *remaining);
/** Returns a pointer to the header following an ATM header.
*
* @param link A pointer to the ATM header to be skipped
* @param[out] type The ethertype of the next header
* @param[in,out] remaining Updated with the number of captured bytes
* remaining
* @return A pointer to the header following the ATM header, or NULL if
* no subsequent header is present.
*
* Remaining must point to the number of bytes captured from the ATM header
* and beyond. It will be decremented by the number of bytes skipped to find
* the payload.
*
* If the ATM header is complete but there are zero bytes of payload
* after the end of the header, a pointer to where the payload would be is
* returned and remaining will be set to zero. If the ATM header is
* incomplete (truncated), then NULL is returned and remaining will be set to
* 0. Therefore, it is very important to check the value of remaining after
* calling this function.
*/
DLLEXPORT void *trace_get_payload_from_atm(void *link, uint8_t *type,
uint32_t *remaining);
#ifdef HAVE_BPF
/* A type encapsulating a bpf filter
* This type covers the compiled bpf filter, as well as the original filter
* string
*
*/
/** Internal representation of a BPF filter */
struct libtrace_filter_t {
struct bpf_program filter; /**< The BPF program itself */
char * filterstring; /**< The filter string */
int flag; /**< Indicates if the filter is valid */
struct bpf_jit_t *jitfilter;
};
#else
/** BPF not supported by this system, but we still need to define a structure
* for the filter */
struct libtrace_filter_t {};
#endif
/** Local definition of a PCAP header */
typedef struct libtrace_pcapfile_pkt_hdr_t {
uint32_t ts_sec; /* Seconds portion of the timestamp */
uint32_t ts_usec; /* Microseconds portion of the timestamp */
uint32_t caplen; /* Capture length of the packet */
uint32_t wirelen; /* The wire length of the packet */
} libtrace_pcapfile_pkt_hdr_t;
#ifdef HAVE_DAG
/** Constructor for the DAG format module */
void dag_constructor(void);
#endif
/** Constructor for the ERF format module */
void erf_constructor(void);
/** Constructor for the TSH format module */
void tsh_constructor(void);
/** Constructor for the Legacy DAG format module */
void legacy_constructor(void);
/** Constructor for the Linux Native format module */
void linuxnative_constructor(void);
/** Constructor for the Linux Ring format module */
void linuxring_constructor(void);
/** Constructor for the PCAP format module */
void pcap_constructor(void);
/** Constructor for the PCAP File format module */
void pcapfile_constructor(void);
/** Constructor for the PCAP-NG File format module */
void pcapng_constructor(void);
/** Constructor for the RT format module */
void rt_constructor(void);
/** Constructor for the DUCK format module */
void duck_constructor(void);
/** Constructor for the ATM Header format module */
void atmhdr_constructor(void);
/** Constructor for the network DAG format module */
void ndag_constructor(void);
/** Constructor for the live ETSI over TCP format module */
void etsilive_constructor(void);
#ifdef HAVE_BPF
/** Constructor for the BPF format module */
void bpf_constructor(void);
#endif
#if HAVE_DPDK
/** Constructor for Intels DPDK format module */
void dpdk_constructor(void);
/** Constructor for receiving network DAG via Intels DPDK format module */
void dpdkndag_constructor(void);
#endif
/** Extracts the RadioTap flags from a wireless link header
*
* @param link A pointer to the wireless link header
* @param linktype The link type of the wireless header
* @param[out] flags Space to store the extracted flags
* @return True if libtrace was able to extract flags from the link header,
* false otherwise.
*
* This function has been left internal because it is not portable across
* drivers.
*/
bool trace_get_wireless_flags(void *link, libtrace_linktype_t linktype, uint8_t *flags);
#define TRACE_RADIOTAP_F_FCS 0x10
#ifdef __cplusplus
}
#endif
#endif /* LIBTRACE_INT_H */