1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation.  You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 //--------------------------------------------------------------------------
18 // packet_manager.cc author Josh Rosenbaum <jrosenba@cisco.com>
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include "packet_manager.h"
25 
26 #include <daq.h>
27 #include <mutex>
28 
29 #include "codecs/codec_module.h"
30 #include "codecs/ip/checksum.h"
31 #include "detection/detection_engine.h"
32 #include "log/text_log.h"
33 #include "main/snort_config.h"
34 #include "main/snort_debug.h"
35 #include "packet_io/active.h"
36 #include "packet_io/sfdaq.h"
37 #include "profiler/profiler_defs.h"
38 #include "stream/stream.h"
39 
40 #include "eth.h"
41 #include "icmp4.h"
42 #include "icmp6.h"
43 
44 using namespace snort;
45 
46 THREAD_LOCAL ProfileStats decodePerfStats;
47 
48 // Decoding statistics
49 
50 // this may be my longer member declaration ... ever
51 THREAD_LOCAL std::array<PegCount,PacketManager::stat_offset +
52 CodecManager::s_protocols.size()> PacketManager::s_stats {
53     { 0 }
54 };
55 
56 //PacketManager::s_stats{{0}};
57 std::array<PegCount, PacketManager::s_stats.size()> PacketManager::g_stats;
58 
59 // names which will be printed for the first three statistics
60 // in s_stats/g_stats
61 const std::array<const char*, PacketManager::stat_offset> PacketManager::stat_names =
62 {
63     {
64         "total",
65         "other",
66         "discards",
67         "depth_exceeded"
68     }
69 };
70 
71 // Encoder Foo
72 static THREAD_LOCAL std::array<uint8_t, Codec::PKT_MAX>* s_pkt;
73 
thread_init()74 void PacketManager::thread_init()
75 {
76     s_pkt = new std::array<uint8_t, Codec::PKT_MAX>{ {0} };
77 }
78 
thread_term()79 void PacketManager::thread_term()
80 {
81     delete s_pkt;
82 }
83 
84 //-------------------------------------------------------------------------
85 // Private helper functions
86 //-------------------------------------------------------------------------
87 
push_layer(Packet * p,CodecData & codec_data,ProtocolId prot_id,const uint8_t * hdr_start,uint32_t len)88 inline bool PacketManager::push_layer(Packet* p, CodecData& codec_data, ProtocolId prot_id,
89     const uint8_t* hdr_start, uint32_t len)
90 {
91     if ( p->num_layers == CodecManager::get_max_layers() )
92     {
93         if (!(codec_data.codec_flags & CODEC_LAYERS_EXCEEDED))
94         {
95             codec_data.codec_flags |= CODEC_LAYERS_EXCEEDED;
96             DetectionEngine::queue_event(GID_DECODE, DECODE_TOO_MANY_LAYERS);
97             s_stats[depth_exceeded]++;
98         }
99         return false;
100     }
101 
102     Layer& lyr = p->layers[p->num_layers++];
103     lyr.prot_id = prot_id;
104     lyr.start = hdr_start;
105     lyr.length = (uint16_t)len;
106 //    lyr.invalid_bits = p->byte_skip;  -- currently unused
107 
108     return true;
109 }
110 
get_layer_codec(const Layer & lyr,int idx)111 inline Codec* PacketManager::get_layer_codec(const Layer& lyr, int idx)
112 {
113     ProtocolIndex mapped_prot;
114     // prot_id == ProtocolId::FINISHED_DECODE is a special case for root codecs not registering a protocol ID
115     if (idx == 0 && (lyr.prot_id == CodecManager::grinder_id || lyr.prot_id == ProtocolId::FINISHED_DECODE))
116         mapped_prot = CodecManager::grinder;
117     else
118         mapped_prot = CodecManager::s_proto_map[to_utype(lyr.prot_id)];
119     return CodecManager::s_protocols[mapped_prot];
120 }
121 
pop_teredo(Packet * p,RawData & raw)122 void PacketManager::pop_teredo(Packet* p, RawData& raw)
123 {
124     p->proto_bits &= ~PROTO_BIT__TEREDO;
125     if ( p->context->conf->tunnel_bypass_enabled(TUNNEL_TEREDO) )
126         p->active->clear_tunnel_bypass();
127 
128     const ProtocolIndex mapped_prot = CodecManager::s_proto_map[to_utype(ProtocolId::TEREDO)];
129     s_stats[mapped_prot + stat_offset]--;
130     p->num_layers--;
131 
132     const Layer& lyr = p->layers[p->num_layers];
133     const uint16_t lyr_len = raw.data - lyr.start;
134     raw.data = lyr.start;
135     raw.len += lyr_len;
136 }
137 
handle_decode_failure(Packet * p,RawData & raw,const CodecData & codec_data,const DecodeData & unsure_encap_ptrs,ProtocolId prev_prot_id)138 void PacketManager::handle_decode_failure(Packet* p, RawData& raw, const CodecData& codec_data,
139     const DecodeData& unsure_encap_ptrs, ProtocolId prev_prot_id)
140 {
141     if (codec_data.codec_flags & CODEC_UNSURE_ENCAP)
142     {
143         p->ptrs = unsure_encap_ptrs;
144 
145         switch (p->layers[p->num_layers - 1].prot_id)
146         {
147             case ProtocolId::ESP:
148                 // Hardcoding ESP because we trust iff the layer
149                 // immediately preceding the fail is ESP.
150                 p->ptrs.decode_flags |= DECODE_PKT_TRUST;
151                 break;
152 
153             case ProtocolId::TEREDO:
154                 // if we just decoded teredo and the next
155                 // layer fails, we made a mistake. Therefore,
156                 // remove this bit.
157                 pop_teredo(p, raw);
158                 break;
159             default:
160                 break;
161         }
162         return;
163     }
164 
165     if ( (p->num_layers > 0) && (p->layers[p->num_layers - 1].prot_id == ProtocolId::TEREDO) &&
166         (prev_prot_id == ProtocolId::IPV6) )
167     {
168         pop_teredo(p, raw);
169     }
170 
171     // if the codec exists, it failed
172     if (CodecManager::s_proto_map[to_utype(prev_prot_id)])
173     {
174         s_stats[discards]++;
175     }
176     else
177     {
178         s_stats[other_codecs]++;
179 
180         if ( (to_utype(ProtocolId::MIN_UNASSIGNED_IP_PROTO) <= to_utype(prev_prot_id)) &&
181                 (to_utype(prev_prot_id) <= std::numeric_limits<uint8_t>::max()) )
182         {
183             DetectionEngine::queue_event(GID_DECODE, DECODE_IP_UNASSIGNED_PROTO);
184         }
185     }
186 }
187 
payload_offset_from_daq_mismatch(const uint8_t * pkt,const RawData & raw)188 static inline bool payload_offset_from_daq_mismatch(const uint8_t* pkt, const RawData& raw)
189 {
190     const DAQ_PktDecodeData_t* pdd =
191         (const DAQ_PktDecodeData_t*) daq_msg_get_meta(raw.daq_msg, DAQ_PKT_META_DECODE_DATA);
192     if ( !pdd || (pdd->payload_offset == DAQ_PKT_DECODE_OFFSET_INVALID) )
193         return false;
194     // compare payload offset from DAQ with decoded data offset
195     if ( raw.data - pkt != pdd->payload_offset )
196         return true;
197     return false;
198 }
199 
200 //-------------------------------------------------------------------------
201 // Initialization and setup
202 //-------------------------------------------------------------------------
203 
204 // Assertions required for this code to work
205 
206 //  Look below inside main decode() loop for these static_asserts
207 static_assert(CODEC_ENCAP_LAYER == (CODEC_UNSURE_ENCAP | CODEC_SAVE_LAYER),
208     "If this is an encapsulated layer, you must also set UNSURE_ENCAP"
209     " and SAVE_LAYER");
210 
211 //-------------------------------------------------------------------------
212 // Encode/Decode functions
213 //-------------------------------------------------------------------------
decode(Packet * p,const DAQ_PktHdr_t * pkthdr,const uint8_t * pkt,uint32_t pktlen,bool cooked,bool retry)214 void PacketManager::decode(
215     Packet* p, const DAQ_PktHdr_t* pkthdr, const uint8_t* pkt, uint32_t pktlen, bool cooked, bool retry)
216 {
217     Profile profile(decodePerfStats);
218 
219     DecodeData unsure_encap_ptrs;
220 
221     ProtocolIndex mapped_prot = CodecManager::grinder;
222     ProtocolId prev_prot_id = CodecManager::grinder_id;
223 
224     RawData raw(p->daq_msg, pkt, pktlen);
225     CodecData codec_data(p->context->conf, ProtocolId::FINISHED_DECODE);
226 
227     if (cooked)
228         codec_data.codec_flags |= CODEC_STREAM_REBUILT;
229 
230     // initialize all Packet information
231     p->reset();
232     p->pkth = pkthdr;
233     p->pkt = pkt;
234     p->pktlen = pktlen;
235     if (retry)
236         p->packet_flags |= PKT_RETRY;
237     layer::set_packet_pointer(p);
238 
239     s_stats[total_processed]++;
240 
241     // loop until the protocol id is no longer valid
242     while (CodecManager::s_protocols[mapped_prot]->decode(raw, codec_data, p->ptrs))
243     {
244         debug_logf(decode_trace, nullptr,
245             "Codec %s (0x%0*hx) starts at %u, length is %hu\n",
246             CodecManager::s_protocols[mapped_prot]->get_name(),
247             (static_cast<uint16_t>(prev_prot_id) < 0xFF) ? 2 : 4,
248             static_cast<uint16_t>(prev_prot_id),
249             pktlen - raw.len, codec_data.lyr_len);
250 
251         if (codec_data.codec_flags & CODEC_COMPOUND)
252         {
253             for (int idx = 0; idx < codec_data.compound_layer_cnt; idx++)
254             {
255                 CompoundLayer* clyr = &codec_data.compound_layers[idx];
256 
257                 // If this was an IP layer, stash the next protocol in the Packet for later
258                 if (clyr->proto_bits & (PROTO_BIT__IP | PROTO_BIT__IP6_EXT) &&
259                     idx + 1 < codec_data.compound_layer_cnt)
260                 {
261                     CompoundLayer* nclyr = &codec_data.compound_layers[idx + 1];
262                     p->ip_proto_next = convert_protocolid_to_ipprotocol(nclyr->layer.prot_id);
263                 }
264                 p->proto_bits |= clyr->proto_bits;
265 
266                 // If we have reached the MAX_LAYERS, we keep decoding
267                 // but no longer keep track of the layers.
268                 if (!push_layer(p, codec_data, clyr->layer.prot_id, clyr->layer.start, clyr->layer.length))
269                     continue;
270 
271                 // Cache the index of the vlan layer for quick access.
272                 if (clyr->proto_bits == PROTO_BIT__VLAN)
273                     p->vlan_idx = p->num_layers - 1;
274             }
275             codec_data.codec_flags &= ~CODEC_COMPOUND;
276         }
277         else
278         {
279             // If this was an IP layer, stash the next protocol in the Packet for later
280             if (codec_data.proto_bits & (PROTO_BIT__IP | PROTO_BIT__IP6_EXT))
281             {
282                 // FIXIT-M refactor when ip_proto's become an array
283                 if (p->is_fragment())
284                 {
285                     if (prev_prot_id == ProtocolId::FRAGMENT)
286                     {
287                         const ip::IP6Frag* const fragh = reinterpret_cast<const ip::IP6Frag*>(raw.data);
288                         p->ip_proto_next = fragh->next();
289                     }
290                     else
291                         p->ip_proto_next = p->ptrs.ip_api.get_ip4h()->proto();
292                 }
293                 else
294                 {
295                     if (codec_data.next_prot_id != ProtocolId::FINISHED_DECODE)
296                         p->ip_proto_next = convert_protocolid_to_ipprotocol(codec_data.next_prot_id);
297                 }
298             }
299 
300             // If we have reached the MAX_LAYERS, we keep decoding
301             // but no longer keep track of the layers.
302             if (push_layer(p, codec_data, prev_prot_id, raw.data, codec_data.lyr_len))
303             {
304                 // Cache the index of the vlan layer for quick access.
305                 if (codec_data.proto_bits == PROTO_BIT__VLAN)
306                     p->vlan_idx = p->num_layers - 1;
307             }
308         }
309 
310         if (codec_data.tunnel_bypass)
311         {
312             p->active->set_tunnel_bypass();
313             codec_data.tunnel_bypass = false;
314         }
315 
316         // Sanity check the next protocol ID is a valid ethertype
317         if (codec_data.codec_flags & CODEC_ETHER_NEXT)
318         {
319             if (codec_data.next_prot_id < ProtocolId::ETHERTYPE_MINIMUM)
320             {
321                 DetectionEngine::queue_event(GID_DECODE, DECODE_BAD_ETHER_TYPE);
322                 break;
323             }
324             codec_data.codec_flags &= ~CODEC_ETHER_NEXT;
325         }
326 
327         /*
328          * We only want the layer immediately following SAVE_LAYER to have the
329          * UNSURE_ENCAP flag set.  So, if this is a SAVE_LAYER, zero out the
330          * bit and the next time around, when this is no longer SAVE_LAYER,
331          * we will zero out the UNSURE_ENCAP flag.
332          */
333         if (codec_data.codec_flags & CODEC_SAVE_LAYER)
334         {
335             codec_data.codec_flags &= ~CODEC_SAVE_LAYER;
336             unsure_encap_ptrs = p->ptrs;
337         }
338         else if (codec_data.codec_flags & CODEC_UNSURE_ENCAP)
339             codec_data.codec_flags &= ~CODEC_UNSURE_ENCAP;
340 
341         // internal statistics and record keeping
342         s_stats[mapped_prot + stat_offset]++; // add correct decode for previous layer
343         mapped_prot = CodecManager::s_proto_map[to_utype(codec_data.next_prot_id)];
344         prev_prot_id = codec_data.next_prot_id;
345 
346         // Shrink the buffer of undecoded data
347         const uint16_t curr_lyr_len = codec_data.lyr_len + codec_data.invalid_bytes;
348         assert(curr_lyr_len <= raw.len);
349         raw.len -= curr_lyr_len;
350         raw.data += curr_lyr_len;
351 
352         p->proto_bits |= codec_data.proto_bits;
353 
354         // Reset the volatile part of the codec data for the next codec to decode into
355         codec_data.next_prot_id = ProtocolId::FINISHED_DECODE;
356         codec_data.lyr_len = 0;
357         codec_data.invalid_bytes = 0;
358         codec_data.proto_bits = 0;
359     }
360 
361     debug_logf(decode_trace, nullptr, "Payload starts at %u, length is %u\n", pktlen - raw.len, raw.len);
362 
363     if (p->num_layers > 0)
364         s_stats[mapped_prot + stat_offset]++;
365 
366     // if the final protocol ID is not the default codec, a Codec failed
367     if (prev_prot_id != ProtocolId::FINISHED_DECODE || p->num_layers == 0 )
368         handle_decode_failure(p, raw, codec_data, unsure_encap_ptrs, prev_prot_id);
369 
370     if (payload_offset_from_daq_mismatch(pkt, raw))
371         p->active->set_tunnel_bypass();
372 
373     // set any final Packet fields
374     p->data = raw.data;
375     p->dsize = (uint16_t)raw.len;
376     p->proto_bits |= codec_data.proto_bits;
377 
378     if (!p->proto_bits)
379         p->proto_bits = PROTO_BIT__OTHER;
380 }
381 
382 //-------------------------------------------------------------------------
383 // encoders operate layer by layer:
384 //-------------------------------------------------------------------------
385 
386 //-------------------------------------------------------------------------
387 // encoders:
388 // - raw pkt data only, no need for Packet stuff except to facilitate
389 //   encoding
390 // - don't include original options
391 // - inner layer differs from original (eg tcp data segment becomes rst)
392 // - must ensure proper ttl/hop limit for reverse direction
393 //
394 // iterate over decoded layers and encode the response packet.  actually
395 // make nested calls.  on the way in we setup invariant stuff and as we
396 // unwind the stack we finish up encoding in a more normal fashion (now
397 // the outer layer knows the length of the inner layer, etc.).
398 //
399 // when multiple responses are sent, both forwards and backwards directions,
400 // or multiple ICMP types (unreachable port, host, net), it may be possible
401 // to reuse the 1st encoding and just tweak it.  optimization for later
402 // consideration.
403 
404 // pci is copied from in to out
405 // * addresses / ports are swapped if !fwd
406 // * options, etc. are stripped
407 // * checksums etc. are set
408 // * if next layer is udp, it is set to icmp unreachable w/udp
409 // * if next layer is tcp, it becomes a tcp rst or tcp fin w/opt data
410 //-------------------------------------------------------------------------
411 
GetTTL(const Packet * const p,bool forward)412 static inline uint8_t GetTTL(const Packet* const p, bool forward)
413 {
414     char dir;
415     uint8_t ttl;
416     const bool outer = p->ptrs.ip_api.is_ip();
417 
418     if ( !p->flow )
419         return 0;
420 
421     if ( p->is_from_client() )
422         dir = forward ? FROM_CLIENT : FROM_SERVER;
423     else
424         dir = forward ? FROM_SERVER : FROM_CLIENT;
425 
426     // outermost ip is considered to be outer here,
427     // even if it is the only ip layer ...
428     ttl = Stream::get_flow_ttl(p->flow, dir, outer);
429 
430     // if we don't get outer, we use inner
431     if ( 0 == ttl && outer )
432         ttl = Stream::get_flow_ttl(p->flow, dir, false);
433 
434     return ttl;
435 }
436 
encode(const Packet * p,EncodeFlags flags,uint8_t lyr_start,IpProtocol next_prot,Buffer & buf)437 bool PacketManager::encode(const Packet* p,
438     EncodeFlags flags,
439     uint8_t lyr_start,
440     IpProtocol next_prot,
441     Buffer& buf)
442 {
443     if ( Packet* pe = DetectionEngine::get_encode_packet() )
444         p = pe;
445 
446     uint8_t ttl = GetTTL(p, (flags & ENC_FLAG_FWD));
447     if ( ttl )
448         flags |=  ENC_FLAG_TTL;
449     else
450         ttl = 0;
451 
452     if ( SFDAQ::forwarding_packet(p->pkth) )
453         flags |= ENC_FLAG_INLINE;
454 
455     ip::IpApi tmp_api;
456     EncState enc(tmp_api, flags, next_prot, ttl, p->dsize);
457 
458     const Layer* const lyrs = p->layers;
459     int8_t outer_layer = lyr_start;
460     int8_t inner_layer = lyr_start;
461 
462     // We need the IP layer associated with every protocol
463     // so checksums can be computed.
464     while (layer::set_inner_ip_api(p, tmp_api, inner_layer))
465     {
466         for (int i = outer_layer; i > inner_layer; --i)
467         {
468             const Layer& l = lyrs[i];
469             Codec* cd = get_layer_codec(l, i);
470             if (!cd->encode(l.start, l.length, enc, buf, p->flow))
471                 return false;
472         }
473         outer_layer = inner_layer;
474         // inner_layer is set in 'layer::set_inner_ip_api'
475     }
476 
477     // Now, we can encode all of the layers between the DLT and
478     // outermost IP layer
479     tmp_api.reset();
480     for (int i = outer_layer; i >= 0; --i)
481     {
482         const Layer& l = lyrs[i];
483         Codec* cd = get_layer_codec(l, i);
484         if (!cd->encode(l.start, l.length, enc, buf, p->flow))
485             return false;
486     }
487 
488     return true;
489 }
490 
encode_response(TcpResponse type,EncodeFlags flags,const Packet * p,uint32_t & len,const uint8_t * const payload,uint32_t payload_len)491 const uint8_t* PacketManager::encode_response(
492     TcpResponse type, EncodeFlags flags, const Packet* p, uint32_t& len,
493     const uint8_t* const payload, uint32_t payload_len)
494 {
495     Buffer buf(s_pkt->data(), s_pkt->size());
496 
497     switch (type)
498     {
499     case TcpResponse::FIN:
500         if (payload && (payload_len > 0))
501         {
502             if (!buf.allocate(payload_len))
503                 return nullptr;
504 
505             memcpy(buf.data(), payload, payload_len);
506             flags |= ENC_FLAG_PAY;
507         }
508         flags |= ENC_FLAG_FIN;
509         break;
510 
511     case TcpResponse::PUSH:
512         if (payload && (payload_len > 0))
513         {
514             if (!buf.allocate(payload_len))
515                 return nullptr;
516 
517             memcpy(buf.data(), payload, payload_len);
518             flags |= ENC_FLAG_PAY;
519         }
520         flags |= ENC_FLAG_PSH;
521         break;
522 
523     case TcpResponse::RST:      // No payload, so do nothing.
524     default:     // future proof
525         break;
526     }
527 
528     // FIXIT-M check flags if we should skip something
529     if (encode(p, flags, p->num_layers-1, IpProtocol::PROTO_NOT_SET, buf))
530     {
531         len = buf.size();
532         return buf.data() + buf.off;
533     }
534 
535     len = 0;
536     return nullptr;
537 }
538 
encode_reject(UnreachResponse type,EncodeFlags flags,const Packet * p,uint32_t & len)539 const uint8_t* PacketManager::encode_reject(UnreachResponse type,
540     EncodeFlags flags, const Packet* p, uint32_t& len)
541 {
542     Buffer buf(s_pkt->data(), s_pkt->size());
543 
544     if (p->is_ip4())
545     {
546         // FIXIT-M check flags if we should skip something
547         const int inner_ip_index = layer::get_inner_ip_lyr_index(p);
548         assert(inner_ip_index >= 0);
549         assert(inner_ip_index+1 < p->num_layers);
550 
551         /*  Building this packet from the inside out */
552         if (!buf.allocate(icmp::ICMP_UNREACH_DATA_LEN))
553             return nullptr;
554 
555         memcpy(buf.data(), p->layers[inner_ip_index+1].start, icmp::ICMP_UNREACH_DATA_LEN);
556 
557         const ip::IP4Hdr* const ip4h =
558             reinterpret_cast<const ip::IP4Hdr*>(p->layers[inner_ip_index].start);
559         const uint8_t ip_len = ip4h->hlen();
560 
561         if (!buf.allocate(ip_len))
562             return nullptr;
563         memcpy(buf.data(), ip4h, ip_len);
564 
565         // If this returns false, we're down pig creek.
566         if (!buf.allocate(sizeof(icmp::Icmp4Base)))
567             return nullptr;
568 
569         icmp::Icmp4Base* const icmph = reinterpret_cast<icmp::Icmp4Base*>(buf.data());
570         icmph->type = icmp::IcmpType::DEST_UNREACH;
571         icmph->csum = 0;
572         icmph->opt32 = 0;
573 
574         switch (type)
575         {
576         case UnreachResponse::NET:
577             icmph->code = icmp::IcmpCode::NET_UNREACH;
578             break;
579         case UnreachResponse::HOST:
580             icmph->code = icmp::IcmpCode::HOST_UNREACH;
581             break;
582         case UnreachResponse::PORT:
583             icmph->code = icmp::IcmpCode::PORT_UNREACH;
584             break;
585         case UnreachResponse::FWD:
586             icmph->code = icmp::IcmpCode::PKT_FILTERED;
587             break;
588         default:     // future proofing
589             icmph->code = icmp::IcmpCode::PORT_UNREACH;
590         }
591 
592         icmph->csum = checksum::icmp_cksum((uint16_t*)buf.data(), buf.size());
593 
594         if (encode(p, flags, inner_ip_index, IpProtocol::ICMPV4, buf))
595         {
596             len = buf.size();
597             return buf.data() + buf.off;
598         }
599 
600         len = 0;
601         return nullptr;
602     }
603     else if (p->is_ip6())
604     {
605         // FIXIT-M check flags if we should skip ip6_options
606         const int inner_ip_index = layer::get_inner_ip_lyr_index(p);
607         assert(inner_ip_index >= 0);
608         assert(inner_ip_index+1 < p->num_layers);
609 
610         // FIXIT-L copy up to minimum MTU worth of data
611         // FIXIT-L check if we have the full 8 bytes of data.
612         if (!buf.allocate(icmp::ICMP_UNREACH_DATA_LEN))
613             return nullptr;
614         memcpy(buf.data(), p->layers[inner_ip_index+1].start, icmp::ICMP_UNREACH_DATA_LEN);
615 
616         // copy original ip header
617         if (!buf.allocate(ip::IP6_HEADER_LEN))
618             return nullptr;
619         const ip::IP6Hdr* const ip6h = p->ptrs.ip_api.get_ip6h();
620         memcpy(buf.data(), ip6h, ip::IP6_HEADER_LEN);
621 
622         if (!buf.allocate(sizeof(icmp::Icmp6Hdr)))
623             return nullptr;
624 
625         icmp::Icmp6Hdr* const icmph = reinterpret_cast<icmp::Icmp6Hdr*>(buf.data());
626         icmph->type = icmp::Icmp6Types::DESTINATION_UNREACHABLE;
627         icmph->csum = 0;
628         icmph->opt32 = 0;
629 
630         switch (type)
631         {
632         case UnreachResponse::NET:
633             icmph->code = icmp::Icmp6Code::UNREACH_NET;
634             break;
635         case UnreachResponse::HOST:
636             icmph->code = icmp::Icmp6Code::UNREACH_HOST;
637             break;
638         case UnreachResponse::PORT:
639             icmph->code = icmp::Icmp6Code::UNREACH_PORT;
640             break;
641         case UnreachResponse::FWD:
642             icmph->code = icmp::Icmp6Code::UNREACH_FILTER_PROHIB;
643             break;
644         default:     // future proofing
645             icmph->code = icmp::Icmp6Code::UNREACH_PORT;
646         }
647 
648         checksum::Pseudoheader6 ps6;
649         const int ip_len = buf.size();
650         memcpy(ps6.hdr.sip, ip6h->get_src()->u6_addr8, sizeof(ps6.hdr.sip));
651         memcpy(ps6.hdr.dip, ip6h->get_dst()->u6_addr8, sizeof(ps6.hdr.dip));
652         ps6.hdr.zero = 0;
653         ps6.hdr.protocol = IpProtocol::ICMPV6;
654         ps6.hdr.len = htons((uint16_t)(ip_len));
655 
656         icmph->csum = checksum::icmp_cksum((uint16_t*)buf.data(), ip_len, ps6);
657 
658         if (encode(p, flags, inner_ip_index, IpProtocol::ICMPV6, buf))
659         {
660             len = buf.size();
661             return buf.data() + buf.off;
662         }
663 
664         len = 0;
665         return nullptr;
666     }
667     else
668     {
669         return nullptr;
670     }
671 }
672 
init_daq_pkthdr(const Packet * p,Packet * c,const DAQ_PktHdr_t * phdr,uint32_t opaque)673 static void init_daq_pkthdr(
674     const Packet* p, Packet* c, const DAQ_PktHdr_t* phdr, uint32_t opaque)
675 {
676     if ( !phdr )
677         phdr = p->pkth;
678 
679     assert(c->pkth == c->context->pkth);
680     DAQ_PktHdr_t* pkth = c->context->pkth;
681     pkth->ingress_index = phdr->ingress_index;
682     pkth->ingress_group = phdr->ingress_group;
683     pkth->egress_index = phdr->egress_index;
684     pkth->egress_group = phdr->egress_group;
685     pkth->flags = phdr->flags;
686     pkth->address_space_id = phdr->address_space_id;
687     pkth->opaque = opaque;
688 }
689 
690 //-------------------------------------------------------------------------
691 // formatters:
692 // - these packets undergo detection
693 // - need to set Packet stuff except for frag which calls grinder
694 // - include original options except for frag inner ip
695 // - inner layer header is very similar but payload differs
696 // - original ttl is always used
697 //-------------------------------------------------------------------------
698 
format_tcp(EncodeFlags,const Packet * p,Packet * c,PseudoPacketType type,const DAQ_PktHdr_t * phdr,uint32_t opaque)699 int PacketManager::format_tcp(
700     EncodeFlags, const Packet* p, Packet* c, PseudoPacketType type,
701     const DAQ_PktHdr_t* phdr, uint32_t opaque)
702 {
703     uint32_t cflags = c->packet_flags;
704     c->reset();
705     init_daq_pkthdr(p, c, phdr, opaque);
706 
707     c->packet_flags = cflags | PKT_PSEUDO;
708     c->pseudo_type = type;
709 
710     // cooked packet gets same policy as raw
711     c->user_inspection_policy_id = p->user_inspection_policy_id;
712     c->user_ips_policy_id = p->user_ips_policy_id;
713     c->user_network_policy_id = p->user_network_policy_id;
714     c->ip_proto_next = p->ip_proto_next;
715 
716     // setup pkt capture header
717     c->pktlen = 0;
718     assert(c->pkth == c->context->pkth);
719     c->context->pkth->pktlen = 0;
720     c->context->pkth->ts = p->pkth->ts;
721 
722     return 0;
723 }
724 
encode_format(EncodeFlags f,const Packet * p,Packet * c,PseudoPacketType type,const DAQ_PktHdr_t * phdr,uint32_t opaque)725 int PacketManager::encode_format(
726     EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type,
727     const DAQ_PktHdr_t* phdr, uint32_t opaque)
728 {
729     bool update_ip4_len = false;
730     uint8_t num_layers;
731 
732     if ( f & ENC_FLAG_DEF )
733     {
734         /*
735          * By its definitions, this flag means 'stop before innermost ip4
736          * opts or ip6 frag header'. So, stop after the ip4 layer IP4 will format itself, and now
737          * we ensure that the ip6_frag header is not copied too.
738          */
739 
740         if ( p->is_ip6() )
741         {
742             num_layers = layer::get_inner_ip6_frag_index(p);
743         }
744         else
745         {
746             num_layers = layer::get_inner_ip_lyr_index(p) + 1;
747             update_ip4_len = true;
748         }
749     }
750     else if ( f & ENC_FLAG_NET )
751         num_layers = layer::get_inner_ip_lyr_index(p) + 1;
752     else
753         num_layers = p->num_layers;
754 
755     if ( num_layers == 0 )
756         return -1;
757 
758     init_daq_pkthdr(p, c, phdr, opaque);
759 
760     // copy raw packet data to clone
761     Layer* lyr = &p->layers[num_layers - 1];
762     int len = lyr->start - p->pkt + lyr->length;
763     memcpy((void*)c->pkt, p->pkt, len);
764 
765     const bool reverse = !(f & ENC_FLAG_FWD);
766 
767     // set up and format layers
768     for ( int i = 0; i < num_layers; i++ )
769     {
770         const uint8_t* b = c->pkt + (p->layers[i].start - p->pkt); // == c->pkt + p->layers[i].len
771         lyr = &c->layers[i];
772 
773         lyr->prot_id = p->layers[i].prot_id;
774         lyr->length = p->layers[i].length;
775         lyr->start = b;
776 
777         // NOTE: this must always go from outer to inner
778         //       to ensure a valid ip header
779         Codec* cd = get_layer_codec(*lyr, i);
780         cd->format(reverse, const_cast<uint8_t*>(lyr->start), c->ptrs);
781     }
782 
783     if ( update_ip4_len )
784     {
785         lyr = &c->layers[num_layers - 1];
786         ip::IP4Hdr* ip4h = reinterpret_cast<ip::IP4Hdr*>(const_cast<uint8_t*>(lyr->start));
787         lyr->length = ip::IP4_HEADER_LEN;
788         ip4h->set_ip_len(ip::IP4_HEADER_LEN);
789         ip4h->set_hlen(ip::IP4_HEADER_LEN >> 2);
790     }
791 
792     // setup payload info
793     c->num_layers = num_layers;
794     c->data = lyr->start + lyr->length;
795     len = c->data - c->pkt;
796 
797     // len < ETHERNET_HEADER_LEN + VLAN_HEADER + ETHERNET_MTU
798     assert((unsigned)len < Codec::PKT_MAX - c->max_dsize);
799 
800     c->proto_bits = p->proto_bits;
801     c->ip_proto_next = p->ip_proto_next;
802     c->packet_flags |= PKT_PSEUDO;
803     c->pseudo_type = type;
804 
805     // cooked packet gets same policy as raw
806     c->user_inspection_policy_id = p->user_inspection_policy_id;
807     c->user_ips_policy_id = p->user_ips_policy_id;
808     c->user_network_policy_id = p->user_network_policy_id;
809 
810     // setup pkt capture header
811     c->pktlen = len;
812     assert(c->pkth == c->context->pkth);
813     c->context->pkth->pktlen = len;
814     c->context->pkth->ts = p->pkth->ts;
815 
816     layer::set_packet_pointer(c);  // ensure we are looking at the new packet
817     return 0;
818 }
819 
820 //-------------------------------------------------------------------------
821 // updaters:  these functions set length and checksum fields, only needed
822 // when a packet is modified.  some packets only have replacements so only
823 // the checksums need to be updated.  we always set the length rather than
824 // checking each time if needed.
825 //-------------------------------------------------------------------------
826 
add_flag(UpdateFlags & flags,UpdateFlags flag_to_add,const Packet * const p,decltype(Packet::packet_flags)pkt_flag)827 static inline void add_flag(
828     UpdateFlags& flags, UpdateFlags flag_to_add, const Packet* const p,
829     decltype(Packet::packet_flags)pkt_flag)  // future proofing.
830 {
831     if ( p->packet_flags & pkt_flag )
832         flags |= flag_to_add;
833 }
834 
encode_update(Packet * p)835 void PacketManager::encode_update(Packet* p)
836 {
837     uint32_t len = p->dsize;
838 
839     UpdateFlags flags = 0;
840     add_flag(flags, UPD_COOKED, p, PKT_PSEUDO);
841     add_flag(flags, UPD_MODIFIED, p, PKT_MODIFIED);
842     add_flag(flags, UPD_RESIZED, p, PKT_RESIZED);
843     add_flag(flags, UPD_REBUILT_FRAG, p, PKT_REBUILT_FRAG);
844 
845     int8_t outer_layer = p->num_layers-1;
846     int8_t inner_layer = p->num_layers-1;
847     const Layer* const lyr = p->layers;
848     ip::IpApi tmp_api;
849 
850     // update the rest of the ip layers with the correct IP reference.
851     while (layer::set_inner_ip_api(p, tmp_api, inner_layer))
852     {
853         for (int i = outer_layer; i > inner_layer; --i)
854         {
855             const Layer& l = lyr[i];
856             Codec* cd = get_layer_codec(l, i);
857             cd->update(tmp_api, flags, const_cast<uint8_t*>(l.start), l.length, len);
858         }
859         outer_layer = inner_layer;
860         // inner_layer is set in 'layer::set_inner_ip_api'
861     }
862 
863     tmp_api.reset();
864     for (int i = outer_layer; i >= 0; --i)
865     {
866         const Layer& l = lyr[i];
867         ProtocolIndex mapped_prot = CodecManager::s_proto_map[to_utype(l.prot_id)];
868         CodecManager::s_protocols[mapped_prot]->update(
869             tmp_api, flags, const_cast<uint8_t*>(l.start), l.length, len);
870     }
871 
872     if ( !(p->packet_flags & PKT_MODIFIED) || (p->packet_flags & PKT_RESIZED) )
873     {
874         p->pktlen = len;
875         // Only attempt to update the DAQ packet header for manufactured (defragged) packets.  If
876         // this is the original wire packet, leave the header alone; the drop/inject for resize
877         // will use pktlen from Packet for the injection length.
878         // FIXIT-L there should be a better way to detect that this is manufactured packet
879         if (p->pkth == p->context->pkth)
880             p->context->pkth->pktlen = len;
881     }
882 }
883 
884 //-------------------------------------------------------------------------
885 // codec support and statistics
886 //-------------------------------------------------------------------------
887 
encode_get_max_payload(const Packet * p)888 uint16_t PacketManager::encode_get_max_payload(const Packet* p)
889 {
890     if ( !p->num_layers )
891         return 0;
892 
893     const Layer& l = p->layers[p->num_layers - 1];
894     return ETHERNET_MTU - (l.start - p->layers[0].start) - l.length;
895 }
896 
dump_stats()897 void PacketManager::dump_stats()
898 {
899     std::vector<const char*> pkt_names;
900 
901     // zero out the default codecs
902     g_stats[stat_offset] = 0;
903     g_stats[CodecManager::s_proto_map[to_utype(ProtocolId::FINISHED_DECODE)] + stat_offset] = 0;
904 
905     for (unsigned int i = 0; i < stat_names.size(); i++)
906         pkt_names.emplace_back(stat_names[i]);
907 
908     for (int i = 0; CodecManager::s_protocols[i] != nullptr; i++)
909         pkt_names.emplace_back(CodecManager::s_protocols[i]->get_name());
910 
911     show_percent_stats((PegCount*)&g_stats, &pkt_names[0],
912         (unsigned int)pkt_names.size(), "codec");
913 }
914 
reset_stats()915 void PacketManager::reset_stats()
916 {
917     std::fill(std::begin(g_stats), std::end(g_stats), 0);
918     std::fill(std::begin(s_stats), std::end(s_stats), 0);
919 }
920 
accumulate()921 void PacketManager::accumulate()
922 {
923     static std::mutex stats_mutex;
924 
925     std::lock_guard<std::mutex> lock(stats_mutex);
926     sum_stats(&g_stats[0], &s_stats[0], s_stats.size());
927 
928     // mutex is automatically unlocked
929 }
930 
get_proto_name(ProtocolId protocol)931 const char* PacketManager::get_proto_name(ProtocolId protocol)
932 { return CodecManager::s_protocols[CodecManager::s_proto_map[to_utype(protocol)]]->get_name(); }
933 
get_proto_name(IpProtocol protocol)934 const char* PacketManager::get_proto_name(IpProtocol protocol)
935 { return CodecManager::s_protocols[CodecManager::s_proto_map[to_utype(protocol)]]->get_name(); }
936 
log_protocols(TextLog * const text_log,const Packet * const p)937 void PacketManager::log_protocols(TextLog* const text_log,
938     const Packet* const p)
939 {
940     uint8_t num_layers = p->num_layers;
941     const Layer* const lyr = p->layers;
942 
943     if (num_layers != 0)
944     {
945         int i = 0;
946         // Special case for root codecs not registering a protocol ID
947         if (lyr[0].prot_id == CodecManager::grinder_id || lyr[0].prot_id == ProtocolId::FINISHED_DECODE)
948         {
949             Codec* cd = CodecManager::s_protocols[CodecManager::grinder];
950             TextLog_Print(text_log, "%s(DLT):  ", cd->get_name());
951             cd->log(text_log, lyr[0].start, lyr[0].length);
952             i++;
953         }
954 
955         for (; i < num_layers; i++)
956         {
957             const auto protocol = to_utype(lyr[i].prot_id);
958             const uint8_t codec_offset =  CodecManager::s_proto_map[protocol];
959             Codec* cd = CodecManager::s_protocols[codec_offset];
960 
961             TextLog_NewLine(text_log);
962             TextLog_Print(text_log, "%s", cd->get_name());
963 
964             if (protocol <= 0xFF)
965                 TextLog_Print(text_log, "(0x%02x)", protocol);
966             else
967                 TextLog_Print(text_log, "(0x%04x)", protocol);
968 
969             TextLog_Puts(text_log, ":  ");
970             cd->log(text_log, lyr[i].start, lyr[i].length);
971         }
972     }
973 }
974