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