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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
/* 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 Victor Julien <victor@inliniac.net>
*
* Flow utility functions
*/
#include "suricata-common.h"
#include "threads.h"
#include "flow.h"
#include "flow-private.h"
#include "flow-util.h"
#include "flow-var.h"
#include "app-layer.h"
#include "util-var.h"
#include "util-debug.h"
#include "flow-storage.h"
#include "detect.h"
#include "detect-engine-state.h"
/** \brief allocate a flow
*
* We check against the memuse counter. If it passes that check we increment
* the counter first, then we try to alloc.
*
* \retval f the flow or NULL on out of memory
*/
Flow *FlowAlloc(void)
{
Flow *f;
size_t size = sizeof(Flow) + FlowStorageSize();
if (!(FLOW_CHECK_MEMCAP(size))) {
return NULL;
}
(void) SC_ATOMIC_ADD(flow_memuse, size);
f = SCMalloc(size);
if (unlikely(f == NULL)) {
(void)SC_ATOMIC_SUB(flow_memuse, size);
return NULL;
}
memset(f, 0, size);
/* coverity[missing_lock] */
FLOW_INITIALIZE(f);
return f;
}
/**
* \brief cleanup & free the memory of a flow
*
* \param f flow to clear & destroy
*/
void FlowFree(Flow *f)
{
FLOW_DESTROY(f);
SCFree(f);
size_t size = sizeof(Flow) + FlowStorageSize();
(void) SC_ATOMIC_SUB(flow_memuse, size);
}
/**
* \brief Function to map the protocol to the defined FLOW_PROTO_* enumeration.
*
* \param proto protocol which is needed to be mapped
*/
uint8_t FlowGetProtoMapping(uint8_t proto)
{
switch (proto) {
case IPPROTO_TCP:
return FLOW_PROTO_TCP;
case IPPROTO_UDP:
return FLOW_PROTO_UDP;
case IPPROTO_ICMP:
return FLOW_PROTO_ICMP;
case IPPROTO_SCTP:
return FLOW_PROTO_SCTP;
default:
return FLOW_PROTO_DEFAULT;
}
}
uint8_t FlowGetReverseProtoMapping(uint8_t rproto)
{
switch (rproto) {
case FLOW_PROTO_TCP:
return IPPROTO_TCP;
case FLOW_PROTO_UDP:
return IPPROTO_UDP;
case FLOW_PROTO_ICMP:
return IPPROTO_ICMP;
case FLOW_PROTO_SCTP:
return IPPROTO_SCTP;
default:
exit(EXIT_FAILURE);
}
}
/* initialize the flow from the first packet
* we see from it. */
void FlowInit(Flow *f, const Packet *p)
{
SCEnter();
SCLogDebug("flow %p", f);
f->proto = p->proto;
f->recursion_level = p->recursion_level;
f->vlan_id[0] = p->vlan_id[0];
f->vlan_id[1] = p->vlan_id[1];
if (PKT_IS_IPV4(p)) {
FLOW_SET_IPV4_SRC_ADDR_FROM_PACKET(p, &f->src);
FLOW_SET_IPV4_DST_ADDR_FROM_PACKET(p, &f->dst);
f->flags |= FLOW_IPV4;
} else if (PKT_IS_IPV6(p)) {
FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET(p, &f->src);
FLOW_SET_IPV6_DST_ADDR_FROM_PACKET(p, &f->dst);
f->flags |= FLOW_IPV6;
}
#ifdef DEBUG
/* XXX handle default */
else {
printf("FIXME: %s:%s:%" PRId32 "\n", __FILE__, __FUNCTION__, __LINE__);
}
#endif
if (p->tcph != NULL) { /* XXX MACRO */
SET_TCP_SRC_PORT(p,&f->sp);
SET_TCP_DST_PORT(p,&f->dp);
} else if (p->udph != NULL) { /* XXX MACRO */
SET_UDP_SRC_PORT(p,&f->sp);
SET_UDP_DST_PORT(p,&f->dp);
} else if (p->icmpv4h != NULL) {
f->type = p->type;
f->code = p->code;
} else if (p->icmpv6h != NULL) {
f->type = p->type;
f->code = p->code;
} else if (p->sctph != NULL) { /* XXX MACRO */
SET_SCTP_SRC_PORT(p,&f->sp);
SET_SCTP_DST_PORT(p,&f->dp);
} /* XXX handle default */
#ifdef DEBUG
else {
printf("FIXME: %s:%s:%" PRId32 "\n", __FILE__, __FUNCTION__, __LINE__);
}
#endif
COPY_TIMESTAMP(&p->ts, &f->startts);
f->protomap = FlowGetProtoMapping(f->proto);
SCReturn;
}
|