zeek/src/iosource/Packet.h
Robin Sommer d59bb2e9d1 Merge branch 'topic/jgras/mac-logging' of https://github.com/J-Gras/bro
Thanks! I've tweaked this a bit further, have a look.

BIT-1613 #merged
2016-06-06 17:59:34 -07:00

225 lines
5.7 KiB
C++

#ifndef packet_h
#define packet_h
#include "Desc.h"
#include "IP.h"
#include "NetVar.h"
/**
* The Layer 3 type of a packet, as determined by the parsing code in Packet.
*/
enum Layer3Proto {
L3_UNKNOWN = -1, /// Layer 3 type could not be determined.
L3_IPV4 = 1, /// Layer 3 is IPv4.
L3_IPV6 = 2, /// Layer 3 is IPv6.
L3_ARP = 3, /// Layer 3 is ARP.
};
/**
* A link-layer packet.
*
* Note that for serialization we don't use much of the support provided by
* the serialization framework. Serialize/Unserialize do all the work by
* themselves. In particular, Packets aren't derived from SerialObj. They are
* completely seperate and self-contained entities, and we don't need any of
* the sophisticated features like object caching.
*/
class Packet {
public:
/**
* Construct and initialize from packet data.
*
* @param link_type The link type in the form of a \c DLT_* constant.
*
* @param ts The timestamp associated with the packet.
*
* @param caplen The number of bytes valid in *data*.
*
* @param len The wire length of the packet, which must be more or
* equal *caplen* (but can't be less).
*
* @param data A pointer to the raw packet data, starting with the
* layer 2 header. The pointer must remain valid for the lifetime of
* the Packet instance, unless *copy* is true.
*
* @param copy If true, the constructor will make an internal copy of
* *data*, so that the caller can release its version.
*
* @param tag A textual tag to associate with the packet for
* differentiating the input streams.
*/
Packet(int link_type, struct timeval *ts, uint32 caplen,
uint32 len, const u_char *data, int copy = false,
std::string tag = std::string(""))
: data(0), l2_src(0), l2_dst(0)
{
Init(link_type, ts, caplen, len, data, copy, tag);
}
/**
* Default constructor. For internal use only.
*/
Packet() : data(0), l2_src(0), l2_dst(0)
{
struct timeval ts = {0, 0};
Init(0, &ts, 0, 0, 0);
}
/**
* Destructor.
*/
~Packet()
{
if ( copy )
delete [] data;
}
/**
* (Re-)initialize from packet data.
*
* @param link_type The link type in the form of a \c DLT_* constant.
*
* @param ts The timestamp associated with the packet.
*
* @param caplen The number of bytes valid in *data*.
*
* @param len The wire length of the packet, which must be more or
* equal *caplen* (but can't be less).
*
* @param data A pointer to the raw packet data, starting with the
* layer 2 header. The pointer must remain valid for the lifetime of
* the Packet instance, unless *copy* is true.
*
* @param copy If true, the constructor will make an internal copy of
* *data*, so that the caller can release its version.
*
* @param tag A textual tag to associate with the packet for
* differentiating the input streams.
*/
void Init(int link_type, struct timeval *ts, uint32 caplen,
uint32 len, const u_char *data, int copy = false,
std::string tag = std::string(""));
/**
* Returns true if parsing the layer 2 fields failed, including when
* no data was passed into the constructor in the first place.
*/
bool Layer2Valid()
{
return l2_valid;
}
/**
* Interprets the Layer 3 of the packet as IP and returns a
* correspondign object.
*/
const IP_Hdr IP() const
{ return IP_Hdr((struct ip *) (data + hdr_size), false); }
/**
* Returns a \c raw_pkt_hdr RecordVal, which includes layer 2 and
* also everything in IP_Hdr (i.e., IP4/6 + TCP/UDP/ICMP).
*/
RecordVal* BuildPktHdrVal() const;
/**
* Static method returning the link-layer header size for a given
* link type.
*
* @param link_type The link tyoe.
*
* @return The header size in bytes, or -1 if not known.
*/
static int GetLinkHeaderSize(int link_type);
/**
* Describes the packet, with standard signature.
*/
void Describe(ODesc* d) const;
/**
* Serializes the packet, with standard signature.
*/
bool Serialize(SerialInfo* info) const;
/**
* Unserializes the packet, with standard signature.
*/
static Packet* Unserialize(UnserialInfo* info);
/**
* Maximal length of a layer 2 address.
*/
static const int l2_addr_len = 6;
// These are passed in through the constructor.
std::string tag; /// Used in serialization
double time; /// Timestamp reconstituted as float
struct timeval ts; /// Capture timestamp
const u_char* data; /// Packet data.
uint32 len; /// Actual length on wire
uint32 cap_len; /// Captured packet length
uint32 link_type; /// pcap link_type (DLT_EN10MB, DLT_RAW, etc)
// These are computed from Layer 2 data. These fields are only valid if
// Layer2Valid() returns true.
/**
* Layer 2 header size. Valid iff Layer2Valid() returns true.
*/
uint32 hdr_size;
/**
* Layer 3 protocol identified (if any). Valid iff Layer2Valid()
* returns true.
*/
Layer3Proto l3_proto;
/**
* If layer 2 is Ethernet, innermost ethertype field. Valid iff
* Layer2Valid() returns true.
*/
uint32 eth_type;
/**
* Layer 2 source address. Valid iff Layer2Valid() returns true.
*/
const u_char* l2_src;
/**
* Layer 2 destination address. Valid iff Layer2Valid() returns
* true.
*/
const u_char* l2_dst;
/**
* (Outermost) VLAN tag if any, else 0. Valid iff Layer2Valid()
* returns true.
*/
uint32 vlan;
/**
* (Innermost) VLAN tag if any, else 0. Valid iff Layer2Valid()
* returns true.
*/
uint32 inner_vlan;
private:
// Calculate layer 2 attributes. Sets
void ProcessLayer2();
// Wrapper to generate a packet-level weird.
void Weird(const char* name);
// Renders an MAC address into its ASCII representation.
Val *FmtEUI48(const u_char *mac) const;
// True if we need to delete associated packet memory upon
// destruction.
bool copy;
// True if L2 processing succeeded.
bool l2_valid;
};
#endif // packet_h