diff --git a/src/Net.cc b/src/Net.cc index c63d706ef4..2a368c47ef 100644 --- a/src/Net.cc +++ b/src/Net.cc @@ -270,7 +270,7 @@ void net_packet_dispatch(double t, const Packet* pkt, iosource::PktSrc* src_ps) } } - sessions->DispatchPacket(t, pkt, src_ps); + sessions->NextPacket(t, pkt); mgr.Drain(); if ( sp ) diff --git a/src/NetVar.cc b/src/NetVar.cc index dc049005bb..5585cf8211 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -226,8 +226,6 @@ int suppress_local_output; double timer_mgr_inactivity_timeout; -int time_machine_profiling; - StringVal* trace_output_file; int record_all_packets; @@ -522,7 +520,6 @@ void init_net_var() timer_mgr_inactivity_timeout = opt_internal_double("timer_mgr_inactivity_timeout"); - time_machine_profiling = opt_internal_int("time_machine_profiling"); script_id = internal_type("script_id")->AsRecordType(); id_table = internal_type("id_table")->AsTableType(); diff --git a/src/NetVar.h b/src/NetVar.h index efadaaad6d..97018121f9 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -230,8 +230,6 @@ extern int suppress_local_output; extern double timer_mgr_inactivity_timeout; -extern int time_machine_profiling; - extern StringVal* trace_output_file; extern int record_all_packets; diff --git a/src/Serializer.cc b/src/Serializer.cc index 554e8b36b6..49e57c0216 100644 --- a/src/Serializer.cc +++ b/src/Serializer.cc @@ -1122,87 +1122,3 @@ void EventPlayer::Process() ne_time = 0; } - -void Packet::Describe(ODesc* d) const - { - const IP_Hdr ip = IP(); - d->Add(ip.SrcAddr()); - d->Add("->"); - d->Add(ip.DstAddr()); - } - -bool Packet::Serialize(SerialInfo* info) const - { - return SERIALIZE(uint32(ts.tv_sec)) && - SERIALIZE(uint32(ts.tv_usec)) && - SERIALIZE(uint32(len)) && - SERIALIZE(link_type) && - info->s->Write(tag.c_str(), tag.length(), "tag") && - info->s->Write((const char*)data, cap_len, "data"); - } - -static BroFile* profiling_output = 0; - -#ifdef DEBUG -static iosource::PktDumper* dump = 0; -#endif - -Packet* Packet::Unserialize(UnserialInfo* info) - { - struct timeval ts; - uint32 len, link_type; - - if ( ! (UNSERIALIZE((uint32 *)&ts.tv_sec) && - UNSERIALIZE((uint32 *)&ts.tv_usec) && - UNSERIALIZE(&len) && - UNSERIALIZE(&link_type)) ) - return 0; - - char* tag; - if ( ! info->s->Read((char**) &tag, 0, "tag") ) - return 0; - - const u_char* pkt; - int caplen; - if ( ! info->s->Read((char**) &pkt, &caplen, "data") ) - { - delete [] tag; - return 0; - } - - Packet *p = new Packet(link_type, &ts, caplen, len, pkt, true, - std::string(tag)); - delete [] tag; - - // For the global timer manager, we take the global network_time as the - // packet's timestamp for feeding it into our packet loop. - if ( p->tag == "" ) - p->time = timer_mgr->Time(); - else - p->time = p->ts.tv_sec + double(p->ts.tv_usec) / 1e6; - - if ( time_machine_profiling ) - { - if ( ! profiling_output ) - profiling_output = - new BroFile("tm-prof.packets.log", "w"); - - profiling_output->Write(fmt("%.6f %s %d\n", current_time(), - (p->tag != "" ? p->tag.c_str() : "-"), p->len)); - } - -#ifdef DEBUG - if ( debug_logger.IsEnabled(DBG_TM) ) - { - if ( ! dump ) - dump = iosource_mgr->OpenPktDumper("tm.pcap", true); - - if ( dump ) - { - dump->Dump(p); - } - } -#endif - - return p; - } diff --git a/src/Sessions.cc b/src/Sessions.cc index 0d4e42e534..7b7974bfce 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -15,7 +15,6 @@ #include "Sessions.h" #include "Reporter.h" #include "OSFinger.h" -#include "iosource/Layer2.h" #include "analyzer/protocol/icmp/ICMP.h" #include "analyzer/protocol/udp/UDP.h" @@ -166,22 +165,17 @@ void NetSessions::Done() { } -void NetSessions::DispatchPacket(double t, const Packet* pkt, - iosource::PktSrc* src_ps) +void NetSessions::NextPacket(double t, const Packet* pkt) { SegmentProfiler(segment_logger, "dispatching-packet"); if ( raw_packet ) { val_list* vl = new val_list(); - L2_Hdr l2_hdr(pkt); - vl->append(l2_hdr.BuildPktHdrVal()); + vl->append(pkt->BuildPktHdrVal()); mgr.QueueEvent(raw_packet, vl); } - ProcNextPacket(t, pkt); - } - if ( pkt_profiler ) pkt_profiler->ProfilePkt(t, pkt->cap_len); diff --git a/src/Sessions.h b/src/Sessions.h index 6561b555e7..1780bbdb24 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -66,11 +66,8 @@ public: NetSessions(); ~NetSessions(); - // Main entry point for packet processing. Dispatches the packet - // either through NextPacket(), optionally employing the packet - // sorter first. - void DispatchPacket(double t, const Packet* pkt, - iosource::PktSrc* src_ps); + // Main entry point for packet processing. + void NextPacket(double t, const Packet* pkt); void Done(); // call to drain events before destructing diff --git a/src/iosource/CMakeLists.txt b/src/iosource/CMakeLists.txt index b08e62334a..b1de9bddaf 100644 --- a/src/iosource/CMakeLists.txt +++ b/src/iosource/CMakeLists.txt @@ -11,7 +11,6 @@ add_subdirectory(pcap) set(iosource_SRCS BPF_Program.cc Component.cc - Layer2.cc Manager.cc Packet.cc PktDumper.cc diff --git a/src/iosource/Layer2.cc b/src/iosource/Layer2.cc deleted file mode 100644 index b7e8c508f3..0000000000 --- a/src/iosource/Layer2.cc +++ /dev/null @@ -1,117 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -#include "IP.h" -#include "Type.h" -#include "Val.h" -#include "Var.h" -#include "NetVar.h" -#include "iosource/Layer2.h" -#include "iosource/Packet.h" - -extern "C" { -#include -#include -#include -#include -#include -#include -#ifdef HAVE_NET_ETHERNET_H -#include -#elif defined(HAVE_SYS_ETHERNET_H) -#include -#elif defined(HAVE_NETINET_IF_ETHER_H) -#include -#elif defined(HAVE_NET_ETHERTYPES_H) -#include -#endif -} - - -Val *L2_Hdr::fmt_eui48(const u_char *mac) const - { - char buf[20]; - snprintf(buf, sizeof buf, "%02x:%02x:%02x:%02x:%02x:%02x", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return new StringVal(buf); - } - -RecordVal* L2_Hdr::BuildPktHdrVal() const - { - static RecordType* l2_hdr_type = 0; - static RecordType* raw_pkt_hdr_type = 0; - - if ( ! raw_pkt_hdr_type ) - { - raw_pkt_hdr_type = internal_type("raw_pkt_hdr")->AsRecordType(); - l2_hdr_type = internal_type("l2_hdr")->AsRecordType(); - } - - RecordVal* pkt_hdr = new RecordVal(raw_pkt_hdr_type); - RecordVal* l2_hdr = new RecordVal(l2_hdr_type); - - int is_ethernet = (pkt->link_type == DLT_EN10MB) ? 1 : 0; - - int l3 = BifEnum::L3_UNKNOWN; - - if ( pkt->l3_proto == L3_IPV4 ) - l3 = BifEnum::L3_IPV4; - - else if ( pkt->l3_proto == L3_IPV6 ) - l3 = BifEnum::L3_IPV6; - - else if ( pkt->l3_proto == L3_ARP ) - l3 = BifEnum::L3_ARP; - - // l2_hdr layout: - // encap: link_encap; ##< L2 link encapsulation - // len: count; ##< Total frame length on wire - // cap_len: count; ##< Captured length - // src: string &optional; ##< L2 source (if ethernet) - // dst: string &optional; ##< L2 destination (if ethernet) - // vlan: count &optional; ##< VLAN tag if any (and ethernet) - // ethertype: count &optional; ##< If ethernet - // proto: layer3_proto; ##< L3 proto - - if ( is_ethernet ) - { - // Ethernet header layout is: - // dst[6bytes] src[6bytes] ethertype[2bytes]... - l2_hdr->Assign(0, new EnumVal(BifEnum::LINK_ETHERNET, BifType::Enum::link_encap)); - l2_hdr->Assign(3, fmt_eui48(pkt->data + 6)); // src - l2_hdr->Assign(4, fmt_eui48(pkt->data)); // dst - - if ( pkt->vlan ) - l2_hdr->Assign(5, new Val(pkt->vlan, TYPE_COUNT)); - - l2_hdr->Assign(6, new Val(pkt->eth_type, TYPE_COUNT)); - - if ( pkt->eth_type == ETHERTYPE_ARP || pkt->eth_type == ETHERTYPE_REVARP ) - // We also identify ARP for L3 over ethernet - l3 = BifEnum::L3_ARP; - } - else - l2_hdr->Assign(0, new EnumVal(BifEnum::LINK_UNKNOWN, BifType::Enum::link_encap)); - - l2_hdr->Assign(1, new Val(pkt->len, TYPE_COUNT)); - l2_hdr->Assign(2, new Val(pkt->cap_len, TYPE_COUNT)); - - l2_hdr->Assign(7, new EnumVal(l3, BifType::Enum::layer3_proto)); - - pkt_hdr->Assign(0, l2_hdr); - - if ( pkt->l3_proto == L3_IPV4 ) - { - IP_Hdr ip_hdr((const struct ip*)(pkt->data + pkt->hdr_size), false); - return ip_hdr.BuildPktHdrVal(pkt_hdr, 1); - } - - else if ( pkt->l3_proto == L3_IPV6 ) - { - IP_Hdr ip6_hdr((const struct ip6_hdr*)(pkt->data + pkt->hdr_size), false, pkt->cap_len); - return ip6_hdr.BuildPktHdrVal(pkt_hdr, 1); - } - - else - return pkt_hdr; - } - diff --git a/src/iosource/Layer2.h b/src/iosource/Layer2.h deleted file mode 100644 index 7152836ffc..0000000000 --- a/src/iosource/Layer2.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef l2_h -#define l2_h - -#include "config.h" -#include "net_util.h" -#include "IP.h" -#include "Reporter.h" -#include "Val.h" -#include "Type.h" -#include - -class Packet; - -/** - * A class that wraps an L2 packet. - */ -class L2_Hdr { -public: - L2_Hdr(const Packet *arg_pkt) : pkt(arg_pkt) { } - ~L2_Hdr() { } - - /** - * Returns a raw_pkt_hdr RecordVal, which includes L2 and also - * everything in IP_Hdr (i.e. IP4/6 + tcp/udp/icmp) - */ - RecordVal* BuildPktHdrVal() const; - -private: - Val *fmt_eui48(const u_char *mac) const; - const Packet *pkt; -}; - -#endif diff --git a/src/iosource/Packet.cc b/src/iosource/Packet.cc index 41e5e31a8e..2ff910ed52 100644 --- a/src/iosource/Packet.cc +++ b/src/iosource/Packet.cc @@ -1,6 +1,54 @@ #include "Packet.h" #include "Sessions.h" +#include "iosource/Manager.h" + +extern "C" { +#ifdef HAVE_NET_ETHERNET_H +#include +#elif defined(HAVE_SYS_ETHERNET_H) +#include +#elif defined(HAVE_NETINET_IF_ETHER_H) +#include +#elif defined(HAVE_NET_ETHERTYPES_H) +#include +#endif +} + +void Packet::Init(int arg_link_type, struct timeval *arg_ts, uint32 arg_caplen, + uint32 arg_len, const u_char *arg_data, int arg_copy, + std::string arg_tag) + { + if ( data && copy ) + delete [] data; + + link_type = arg_link_type; + ts = *arg_ts; + cap_len = arg_caplen; + len = arg_len; + tag = arg_tag; + + copy = arg_copy; + + if ( arg_data && arg_copy ) + { + data = new u_char[arg_caplen]; + memcpy(const_cast(data), arg_data, arg_caplen); + } + else + data = arg_data; + + time = ts.tv_sec + double(ts.tv_usec) / 1e6; + hdr_size = GetLinkHeaderSize(arg_link_type); + l3_proto = L3_UNKNOWN; + eth_type = 0; + vlan = 0; + + l2_valid = false; + + if ( data ) + ProcessLayer2(); + } void Packet::Weird(const char* name) { @@ -261,10 +309,169 @@ void Packet::ProcessLayer2() } // We've now determined (a) L3_IPV4 vs (b) L3_IPV6 vs - // (c) L3_ARP vs (d) L3_UNKNOWN (0 == anything else) + // (c) L3_ARP vs (d) L3_UNKNOWN. l3_proto = l3_proto; // Calculate how much header we've used up. hdr_size = (pdata - data); } +RecordVal* Packet::BuildPktHdrVal() const + { + static RecordType* l2_hdr_type = 0; + static RecordType* raw_pkt_hdr_type = 0; + + if ( ! raw_pkt_hdr_type ) + { + raw_pkt_hdr_type = internal_type("raw_pkt_hdr")->AsRecordType(); + l2_hdr_type = internal_type("l2_hdr")->AsRecordType(); + } + + RecordVal* pkt_hdr = new RecordVal(raw_pkt_hdr_type); + RecordVal* l2_hdr = new RecordVal(l2_hdr_type); + + int is_ethernet = (link_type == DLT_EN10MB) ? 1 : 0; + + int l3 = BifEnum::L3_UNKNOWN; + + if ( l3_proto == L3_IPV4 ) + l3 = BifEnum::L3_IPV4; + + else if ( l3_proto == L3_IPV6 ) + l3 = BifEnum::L3_IPV6; + + else if ( l3_proto == L3_ARP ) + l3 = BifEnum::L3_ARP; + + // l2_hdr layout: + // encap: link_encap; ##< L2 link encapsulation + // len: count; ##< Total frame length on wire + // cap_len: count; ##< Captured length + // src: string &optional; ##< L2 source (if ethernet) + // dst: string &optional; ##< L2 destination (if ethernet) + // vlan: count &optional; ##< VLAN tag if any (and ethernet) + // ethertype: count &optional; ##< If ethernet + // proto: layer3_proto; ##< L3 proto + + if ( is_ethernet ) + { + // Ethernet header layout is: + // dst[6bytes] src[6bytes] ethertype[2bytes]... + l2_hdr->Assign(0, new EnumVal(BifEnum::LINK_ETHERNET, BifType::Enum::link_encap)); + l2_hdr->Assign(3, FmtEUI48(data + 6)); // src + l2_hdr->Assign(4, FmtEUI48(data)); // dst + + if ( vlan ) + l2_hdr->Assign(5, new Val(vlan, TYPE_COUNT)); + + l2_hdr->Assign(6, new Val(eth_type, TYPE_COUNT)); + + if ( eth_type == ETHERTYPE_ARP || eth_type == ETHERTYPE_REVARP ) + // We also identify ARP for L3 over ethernet + l3 = BifEnum::L3_ARP; + } + else + l2_hdr->Assign(0, new EnumVal(BifEnum::LINK_UNKNOWN, BifType::Enum::link_encap)); + + l2_hdr->Assign(1, new Val(len, TYPE_COUNT)); + l2_hdr->Assign(2, new Val(cap_len, TYPE_COUNT)); + + l2_hdr->Assign(7, new EnumVal(l3, BifType::Enum::layer3_proto)); + + pkt_hdr->Assign(0, l2_hdr); + + if ( l3_proto == L3_IPV4 ) + { + IP_Hdr ip_hdr((const struct ip*)(data + hdr_size), false); + return ip_hdr.BuildPktHdrVal(pkt_hdr, 1); + } + + else if ( l3_proto == L3_IPV6 ) + { + IP_Hdr ip6_hdr((const struct ip6_hdr*)(data + hdr_size), false, cap_len); + return ip6_hdr.BuildPktHdrVal(pkt_hdr, 1); + } + + else + return pkt_hdr; + } + +Val *Packet::FmtEUI48(const u_char *mac) const + { + char buf[20]; + snprintf(buf, sizeof buf, "%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return new StringVal(buf); + } + +void Packet::Describe(ODesc* d) const + { + const IP_Hdr ip = IP(); + d->Add(ip.SrcAddr()); + d->Add("->"); + d->Add(ip.DstAddr()); + } + +bool Packet::Serialize(SerialInfo* info) const + { + return SERIALIZE(uint32(ts.tv_sec)) && + SERIALIZE(uint32(ts.tv_usec)) && + SERIALIZE(uint32(len)) && + SERIALIZE(link_type) && + info->s->Write(tag.c_str(), tag.length(), "tag") && + info->s->Write((const char*)data, cap_len, "data"); + } + +#ifdef DEBUG +static iosource::PktDumper* dump = 0; +#endif + +Packet* Packet::Unserialize(UnserialInfo* info) + { + struct timeval ts; + uint32 len, link_type; + + if ( ! (UNSERIALIZE((uint32 *)&ts.tv_sec) && + UNSERIALIZE((uint32 *)&ts.tv_usec) && + UNSERIALIZE(&len) && + UNSERIALIZE(&link_type)) ) + return 0; + + char* tag; + if ( ! info->s->Read((char**) &tag, 0, "tag") ) + return 0; + + const u_char* pkt; + int caplen; + if ( ! info->s->Read((char**) &pkt, &caplen, "data") ) + { + delete [] tag; + return 0; + } + + Packet *p = new Packet(link_type, &ts, caplen, len, pkt, true, + std::string(tag)); + delete [] tag; + + // For the global timer manager, we take the global network_time as the + // packet's timestamp for feeding it into our packet loop. + if ( p->tag == "" ) + p->time = timer_mgr->Time(); + else + p->time = p->ts.tv_sec + double(p->ts.tv_usec) / 1e6; + +#ifdef DEBUG + if ( debug_logger.IsEnabled(DBG_TM) ) + { + if ( ! dump ) + dump = iosource_mgr->OpenPktDumper("tm.pcap", true); + + if ( dump ) + { + dump->Dump(p); + } + } +#endif + + return p; + } diff --git a/src/iosource/Packet.h b/src/iosource/Packet.h index f4f4c01709..eaa1b90210 100644 --- a/src/iosource/Packet.h +++ b/src/iosource/Packet.h @@ -5,94 +5,125 @@ #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, - L3_IPV4 = 1, - L3_IPV6 = 2, - L3_ARP = 3, + 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. - +/** + * 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: - Packet() + /** + * 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) + { + Init(link_type, ts, caplen, len, data, copy, tag); + } + + /** + * Default constructor. For internal use only. + */ + Packet() : data(0) { struct timeval ts = {0, 0}; Init(0, &ts, 0, 0, 0); } - // Construct and initialize from packet data. - // - // arg_free: If true makes an internal copy of the *data*. If false, - // stores just a pointer to *data*, which must remain valid. - Packet(int arg_link_type, struct timeval *arg_ts, uint32 arg_caplen, - uint32 arg_len, const u_char *arg_data, int arg_free = false, - std::string arg_tag = std::string("")) - { - Init(arg_link_type, arg_ts, arg_caplen, arg_len, arg_data, arg_free, arg_tag); - } + /** + * Destructor. + */ ~Packet() { - if ( free ) + if ( copy ) delete [] data; } - // Initialize with data from pointer. - // - // arg_free: If true makes an internal copy of the *data*. If false, - // stores just a pointer to *data*, which must remain valid. - void Init(int arg_link_type, struct timeval *arg_ts, uint32 arg_caplen, - uint32 arg_len, const u_char *arg_data, int arg_free = false, - std::string arg_tag = std::string(""), uint32 arg_hdrsize = 0) - { - link_type = arg_link_type; - ts = *arg_ts; - cap_len = arg_caplen; - len = arg_len; - free = arg_free; + /** + * (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("")); - if ( free ) - { - data = new u_char[cap_len]; - memcpy(const_cast(data), arg_data, cap_len); - } - else - data = arg_data; - - hdr_size = arg_hdrsize; - l3_proto = L3_UNKNOWN; - tag = arg_tag; - time = ts.tv_sec + double(ts.tv_usec) / 1e6; - eth_type = 0; - vlan = 0; - - l2_valid = false; - - if ( data ) - ProcessLayer2(); - } - - const IP_Hdr IP() const - { return IP_Hdr((struct ip *) (data + hdr_size), false); } - - // Returns true if parsing the Layer 2 fields failed, including when - // no data was passed into the constructor in the first place. + /** + * 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; } - void Describe(ODesc* d) const; + /** + * 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); } /** - * Helper method to return the header size for a given link tyoe. + * 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. * @@ -100,7 +131,19 @@ public: */ 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); // These are passed in through the constructor. @@ -114,10 +157,29 @@ public: // These are computed from Layer 2 data. These fields are only valid if // Layer2Valid() returns true. - uint32 hdr_size; /// Layer 2 header size - Layer3Proto l3_proto; /// Layer 3 protocol identified (if any) - uint32 eth_type; /// If L2==ethernet, innermost ethertype field - uint32 vlan; /// (Outermost) VLan tag if any, else 0 + + /** + * 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; /// + + /** + * (Outermost) VLAN tag if any, else 0. Valid iff Layer2Valid() + * returns true. + */ + uint32 vlan; /// private: // Calculate layer 2 attributes. Sets @@ -126,8 +188,12 @@ private: // Wrapper to generate a packet-level weird. void Weird(const char* name); - // should we delete associated packet memory upon destruction. - bool free; + // 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;