1 /* Copyright (C) 2007-2019 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \defgroup decode Packet decoding
20  *
21  * \brief Code in charge of protocol decoding
22  *
23  * The task of decoding packets is made in different files and
24  * as Suricata is supporting encapsulation there is a potential
25  * recursivity in the call.
26  *
27  * For each protocol a DecodePROTO function is provided. For
28  * example we have DecodeIPV4() for IPv4 and DecodePPP() for
29  * PPP.
30  *
31  * These functions have all a pkt and a len argument which
32  * are respectively a pointer to the protocol data and the length
33  * of this protocol data.
34  *
35  * \attention The pkt parameter must point to the effective data because
36  * it will be used later to set per protocol pointer like Packet::tcph
37  *
38  * @{
39  */
40 
41 
42 /**
43  * \file
44  *
45  * \author Victor Julien <victor@inliniac.net>
46  *
47  * Decode the raw packet
48  */
49 
50 #include "suricata-common.h"
51 #include "suricata.h"
52 #include "conf.h"
53 #include "decode.h"
54 #include "decode-teredo.h"
55 #include "util-debug.h"
56 #include "util-mem.h"
57 #include "app-layer-detect-proto.h"
58 #include "app-layer.h"
59 #include "tm-threads.h"
60 #include "util-error.h"
61 #include "util-print.h"
62 #include "tmqh-packetpool.h"
63 #include "util-profiling.h"
64 #include "pkt-var.h"
65 #include "util-mpm-ac.h"
66 #include "util-hash-string.h"
67 #include "output.h"
68 #include "output-flow.h"
69 #include "flow-storage.h"
70 
71 uint32_t default_packet_size = 0;
72 extern bool stats_decoder_events;
73 extern const char *stats_decoder_events_prefix;
74 extern bool stats_stream_events;
75 uint8_t decoder_max_layers = PKT_DEFAULT_MAX_DECODED_LAYERS;
76 
77 static int DecodeTunnel(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t,
78         enum DecodeTunnelProto) WARN_UNUSED;
79 
DecodeTunnel(ThreadVars * tv,DecodeThreadVars * dtv,Packet * p,const uint8_t * pkt,uint32_t len,enum DecodeTunnelProto proto)80 static int DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt,
81         uint32_t len, enum DecodeTunnelProto proto)
82 {
83     switch (proto) {
84         case DECODE_TUNNEL_PPP:
85             return DecodePPP(tv, dtv, p, pkt, len);
86         case DECODE_TUNNEL_IPV4:
87             return DecodeIPV4(tv, dtv, p, pkt, len);
88         case DECODE_TUNNEL_IPV6:
89         case DECODE_TUNNEL_IPV6_TEREDO:
90             return DecodeIPV6(tv, dtv, p, pkt, len);
91         case DECODE_TUNNEL_VLAN:
92             return DecodeVLAN(tv, dtv, p, pkt, len);
93         case DECODE_TUNNEL_ETHERNET:
94             return DecodeEthernet(tv, dtv, p, pkt, len);
95         case DECODE_TUNNEL_ERSPANII:
96             return DecodeERSPAN(tv, dtv, p, pkt, len);
97         case DECODE_TUNNEL_ERSPANI:
98             return DecodeERSPANTypeI(tv, dtv, p, pkt, len);
99         default:
100             SCLogDebug("FIXME: DecodeTunnel: protocol %" PRIu32 " not supported.", proto);
101             break;
102     }
103     return TM_ECODE_OK;
104 }
105 
106 /**
107  * \brief Return a malloced packet.
108  */
PacketFree(Packet * p)109 void PacketFree(Packet *p)
110 {
111     PACKET_DESTRUCTOR(p);
112     SCFree(p);
113 }
114 
115 /**
116  * \brief Finalize decoding of a packet
117  *
118  * This function needs to be call at the end of decode
119  * functions when decoding has been successful.
120  *
121  */
PacketDecodeFinalize(ThreadVars * tv,DecodeThreadVars * dtv,Packet * p)122 void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
123 {
124     if (p->flags & PKT_IS_INVALID) {
125         StatsIncr(tv, dtv->counter_invalid);
126     }
127 }
128 
PacketUpdateEngineEventCounters(ThreadVars * tv,DecodeThreadVars * dtv,Packet * p)129 void PacketUpdateEngineEventCounters(ThreadVars *tv,
130         DecodeThreadVars *dtv, Packet *p)
131 {
132     for (uint8_t i = 0; i < p->events.cnt; i++) {
133         const uint8_t e = p->events.events[i];
134 
135         if (e <= DECODE_EVENT_PACKET_MAX && !stats_decoder_events)
136             continue;
137         else if (e > DECODE_EVENT_PACKET_MAX && !stats_stream_events)
138             continue;
139         StatsIncr(tv, dtv->counter_engine_events[e]);
140     }
141 }
142 
143 /**
144  * \brief Get a malloced packet.
145  *
146  * \retval p packet, NULL on error
147  */
PacketGetFromAlloc(void)148 Packet *PacketGetFromAlloc(void)
149 {
150     Packet *p = SCMalloc(SIZE_OF_PACKET);
151     if (unlikely(p == NULL)) {
152         return NULL;
153     }
154 
155     memset(p, 0, SIZE_OF_PACKET);
156     PACKET_INITIALIZE(p);
157     p->ReleasePacket = PacketFree;
158     p->flags |= PKT_ALLOC;
159 
160     SCLogDebug("allocated a new packet only using alloc...");
161 
162     PACKET_PROFILING_START(p);
163     return p;
164 }
165 
166 /**
167  * \brief Return a packet to where it was allocated.
168  */
PacketFreeOrRelease(Packet * p)169 void PacketFreeOrRelease(Packet *p)
170 {
171     if (p->flags & PKT_ALLOC)
172         PacketFree(p);
173     else {
174         p->ReleasePacket = PacketPoolReturnPacket;
175         PacketPoolReturnPacket(p);
176     }
177 }
178 
179 /**
180  *  \brief Get a packet. We try to get a packet from the packetpool first, but
181  *         if that is empty we alloc a packet that is free'd again after
182  *         processing.
183  *
184  *  \retval p packet, NULL on error
185  */
PacketGetFromQueueOrAlloc(void)186 Packet *PacketGetFromQueueOrAlloc(void)
187 {
188     /* try the pool first */
189     Packet *p = PacketPoolGetPacket();
190 
191     if (p == NULL) {
192         /* non fatal, we're just not processing a packet then */
193         p = PacketGetFromAlloc();
194     } else {
195         PACKET_PROFILING_START(p);
196     }
197 
198     return p;
199 }
200 
PacketCallocExtPkt(Packet * p,int datalen)201 inline int PacketCallocExtPkt(Packet *p, int datalen)
202 {
203     if (! p->ext_pkt) {
204         p->ext_pkt = SCCalloc(1, datalen);
205         if (unlikely(p->ext_pkt == NULL)) {
206             SET_PKT_LEN(p, 0);
207             return -1;
208         }
209     }
210     return 0;
211 }
212 
213 /**
214  *  \brief Copy data to Packet payload at given offset
215  *
216  * This function copies data/payload to a Packet. It uses the
217  * space allocated at Packet creation (pointed by Packet::pkt)
218  * or allocate some memory (pointed by Packet::ext_pkt) if the
219  * data size is to big to fit in initial space (of size
220  * default_packet_size).
221  *
222  *  \param Pointer to the Packet to modify
223  *  \param Offset of the copy relatively to payload of Packet
224  *  \param Pointer to the data to copy
225  *  \param Length of the data to copy
226  */
PacketCopyDataOffset(Packet * p,uint32_t offset,const uint8_t * data,uint32_t datalen)227 inline int PacketCopyDataOffset(Packet *p, uint32_t offset, const uint8_t *data, uint32_t datalen)
228 {
229     if (unlikely(offset + datalen > MAX_PAYLOAD_SIZE)) {
230         /* too big */
231         SET_PKT_LEN(p, 0);
232         return -1;
233     }
234 
235     /* Do we have already an packet with allocated data */
236     if (! p->ext_pkt) {
237         uint32_t newsize = offset + datalen;
238         // check overflow
239         if (newsize < offset)
240             return -1;
241         if (newsize <= default_packet_size) {
242             /* data will fit in memory allocated with packet */
243             memcpy(GET_PKT_DIRECT_DATA(p) + offset, data, datalen);
244         } else {
245             /* here we need a dynamic allocation */
246             p->ext_pkt = SCMalloc(MAX_PAYLOAD_SIZE);
247             if (unlikely(p->ext_pkt == NULL)) {
248                 SET_PKT_LEN(p, 0);
249                 return -1;
250             }
251             /* copy initial data */
252             memcpy(p->ext_pkt, GET_PKT_DIRECT_DATA(p), GET_PKT_DIRECT_MAX_SIZE(p));
253             /* copy data as asked */
254             memcpy(p->ext_pkt + offset, data, datalen);
255         }
256     } else {
257         memcpy(p->ext_pkt + offset, data, datalen);
258     }
259     return 0;
260 }
261 
262 /**
263  *  \brief Copy data to Packet payload and set packet length
264  *
265  *  \param Pointer to the Packet to modify
266  *  \param Pointer to the data to copy
267  *  \param Length of the data to copy
268  */
PacketCopyData(Packet * p,const uint8_t * pktdata,uint32_t pktlen)269 inline int PacketCopyData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
270 {
271     SET_PKT_LEN(p, (size_t)pktlen);
272     return PacketCopyDataOffset(p, 0, pktdata, pktlen);
273 }
274 
275 /**
276  *  \brief Setup a pseudo packet (tunnel)
277  *
278  *  \param parent parent packet for this pseudo pkt
279  *  \param pkt raw packet data
280  *  \param len packet data length
281  *  \param proto protocol of the tunneled packet
282  *
283  *  \retval p the pseudo packet or NULL if out of memory
284  */
PacketTunnelPktSetup(ThreadVars * tv,DecodeThreadVars * dtv,Packet * parent,const uint8_t * pkt,uint32_t len,enum DecodeTunnelProto proto)285 Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *parent,
286                              const uint8_t *pkt, uint32_t len, enum DecodeTunnelProto proto)
287 {
288     int ret;
289 
290     SCEnter();
291 
292     /* get us a packet */
293     Packet *p = PacketGetFromQueueOrAlloc();
294     if (unlikely(p == NULL)) {
295         SCReturnPtr(NULL, "Packet");
296     }
297 
298     /* copy packet and set length, proto */
299     PacketCopyData(p, pkt, len);
300     p->recursion_level = parent->recursion_level + 1;
301     p->ts.tv_sec = parent->ts.tv_sec;
302     p->ts.tv_usec = parent->ts.tv_usec;
303     p->datalink = DLT_RAW;
304     p->tenant_id = parent->tenant_id;
305     p->livedev = parent->livedev;
306 
307     /* set the root ptr to the lowest layer */
308     if (parent->root != NULL)
309         p->root = parent->root;
310     else
311         p->root = parent;
312 
313     /* tell new packet it's part of a tunnel */
314     SET_TUNNEL_PKT(p);
315 
316     ret = DecodeTunnel(tv, dtv, p, GET_PKT_DATA(p),
317                        GET_PKT_LEN(p), proto);
318 
319     if (unlikely(ret != TM_ECODE_OK) ||
320             (proto == DECODE_TUNNEL_IPV6_TEREDO && (p->flags & PKT_IS_INVALID)))
321     {
322         /* Not a (valid) tunnel packet */
323         SCLogDebug("tunnel packet is invalid");
324 
325         p->root = NULL;
326         UNSET_TUNNEL_PKT(p);
327         TmqhOutputPacketpool(tv, p);
328         SCReturnPtr(NULL, "Packet");
329     }
330 
331 
332     /* tell parent packet it's part of a tunnel */
333     SET_TUNNEL_PKT(parent);
334 
335     /* increment tunnel packet refcnt in the root packet */
336     TUNNEL_INCR_PKT_TPR(p);
337 
338     /* disable payload (not packet) inspection on the parent, as the payload
339      * is the packet we will now run through the system separately. We do
340      * check it against the ip/port/other header checks though */
341     DecodeSetNoPayloadInspectionFlag(parent);
342     SCReturnPtr(p, "Packet");
343 }
344 
345 /**
346  *  \brief Setup a pseudo packet (reassembled frags)
347  *
348  *  Difference with PacketPseudoPktSetup is that this func doesn't increment
349  *  the recursion level. It needs to be on the same level as the frags because
350  *  we run the flow engine against this and we need to get the same flow.
351  *
352  *  \param parent parent packet for this pseudo pkt
353  *  \param pkt raw packet data
354  *  \param len packet data length
355  *  \param proto protocol of the tunneled packet
356  *
357  *  \retval p the pseudo packet or NULL if out of memory
358  */
PacketDefragPktSetup(Packet * parent,const uint8_t * pkt,uint32_t len,uint8_t proto)359 Packet *PacketDefragPktSetup(Packet *parent, const uint8_t *pkt, uint32_t len, uint8_t proto)
360 {
361     SCEnter();
362 
363     /* get us a packet */
364     Packet *p = PacketGetFromQueueOrAlloc();
365     if (unlikely(p == NULL)) {
366         SCReturnPtr(NULL, "Packet");
367     }
368 
369     /* set the root ptr to the lowest layer */
370     if (parent->root != NULL)
371         p->root = parent->root;
372     else
373         p->root = parent;
374 
375     /* copy packet and set lenght, proto */
376     if (pkt && len) {
377         PacketCopyData(p, pkt, len);
378     }
379     p->recursion_level = parent->recursion_level; /* NOT incremented */
380     p->ts.tv_sec = parent->ts.tv_sec;
381     p->ts.tv_usec = parent->ts.tv_usec;
382     p->datalink = DLT_RAW;
383     p->tenant_id = parent->tenant_id;
384     /* tell new packet it's part of a tunnel */
385     SET_TUNNEL_PKT(p);
386     p->vlan_id[0] = parent->vlan_id[0];
387     p->vlan_id[1] = parent->vlan_id[1];
388     p->vlan_idx = parent->vlan_idx;
389     p->livedev = parent->livedev;
390 
391     SCReturnPtr(p, "Packet");
392 }
393 
394 /**
395  *  \brief inform defrag "parent" that a pseudo packet is
396  *         now associated to it.
397  */
PacketDefragPktSetupParent(Packet * parent)398 void PacketDefragPktSetupParent(Packet *parent)
399 {
400     /* tell parent packet it's part of a tunnel */
401     SET_TUNNEL_PKT(parent);
402 
403     /* increment tunnel packet refcnt in the root packet */
404     TUNNEL_INCR_PKT_TPR(parent);
405 
406     /* disable payload (not packet) inspection on the parent, as the payload
407      * is the packet we will now run through the system separately. We do
408      * check it against the ip/port/other header checks though */
409     DecodeSetNoPayloadInspectionFlag(parent);
410 }
411 
412 /**
413  *  \note if p->flow is set, the flow is locked
414  */
PacketBypassCallback(Packet * p)415 void PacketBypassCallback(Packet *p)
416 {
417     if (PKT_IS_PSEUDOPKT(p))
418         return;
419 
420 #ifdef CAPTURE_OFFLOAD
421     /* Don't try to bypass if flow is already out or
422      * if we have failed to do it once */
423     if (p->flow) {
424         int state = p->flow->flow_state;
425         if ((state == FLOW_STATE_LOCAL_BYPASSED) ||
426                 (state == FLOW_STATE_CAPTURE_BYPASSED)) {
427             return;
428         }
429         FlowBypassInfo *fc = SCCalloc(sizeof(FlowBypassInfo), 1);
430         if (fc) {
431             FlowSetStorageById(p->flow, GetFlowBypassInfoID(), fc);
432         } else {
433             return;
434         }
435     }
436     if (p->BypassPacketsFlow && p->BypassPacketsFlow(p)) {
437         if (p->flow) {
438             FlowUpdateState(p->flow, FLOW_STATE_CAPTURE_BYPASSED);
439         }
440     } else {
441         if (p->flow) {
442             FlowUpdateState(p->flow, FLOW_STATE_LOCAL_BYPASSED);
443         }
444     }
445 #else /* CAPTURE_OFFLOAD */
446     if (p->flow) {
447         int state = p->flow->flow_state;
448         if (state == FLOW_STATE_LOCAL_BYPASSED)
449             return;
450         FlowUpdateState(p->flow, FLOW_STATE_LOCAL_BYPASSED);
451     }
452 #endif
453 }
454 
455 /** \brief switch direction of a packet */
PacketSwap(Packet * p)456 void PacketSwap(Packet *p)
457 {
458     if (PKT_IS_TOSERVER(p)) {
459         p->flowflags &= ~FLOW_PKT_TOSERVER;
460         p->flowflags |= FLOW_PKT_TOCLIENT;
461 
462         if (p->flowflags & FLOW_PKT_TOSERVER_FIRST) {
463             p->flowflags &= ~FLOW_PKT_TOSERVER_FIRST;
464             p->flowflags |= FLOW_PKT_TOCLIENT_FIRST;
465         }
466     } else {
467         p->flowflags &= ~FLOW_PKT_TOCLIENT;
468         p->flowflags |= FLOW_PKT_TOSERVER;
469 
470         if (p->flowflags & FLOW_PKT_TOCLIENT_FIRST) {
471             p->flowflags &= ~FLOW_PKT_TOCLIENT_FIRST;
472             p->flowflags |= FLOW_PKT_TOSERVER_FIRST;
473         }
474     }
475 }
476 
477 /* counter name store */
478 static HashTable *g_counter_table = NULL;
479 static SCMutex g_counter_table_mutex = SCMUTEX_INITIALIZER;
480 
DecodeUnregisterCounters(void)481 void DecodeUnregisterCounters(void)
482 {
483     SCMutexLock(&g_counter_table_mutex);
484     if (g_counter_table) {
485         HashTableFree(g_counter_table);
486         g_counter_table = NULL;
487     }
488     SCMutexUnlock(&g_counter_table_mutex);
489 }
490 
DecodeRegisterPerfCounters(DecodeThreadVars * dtv,ThreadVars * tv)491 void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
492 {
493     /* register counters */
494     dtv->counter_pkts = StatsRegisterCounter("decoder.pkts", tv);
495     dtv->counter_bytes = StatsRegisterCounter("decoder.bytes", tv);
496     dtv->counter_invalid = StatsRegisterCounter("decoder.invalid", tv);
497     dtv->counter_ipv4 = StatsRegisterCounter("decoder.ipv4", tv);
498     dtv->counter_ipv6 = StatsRegisterCounter("decoder.ipv6", tv);
499     dtv->counter_eth = StatsRegisterCounter("decoder.ethernet", tv);
500     dtv->counter_chdlc = StatsRegisterCounter("decoder.chdlc", tv);
501     dtv->counter_raw = StatsRegisterCounter("decoder.raw", tv);
502     dtv->counter_null = StatsRegisterCounter("decoder.null", tv);
503     dtv->counter_sll = StatsRegisterCounter("decoder.sll", tv);
504     dtv->counter_tcp = StatsRegisterCounter("decoder.tcp", tv);
505     dtv->counter_udp = StatsRegisterCounter("decoder.udp", tv);
506     dtv->counter_sctp = StatsRegisterCounter("decoder.sctp", tv);
507     dtv->counter_icmpv4 = StatsRegisterCounter("decoder.icmpv4", tv);
508     dtv->counter_icmpv6 = StatsRegisterCounter("decoder.icmpv6", tv);
509     dtv->counter_ppp = StatsRegisterCounter("decoder.ppp", tv);
510     dtv->counter_pppoe = StatsRegisterCounter("decoder.pppoe", tv);
511     dtv->counter_geneve = StatsRegisterCounter("decoder.geneve", tv);
512     dtv->counter_gre = StatsRegisterCounter("decoder.gre", tv);
513     dtv->counter_vlan = StatsRegisterCounter("decoder.vlan", tv);
514     dtv->counter_vlan_qinq = StatsRegisterCounter("decoder.vlan_qinq", tv);
515     dtv->counter_vxlan = StatsRegisterCounter("decoder.vxlan", tv);
516     dtv->counter_vntag = StatsRegisterCounter("decoder.vntag", tv);
517     dtv->counter_ieee8021ah = StatsRegisterCounter("decoder.ieee8021ah", tv);
518     dtv->counter_teredo = StatsRegisterCounter("decoder.teredo", tv);
519     dtv->counter_ipv4inipv6 = StatsRegisterCounter("decoder.ipv4_in_ipv6", tv);
520     dtv->counter_ipv6inipv6 = StatsRegisterCounter("decoder.ipv6_in_ipv6", tv);
521     dtv->counter_mpls = StatsRegisterCounter("decoder.mpls", tv);
522     dtv->counter_avg_pkt_size = StatsRegisterAvgCounter("decoder.avg_pkt_size", tv);
523     dtv->counter_max_pkt_size = StatsRegisterMaxCounter("decoder.max_pkt_size", tv);
524     dtv->counter_max_mac_addrs_src = StatsRegisterMaxCounter("decoder.max_mac_addrs_src", tv);
525     dtv->counter_max_mac_addrs_dst = StatsRegisterMaxCounter("decoder.max_mac_addrs_dst", tv);
526     dtv->counter_erspan = StatsRegisterMaxCounter("decoder.erspan", tv);
527     dtv->counter_flow_memcap = StatsRegisterCounter("flow.memcap", tv);
528 
529     dtv->counter_flow_tcp = StatsRegisterCounter("flow.tcp", tv);
530     dtv->counter_flow_udp = StatsRegisterCounter("flow.udp", tv);
531     dtv->counter_flow_icmp4 = StatsRegisterCounter("flow.icmpv4", tv);
532     dtv->counter_flow_icmp6 = StatsRegisterCounter("flow.icmpv6", tv);
533     dtv->counter_flow_tcp_reuse = StatsRegisterCounter("flow.tcp_reuse", tv);
534     dtv->counter_flow_get_used = StatsRegisterCounter("flow.get_used", tv);
535     dtv->counter_flow_get_used_eval = StatsRegisterCounter("flow.get_used_eval", tv);
536     dtv->counter_flow_get_used_eval_reject = StatsRegisterCounter("flow.get_used_eval_reject", tv);
537     dtv->counter_flow_get_used_eval_busy = StatsRegisterCounter("flow.get_used_eval_busy", tv);
538     dtv->counter_flow_get_used_failed = StatsRegisterCounter("flow.get_used_failed", tv);
539 
540     dtv->counter_flow_spare_sync_avg = StatsRegisterAvgCounter("flow.wrk.spare_sync_avg", tv);
541     dtv->counter_flow_spare_sync = StatsRegisterCounter("flow.wrk.spare_sync", tv);
542     dtv->counter_flow_spare_sync_incomplete = StatsRegisterCounter("flow.wrk.spare_sync_incomplete", tv);
543     dtv->counter_flow_spare_sync_empty = StatsRegisterCounter("flow.wrk.spare_sync_empty", tv);
544 
545     dtv->counter_defrag_ipv4_fragments =
546         StatsRegisterCounter("defrag.ipv4.fragments", tv);
547     dtv->counter_defrag_ipv4_reassembled =
548         StatsRegisterCounter("defrag.ipv4.reassembled", tv);
549     dtv->counter_defrag_ipv4_timeouts =
550         StatsRegisterCounter("defrag.ipv4.timeouts", tv);
551     dtv->counter_defrag_ipv6_fragments =
552         StatsRegisterCounter("defrag.ipv6.fragments", tv);
553     dtv->counter_defrag_ipv6_reassembled =
554         StatsRegisterCounter("defrag.ipv6.reassembled", tv);
555     dtv->counter_defrag_ipv6_timeouts =
556         StatsRegisterCounter("defrag.ipv6.timeouts", tv);
557     dtv->counter_defrag_max_hit =
558         StatsRegisterCounter("defrag.max_frag_hits", tv);
559 
560     for (int i = 0; i < DECODE_EVENT_MAX; i++) {
561         BUG_ON(i != (int)DEvents[i].code);
562 
563         if (i <= DECODE_EVENT_PACKET_MAX && !stats_decoder_events)
564             continue;
565         else if (i > DECODE_EVENT_PACKET_MAX && !stats_stream_events)
566             continue;
567 
568         if (i < DECODE_EVENT_PACKET_MAX &&
569                 strncmp(DEvents[i].event_name, "decoder.", 8) == 0)
570         {
571             SCMutexLock(&g_counter_table_mutex);
572             if (g_counter_table == NULL) {
573                 g_counter_table = HashTableInit(256, StringHashFunc,
574                         StringHashCompareFunc,
575                         StringHashFreeFunc);
576                 if (g_counter_table == NULL) {
577                     FatalError(SC_ERR_INITIALIZATION, "decoder counter hash "
578                             "table init failed");
579                 }
580             }
581 
582             char name[256];
583             char *dot = strchr(DEvents[i].event_name, '.');
584             BUG_ON(!dot);
585             snprintf(name, sizeof(name), "%s.%s",
586                     stats_decoder_events_prefix, dot+1);
587 
588             const char *found = HashTableLookup(g_counter_table, name, 0);
589             if (!found) {
590                 char *add = SCStrdup(name);
591                 if (add == NULL)
592                     FatalError(SC_ERR_INITIALIZATION, "decoder counter hash "
593                             "table name init failed");
594                 int r = HashTableAdd(g_counter_table, add, 0);
595                 if (r != 0)
596                     FatalError(SC_ERR_INITIALIZATION, "decoder counter hash "
597                             "table name add failed");
598                 found = add;
599             }
600             dtv->counter_engine_events[i] = StatsRegisterCounter(
601                     found, tv);
602 
603             SCMutexUnlock(&g_counter_table_mutex);
604         } else {
605             dtv->counter_engine_events[i] = StatsRegisterCounter(
606                     DEvents[i].event_name, tv);
607         }
608     }
609 
610     return;
611 }
612 
DecodeUpdatePacketCounters(ThreadVars * tv,const DecodeThreadVars * dtv,const Packet * p)613 void DecodeUpdatePacketCounters(ThreadVars *tv,
614                                 const DecodeThreadVars *dtv, const Packet *p)
615 {
616     StatsIncr(tv, dtv->counter_pkts);
617     //StatsIncr(tv, dtv->counter_pkts_per_sec);
618     StatsAddUI64(tv, dtv->counter_bytes, GET_PKT_LEN(p));
619     StatsAddUI64(tv, dtv->counter_avg_pkt_size, GET_PKT_LEN(p));
620     StatsSetUI64(tv, dtv->counter_max_pkt_size, GET_PKT_LEN(p));
621 }
622 
623 /**
624  *  \brief Debug print function for printing addresses
625  *
626  *  \param Address object
627  *
628  *  \todo IPv6
629  */
AddressDebugPrint(Address * a)630 void AddressDebugPrint(Address *a)
631 {
632     if (a == NULL)
633         return;
634 
635     switch (a->family) {
636         case AF_INET:
637         {
638             char s[16];
639             PrintInet(AF_INET, (const void *)&a->addr_data32[0], s, sizeof(s));
640             SCLogDebug("%s", s);
641             break;
642         }
643     }
644 }
645 
646 /** \brief Alloc and setup DecodeThreadVars */
DecodeThreadVarsAlloc(ThreadVars * tv)647 DecodeThreadVars *DecodeThreadVarsAlloc(ThreadVars *tv)
648 {
649     DecodeThreadVars *dtv = NULL;
650 
651     if ( (dtv = SCMalloc(sizeof(DecodeThreadVars))) == NULL)
652         return NULL;
653     memset(dtv, 0, sizeof(DecodeThreadVars));
654 
655     dtv->app_tctx = AppLayerGetCtxThread(tv);
656 
657     if (OutputFlowLogThreadInit(tv, NULL, &dtv->output_flow_thread_data) != TM_ECODE_OK) {
658         SCLogError(SC_ERR_THREAD_INIT, "initializing flow log API for thread failed");
659         DecodeThreadVarsFree(tv, dtv);
660         return NULL;
661     }
662 
663     return dtv;
664 }
665 
DecodeThreadVarsFree(ThreadVars * tv,DecodeThreadVars * dtv)666 void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
667 {
668     if (dtv != NULL) {
669         if (dtv->app_tctx != NULL)
670             AppLayerDestroyCtxThread(dtv->app_tctx);
671 
672         if (dtv->output_flow_thread_data != NULL)
673             OutputFlowLogThreadDeinit(tv, dtv->output_flow_thread_data);
674 
675         SCFree(dtv);
676     }
677 }
678 
679 /**
680  * \brief Set data for Packet and set length when zero copy is used
681  *
682  *  \param Pointer to the Packet to modify
683  *  \param Pointer to the data
684  *  \param Length of the data
685  */
PacketSetData(Packet * p,const uint8_t * pktdata,uint32_t pktlen)686 inline int PacketSetData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
687 {
688     SET_PKT_LEN(p, (size_t)pktlen);
689     if (unlikely(!pktdata)) {
690         return -1;
691     }
692     // ext_pkt cannot be const (because we sometimes copy)
693     p->ext_pkt = (uint8_t *) pktdata;
694     p->flags |= PKT_ZERO_COPY;
695 
696     return 0;
697 }
698 
PktSrcToString(enum PktSrcEnum pkt_src)699 const char *PktSrcToString(enum PktSrcEnum pkt_src)
700 {
701     const char *pkt_src_str = "<unknown>";
702     switch (pkt_src) {
703         case PKT_SRC_WIRE:
704             pkt_src_str = "wire/pcap";
705             break;
706         case PKT_SRC_DECODER_GRE:
707             pkt_src_str = "gre tunnel";
708             break;
709         case PKT_SRC_DECODER_IPV4:
710             pkt_src_str = "ipv4 tunnel";
711             break;
712         case PKT_SRC_DECODER_IPV6:
713             pkt_src_str = "ipv6 tunnel";
714             break;
715         case PKT_SRC_DECODER_TEREDO:
716             pkt_src_str = "teredo tunnel";
717             break;
718         case PKT_SRC_DEFRAG:
719             pkt_src_str = "defrag";
720             break;
721         case PKT_SRC_STREAM_TCP_DETECTLOG_FLUSH:
722             pkt_src_str = "stream (detect/log)";
723             break;
724         case PKT_SRC_FFR:
725             pkt_src_str = "stream (flow timeout)";
726             break;
727         case PKT_SRC_DECODER_GENEVE:
728             pkt_src_str = "geneve encapsulation";
729             break;
730         case PKT_SRC_DECODER_VXLAN:
731             pkt_src_str = "vxlan encapsulation";
732             break;
733         case PKT_SRC_DETECT_RELOAD_FLUSH:
734             pkt_src_str = "detect reload flush";
735             break;
736         case PKT_SRC_CAPTURE_TIMEOUT:
737             pkt_src_str = "capture timeout flush";
738             break;
739     }
740     return pkt_src_str;
741 }
742 
CaptureStatsUpdate(ThreadVars * tv,CaptureStats * s,const Packet * p)743 void CaptureStatsUpdate(ThreadVars *tv, CaptureStats *s, const Packet *p)
744 {
745     if (unlikely(PACKET_TEST_ACTION(p, (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)))) {
746         StatsIncr(tv, s->counter_ips_rejected);
747     } else if (unlikely(PACKET_TEST_ACTION(p, ACTION_DROP))) {
748         StatsIncr(tv, s->counter_ips_blocked);
749     } else if (unlikely(p->flags & PKT_STREAM_MODIFIED)) {
750         StatsIncr(tv, s->counter_ips_replaced);
751     } else {
752         StatsIncr(tv, s->counter_ips_accepted);
753     }
754 }
755 
CaptureStatsSetup(ThreadVars * tv,CaptureStats * s)756 void CaptureStatsSetup(ThreadVars *tv, CaptureStats *s)
757 {
758     s->counter_ips_accepted = StatsRegisterCounter("ips.accepted", tv);
759     s->counter_ips_blocked = StatsRegisterCounter("ips.blocked", tv);
760     s->counter_ips_rejected = StatsRegisterCounter("ips.rejected", tv);
761     s->counter_ips_replaced = StatsRegisterCounter("ips.replaced", tv);
762 }
763 
DecodeGlobalConfig(void)764 void DecodeGlobalConfig(void)
765 {
766     DecodeTeredoConfig();
767     DecodeGeneveConfig();
768     DecodeVXLANConfig();
769     DecodeERSPANConfig();
770     DecodeVNTagConfig();
771     intmax_t value = 0;
772     if (ConfGetInt("decoder.max-layers", &value) == 1) {
773         if (value < 0 || value > UINT8_MAX) {
774             SCLogWarning(SC_ERR_INVALID_VALUE, "Invalid value for decoder.max-layers");
775         } else {
776             decoder_max_layers = value;
777         }
778     }
779 }
780 
781 /**
782  * @}
783  */
784