Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions cpworker/src/output_zmq.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,7 @@ int zmq_send_packet(output_base_t *self, const struct pcap_pkthdr *header, const
uint16_t ether_type = ntohs(eth_hdr_copy.ether_type);
size_t vlan_total_size = 0;

while (ether_type == ETHERTYPE_VLAN || ether_type == ETHERTYPE_DOT1AD || ether_type == ETHERTYPE_VLAN_9100 ||
ether_type == ETHERTYPE_VLAN_9200)
while (is_vlan_ethertype(ether_type))
{
size_t vlan_offset = sizeof(struct ether_header) + vlan_total_size;
if (vlan_offset + sizeof(struct vlan_header) > data_len)
Expand Down
32 changes: 9 additions & 23 deletions cpworker/src/req_pattern.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,6 @@ static bool evaluate(Node *node, const ip_addr_t *ip, uint16_t port)
#define IPPORT_FLAGS_IP 0x01
#define IPPORT_FLAGS_PORT 0x02

static int extract_ipport_from_vlan_layer(const struct pcap_pkthdr *header, const uint8_t *pkt_data, size_t data_offset,
ip_addr_t *sip, uint16_t *sport, ip_addr_t *dip, uint16_t *dport);
static int extract_ipport_from_ipv4_layer(const struct pcap_pkthdr *header, const uint8_t *pkt_data, size_t data_offset,
ip_addr_t *sip, uint16_t *sport, ip_addr_t *dip, uint16_t *dport);
static int extract_ipport_from_ipv6_layer(const struct pcap_pkthdr *header, const uint8_t *pkt_data, size_t data_offset,
Expand All @@ -376,33 +374,21 @@ static int extract_ipport_from_ether_layer(const struct pcap_pkthdr *header, con
uint16_t eth_type = ntohs(eth_hdr->ether_type);
size_t next_data_offset = data_offset + eth_hdr_len;

if (eth_type == ETHERTYPE_IP)
return extract_ipport_from_ipv4_layer(header, pkt_data, next_data_offset, sip, sport, dip, dport);
else if (eth_type == ETHERTYPE_IPV6)
return extract_ipport_from_ipv6_layer(header, pkt_data, next_data_offset, sip, sport, dip, dport);
else if (eth_type == ETHERTYPE_VLAN)
return extract_ipport_from_vlan_layer(header, pkt_data, next_data_offset, sip, sport, dip, dport);

return 0;
}

static int extract_ipport_from_vlan_layer(const struct pcap_pkthdr *header, const uint8_t *pkt_data, size_t data_offset,
ip_addr_t *sip, uint16_t *sport, ip_addr_t *dip, uint16_t *dport)
{
size_t vlan_hdr_len = sizeof(struct vlan_header);
if (header->caplen < data_offset + vlan_hdr_len)
return 0;
// Skip the whole tag stack (802.1Q, QinQ) to reach the IP layer
while (is_vlan_ethertype(eth_type))
{
if (header->caplen < next_data_offset + sizeof(struct vlan_header))
return 0;

struct vlan_header *vlan_hdr = (struct vlan_header *)(pkt_data + data_offset);
uint16_t eth_type = ntohs(vlan_hdr->ether_type);
size_t next_data_offset = data_offset + vlan_hdr_len;
struct vlan_header *vlan_hdr = (struct vlan_header *)(pkt_data + next_data_offset);
eth_type = ntohs(vlan_hdr->ether_type);
next_data_offset += sizeof(struct vlan_header);
}

if (eth_type == ETHERTYPE_IP)
return extract_ipport_from_ipv4_layer(header, pkt_data, next_data_offset, sip, sport, dip, dport);
else if (eth_type == ETHERTYPE_IPV6)
return extract_ipport_from_ipv6_layer(header, pkt_data, next_data_offset, sip, sport, dip, dport);
else if (eth_type == ETHERTYPE_VLAN)
return extract_ipport_from_vlan_layer(header, pkt_data, next_data_offset, sip, sport, dip, dport);

return 0;
}
Expand Down
9 changes: 9 additions & 0 deletions cpworker/src/vlan.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef CPWORKER_VLAN_H
#define CPWORKER_VLAN_H

#include <net/ethernet.h>
#include <stdbool.h>
#include <stdint.h>

struct vlan_header
Expand All @@ -21,4 +23,11 @@ struct vlan_tag
#define ETHERTYPE_VLAN_9100 0x9100
#define ETHERTYPE_VLAN_9200 0x9200

// 802.1Q, 802.1ad and the legacy 0x9100/0x9200 QinQ TPIDs all carry a 4-byte tag (TCI + next EtherType)
static inline bool is_vlan_ethertype(uint16_t ether_type)
{
return ether_type == ETHERTYPE_VLAN || ether_type == ETHERTYPE_DOT1AD || ether_type == ETHERTYPE_VLAN_9100 ||
ether_type == ETHERTYPE_VLAN_9200;
}

#endif /* CPWORKER_VLAN_H */
1 change: 1 addition & 0 deletions cpworker/tests/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ set(unity_tests
output_rotating_file
output_zmq
packet_split
req_pattern
unix_control
)

Expand Down
Loading
Loading