PageRenderTime 49ms CodeModel.GetById 12ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/decode.h

https://github.com/decanio/suricata-tilera
C Header | 1286 lines | 890 code | 183 blank | 213 comment | 90 complexity | fc029a177ea80419c5a3a1fc29a2e9db MD5 | raw file
   1/* Copyright (C) 2007-2012 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 * \file
  20 *
  21 * \author Victor Julien <victor@inliniac.net>
  22 */
  23
  24#ifndef __DECODE_H__
  25#define __DECODE_H__
  26
  27//#define DBG_THREADS
  28#define COUNTERS
  29
  30#include "suricata-common.h"
  31
  32#include "threadvars.h"
  33
  34typedef enum {
  35    CHECKSUM_VALIDATION_DISABLE,
  36    CHECKSUM_VALIDATION_ENABLE,
  37    CHECKSUM_VALIDATION_AUTO,
  38    CHECKSUM_VALIDATION_RXONLY,
  39    CHECKSUM_VALIDATION_KERNEL,
  40} ChecksumValidationMode;
  41
  42enum {
  43    PKT_SRC_WIRE = 1,
  44    PKT_SRC_DECODER_GRE,
  45    PKT_SRC_DECODER_IPV4,
  46    PKT_SRC_DECODER_IPV6,
  47    PKT_SRC_DECODER_TEREDO,
  48    PKT_SRC_DEFRAG,
  49    PKT_SRC_STREAM_TCP_STREAM_END_PSEUDO,
  50    PKT_SRC_FFR_V2,
  51    PKT_SRC_FFR_SHUTDOWN,
  52};
  53
  54#include "source-nfq.h"
  55#include "source-ipfw.h"
  56#include "source-pcap.h"
  57#include "source-af-packet.h"
  58#include "source-mpipe.h"
  59
  60#include "action-globals.h"
  61
  62#include "decode-ethernet.h"
  63#include "decode-gre.h"
  64#include "decode-ppp.h"
  65#include "decode-pppoe.h"
  66#include "decode-sll.h"
  67#include "decode-ipv4.h"
  68#include "decode-ipv6.h"
  69#include "decode-icmpv4.h"
  70#include "decode-icmpv6.h"
  71#include "decode-tcp.h"
  72#include "decode-udp.h"
  73#include "decode-sctp.h"
  74#include "decode-raw.h"
  75#include "decode-vlan.h"
  76
  77#include "detect-reference.h"
  78
  79#include "app-layer-protos.h"
  80
  81#ifdef __tilegx__
  82#include <gxio/mpipe.h>
  83#elif defined(__tile__)
  84#include <netio/netio.h>
  85#endif
  86
  87#ifdef __SC_CUDA_SUPPORT__
  88#define CUDA_MAX_PAYLOAD_SIZE 1500
  89#endif
  90
  91/* forward declaration */
  92struct DetectionEngineThreadCtx_;
  93
  94/* Address */
  95typedef struct Address_ {
  96    char family;
  97    union {
  98        uint32_t       address_un_data32[4]; /* type-specific field */
  99        uint16_t       address_un_data16[8]; /* type-specific field */
 100        uint8_t        address_un_data8[16]; /* type-specific field */
 101    } address;
 102} Address;
 103
 104#define addr_data32 address.address_un_data32
 105#define addr_data16 address.address_un_data16
 106#define addr_data8  address.address_un_data8
 107
 108#define COPY_ADDRESS(a, b) do {                    \
 109        (b)->family = (a)->family;                 \
 110        (b)->addr_data32[0] = (a)->addr_data32[0]; \
 111        (b)->addr_data32[1] = (a)->addr_data32[1]; \
 112        (b)->addr_data32[2] = (a)->addr_data32[2]; \
 113        (b)->addr_data32[3] = (a)->addr_data32[3]; \
 114    } while (0)
 115
 116/* Set the IPv4 addressesinto the Addrs of the Packet.
 117 * Make sure p->ip4h is initialized and validated.
 118 *
 119 * We set the rest of the struct to 0 so we can
 120 * prevent using memset. */
 121#define SET_IPV4_SRC_ADDR(p, a) do {                              \
 122        (a)->family = AF_INET;                                    \
 123        (a)->addr_data32[0] = (uint32_t)(p)->ip4h->s_ip_src.s_addr; \
 124        (a)->addr_data32[1] = 0;                                  \
 125        (a)->addr_data32[2] = 0;                                  \
 126        (a)->addr_data32[3] = 0;                                  \
 127    } while (0)
 128
 129#define SET_IPV4_DST_ADDR(p, a) do {                              \
 130        (a)->family = AF_INET;                                    \
 131        (a)->addr_data32[0] = (uint32_t)(p)->ip4h->s_ip_dst.s_addr; \
 132        (a)->addr_data32[1] = 0;                                  \
 133        (a)->addr_data32[2] = 0;                                  \
 134        (a)->addr_data32[3] = 0;                                  \
 135    } while (0)
 136
 137/* clear the address structure by setting all fields to 0 */
 138#define CLEAR_ADDR(a) do {       \
 139        (a)->family = 0;         \
 140        (a)->addr_data32[0] = 0; \
 141        (a)->addr_data32[1] = 0; \
 142        (a)->addr_data32[2] = 0; \
 143        (a)->addr_data32[3] = 0; \
 144    } while (0)
 145
 146/* Set the IPv6 addressesinto the Addrs of the Packet.
 147 * Make sure p->ip6h is initialized and validated. */
 148#define SET_IPV6_SRC_ADDR(p, a) do {                    \
 149        (a)->family = AF_INET6;                         \
 150        (a)->addr_data32[0] = (p)->ip6h->s_ip6_src[0];  \
 151        (a)->addr_data32[1] = (p)->ip6h->s_ip6_src[1];  \
 152        (a)->addr_data32[2] = (p)->ip6h->s_ip6_src[2];  \
 153        (a)->addr_data32[3] = (p)->ip6h->s_ip6_src[3];  \
 154    } while (0)
 155
 156#define SET_IPV6_DST_ADDR(p, a) do {                    \
 157        (a)->family = AF_INET6;                         \
 158        (a)->addr_data32[0] = (p)->ip6h->s_ip6_dst[0];  \
 159        (a)->addr_data32[1] = (p)->ip6h->s_ip6_dst[1];  \
 160        (a)->addr_data32[2] = (p)->ip6h->s_ip6_dst[2];  \
 161        (a)->addr_data32[3] = (p)->ip6h->s_ip6_dst[3];  \
 162    } while (0)
 163
 164/* Set the TCP ports into the Ports of the Packet.
 165 * Make sure p->tcph is initialized and validated. */
 166#define SET_TCP_SRC_PORT(pkt, prt) do {            \
 167        SET_PORT(TCP_GET_SRC_PORT((pkt)), *(prt)); \
 168    } while (0)
 169
 170#define SET_TCP_DST_PORT(pkt, prt) do {            \
 171        SET_PORT(TCP_GET_DST_PORT((pkt)), *(prt)); \
 172    } while (0)
 173
 174/* Set the UDP ports into the Ports of the Packet.
 175 * Make sure p->udph is initialized and validated. */
 176#define SET_UDP_SRC_PORT(pkt, prt) do {            \
 177        SET_PORT(UDP_GET_SRC_PORT((pkt)), *(prt)); \
 178    } while (0)
 179#define SET_UDP_DST_PORT(pkt, prt) do {            \
 180        SET_PORT(UDP_GET_DST_PORT((pkt)), *(prt)); \
 181    } while (0)
 182
 183/* Set the SCTP ports into the Ports of the Packet.
 184 * Make sure p->sctph is initialized and validated. */
 185#define SET_SCTP_SRC_PORT(pkt, prt) do {            \
 186        SET_PORT(SCTP_GET_SRC_PORT((pkt)), *(prt)); \
 187    } while (0)
 188
 189#define SET_SCTP_DST_PORT(pkt, prt) do {            \
 190        SET_PORT(SCTP_GET_DST_PORT((pkt)), *(prt)); \
 191    } while (0)
 192
 193
 194
 195#define GET_IPV4_SRC_ADDR_U32(p) ((p)->src.addr_data32[0])
 196#define GET_IPV4_DST_ADDR_U32(p) ((p)->dst.addr_data32[0])
 197#define GET_IPV4_SRC_ADDR_PTR(p) ((p)->src.addr_data32)
 198#define GET_IPV4_DST_ADDR_PTR(p) ((p)->dst.addr_data32)
 199
 200#define GET_IPV6_SRC_ADDR(p) ((p)->src.addr_data32)
 201#define GET_IPV6_DST_ADDR(p) ((p)->dst.addr_data32)
 202#define GET_TCP_SRC_PORT(p)  ((p)->sp)
 203#define GET_TCP_DST_PORT(p)  ((p)->dp)
 204
 205#define GET_PKT_LEN(p) ((p)->pktlen)
 206#define GET_PKT_DATA(p) ((((p)->ext_pkt) == NULL ) ? (p)->pkt : (p)->ext_pkt)
 207#define GET_PKT_DIRECT_DATA(p) ((p)->pkt)
 208#define GET_PKT_DIRECT_MAX_SIZE(p) (default_packet_size)
 209
 210#define SET_PKT_LEN(p, len) do { \
 211    (p)->pktlen = (len); \
 212    } while (0)
 213
 214
 215/* Port is just a uint16_t */
 216typedef uint16_t Port;
 217#define SET_PORT(v, p) ((p) = (v))
 218#define COPY_PORT(a,b) ((b) = (a))
 219
 220#define CMP_ADDR(a1, a2) \
 221    (((a1)->addr_data32[3] == (a2)->addr_data32[3] && \
 222      (a1)->addr_data32[2] == (a2)->addr_data32[2] && \
 223      (a1)->addr_data32[1] == (a2)->addr_data32[1] && \
 224      (a1)->addr_data32[0] == (a2)->addr_data32[0]))
 225#define CMP_PORT(p1, p2) \
 226    ((p1) == (p2))
 227
 228/*Given a packet pkt offset to the start of the ip header in a packet
 229 *We determine the ip version. */
 230#define IP_GET_RAW_VER(pkt) ((((pkt)[0] & 0xf0) >> 4))
 231
 232#define PKT_IS_IPV4(p)      (((p)->ip4h != NULL))
 233#define PKT_IS_IPV6(p)      (((p)->ip6h != NULL))
 234#define PKT_IS_TCP(p)       (((p)->tcph != NULL))
 235#define PKT_IS_UDP(p)       (((p)->udph != NULL))
 236#define PKT_IS_ICMPV4(p)    (((p)->icmpv4h != NULL))
 237#define PKT_IS_ICMPV6(p)    (((p)->icmpv6h != NULL))
 238#define PKT_IS_TOSERVER(p)  (((p)->flowflags & FLOW_PKT_TOSERVER))
 239#define PKT_IS_TOCLIENT(p)  (((p)->flowflags & FLOW_PKT_TOCLIENT))
 240
 241#define IPH_IS_VALID(p) (PKT_IS_IPV4((p)) || PKT_IS_IPV6((p)))
 242
 243/* Retrieve proto regardless of IP version */
 244#define IP_GET_IPPROTO(p) \
 245    (p->proto ? p->proto : \
 246    (PKT_IS_IPV4((p))? IPV4_GET_IPPROTO((p)) : (PKT_IS_IPV6((p))? IPV6_GET_L4PROTO((p)) : 0)))
 247
 248/* structure to store the sids/gids/etc the detection engine
 249 * found in this packet */
 250typedef struct PacketAlert_ {
 251    SigIntId num; /* Internal num, used for sorting */
 252    SigIntId order_id; /* Internal num, used for sorting */
 253    uint8_t action; /* Internal num, used for sorting */
 254    uint8_t flags;
 255    struct Signature_ *s;
 256} PacketAlert;
 257
 258/** After processing an alert by the thresholding module, if at
 259 *  last it gets triggered, we might want to stick the drop action to
 260 *  the flow on IPS mode */
 261#define PACKET_ALERT_FLAG_DROP_FLOW     0x01
 262/** alert was generated based on state */
 263#define PACKET_ALERT_FLAG_STATE_MATCH   0x02
 264/** alert was generated based on stream */
 265#define PACKET_ALERT_FLAG_STREAM_MATCH  0x04
 266
 267#define PACKET_ALERT_MAX 15
 268
 269typedef struct PacketAlerts_ {
 270    uint16_t cnt;
 271    PacketAlert alerts[PACKET_ALERT_MAX];
 272} PacketAlerts;
 273
 274/** number of decoder events we support per packet. Power of 2 minus 1
 275 *  for memory layout */
 276#define PACKET_ENGINE_EVENT_MAX 15
 277
 278/** data structure to store decoder, defrag and stream events */
 279typedef struct PacketEngineEvents_ {
 280    uint8_t cnt;                                /**< number of events */
 281    uint8_t events[PACKET_ENGINE_EVENT_MAX];   /**< array of events */
 282} PacketEngineEvents;
 283
 284typedef struct PktVar_ {
 285    char *name;
 286    struct PktVar_ *next; /* right now just implement this as a list,
 287                           * in the long run we have thing of something
 288                           * faster. */
 289    uint8_t *value;
 290    uint16_t value_len;
 291} PktVar;
 292
 293#ifdef PROFILING
 294
 295/** \brief Per TMM stats storage */
 296typedef struct PktProfilingTmmData_ {
 297    uint64_t ticks_start;
 298    uint64_t ticks_end;
 299#ifdef PROFILE_LOCKING
 300    uint64_t mutex_lock_cnt;
 301    uint64_t mutex_lock_wait_ticks;
 302    uint64_t mutex_lock_contention;
 303    uint64_t spin_lock_cnt;
 304    uint64_t spin_lock_wait_ticks;
 305    uint64_t spin_lock_contention;
 306    uint64_t rww_lock_cnt;
 307    uint64_t rww_lock_wait_ticks;
 308    uint64_t rww_lock_contention;
 309    uint64_t rwr_lock_cnt;
 310    uint64_t rwr_lock_wait_ticks;
 311    uint64_t rwr_lock_contention;
 312#endif
 313} PktProfilingTmmData;
 314
 315typedef struct PktProfilingDetectData_ {
 316    uint64_t ticks_start;
 317    uint64_t ticks_end;
 318    uint64_t ticks_spent;
 319} PktProfilingDetectData;
 320
 321typedef struct PktProfilingAppData_ {
 322    uint64_t ticks_spent;
 323} PktProfilingAppData;
 324
 325/** \brief Per pkt stats storage */
 326typedef struct PktProfiling_ {
 327    uint64_t ticks_start;
 328    uint64_t ticks_end;
 329
 330    PktProfilingTmmData tmm[TMM_SIZE];
 331    PktProfilingAppData app[ALPROTO_MAX];
 332    PktProfilingDetectData detect[PROF_DETECT_SIZE];
 333    uint64_t proto_detect;
 334} PktProfiling;
 335
 336#endif /* PROFILING */
 337
 338/* forward declartion since Packet struct definition requires this */
 339struct PacketQueue_;
 340
 341/* sizes of the members:
 342 * src: 17 bytes
 343 * dst: 17 bytes
 344 * sp/type: 1 byte
 345 * dp/code: 1 byte
 346 * proto: 1 byte
 347 * recurs: 1 byte
 348 *
 349 * sum of above: 38 bytes
 350 *
 351 * flow ptr: 4/8 bytes
 352 * flags: 1 byte
 353 * flowflags: 1 byte
 354 *
 355 * sum of above 44/48 bytes
 356 */
 357#ifndef __tile__
 358
 359typedef struct Packet_
 360{
 361    /* Addresses, Ports and protocol
 362     * these are on top so we can use
 363     * the Packet as a hash key */
 364    Address src;
 365    Address dst;
 366    union {
 367        Port sp;
 368        uint8_t type;
 369    };
 370    union {
 371        Port dp;
 372        uint8_t code;
 373    };
 374    uint8_t proto;
 375    /* make sure we can't be attacked on when the tunneled packet
 376     * has the exact same tuple as the lower levels */
 377    uint8_t recursion_level;
 378
 379    /* Pkt Flags */
 380    uint32_t flags;
 381
 382    /* flow */
 383    uint8_t flowflags;
 384
 385    uint8_t pkt_src;
 386
 387    struct Flow_ *flow;
 388
 389    struct timeval ts;
 390
 391    union {
 392        /* nfq stuff */
 393#ifdef NFQ
 394        NFQPacketVars nfq_v;
 395#endif /* NFQ */
 396#ifdef IPFW
 397        IPFWPacketVars ipfw_v;
 398#endif /* IPFW */
 399#ifdef AF_PACKET
 400        AFPPacketVars afp_v;
 401#endif
 402
 403        /** libpcap vars: shared by Pcap Live mode and Pcap File mode */
 404        PcapPacketVars pcap_v;
 405    };
 406
 407    /** data linktype in host order */
 408    int datalink;
 409
 410    /* IPS action to take */
 411    uint8_t action;
 412
 413    /* used to hold flowbits only if debuglog is enabled */
 414    int debuglog_flowbits_names_len;
 415    const char **debuglog_flowbits_names;
 416
 417    /** The release function for packet data */
 418    TmEcode (*ReleaseData)(ThreadVars *, struct Packet_ *);
 419
 420    /* pkt vars */
 421    PktVar *pktvar;
 422
 423    /* header pointers */
 424    EthernetHdr *ethh;
 425
 426    IPV4Hdr *ip4h;
 427    IPV4Vars ip4vars;
 428
 429    IPV6Hdr *ip6h;
 430    IPV6Vars ip6vars;
 431    IPV6ExtHdrs ip6eh;
 432
 433    TCPHdr *tcph;
 434    TCPVars tcpvars;
 435
 436    UDPHdr *udph;
 437    UDPVars udpvars;
 438
 439    SCTPHdr *sctph;
 440
 441    ICMPV4Hdr *icmpv4h;
 442    ICMPV4Vars icmpv4vars;
 443
 444    ICMPV6Hdr *icmpv6h;
 445    ICMPV6Vars icmpv6vars;
 446
 447    PPPHdr *ppph;
 448    PPPOESessionHdr *pppoesh;
 449    PPPOEDiscoveryHdr *pppoedh;
 450
 451    GREHdr *greh;
 452
 453    VLANHdr *vlanh;
 454
 455    /* ptr to the payload of the packet
 456     * with it's length. */
 457    uint8_t *payload;
 458    uint16_t payload_len;
 459
 460    /* storage: set to pointer to heap and extended via allocation if necessary */
 461    uint8_t *pkt;
 462    uint8_t *ext_pkt;
 463    uint32_t pktlen;
 464
 465    /* Incoming interface */
 466    struct LiveDevice_ *livedev;
 467
 468    PacketAlerts alerts;
 469
 470    struct Host_ *host_src;
 471    struct Host_ *host_dst;
 472
 473    /** packet number in the pcap file, matches wireshark */
 474    uint64_t pcap_cnt;
 475
 476    /** mutex to protect access to:
 477     *  - tunnel_rtv_cnt
 478     *  - tunnel_tpr_cnt
 479     */
 480    SCMutex tunnel_mutex;
 481    /* ready to set verdict counter, only set in root */
 482    uint16_t tunnel_rtv_cnt;
 483    /* tunnel packet ref count */
 484    uint16_t tunnel_tpr_cnt;
 485
 486    /* engine events */
 487    PacketEngineEvents events;
 488
 489    /* double linked list ptrs */
 490    struct Packet_ *next;
 491    struct Packet_ *prev;
 492
 493    /* tunnel/encapsulation handling */
 494    struct Packet_ *root; /* in case of tunnel this is a ptr
 495                           * to the 'real' packet, the one we
 496                           * need to set the verdict on --
 497                           * It should always point to the lowest
 498                           * packet in a encapsulated packet */
 499
 500    /* required for cuda support */
 501#ifdef __SC_CUDA_SUPPORT__
 502    /* indicates if the cuda mpm would be conducted or a normal cpu mpm would
 503     * be conduced on this packet.  If it is set to 0, the cpu mpm; else cuda mpm */
 504    uint8_t cuda_mpm_enabled;
 505    /* indicates if the cuda mpm has finished running the mpm and processed the
 506     * results for this packet, assuming if cuda_mpm_enabled has been set for this
 507     * packet */
 508    uint16_t cuda_done;
 509    /* used by the detect thread and the cuda mpm dispatcher thread.  The detect
 510     * thread would wait on this cond var, if the cuda mpm dispatcher thread
 511     * still hasn't processed the packet.  The dispatcher would use this cond
 512     * to inform the detect thread(in case it is waiting on this packet), once
 513     * the dispatcher is done processing the packet results */
 514    SCMutex cuda_mutex;
 515    SCCondT cuda_cond;
 516    /* the extra 1 in the 1481, is to hold the no_of_matches from the mpm run */
 517    uint16_t mpm_offsets[CUDA_MAX_PAYLOAD_SIZE + 1];
 518#endif
 519
 520#ifdef PROFILING
 521    PktProfiling profile;
 522#endif
 523} Packet;
 524
 525#else
 526
 527/* __tile__ */
 528typedef struct Packet_
 529{
 530    /* Addresses, Ports and protocol
 531     * these are on top so we can use
 532     * the Packet as a hash key */
 533    Address src;
 534    Address dst;
 535    union {
 536        Port sp;
 537        uint8_t type;
 538    };
 539    union {
 540        Port dp;
 541        uint8_t code;
 542    };
 543    uint8_t proto;
 544    /* make sure we can't be attacked on when the tunneled packet
 545     * has the exact same tuple as the lower levels */
 546    uint8_t recursion_level;
 547
 548    /* Pkt Flags */
 549    uint32_t flags;
 550
 551    /* flow */
 552    uint8_t flowflags;
 553
 554    uint8_t pkt_src;
 555
 556    struct Flow_ *flow;
 557
 558    /* data linktype in host order */
 559    uint16_t datalink;
 560
 561    /* IPS action to take */
 562    uint8_t action;
 563
 564    /* double linked list ptrs */
 565    struct Packet_ *next;
 566    struct Packet_ *prev;
 567
 568    union {
 569        struct timespec ts_nsec; /* time from mpipe */
 570        struct timeval ts;
 571    };
 572
 573    /* used to hold flowbits only if debuglog is enabled */
 574    int debuglog_flowbits_names_len;
 575    const char **debuglog_flowbits_names;
 576
 577    /** The release function for packet data */
 578    TmEcode (*ReleaseData)(ThreadVars *, struct Packet_ *);
 579
 580    EthernetHdr *ethh;
 581
 582    /* pkt vars */
 583    PktVar *pktvar;
 584
 585    /* header pointers */
 586    IPV4Hdr *ip4h;
 587    IPV6Hdr *ip6h;
 588    TCPHdr *tcph;
 589    UDPHdr *udph;
 590    SCTPHdr *sctph;
 591    ICMPV4Hdr *icmpv4h;
 592    ICMPV6Hdr *icmpv6h;
 593
 594    PPPHdr *ppph;
 595    PPPOESessionHdr *pppoesh;
 596    PPPOEDiscoveryHdr *pppoedh;
 597
 598    GREHdr *greh;
 599
 600    VLANHdr *vlanh;
 601
 602    /* ptr to the payload of the packet
 603     * with it's length. */
 604    uint8_t *payload;
 605    uint16_t payload_len;
 606
 607    /* storage: set to pointer to heap and extended via allocation if necessary */
 608    uint8_t *pkt;
 609    uint8_t *ext_pkt;
 610    uint32_t pktlen;
 611
 612    /* Incoming interface */
 613    struct LiveDevice_ *livedev;
 614
 615#if 1
 616    union {
 617        IPV4Vars ip4vars;
 618        struct {
 619            IPV6Vars ip6vars;
 620            IPV6ExtHdrs ip6eh;
 621        };
 622    };
 623    union {
 624        TCPVars tcpvars;
 625        UDPVars udpvars;
 626        ICMPV4Vars icmpv4vars;
 627        ICMPV6Vars icmpv6vars;
 628    };
 629#else
 630    IPV4Vars ip4vars /*__attribute__((aligned(64)))*/;
 631    IPV6Vars ip6vars /*__attribute__((aligned(64)))*/;
 632    IPV6ExtHdrs ip6eh /*__attribute__((aligned(64)))*/;
 633    TCPVars tcpvars /*__attribute__((aligned(64)))*/;
 634    UDPVars udpvars /*__attribute__((aligned(64)))*/;
 635    ICMPV4Vars icmpv4vars /*__attribute__((aligned(64)))*/;
 636    ICMPV6Vars icmpv6vars /*__attribute__((aligned(64)))*/;
 637#endif
 638
 639    /** packet number in the pcap file, matches wireshark */
 640    uint64_t pcap_cnt;
 641
 642    /** mutex to protect access to:
 643     *  - tunnel_rtv_cnt
 644     *  - tunnel_tpr_cnt
 645     */
 646    SCMutex tunnel_mutex;
 647    /* ready to set verdict counter, only set in root */
 648    uint16_t tunnel_rtv_cnt;
 649    /* tunnel packet ref count */
 650    uint16_t tunnel_tpr_cnt;
 651
 652    /* tunnel/encapsulation handling */
 653    struct Packet_ *root; /* in case of tunnel this is a ptr
 654                           * to the 'real' packet, the one we
 655                           * need to set the verdict on --
 656                           * It should always point to the lowest
 657                           * packet in a encapsulated packet */
 658
 659    /* engine events */
 660    PacketEngineEvents events;
 661    PacketAlerts alerts;
 662
 663    struct Host_ *host_src;
 664    struct Host_ *host_dst;
 665
 666    /* required for cuda support */
 667#ifdef __SC_CUDA_SUPPORT__
 668    /* indicates if the cuda mpm would be conducted or a normal cpu mpm would
 669     * be conduced on this packet.  If it is set to 0, the cpu mpm; else cuda mpm */
 670    uint8_t cuda_mpm_enabled;
 671    /* indicates if the cuda mpm has finished running the mpm and processed the
 672     * results for this packet, assuming if cuda_mpm_enabled has been set for this
 673     * packet */
 674    uint16_t cuda_done;
 675    /* used by the detect thread and the cuda mpm dispatcher thread.  The detect
 676     * thread would wait on this cond var, if the cuda mpm dispatcher thread
 677     * still hasn't processed the packet.  The dispatcher would use this cond
 678     * to inform the detect thread(in case it is waiting on this packet), once
 679     * the dispatcher is done processing the packet results */
 680    SCMutex cuda_mutex;
 681    SCCondT cuda_cond;
 682    /* the extra 1 in the 1481, is to hold the no_of_matches from the mpm run */
 683    uint16_t mpm_offsets[CUDA_MAX_PAYLOAD_SIZE + 1];
 684#endif
 685
 686#ifdef PROFILING
 687    PktProfiling profile;
 688#endif
 689    union {
 690        /* nfq stuff */
 691#ifdef NFQ
 692        NFQPacketVars nfq_v;
 693#endif /* NFQ */
 694
 695#ifdef IPFW
 696        IPFWPacketVars ipfw_v;
 697#endif /* IPFW */
 698
 699        /** libpcap vars: shared by Pcap Live mode and Pcap File mode */
 700        PcapPacketVars pcap_v;
 701
 702#ifdef __tilegx__
 703        /* tilegx mpipe stuff */
 704        MpipePacketVars mpipe_v;
 705#else
 706        /* Tile64 netio stuff */
 707    	netio_pkt_t netio_packet;
 708#endif
 709    };
 710
 711} __attribute__((aligned(128))) Packet;
 712
 713#endif
 714
 715#define DEFAULT_PACKET_SIZE (1500 + ETHERNET_HEADER_LEN)
 716/* storage: maximum ip packet size + link header */
 717#define MAX_PAYLOAD_SIZE (IPV6_HEADER_LEN + 65536 + 28)
 718uint32_t default_packet_size;
 719#define SIZE_OF_PACKET (default_packet_size + sizeof(Packet))
 720
 721typedef struct PacketQueue_ {
 722    Packet *top;
 723    Packet *bot;
 724#ifdef __tile__
 725    int32_t len;    /* -1 signals termination */
 726#else
 727    uint32_t len;
 728#endif
 729#ifdef DBG_PERF
 730    uint32_t dbg_maxlen;
 731#endif /* DBG_PERF */
 732#ifdef __tile__
 733    volatile uint32_t cond_q;
 734    SCMutex mutex_q /*__attribute__((aligned(64)))*/;
 735} __attribute__((aligned(64))) PacketQueue;
 736#else
 737    SCMutex mutex_q;
 738    SCCondT cond_q;
 739} PacketQueue;
 740#endif
 741
 742/** \brief Specific ctx for AL proto detection */
 743typedef struct AlpProtoDetectDirectionThread_ {
 744    MpmThreadCtx mpm_ctx;
 745    PatternMatcherQueue pmq;
 746} AlpProtoDetectDirectionThread;
 747
 748/** \brief Specific ctx for AL proto detection */
 749typedef struct AlpProtoDetectThreadCtx_ {
 750    AlpProtoDetectDirectionThread toserver;
 751    AlpProtoDetectDirectionThread toclient;
 752
 753    void *alproto_local_storage[ALPROTO_MAX];
 754
 755#ifdef PROFILING
 756    uint64_t ticks_start;
 757    uint64_t ticks_end;
 758    uint64_t ticks_spent;
 759    uint16_t alproto;
 760    uint64_t proto_detect_ticks_start;
 761    uint64_t proto_detect_ticks_end;
 762    uint64_t proto_detect_ticks_spent;
 763#endif
 764} AlpProtoDetectThreadCtx;
 765
 766/** \brief Structure to hold thread specific data for all decode modules */
 767typedef struct DecodeThreadVars_
 768{
 769    /** Specific context for udp protocol detection (here atm) */
 770    AlpProtoDetectThreadCtx udp_dp_ctx;
 771
 772    /** stats/counters */
 773    uint16_t counter_pkts;
 774    uint16_t counter_pkts_per_sec;
 775    uint16_t counter_bytes;
 776    uint16_t counter_bytes_per_sec;
 777    uint16_t counter_mbit_per_sec;
 778    uint16_t counter_ipv4;
 779    uint16_t counter_ipv6;
 780    uint16_t counter_eth;
 781    uint16_t counter_sll;
 782    uint16_t counter_raw;
 783    uint16_t counter_tcp;
 784    uint16_t counter_udp;
 785    uint16_t counter_sctp;
 786    uint16_t counter_icmpv4;
 787    uint16_t counter_icmpv6;
 788    uint16_t counter_ppp;
 789    uint16_t counter_gre;
 790    uint16_t counter_vlan;
 791    uint16_t counter_pppoe;
 792    uint16_t counter_teredo;
 793    uint16_t counter_ipv4inipv6;
 794    uint16_t counter_ipv6inipv6;
 795    uint16_t counter_avg_pkt_size;
 796    uint16_t counter_max_pkt_size;
 797
 798    /** frag stats - defrag runs in the context of the decoder. */
 799    uint16_t counter_defrag_ipv4_fragments;
 800    uint16_t counter_defrag_ipv4_reassembled;
 801    uint16_t counter_defrag_ipv4_timeouts;
 802    uint16_t counter_defrag_ipv6_fragments;
 803    uint16_t counter_defrag_ipv6_reassembled;
 804    uint16_t counter_defrag_ipv6_timeouts;
 805    uint16_t counter_defrag_max_hit;
 806} DecodeThreadVars;
 807
 808/**
 809 *  \brief reset these to -1(indicates that the packet is fresh from the queue)
 810 */
 811#define PACKET_RESET_CHECKSUMS(p) do { \
 812        (p)->ip4vars.comp_csum = -1;   \
 813        (p)->tcpvars.comp_csum = -1;      \
 814        (p)->udpvars.comp_csum = -1;      \
 815        (p)->icmpv4vars.comp_csum = -1;   \
 816        (p)->icmpv6vars.comp_csum = -1;   \
 817    } while (0)
 818
 819/**
 820 *  \brief Initialize a packet structure for use.
 821 */
 822#ifndef __SC_CUDA_SUPPORT__
 823#ifdef __tile__
 824#define PACKET_INITIALIZE(p) { \
 825    memset((p), 0x00, sizeof(Packet)); \
 826    SCMutexInit(&(p)->tunnel_mutex, NULL); \
 827    PACKET_RESET_CHECKSUMS((p)); \
 828    (p)->pkt = ((uint8_t *)(p)) + sizeof(Packet); \
 829    (p)->livedev = NULL; \
 830}
 831#else
 832#define PACKET_INITIALIZE(p) { \
 833    memset((p), 0x00, SIZE_OF_PACKET); \
 834    SCMutexInit(&(p)->tunnel_mutex, NULL); \
 835    PACKET_RESET_CHECKSUMS((p)); \
 836    (p)->pkt = ((uint8_t *)(p)) + sizeof(Packet); \
 837    (p)->livedev = NULL; \
 838}
 839#endif
 840#else
 841#ifdef __tile__
 842#define PACKET_INITIALIZE(p) { \
 843    memset((p), 0x00, sizeof(Packet)); \
 844    SCMutexInit(&(p)->tunnel_mutex, NULL); \
 845    PACKET_RESET_CHECKSUMS((p)); \
 846    SCMutexInit(&(p)->cuda_mutex, NULL); \
 847    SCCondInit(&(p)->cuda_cond, NULL); \
 848    (p)->pkt = ((uint8_t *)(p)) + sizeof(Packet); \
 849    (p)->livedev = NULL; \
 850}
 851#else
 852#define PACKET_INITIALIZE(p) { \
 853    memset((p), 0x00, SIZE_OF_PACKET); \
 854    SCMutexInit(&(p)->tunnel_mutex, NULL); \
 855    PACKET_RESET_CHECKSUMS((p)); \
 856    SCMutexInit(&(p)->cuda_mutex, NULL); \
 857    SCCondInit(&(p)->cuda_cond, NULL); \
 858    (p)->pkt = ((uint8_t *)(p)) + sizeof(Packet); \
 859    (p)->livedev = NULL; \
 860}
 861#endif
 862#endif
 863
 864/**
 865 *  \brief Recycle a packet structure for reuse.
 866 *  \todo the mutex destroy & init is necessary because of the memset, reconsider
 867 */
 868#ifndef __tile__
 869
 870#define PACKET_DO_RECYCLE(p) do {               \
 871        CLEAR_ADDR(&(p)->src);                  \
 872        CLEAR_ADDR(&(p)->dst);                  \
 873        (p)->sp = 0;                            \
 874        (p)->dp = 0;                            \
 875        (p)->proto = 0;                         \
 876        (p)->recursion_level = 0;               \
 877        (p)->flags = 0;                         \
 878        (p)->flowflags = 0;                     \
 879        (p)->pkt_src = 0;                       \
 880        FlowDeReference(&((p)->flow));          \
 881        (p)->ts.tv_sec = 0;                     \
 882        (p)->ts.tv_usec = 0;                    \
 883        (p)->datalink = 0;                      \
 884        (p)->action = 0;                        \
 885        if ((p)->pktvar != NULL) {              \
 886            PktVarFree((p)->pktvar);            \
 887            (p)->pktvar = NULL;                 \
 888        }                                       \
 889        (p)->ethh = NULL;                       \
 890        if ((p)->ip4h != NULL) {                \
 891            CLEAR_IPV4_PACKET((p));             \
 892        }                                       \
 893        if ((p)->ip6h != NULL) {                \
 894            CLEAR_IPV6_PACKET((p));             \
 895        }                                       \
 896        if ((p)->tcph != NULL) {                \
 897            CLEAR_TCP_PACKET((p));              \
 898        }                                       \
 899        if ((p)->udph != NULL) {                \
 900            CLEAR_UDP_PACKET((p));              \
 901        }                                       \
 902        if ((p)->sctph != NULL) {               \
 903            CLEAR_SCTP_PACKET((p));             \
 904        }                                       \
 905        if ((p)->icmpv4h != NULL) {             \
 906            CLEAR_ICMPV4_PACKET((p));           \
 907        }                                       \
 908        if ((p)->icmpv6h != NULL) {             \
 909            CLEAR_ICMPV6_PACKET((p));           \
 910        }                                       \
 911        (p)->ppph = NULL;                       \
 912        (p)->pppoesh = NULL;                    \
 913        (p)->pppoedh = NULL;                    \
 914        (p)->greh = NULL;                       \
 915        (p)->vlanh = NULL;                      \
 916        (p)->payload = NULL;                    \
 917        (p)->payload_len = 0;                   \
 918        (p)->pktlen = 0;                        \
 919        (p)->alerts.cnt = 0;                    \
 920        HostDeReference(&((p)->host_src));      \
 921        HostDeReference(&((p)->host_dst));      \
 922        (p)->pcap_cnt = 0;                      \
 923        (p)->tunnel_rtv_cnt = 0;                \
 924        (p)->tunnel_tpr_cnt = 0;                \
 925        SCMutexDestroy(&(p)->tunnel_mutex);     \
 926        SCMutexInit(&(p)->tunnel_mutex, NULL);  \
 927        (p)->events.cnt = 0;                    \
 928        (p)->next = NULL;                       \
 929        (p)->prev = NULL;                       \
 930        (p)->root = NULL;                       \
 931        (p)->livedev = NULL;                    \
 932        (p)->ReleaseData = NULL;                \
 933        PACKET_RESET_CHECKSUMS((p));            \
 934        PACKET_PROFILING_RESET((p));            \
 935    } while (0)
 936
 937#else
 938
 939/* __tile__ */
 940#define PACKET_DO_RECYCLE(p) do {               \
 941        __insn_prefetch(&(p)->pktvar);		\
 942        __insn_prefetch(&(p)->alerts.cnt); \
 943        __insn_prefetch(&(p)->events.cnt); \
 944	uint64_t *llp = (uint64_t *)(p);	\
 945        __insn_wh64(llp);		\
 946        __insn_wh64(&llp[8]);		\
 947	llp[0] = 0;				\
 948	llp[1] = 0;				\
 949	llp[2] = 0;				\
 950	llp[3] = 0;				\
 951	llp[4] = 0;				\
 952	llp[5] = 0;				\
 953	llp[6] = 0;				\
 954	llp[7] = 0;				\
 955	llp[8] = 0;				\
 956	llp[9] = 0;				\
 957	llp[10] = 0;				\
 958	llp[11] = 0;				\
 959	llp[12] = 0;				\
 960	llp[13] = 0;				\
 961	llp[14] = 0;				\
 962	llp[15] = 0;				\
 963        /*CLEAR_ADDR(&(p)->src);*/                  \
 964        /*CLEAR_ADDR(&(p)->dst);*/                  \
 965        /*(p)->sp = 0;*/                            \
 966        /*(p)->dp = 0;*/                            \
 967        /*(p)->proto = 0;*/                         \
 968        /*(p)->recursion_level = 0;*/               \
 969        /*(p)->flags = 0;*/                         \
 970        /*(p)->flowflags = 0;*/                     \
 971        /* (p)->pkt_src = 0; */                     \
 972        /*(p)->flow = NULL;*/                       \
 973        /*(p)->ts.tv_sec = 0;*/                     \
 974        /*(p)->ts.tv_usec = 0;*/                    \
 975        /*(p)->datalink = 0;*/                      \
 976        /*(p)->action = 0;*/                        \
 977        FlowDeReference(&((p)->flow));          \
 978        if ((p)->pktvar != NULL) {              \
 979            PktVarFree((p)->pktvar);            \
 980            (p)->pktvar = NULL;                 \
 981        }                                       \
 982        /*(p)->ethh = NULL;*/                       \
 983        if ((p)->ip4h != NULL) {                \
 984            CLEAR_IPV4_PACKET((p));             \
 985        }                                       \
 986        if ((p)->ip6h != NULL) {                \
 987            CLEAR_IPV6_PACKET((p));             \
 988        }                                       \
 989        if ((p)->tcph != NULL) {                \
 990            CLEAR_TCP_PACKET((p));              \
 991        }                                       \
 992        if ((p)->udph != NULL) {                \
 993            CLEAR_UDP_PACKET((p));              \
 994        }                                       \
 995        if ((p)->sctph != NULL) {                \
 996            CLEAR_SCTP_PACKET((p));              \
 997        }                                       \
 998        if ((p)->icmpv4h != NULL) {             \
 999            CLEAR_ICMPV4_PACKET((p));           \
1000        }                                       \
1001        if ((p)->icmpv6h != NULL) {             \
1002            CLEAR_ICMPV6_PACKET((p));           \
1003        }                                       \
1004        (p)->ppph = NULL;                       \
1005        (p)->pppoesh = NULL;                    \
1006        (p)->pppoedh = NULL;                    \
1007        (p)->greh = NULL;                       \
1008        (p)->vlanh = NULL;                      \
1009        (p)->payload = NULL;                    \
1010        (p)->payload_len = 0;                   \
1011        (p)->pktlen = 0;                        \
1012        if (unlikely((p)->alerts.cnt)) (p)->alerts.cnt = 0; \
1013        HostDeReference(&((p)->host_src));      \
1014        HostDeReference(&((p)->host_dst));      \
1015        (p)->pcap_cnt = 0;                      \
1016        (p)->tunnel_rtv_cnt = 0;                \
1017        (p)->tunnel_tpr_cnt = 0;                \
1018        SCMutexDestroy(&(p)->tunnel_mutex);     \
1019        SCMutexInit(&(p)->tunnel_mutex, NULL);  \
1020        if ((p)->events.cnt) (p)->events.cnt = 0; \
1021        /*(p)->next = NULL;*/                   \
1022        /*(p)->prev = NULL;*/                   \
1023        (p)->root = NULL;                       \
1024        (p)->livedev = NULL;                    \
1025        PACKET_RESET_CHECKSUMS((p));            \
1026        PACKET_PROFILING_RESET((p));            \
1027    } while (0)
1028
1029#endif
1030
1031#ifndef __SC_CUDA_SUPPORT__
1032#define PACKET_RECYCLE(p) PACKET_DO_RECYCLE((p))
1033#else
1034#define PACKET_RECYCLE(p) do {                  \
1035    PACKET_DO_RECYCLE((p));                     \
1036    SCMutexDestroy(&(p)->cuda_mutex);           \
1037    SCCondDestroy(&(p)->cuda_cond);             \
1038    SCMutexInit(&(p)->cuda_mutex, NULL);        \
1039    SCCondInit(&(p)->cuda_cond, NULL);          \
1040    PACKET_RESET_CHECKSUMS((p));                \
1041} while(0)
1042#endif
1043
1044/**
1045 *  \brief Cleanup a packet so that we can free it. No memset needed..
1046 */
1047#ifndef __SC_CUDA_SUPPORT__
1048#define PACKET_CLEANUP(p) do {                  \
1049        if ((p)->pktvar != NULL) {              \
1050            PktVarFree((p)->pktvar);            \
1051        }                                       \
1052        SCMutexDestroy(&(p)->tunnel_mutex);     \
1053    } while (0)
1054#else
1055#define PACKET_CLEANUP(p) do {                  \
1056    if ((p)->pktvar != NULL) {                  \
1057        PktVarFree((p)->pktvar);                \
1058    }                                           \
1059    SCMutexDestroy(&(p)->tunnel_mutex);         \
1060    SCMutexDestroy(&(p)->cuda_mutex);           \
1061    SCCondDestroy(&(p)->cuda_cond);             \
1062} while(0)
1063#endif
1064
1065
1066/* macro's for setting the action
1067 * handle the case of a root packet
1068 * for tunnels */
1069#define ALERT_PACKET(p) do { \
1070    ((p)->root ? \
1071     ((p)->root->action = ACTION_ALERT) : \
1072     ((p)->action = ACTION_ALERT)); \
1073} while (0)
1074
1075#define ACCEPT_PACKET(p) do { \
1076    ((p)->root ? \
1077     ((p)->root->action = ACTION_ACCEPT) : \
1078     ((p)->action = ACTION_ACCEPT)); \
1079} while (0)
1080
1081#define DROP_PACKET(p) do { \
1082    ((p)->root ? \
1083     ((p)->root->action = ACTION_DROP) : \
1084     ((p)->action = ACTION_DROP)); \
1085} while (0)
1086
1087#define REJECT_PACKET(p) do { \
1088    ((p)->root ? \
1089     ((p)->root->action = (ACTION_REJECT|ACTION_DROP)) : \
1090     ((p)->action = (ACTION_REJECT|ACTION_DROP))); \
1091} while (0)
1092
1093#define REJECT_PACKET_DST(p) do { \
1094    ((p)->root ? \
1095     ((p)->root->action = (ACTION_REJECT_DST|ACTION_DROP)) : \
1096     ((p)->action = (ACTION_REJECT_DST|ACTION_DROP))); \
1097} while (0)
1098
1099#define REJECT_PACKET_BOTH(p) do { \
1100    ((p)->root ? \
1101     ((p)->root->action = (ACTION_REJECT_BOTH|ACTION_DROP)) : \
1102     ((p)->action = (ACTION_REJECT_BOTH|ACTION_DROP))); \
1103} while (0)
1104
1105#define PASS_PACKET(p) do { \
1106    ((p)->root ? \
1107     ((p)->root->action = ACTION_PASS) : \
1108     ((p)->action = ACTION_PASS)); \
1109} while (0)
1110
1111#define TUNNEL_INCR_PKT_RTV(p) do {                                                 \
1112        SCMutexLock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex);     \
1113        ((p)->root ? (p)->root->tunnel_rtv_cnt++ : (p)->tunnel_rtv_cnt++);          \
1114        SCMutexUnlock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex);   \
1115    } while (0)
1116
1117#define TUNNEL_INCR_PKT_TPR(p) do {                                                 \
1118        SCMutexLock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex);     \
1119        ((p)->root ? (p)->root->tunnel_tpr_cnt++ : (p)->tunnel_tpr_cnt++);          \
1120        SCMutexUnlock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex);   \
1121    } while (0)
1122
1123#define TUNNEL_DECR_PKT_TPR(p) do {                                                 \
1124        SCMutexLock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex);     \
1125        ((p)->root ? (p)->root->tunnel_tpr_cnt-- : (p)->tunnel_tpr_cnt--);          \
1126        SCMutexUnlock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex);   \
1127    } while (0)
1128
1129#define TUNNEL_DECR_PKT_TPR_NOLOCK(p) do {                                          \
1130        ((p)->root ? (p)->root->tunnel_tpr_cnt-- : (p)->tunnel_tpr_cnt--);          \
1131    } while (0)
1132
1133#define TUNNEL_PKT_RTV(p) ((p)->root ? (p)->root->tunnel_rtv_cnt : (p)->tunnel_rtv_cnt)
1134#define TUNNEL_PKT_TPR(p) ((p)->root ? (p)->root->tunnel_tpr_cnt : (p)->tunnel_tpr_cnt)
1135
1136#define IS_TUNNEL_PKT(p)            (((p)->flags & PKT_TUNNEL))
1137#define SET_TUNNEL_PKT(p)           ((p)->flags |= PKT_TUNNEL)
1138#define IS_TUNNEL_ROOT_PKT(p)       (IS_TUNNEL_PKT(p) && (p)->root == NULL)
1139
1140#define IS_TUNNEL_PKT_VERDICTED(p)  (((p)->flags & PKT_TUNNEL_VERDICTED))
1141#define SET_TUNNEL_PKT_VERDICTED(p) ((p)->flags |= PKT_TUNNEL_VERDICTED)
1142
1143
1144void DecodeRegisterPerfCounters(DecodeThreadVars *, ThreadVars *);
1145Packet *PacketPseudoPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto);
1146Packet *PacketDefragPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto);
1147#ifdef __tile__
1148Packet *PacketGetFromQueueOrAlloc(int pool);
1149#else
1150Packet *PacketGetFromQueueOrAlloc(void);
1151#endif
1152Packet *PacketGetFromAlloc(void);
1153int PacketCopyData(Packet *p, uint8_t *pktdata, int pktlen);
1154int PacketSetData(Packet *p, uint8_t *pktdata, int pktlen);
1155int PacketCopyDataOffset(Packet *p, int offset, uint8_t *data, int datalen);
1156
1157DecodeThreadVars *DecodeThreadVarsAlloc(ThreadVars *tv);
1158
1159/* decoder functions */
1160void DecodeEthernet(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1161void DecodeSll(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1162void DecodePPP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1163void DecodePPPOESession(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1164void DecodePPPOEDiscovery(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1165void DecodeTunnel(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *, uint8_t);
1166void DecodeRaw(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1167void DecodeIPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1168void DecodeIPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1169void DecodeICMPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1170void DecodeICMPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1171void DecodeTCP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1172void DecodeUDP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1173void DecodeSCTP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1174void DecodeGRE(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1175void DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
1176
1177void AddressDebugPrint(Address *);
1178
1179/** \brief Set the No payload inspection Flag for the packet.
1180 *
1181 * \param p Packet to set the flag in
1182 */
1183#define DecodeSetNoPayloadInspectionFlag(p) do { \
1184        (p)->flags |= PKT_NOPAYLOAD_INSPECTION;  \
1185    } while (0)
1186
1187/** \brief Set the No packet inspection Flag for the packet.
1188 *
1189 * \param p Packet to set the flag in
1190 */
1191#define DecodeSetNoPacketInspectionFlag(p) do { \
1192        (p)->flags |= PKT_NOPACKET_INSPECTION;  \
1193    } while (0)
1194
1195
1196#define ENGINE_SET_EVENT(p, e) do { \
1197    SCLogDebug("p %p event %d", (p), e); \
1198    if ((p)->events.cnt < PACKET_ENGINE_EVENT_MAX) { \
1199        (p)->events.events[(p)->events.cnt] = e; \
1200        (p)->events.cnt++; \
1201    } \
1202} while(0)
1203
1204#define ENGINE_ISSET_EVENT(p, e) ({ \
1205    int r = 0; \
1206    uint8_t u; \
1207    for (u = 0; u < (p)->events.cnt; u++) { \
1208        if ((p)->events.events[u] == (e)) { \
1209            r = 1; \
1210            break; \
1211        } \
1212    } \
1213    r; \
1214})
1215
1216/* older libcs don't contain a def for IPPROTO_DCCP
1217 * inside of <netinet/in.h>
1218 * if it isn't defined let's define it here.
1219 */
1220#ifndef IPPROTO_DCCP
1221#define IPPROTO_DCCP 33
1222#endif
1223
1224/* older libcs don't contain a def for IPPROTO_SCTP
1225 * inside of <netinet/in.h>
1226 * if it isn't defined let's define it here.
1227 */
1228#ifndef IPPROTO_SCTP
1229#define IPPROTO_SCTP 132
1230#endif
1231
1232/* pcap provides this, but we don't want to depend on libpcap */
1233#ifndef DLT_EN10MB
1234#define DLT_EN10MB 1
1235#endif
1236
1237/* taken from pcap's bpf.h */
1238#ifndef DLT_RAW
1239#ifdef __OpenBSD__
1240#define DLT_RAW     14  /* raw IP */
1241#else
1242#define DLT_RAW     12  /* raw IP */
1243#endif
1244#endif
1245
1246/** libpcap shows us the way to linktype codes
1247 * \todo we need more & maybe put them in a separate file? */
1248#define LINKTYPE_ETHERNET   DLT_EN10MB
1249#define LINKTYPE_LINUX_SLL  113
1250#define LINKTYPE_PPP        9
1251#define LINKTYPE_RAW        DLT_RAW
1252#define PPP_OVER_GRE        11
1253#define VLAN_OVER_GRE       13
1254
1255/*Packet Flags*/
1256#define PKT_NOPACKET_INSPECTION         (1)         /**< Flag to indicate that packet header or contents should not be inspected*/
1257#define PKT_NOPAYLOAD_INSPECTION        (1<<2)      /**< Flag to indicate that packet contents should not be inspected*/
1258#define PKT_ALLOC                       (1<<3)      /**< Packet was alloc'd this run, needs to be freed */
1259#define PKT_HAS_TAG                     (1<<4)      /**< Packet has matched a tag */
1260#define PKT_STREAM_ADD                  (1<<5)      /**< Packet payload was added to reassembled stream */
1261#define PKT_STREAM_EST                  (1<<6)      /**< Packet is part of establised stream */
1262#define PKT_STREAM_EOF                  (1<<7)      /**< Stream is in eof state */
1263#define PKT_HAS_FLOW                    (1<<8)
1264#define PKT_PSEUDO_STREAM_END           (1<<9)      /**< Pseudo packet to end the stream */
1265#define PKT_STREAM_MODIFIED             (1<<10)     /**< Packet is modified by the stream engine, we need to recalc the csum and reinject/replace */
1266#define PKT_MARK_MODIFIED               (1<<11)     /**< Packet mark is modified */
1267#define PKT_STREAM_NOPCAPLOG            (1<<12)     /**< Exclude packet from pcap logging as it's part of a stream that has reassembly depth reached. */
1268
1269#define PKT_TUNNEL                      (1<<13)
1270#define PKT_TUNNEL_VERDICTED            (1<<14)
1271
1272#define PKT_IGNORE_CHECKSUM             (1<<15)     /**< Packet checksum is not computed (TX packet for example) */
1273#define PKT_ZERO_COPY                   (1<<16)     /**< Packet comes from zero copy (ext_pkt must not be freed) */
1274#define PKT_NETIO                       (1<<17)     /**< Packet payload from netio */
1275#define PKT_MPIPE                       (1<<18)     /**< Packet payload from mpipe */
1276
1277#define PKT_HOST_SRC_LOOKED_UP          (1<<19)
1278#define PKT_HOST_DST_LOOKED_UP          (1<<20)
1279
1280/** \brief return 1 if the packet is a pseudo packet */
1281#define PKT_IS_PSEUDOPKT(p) ((p)->flags & PKT_PSEUDO_STREAM_END)
1282
1283#define PKT_SET_SRC(p, src_val) ((p)->pkt_src = src_val)
1284
1285#endif /* __DECODE_H__ */
1286