2727 *
2828 */
2929
30+ #include < cstdint>
3031#include < cstdio>
3132#include < cstring>
3233#include < iostream>
34+ #include < netinet/in.h>
35+ #include < sys/types.h>
36+ #include < cstdint>
37+ #include < cstddef>
38+ #include < inttypes.h>
3339
3440#include " ndp.hpp"
41+ #include " ipfixprobe/packet.hpp"
42+ #include " ipfixprobe/plugin.hpp"
3543#include " parser.hpp"
3644
3745namespace ipxp {
3846
47+ uint64_t extract (const uint8_t * bitvec, size_t start_bit, size_t bit_length) {
48+ size_t start_byte = start_bit / 8 ;
49+ size_t end_bit = start_bit + bit_length;
50+ size_t end_byte = (end_bit + 7 ) / 8 ;
51+ uint64_t value = 0 ;
52+ for (size_t i = 0 ; i < end_byte - start_byte; ++i) {
53+ value |= static_cast <uint64_t >(bitvec[start_byte + i]) << (8 * i);
54+ }
55+ value >>= (start_bit % 8 );
56+ uint64_t mask = (bit_length == 64 ) ? ~0ULL : ((1ULL << bit_length) - 1 );
57+ return value & mask;
58+ }
59+
3960telemetry::Content NdpPacketReader::get_queue_telemetry ()
4061{
4162 telemetry::Dict dict;
4263 dict[" received_packets" ] = m_stats.receivedPackets ;
4364 dict[" received_bytes" ] = m_stats.receivedBytes ;
65+ dict[" bad_metadata" ] = m_stats.bad_metadata ;
4466 return dict;
4567}
4668
@@ -71,21 +93,72 @@ void NdpPacketReader::init(const char *params)
7193 if (parser.m_dev .empty ()) {
7294 throw PluginError (" specify device path" );
7395 }
96+ if (parser.m_metadata == " ctt" ) {
97+ m_ctt_metadata = true ;
98+ }
7499 init_ifc (parser.m_dev );
100+ m_device = parser.m_dev ;
75101}
76102
77103void NdpPacketReader::close ()
78104{
79105 ndpReader.close ();
80106}
81107
108+ #ifdef WITH_CTT
109+ std::pair<std::string, unsigned > NdpPacketReader::get_ctt_config () const
110+ {
111+ std::string dev = m_device;
112+ int channel_id = 0 ;
113+ std::size_t delimiter_found = m_device.find_last_of (" :" );
114+ if (delimiter_found != std::string::npos) {
115+ std::string channel_str = m_device.substr (delimiter_found + 1 );
116+ dev = m_device.substr (0 , delimiter_found);
117+ channel_id = std::stoi (channel_str);
118+ }
119+ return std::make_pair (dev, channel_id);
120+ }
121+ #endif /* WITH_CTT */
122+
82123void NdpPacketReader::init_ifc (const std::string &dev)
83124{
84125 if (ndpReader.init_interface (dev) != 0 ) {
85126 throw PluginError (ndpReader.error_msg );
86127 }
87128}
88129
130+ int NdpPacketReader::parse_ctt_metadata (const ndp_packet *ndp_packet, Metadata_CTT &ctt)
131+ {
132+ if (ndp_packet->header_length != 32 ) {
133+ return -1 ;
134+ }
135+ const uint8_t *metadata = ndp_packet->header ;
136+
137+ ctt.ts .tv_usec = extract (metadata, 0 , 32 );
138+ ctt.ts .tv_sec = extract (metadata, 32 , 32 );
139+ ctt.vlan_tci = extract (metadata, 64 , 16 );
140+ ctt.vlan_vld = extract (metadata, 80 , 1 );
141+ ctt.vlan_stripped = extract (metadata, 81 , 1 );
142+ ctt.ip_csum_status = static_cast <CsumStatus>(extract (metadata, 82 , 2 ));
143+ ctt.l4_csum_status = static_cast <CsumStatus>(extract (metadata, 84 , 2 ));
144+ ctt.parser_status = static_cast <ParserStatus>(extract (metadata, 86 , 2 ));
145+ ctt.ifc = extract (metadata, 88 , 8 );
146+ ctt.filter_bitmap = extract (metadata, 96 , 16 );
147+ ctt.ctt_export_trig = extract (metadata, 112 , 1 );
148+ ctt.ctt_rec_matched = extract (metadata, 113 , 1 );
149+ ctt.ctt_rec_created = extract (metadata, 114 , 1 );
150+ ctt.ctt_rec_deleted = extract (metadata, 115 , 1 );
151+ ctt.flow_hash = extract (metadata, 128 , 64 );
152+ ctt.l2_len = extract (metadata, 192 , 7 );
153+ ctt.l3_len = extract (metadata, 199 , 9 );
154+ ctt.l4_len = extract (metadata, 208 , 8 );
155+ ctt.l2_ptype = static_cast <L2PType>(extract (metadata, 216 , 4 ));
156+ ctt.l3_ptype = static_cast <L3PType>(extract (metadata, 220 , 4 ));
157+ ctt.l4_ptype = static_cast <L4PType>(extract (metadata, 224 , 4 ));
158+
159+ return 0 ;
160+ }
161+
89162InputPlugin::Result NdpPacketReader::get (PacketBlock &packets)
90163{
91164 parser_opt_t opt = {&packets, false , false , 0 };
@@ -107,7 +180,26 @@ InputPlugin::Result NdpPacketReader::get(PacketBlock &packets)
107180 throw PluginError (ndpReader.error_msg );
108181 }
109182 read_pkts++;
110- parse_packet (&opt, m_parser_stats, timestamp, ndp_packet->data , ndp_packet->data_length , ndp_packet->data_length );
183+ #ifdef WITH_CTT
184+ if (m_ctt_metadata) {
185+ Metadata_CTT ctt;
186+ auto flags = ndp_packet->flags ;
187+ int ret = parse_ctt_metadata (ndp_packet, ctt);
188+ if (ret == -1 ) {
189+ m_stats.bad_metadata ++;
190+ parse_packet (&opt, m_parser_stats, timestamp, ndp_packet->data , ndp_packet->data_length , ndp_packet->data_length );
191+ } else {
192+ if (parse_packet_ctt_metadata (&opt, m_parser_stats, ctt, ndp_packet->data , ndp_packet->data_length , ndp_packet->data_length ) == -1 ) {
193+ m_stats.bad_metadata ++;
194+ parse_packet (&opt, m_parser_stats, timestamp, ndp_packet->data , ndp_packet->data_length , ndp_packet->data_length );
195+ }
196+ }
197+ } else {
198+ #endif /* WITH_CTT */
199+ parse_packet (&opt, m_parser_stats, timestamp, ndp_packet->data , ndp_packet->data_length , ndp_packet->data_length );
200+ #ifdef WITH_CTT
201+ }
202+ #endif /* WITH_CTT */
111203 }
112204
113205 m_seen += read_pkts;
0 commit comments