aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/suricata/src/defrag.h
blob: 8bd0325a341f40d2a1f791da8e713f5db5707d03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* Copyright (C) 2007-2013 Open Information Security Foundation
 *
 * You can copy, redistribute or modify this Program under the terms of
 * the GNU General Public License version 2 as published by the Free
 * Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

/**
 * \file
 *
 * \author Endace Technology Limited, Jason Ish <jason.ish@endace.com>
 */

#ifndef __DEFRAG_H__
#define __DEFRAG_H__

#include "util-pool.h"

/**
 * A context for an instance of a fragmentation re-assembler, in case
 * we ever need more than one.
 */
typedef struct DefragContext_ {
    Pool *frag_pool; /**< Pool of fragments. */
    SCMutex frag_pool_lock;

    time_t timeout; /**< Default timeout. */
} DefragContext;

/**
 * Storage for an individual fragment.
 */
typedef struct Frag_ {
    uint16_t offset;            /**< The offset of this fragment, already
                                 *   multiplied by 8. */

    uint16_t len;               /**< The length of this fragment. */

    uint8_t hlen;               /**< The length of this fragments IP header. */

    uint8_t more_frags:4;       /**< More frags? */
    uint8_t skip:4;             /**< Skip this fragment during re-assembly. */

    uint16_t ip_hdr_offset;     /**< Offset in the packet where the IP
                                 * header starts. */
    uint16_t frag_hdr_offset;   /**< Offset in the packet where the frag
                                 * header starts. */

    uint16_t data_offset;       /**< Offset to the packet data. */
    uint16_t data_len;          /**< Length of data. */

    uint16_t ltrim;             /**< Number of leading bytes to trim when
                                 * re-assembling the packet. */

    uint8_t *pkt;               /**< The actual packet. */

#ifdef DEBUG
    uint64_t pcap_cnt;          /**< pcap_cnt of original packet */
#endif

    TAILQ_ENTRY(Frag_) next;    /**< Pointer to next fragment for tailq. */
} Frag;

/** \brief Reset tracker fields except "lock" */
#define DEFRAG_TRACKER_RESET(t) { \
    (t)->timeout = 0; \
    (t)->id = 0; \
    (t)->policy = 0; \
    (t)->af = 0; \
    (t)->seen_last = 0; \
    (t)->remove = 0; \
    CLEAR_ADDR(&(t)->src_addr); \
    CLEAR_ADDR(&(t)->dst_addr); \
    (t)->frags.tqh_first = NULL; \
    (t)->frags.tqh_last = NULL; \
}

/**
 * A defragmentation tracker.  Used to track fragments that make up a
 * single packet.
 */
typedef struct DefragTracker_ {
    SCMutex lock; /**< Mutex for locking list operations on
                           * this tracker. */

    uint16_t vlan_id[2]; /**< VLAN ID tracker applies to. */

    uint32_t id; /**< IP ID for this tracker.  32 bits for IPv6, 16
                  * for IPv4. */

    uint8_t policy; /**< Reassembly policy this tracker will use. */

    uint8_t af; /**< Address family for this tracker, AF_INET or
                 * AF_INET6. */

    uint8_t seen_last; /**< Has this tracker seen the last fragment? */

    uint8_t remove; /**< remove */

    Address src_addr; /**< Source address for this tracker. */
    Address dst_addr; /**< Destination address for this tracker. */

    struct timeval timeout; /**< When this tracker will timeout. */
    uint32_t host_timeout;  /**< Host timeout, statically assigned from the yaml */

    /** use cnt, reference counter */
    SC_ATOMIC_DECLARE(unsigned int, use_cnt);

    TAILQ_HEAD(frag_tailq, Frag_) frags; /**< Head of list of fragments. */

    /** hash pointers, protected by hash row mutex/spin */
    struct DefragTracker_ *hnext;
    struct DefragTracker_ *hprev;

    /** list pointers, protected by tracker-queue mutex/spin */
    struct DefragTracker_ *lnext;
    struct DefragTracker_ *lprev;
} DefragTracker;

void DefragInit(void);
void DefragDestroy(void);
void DefragReload(void); /**< use only in unittests */

uint8_t DefragGetOsPolicy(Packet *);
void DefragTrackerFreeFrags(DefragTracker *);
Packet *Defrag(ThreadVars *, DecodeThreadVars *, Packet *, PacketQueue *);
void DefragRegisterTests(void);

#endif /* __DEFRAG_H__ */