Skip to content

Commit

Permalink
ndp input plugin - add parser that works with metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
jaroslavpesek committed Nov 5, 2024
1 parent c288312 commit 161bd1a
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 47 deletions.
31 changes: 7 additions & 24 deletions input/ndp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ void NdpPacketReader::parse_ctt_metadata(const ndp_packet *ndp_packet, Metadata_
ctt.vlan_tci = extract(metadata, 64, 16);
ctt.vlan_vld = extract(metadata, 80, 1);
ctt.vlan_stripped = extract(metadata, 81, 1);
ctt.ip_csum_status = extract(metadata, 82, 2);
ctt.l4_csum_status = extract(metadata, 84, 2);
ctt.parser_status = extract(metadata, 86, 2);
ctt.ip_csum_status = static_cast<CsumStatus>(extract(metadata, 82, 2));
ctt.l4_csum_status = static_cast<CsumStatus>(extract(metadata, 84, 2));
ctt.parser_status = static_cast<ParserStatus>(extract(metadata, 86, 2));
ctt.ifc = extract(metadata, 88, 8);
ctt.filter_bitmap = extract(metadata, 96, 16);
ctt.ctt_export_trig = extract(metadata, 112, 1);
Expand All @@ -135,9 +135,9 @@ void NdpPacketReader::parse_ctt_metadata(const ndp_packet *ndp_packet, Metadata_
ctt.l2_len = extract(metadata, 192, 7);
ctt.l3_len = extract(metadata, 199, 9);
ctt.l4_len = extract(metadata, 208, 8);
ctt.l2_ptype = extract(metadata, 216, 4);
ctt.l3_ptype = extract(metadata, 220, 4);
ctt.l4_ptype = extract(metadata, 224, 4);
ctt.l2_ptype = static_cast<L2PType>(extract(metadata, 216, 4));
ctt.l3_ptype = static_cast<L3PType>(extract(metadata, 220, 4));
ctt.l4_ptype = static_cast<L4PType>(extract(metadata, 224, 4));

return;
}
Expand Down Expand Up @@ -166,24 +166,7 @@ InputPlugin::Result NdpPacketReader::get(PacketBlock &packets)
if (m_ctt_metadata) {
Metadata_CTT ctt;
parse_ctt_metadata(ndp_packet, ctt);
parse_packet(&opt, m_parser_stats, timestamp, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);

Packet *pkt = &opt.pblock->pkts[opt.pblock->cnt - 1];

// verify metadata with original parser
if(ctt.l2_len + ctt.l3_len + ctt.l4_len != pkt->packet_len - pkt->payload_len) {
printf("Error: ctt.l2_len (%d) + ctt.l3_len (%d) + ctt.l4_len (%d) != pkt->packet_len (%d) - pkt->payload_len (%d)\n", ctt.l2_len, ctt.l3_len, ctt.l4_len, pkt->packet_len, pkt->payload_len);
}
if(pkt->ip_proto == IPPROTO_TCP) {
if(ctt.l4_ptype != 0x1) {
printf("Error: ctt.l4_ptype (%d) != 0x1 but protocol is TCP (%d)\n", ctt.l4_ptype, pkt->ip_proto);
}
}
if(pkt->ip_proto == IPPROTO_UDP) {
if(ctt.l4_ptype != 0x2) {
printf("Error: ctt.l4_ptype (%d) != 0x2 but protocol is UDP (%d)\n", ctt.l4_ptype, pkt->ip_proto);
}
}
parse_packet_ctt_metadata(&opt, m_parser_stats, ctt, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
} else {
parse_packet(&opt, m_parser_stats, timestamp, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
}
Expand Down
25 changes: 2 additions & 23 deletions input/ndp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,9 @@
#include <ipfixprobe/options.hpp>
#include <ipfixprobe/utils.hpp>

namespace ipxp {
#include "ctt.hpp"

struct Metadata_CTT {
timeval ts;
uint16_t vlan_tci;
bool vlan_vld : 1;
bool vlan_stripped : 1;
uint8_t ip_csum_status : 2;
uint8_t l4_csum_status : 2;
uint8_t parser_status : 2;
uint8_t ifc;
uint16_t filter_bitmap;
uint8_t ctt_export_trig : 1;
uint8_t ctt_rec_matched : 1;
uint8_t ctt_rec_created : 1;
uint8_t ctt_rec_deleted : 1;
uint64_t flow_hash;
uint8_t l2_len : 7;
uint16_t l3_len : 9;
uint8_t l4_len : 8;
uint8_t l2_ptype : 4;
uint8_t l3_ptype : 4;
uint8_t l4_ptype : 4;
};
namespace ipxp {

class NdpOptParser : public OptionsParser
{
Expand Down
107 changes: 107 additions & 0 deletions input/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
*/

#include <config.h>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <iostream>
Expand All @@ -35,6 +36,7 @@

#include "parser.hpp"
#include "headers.hpp"
#include "ctt.hpp"
#include <ipfixprobe/packet.hpp>

namespace ipxp {
Expand Down Expand Up @@ -776,4 +778,109 @@ void parse_packet(parser_opt_t *opt, ParserStats& stats, struct timeval ts, cons
opt->pblock->bytes += len;
}

void parse_packet_ctt_metadata(parser_opt_t *opt, ParserStats& stats, const Metadata_CTT& metadata, const uint8_t *data, uint16_t len, uint16_t caplen)
{
if (opt->pblock->cnt >= opt->pblock->size) {
return;
}
Packet *pkt = &opt->pblock->pkts[opt->pblock->cnt];

pkt->packet_len_wire = len;
pkt->ts = metadata.ts;
pkt->src_port = 0;
pkt->dst_port = 0;
pkt->ip_proto = 0;
pkt->ip_ttl = 0;
pkt->ip_flags = 0;
pkt->ip_version = 0;
pkt->ip_payload_len = 0;
pkt->tcp_flags = 0;
pkt->tcp_window = 0;
pkt->tcp_options = 0;
pkt->tcp_mss = 0;
pkt->mplsTop = 0;

stats.seen_packets++;

uint16_t data_offset;
uint32_t l3_hdr_offset = metadata.l2_len;
uint32_t l4_hdr_offset = metadata.l2_len + metadata.l3_len;

try {
// L2
data_offset = parse_eth_hdr(data, caplen, pkt);
if (pkt->ethertype == ETH_P_TRILL) {
data_offset += parse_trill(data + metadata.l2_len, metadata.l2_len, pkt);
stats.trill_packets++;
data_offset += parse_eth_hdr(data + metadata.l2_len, metadata.l2_len, pkt);
}

// L3
if (metadata.l2_ptype == L2_ETHER_IP) {
if (metadata.l3_ptype == L3_IPV4 || metadata.l3_ptype == L3_IPV4_EXT) {
data_offset += parse_ipv4_hdr(data + metadata.l2_len, metadata.l3_len, pkt);
stats.ipv4_packets++;
} else if (metadata.l3_ptype == L3_IPV6 || metadata.l3_ptype == L3_IPV4_EXT) {
data_offset += parse_ipv6_hdr(data + metadata.l2_len, metadata.l3_len, pkt);
stats.ipv6_packets++;
}
} else if (metadata.l2_ptype == L2_ETHER_MPLS) {
data_offset += process_mpls(data + data_offset, caplen - data_offset, pkt);
stats.mpls_packets++;
} else if (metadata.l2_ptype == L2_ETHER_PPPOE) {
data_offset += process_pppoe(data + data_offset, caplen - data_offset, pkt);
stats.pppoe_packets++;
} else { // if not previous, we try delegate to original parser
parse_packet(opt, stats, metadata.ts, data, len, caplen);
return;
}

// L4
if (metadata.l4_ptype == L4_TCP) {
data_offset += parse_tcp_hdr(data + l4_hdr_offset, metadata.l4_len, pkt);
stats.tcp_packets++;
} else if (metadata.l4_ptype == L4_UDP) {
data_offset += parse_udp_hdr(data + l4_hdr_offset, metadata.l4_len, pkt);
stats.udp_packets++;
} else { // if not previous, we try delegate to original parser
parse_packet(opt, stats, metadata.ts, data, len, caplen);
return;
}
} catch (const char *err) {
DEBUG_MSG("%s\n", err);
return;
}

if (pkt->vlan_id) {
stats.vlan_packets++;
}

uint16_t pkt_len = caplen;
pkt->packet = data;
pkt->packet_len = caplen;

if (l4_hdr_offset != l3_hdr_offset) {
if (l4_hdr_offset + pkt->ip_payload_len < 64) {
// Packet contains 0x00 padding bytes, do not include them in payload
pkt_len = l4_hdr_offset + pkt->ip_payload_len;
}
pkt->payload_len_wire = pkt->ip_payload_len - (data_offset - l4_hdr_offset);
} else {
pkt->payload_len_wire = pkt_len - data_offset;
}

pkt->payload_len = pkt->payload_len_wire;
if (pkt->payload_len + data_offset > pkt_len) {
// Set correct size when payload length is bigger than captured payload length
pkt->payload_len = pkt_len - data_offset;
}
pkt->payload = pkt->packet + data_offset;

DEBUG_MSG("Payload length:\t%u\n", pkt->payload_len);
DEBUG_MSG("Packet parser exits: packet parsed\n");
opt->packet_valid = true;
opt->pblock->cnt++;
opt->pblock->bytes += len;
}

}
4 changes: 4 additions & 0 deletions input/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include <ipfixprobe/packet.hpp>
#include <ipfixprobe/parser-stats.hpp>

#include "ctt.hpp"

#ifdef WITH_PCAP
#include <pcap/pcap.h>
#include <pcap/sll.h>
Expand Down Expand Up @@ -85,5 +87,7 @@ typedef struct parser_opt_s {
*/
void parse_packet(parser_opt_t *opt, ParserStats& stats, struct timeval ts, const uint8_t *data, uint16_t len, uint16_t caplen);

void parse_packet_ctt_metadata(parser_opt_t *opt, ParserStats& stats, const Metadata_CTT& metadata, const uint8_t *data, uint16_t len, uint16_t caplen);

}
#endif /* IPXP_INPUT_PARSER_HPP */

0 comments on commit 161bd1a

Please sign in to comment.