L2 section similar to L3 and L4 sections.
Ticket: #6938.
if (!PacketIncreaseCheckLayers(p)) {
return TM_ECODE_FAILED;
}
- p->ethh = (EthernetHdr *)pkt;
+ EthernetHdr *ethh = PacketSetEthernet(p, pkt);
- SCLogDebug("p %p pkt %p ether type %04x", p, pkt, SCNtohs(p->ethh->eth_type));
+ SCLogDebug("p %p pkt %p ether type %04x", p, pkt, SCNtohs(ethh->eth_type));
- DecodeNetworkLayer(tv, dtv, SCNtohs(p->ethh->eth_type), p,
- pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN);
+ DecodeNetworkLayer(tv, dtv, SCNtohs(ethh->eth_type), p, pkt + ETHERNET_HEADER_LEN,
+ len - ETHERNET_HEADER_LEN);
return TM_ECODE_OK;
}
/* forward declaration since Packet struct definition requires this */
struct PacketQueue_;
+enum PacketL2Types {
+ PACKET_L2_UNKNOWN = 0,
+ PACKET_L2_ETHERNET,
+};
+
+struct PacketL2 {
+ enum PacketL2Types type;
+ union L2Hdrs {
+ EthernetHdr *ethh;
+ } hdrs;
+};
+
enum PacketL3Types {
PACKET_L3_UNKNOWN = 0,
PACKET_L3_IPV4,
/* pkt vars */
PktVar *pktvar;
- /* header pointers */
- EthernetHdr *ethh;
-
+ struct PacketL2 l2;
struct PacketL3 l3;
struct PacketL4 l4;
return 0;
}
+static inline bool PacketIsIPv6(const Packet *p)
+{
+ return p->l3.type == PACKET_L3_IPV6;
+}
+
static inline const IPV6Hdr *PacketGetIPv6(const Packet *p)
{
DEBUG_VALIDATE_BUG_ON(!PacketIsIPv6(p));
return p->l3.hdrs.ip6h;
}
-static inline bool PacketIsIPv6(const Packet *p)
+static inline void PacketClearL2(Packet *p)
{
- return p->l3.type == PACKET_L3_IPV6;
+ memset(&p->l2, 0, sizeof(p->l2));
+}
+
+/* Can be called multiple times, e.g. for DCE */
+static inline EthernetHdr *PacketSetEthernet(Packet *p, const uint8_t *buf)
+{
+ DEBUG_VALIDATE_BUG_ON(p->l2.type != PACKET_L2_UNKNOWN && p->l2.type != PACKET_L2_ETHERNET);
+ p->l2.type = PACKET_L2_ETHERNET;
+ p->l2.hdrs.ethh = (EthernetHdr *)buf;
+ return p->l2.hdrs.ethh;
+}
+
+static inline const EthernetHdr *PacketGetEthernet(const Packet *p)
+{
+ DEBUG_VALIDATE_BUG_ON(p->l2.type != PACKET_L2_ETHERNET);
+ return p->l2.hdrs.ethh;
+}
+
+static inline bool PacketIsEthernet(const Packet *p)
+{
+ return p->l2.type == PACKET_L2_ETHERNET;
}
static inline void PacketClearL3(Packet *p)
f->max_ttl_toclient = MAX(f->max_ttl_toclient, ttl);
}
-static inline void FlowUpdateEthernet(ThreadVars *tv, DecodeThreadVars *dtv,
- Flow *f, EthernetHdr *ethh, bool toserver)
+static inline void FlowUpdateEthernet(
+ ThreadVars *tv, DecodeThreadVars *dtv, Flow *f, const Packet *p, bool toserver)
{
- if (ethh && MacSetFlowStorageEnabled()) {
+ if (PacketIsEthernet(p) && MacSetFlowStorageEnabled()) {
+ const EthernetHdr *ethh = PacketGetEthernet(p);
MacSet *ms = FlowGetStorageById(f, MacSetGetFlowStorageID());
if (ms != NULL) {
if (toserver) {
f->flags &= ~FLOW_PROTO_DETECT_TS_DONE;
p->flags |= PKT_PROTO_DETECT_TS_DONE;
}
- FlowUpdateEthernet(tv, dtv, f, p->ethh, true);
+ FlowUpdateEthernet(tv, dtv, f, p, true);
/* update flow's ttl fields if needed */
if (PacketIsIPv4(p)) {
const IPV4Hdr *ip4h = PacketGetIPv4(p);
f->flags &= ~FLOW_PROTO_DETECT_TC_DONE;
p->flags |= PKT_PROTO_DETECT_TC_DONE;
}
- FlowUpdateEthernet(tv, dtv, f, p->ethh, false);
+ FlowUpdateEthernet(tv, dtv, f, p, false);
/* update flow's ttl fields if needed */
if (PacketIsIPv4(p)) {
const IPV4Hdr *ip4h = PacketGetIPv4(p);
{
if (p != NULL) {
/* this is a packet context, so we need to add scalar fields */
- if (p->ethh != NULL) {
+ if (PacketIsEthernet(p)) {
+ const EthernetHdr *ethh = PacketGetEthernet(p);
jb_open_object(js, "ether");
- uint8_t *src = p->ethh->eth_src;
- uint8_t *dst = p->ethh->eth_dst;
+ const uint8_t *src = ethh->eth_src;
+ const uint8_t *dst = ethh->eth_dst;
JSONFormatAndAddMACAddr(js, "src_mac", src, false);
JSONFormatAndAddMACAddr(js, "dest_mac", dst, false);
jb_close(js);
PktVarFree(p->pktvar);
p->pktvar = NULL;
}
- p->ethh = NULL;
+ PacketClearL2(p);
PacketClearL3(p);
PacketClearL4(p);
if (p->tcph != NULL) {
uint32_t src4, dst4;
uint16_t sp, dp;
uint16_t len;
- uint8_t *smac, *dmac;
+ const uint8_t *smac, *dmac;
} Libnet11Packet;
static inline libnet_t *GetCtx(const Packet *p, int injection_type)
static inline void SetupEthernet(Packet *p, Libnet11Packet *lpacket, enum RejectDirection dir)
{
+ const EthernetHdr *ethh = PacketGetEthernet(p);
switch (dir) {
case REJECT_DIR_SRC:
- lpacket->smac = p->ethh->eth_dst;
- lpacket->dmac = p->ethh->eth_src;
+ lpacket->smac = ethh->eth_dst;
+ lpacket->dmac = ethh->eth_src;
break;
case REJECT_DIR_DST:
default:
- lpacket->smac = p->ethh->eth_src;
- lpacket->dmac = p->ethh->eth_dst;
+ lpacket->smac = ethh->eth_src;
+ lpacket->dmac = ethh->eth_dst;
break;
}
}
#include "decode-raw.h"
#include "decode-vntag.h"
#include "decode-vxlan.h"
+#include "decode-pppoe.h"
#include "output-json-stats.h"
}
}
- if (p->ethh == NULL) {
+ if (!PacketIsEthernet(p)) {
SCLogWarning("packet should have an ethernet header");
return;
}
+ const EthernetHdr *ethh = PacketGetEthernet(p);
/* Index of the network device */
socket_address.sll_ifindex = SC_ATOMIC_GET(p->afp_v.peer->if_idx);
/* Address length*/
socket_address.sll_halen = ETH_ALEN;
/* Destination MAC */
- memcpy(socket_address.sll_addr, p->ethh, 6);
+ memcpy(socket_address.sll_addr, ethh, 6);
/* Send packet, locking the socket if necessary */
if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
/* update the packet raw data pointer to start at the new offset */
(void)PacketSetData(p, pstart, plen);
/* update ethernet header pointer to point to the new start of the data */
- p->ethh = (void *)pstart;
+ p->l2.hdrs.ethh = (void *)pstart;
}
}
}
SET_PKT_LEN(p1, ethlen + ipv4len + tcplen + buflen);
- p1->ethh = (EthernetHdr *)raw_eth;
+ PacketSetEthernet(p1, raw_eth);
PacketSetIPV4(p1, raw_ipv4);
p1->tcph = (TCPHdr *)raw_tcp;
p1->src.family = AF_INET;
FAIL_IF(PacketCopyDataOffset(p1, ethlen + ipv4len + tcplen, buf, buflen) == -1);
SET_PKT_LEN(p1, ethlen + ipv4len + tcplen + buflen);
- p1->ethh = (EthernetHdr *)raw_eth;
+ PacketSetEthernet(p1, raw_eth);
PacketSetIPV4(p1, raw_ipv4);
p1->tcph = (TCPHdr *)raw_tcp;
p1->src.family = AF_INET;