Skip to content

Commit 161bd1a

Browse files
committed
ndp input plugin - add parser that works with metadata
1 parent c288312 commit 161bd1a

File tree

4 files changed

+120
-47
lines changed

4 files changed

+120
-47
lines changed

input/ndp.cpp

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ void NdpPacketReader::parse_ctt_metadata(const ndp_packet *ndp_packet, Metadata_
122122
ctt.vlan_tci = extract(metadata, 64, 16);
123123
ctt.vlan_vld = extract(metadata, 80, 1);
124124
ctt.vlan_stripped = extract(metadata, 81, 1);
125-
ctt.ip_csum_status = extract(metadata, 82, 2);
126-
ctt.l4_csum_status = extract(metadata, 84, 2);
127-
ctt.parser_status = extract(metadata, 86, 2);
125+
ctt.ip_csum_status = static_cast<CsumStatus>(extract(metadata, 82, 2));
126+
ctt.l4_csum_status = static_cast<CsumStatus>(extract(metadata, 84, 2));
127+
ctt.parser_status = static_cast<ParserStatus>(extract(metadata, 86, 2));
128128
ctt.ifc = extract(metadata, 88, 8);
129129
ctt.filter_bitmap = extract(metadata, 96, 16);
130130
ctt.ctt_export_trig = extract(metadata, 112, 1);
@@ -135,9 +135,9 @@ void NdpPacketReader::parse_ctt_metadata(const ndp_packet *ndp_packet, Metadata_
135135
ctt.l2_len = extract(metadata, 192, 7);
136136
ctt.l3_len = extract(metadata, 199, 9);
137137
ctt.l4_len = extract(metadata, 208, 8);
138-
ctt.l2_ptype = extract(metadata, 216, 4);
139-
ctt.l3_ptype = extract(metadata, 220, 4);
140-
ctt.l4_ptype = extract(metadata, 224, 4);
138+
ctt.l2_ptype = static_cast<L2PType>(extract(metadata, 216, 4));
139+
ctt.l3_ptype = static_cast<L3PType>(extract(metadata, 220, 4));
140+
ctt.l4_ptype = static_cast<L4PType>(extract(metadata, 224, 4));
141141

142142
return;
143143
}
@@ -166,24 +166,7 @@ InputPlugin::Result NdpPacketReader::get(PacketBlock &packets)
166166
if (m_ctt_metadata) {
167167
Metadata_CTT ctt;
168168
parse_ctt_metadata(ndp_packet, ctt);
169-
parse_packet(&opt, m_parser_stats, timestamp, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
170-
171-
Packet *pkt = &opt.pblock->pkts[opt.pblock->cnt - 1];
172-
173-
// verify metadata with original parser
174-
if(ctt.l2_len + ctt.l3_len + ctt.l4_len != pkt->packet_len - pkt->payload_len) {
175-
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);
176-
}
177-
if(pkt->ip_proto == IPPROTO_TCP) {
178-
if(ctt.l4_ptype != 0x1) {
179-
printf("Error: ctt.l4_ptype (%d) != 0x1 but protocol is TCP (%d)\n", ctt.l4_ptype, pkt->ip_proto);
180-
}
181-
}
182-
if(pkt->ip_proto == IPPROTO_UDP) {
183-
if(ctt.l4_ptype != 0x2) {
184-
printf("Error: ctt.l4_ptype (%d) != 0x2 but protocol is UDP (%d)\n", ctt.l4_ptype, pkt->ip_proto);
185-
}
186-
}
169+
parse_packet_ctt_metadata(&opt, m_parser_stats, ctt, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
187170
} else {
188171
parse_packet(&opt, m_parser_stats, timestamp, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
189172
}

input/ndp.hpp

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,30 +38,9 @@
3838
#include <ipfixprobe/options.hpp>
3939
#include <ipfixprobe/utils.hpp>
4040

41-
namespace ipxp {
41+
#include "ctt.hpp"
4242

43-
struct Metadata_CTT {
44-
timeval ts;
45-
uint16_t vlan_tci;
46-
bool vlan_vld : 1;
47-
bool vlan_stripped : 1;
48-
uint8_t ip_csum_status : 2;
49-
uint8_t l4_csum_status : 2;
50-
uint8_t parser_status : 2;
51-
uint8_t ifc;
52-
uint16_t filter_bitmap;
53-
uint8_t ctt_export_trig : 1;
54-
uint8_t ctt_rec_matched : 1;
55-
uint8_t ctt_rec_created : 1;
56-
uint8_t ctt_rec_deleted : 1;
57-
uint64_t flow_hash;
58-
uint8_t l2_len : 7;
59-
uint16_t l3_len : 9;
60-
uint8_t l4_len : 8;
61-
uint8_t l2_ptype : 4;
62-
uint8_t l3_ptype : 4;
63-
uint8_t l4_ptype : 4;
64-
};
43+
namespace ipxp {
6544

6645
class NdpOptParser : public OptionsParser
6746
{

input/parser.cpp

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
*/
2828

2929
#include <config.h>
30+
#include <cstdint>
3031
#include <cstdio>
3132
#include <cstring>
3233
#include <iostream>
@@ -35,6 +36,7 @@
3536

3637
#include "parser.hpp"
3738
#include "headers.hpp"
39+
#include "ctt.hpp"
3840
#include <ipfixprobe/packet.hpp>
3941

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

781+
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)
782+
{
783+
if (opt->pblock->cnt >= opt->pblock->size) {
784+
return;
785+
}
786+
Packet *pkt = &opt->pblock->pkts[opt->pblock->cnt];
787+
788+
pkt->packet_len_wire = len;
789+
pkt->ts = metadata.ts;
790+
pkt->src_port = 0;
791+
pkt->dst_port = 0;
792+
pkt->ip_proto = 0;
793+
pkt->ip_ttl = 0;
794+
pkt->ip_flags = 0;
795+
pkt->ip_version = 0;
796+
pkt->ip_payload_len = 0;
797+
pkt->tcp_flags = 0;
798+
pkt->tcp_window = 0;
799+
pkt->tcp_options = 0;
800+
pkt->tcp_mss = 0;
801+
pkt->mplsTop = 0;
802+
803+
stats.seen_packets++;
804+
805+
uint16_t data_offset;
806+
uint32_t l3_hdr_offset = metadata.l2_len;
807+
uint32_t l4_hdr_offset = metadata.l2_len + metadata.l3_len;
808+
809+
try {
810+
// L2
811+
data_offset = parse_eth_hdr(data, caplen, pkt);
812+
if (pkt->ethertype == ETH_P_TRILL) {
813+
data_offset += parse_trill(data + metadata.l2_len, metadata.l2_len, pkt);
814+
stats.trill_packets++;
815+
data_offset += parse_eth_hdr(data + metadata.l2_len, metadata.l2_len, pkt);
816+
}
817+
818+
// L3
819+
if (metadata.l2_ptype == L2_ETHER_IP) {
820+
if (metadata.l3_ptype == L3_IPV4 || metadata.l3_ptype == L3_IPV4_EXT) {
821+
data_offset += parse_ipv4_hdr(data + metadata.l2_len, metadata.l3_len, pkt);
822+
stats.ipv4_packets++;
823+
} else if (metadata.l3_ptype == L3_IPV6 || metadata.l3_ptype == L3_IPV4_EXT) {
824+
data_offset += parse_ipv6_hdr(data + metadata.l2_len, metadata.l3_len, pkt);
825+
stats.ipv6_packets++;
826+
}
827+
} else if (metadata.l2_ptype == L2_ETHER_MPLS) {
828+
data_offset += process_mpls(data + data_offset, caplen - data_offset, pkt);
829+
stats.mpls_packets++;
830+
} else if (metadata.l2_ptype == L2_ETHER_PPPOE) {
831+
data_offset += process_pppoe(data + data_offset, caplen - data_offset, pkt);
832+
stats.pppoe_packets++;
833+
} else { // if not previous, we try delegate to original parser
834+
parse_packet(opt, stats, metadata.ts, data, len, caplen);
835+
return;
836+
}
837+
838+
// L4
839+
if (metadata.l4_ptype == L4_TCP) {
840+
data_offset += parse_tcp_hdr(data + l4_hdr_offset, metadata.l4_len, pkt);
841+
stats.tcp_packets++;
842+
} else if (metadata.l4_ptype == L4_UDP) {
843+
data_offset += parse_udp_hdr(data + l4_hdr_offset, metadata.l4_len, pkt);
844+
stats.udp_packets++;
845+
} else { // if not previous, we try delegate to original parser
846+
parse_packet(opt, stats, metadata.ts, data, len, caplen);
847+
return;
848+
}
849+
} catch (const char *err) {
850+
DEBUG_MSG("%s\n", err);
851+
return;
852+
}
853+
854+
if (pkt->vlan_id) {
855+
stats.vlan_packets++;
856+
}
857+
858+
uint16_t pkt_len = caplen;
859+
pkt->packet = data;
860+
pkt->packet_len = caplen;
861+
862+
if (l4_hdr_offset != l3_hdr_offset) {
863+
if (l4_hdr_offset + pkt->ip_payload_len < 64) {
864+
// Packet contains 0x00 padding bytes, do not include them in payload
865+
pkt_len = l4_hdr_offset + pkt->ip_payload_len;
866+
}
867+
pkt->payload_len_wire = pkt->ip_payload_len - (data_offset - l4_hdr_offset);
868+
} else {
869+
pkt->payload_len_wire = pkt_len - data_offset;
870+
}
871+
872+
pkt->payload_len = pkt->payload_len_wire;
873+
if (pkt->payload_len + data_offset > pkt_len) {
874+
// Set correct size when payload length is bigger than captured payload length
875+
pkt->payload_len = pkt_len - data_offset;
876+
}
877+
pkt->payload = pkt->packet + data_offset;
878+
879+
DEBUG_MSG("Payload length:\t%u\n", pkt->payload_len);
880+
DEBUG_MSG("Packet parser exits: packet parsed\n");
881+
opt->packet_valid = true;
882+
opt->pblock->cnt++;
883+
opt->pblock->bytes += len;
884+
}
885+
779886
}

input/parser.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include <ipfixprobe/packet.hpp>
3333
#include <ipfixprobe/parser-stats.hpp>
3434

35+
#include "ctt.hpp"
36+
3537
#ifdef WITH_PCAP
3638
#include <pcap/pcap.h>
3739
#include <pcap/sll.h>
@@ -85,5 +87,7 @@ typedef struct parser_opt_s {
8587
*/
8688
void parse_packet(parser_opt_t *opt, ParserStats& stats, struct timeval ts, const uint8_t *data, uint16_t len, uint16_t caplen);
8789

90+
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);
91+
8892
}
8993
#endif /* IPXP_INPUT_PARSER_HPP */

0 commit comments

Comments
 (0)