[Oisf-devel] [PATCH 1/2] Modify Packet structure and prepare accessor.
Eric Leblond
eleblond at edenwall.com
Mon Nov 15 23:35:45 UTC 2010
This patch modifies decode.c and decode.h to avoid the usage
by default of a bigger than 65535 bytes array in Packet structure.
The idea is that the packet are mainly under 1500 bytes size and
a bigger size must be supported but should not be the default.
If the packet length is bigger than DFLT_PAYLOAD_SIZE then the
data are stored in a dynamically allocated part of the memory.
To ease the modification of the rest of the code, functions to
access and set the payload/length in a Packet have been introduced.
Signed-off-by: Eric Leblond <eleblond at edenwall.com>
---
src/decode.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++-
src/decode.h | 19 ++++++++++-
src/tmqh-packetpool.c | 11 ++++++
3 files changed, 112 insertions(+), 4 deletions(-)
diff --git a/src/decode.c b/src/decode.c
index d9e02a2..bb7a125 100644
--- a/src/decode.c
+++ b/src/decode.c
@@ -27,6 +27,7 @@
#include "suricata.h"
#include "decode.h"
#include "util-debug.h"
+#include "util-mem.h"
#include "app-layer-detect-proto.h"
#include "tm-modules.h"
#include "util-error.h"
@@ -107,8 +108,8 @@ Packet *PacketPseudoPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t
/* copy packet and set lenght, proto */
p->tunnel_proto = proto;
- p->pktlen = len;
- memcpy(&p->pkt, pkt, len);
+ SET_PKT_LEN(p, len);
+ CopyDataToPacket(p, pkt, len);
p->recursion_level = parent->recursion_level + 1;
p->ts.tv_sec = parent->ts.tv_sec;
p->ts.tv_usec = parent->ts.tv_usec;
@@ -243,3 +244,84 @@ DecodeThreadVars *DecodeThreadVarsAlloc() {
return dtv;
}
+
+inline int CopyDataToPacket(Packet *p, uint8_t *pktdata, int pktlen)
+{
+ if (pktlen > MAX_PAYLOAD_SIZE) {
+ /* too big */
+ return -1;
+ }
+ if (! p->ext_pkt) {
+ if (pktlen < DFLT_PAYLOAD_SIZE) {
+ memcpy(&p->pkt, pktdata, pktlen);
+ SET_PKT_LEN(p, (size_t)pktlen);
+ } else {
+ /* here we need a dynamic allocation */
+ p->ext_pkt = SCMalloc(MAX_PAYLOAD_SIZE);
+ memcpy(p->ext_pkt, pktdata, pktlen);
+ SET_PKT_LEN(p, (size_t)pktlen);
+ }
+ } else {
+ memcpy(p->ext_pkt, pktdata, pktlen);
+ SET_PKT_LEN(p, (size_t)pktlen);
+ }
+ return 0;
+}
+
+inline int CopyDataToPacketOffset(Packet *p, int offset, uint8_t *data, int datalen)
+{
+ if (offset + datalen > MAX_PAYLOAD_SIZE) {
+ /* too big */
+ return -1;
+ }
+
+ if (! p->ext_pkt) {
+ if (offset + datalen < DFLT_PAYLOAD_SIZE) {
+ memcpy(&p->pkt + offset, data, datalen);
+ } else {
+ /* here we need a dynamic allocation. This case should rarely
+ * occur as there is a high probability the first frag has
+ * reveal the packet size*/
+ p->ext_pkt = SCMalloc(MAX_PAYLOAD_SIZE);
+ /* copy initial data */
+ memcpy(p->ext_pkt, &p->pkt, p->pktlen);
+ /* copy data as asked */
+ memcpy(p->ext_pkt + offset, data, datalen);
+ /* modify part of the struct ipv4 that were pointing to pkt array
+ * using the fact that offset is the same*/
+ if (p->ethh) {
+ p->ethh = (EthernetHdr *)((uint8_t *)p->ext_pkt + ((uint8_t *)p->ethh - p->pkt));
+ }
+ if (p->ip4h) {
+ p->ip4h = (IPV4Hdr *)((uint8_t *)p->ext_pkt + ((uint8_t *)p->ip4h - p->pkt));
+ }
+ if (p->ip6h) {
+ p->ip6h = (IPV6Hdr *)((uint8_t *)p->ext_pkt + ((uint8_t *)p->ip6h - p->pkt));
+ }
+ if (p->tcph) {
+ p->tcph = (TCPHdr *)((uint8_t *)p->ext_pkt + ((uint8_t *)p->tcph - p->pkt));
+ }
+ if (p->udph) {
+ p->udph = (UDPHdr *)((uint8_t *)p->ext_pkt + ((uint8_t *)p->udph - p->pkt));
+ }
+ if (p->icmpv4h) {
+ p->icmpv4h = (ICMPV4Hdr *)((uint8_t *)p->ext_pkt + ((uint8_t *)p->icmpv4h - p->pkt));
+ }
+ if (p->icmpv6h) {
+ p->icmpv6h = (ICMPV6Hdr *)((uint8_t *)p->ext_pkt + ((uint8_t *)p->icmpv6h - p->pkt));
+ }
+ if (p->ppph) {
+ p->ppph = (PPPHdr *)((uint8_t *)p->ext_pkt + ((uint8_t *)p->ppph - p->pkt));
+ }
+ if (p->greh) {
+ p->greh = (GREHdr *)((uint8_t *)p->ext_pkt + ((uint8_t *)p->greh - p->pkt));
+ }
+ if (p->vlanh) {
+ p->vlanh = (VLANHdr *)((uint8_t *)p->ext_pkt + ((uint8_t *)p->vlanh - p->pkt));
+ }
+ }
+ } else {
+ memcpy(p->ext_pkt + offset, data, datalen);
+ }
+ return 0;
+}
diff --git a/src/decode.h b/src/decode.h
index b911ed5..66fb319 100644
--- a/src/decode.h
+++ b/src/decode.h
@@ -57,6 +57,10 @@
#include "detect-reference.h"
+#define DFLT_PAYLOAD_SIZE 1500
+/* storage: maximum ip packet size + link header */
+#define MAX_PAYLOAD_SIZE IPV6_HEADER_LEN + 65536 + 28
+
#ifdef __SC_CUDA_SUPPORT__
#define CUDA_MAX_PAYLOAD_SIZE 1500
#endif
@@ -163,6 +167,14 @@ typedef struct Address_ {
#define GET_TCP_SRC_PORT(p) ((p)->sp)
#define GET_TCP_DST_PORT(p) ((p)->dp)
+#define GET_PKT_LEN(p) ((p)->pktlen)
+#define GET_PKT_DATA(p) ((((p)->ext_pkt) == NULL ) ? (p)->pkt : (p)->ext_pkt)
+
+#define SET_PKT_LEN(p, len) do { \
+ (p)->pktlen = len; \
+ } while (0)
+
+
/* Port is just a uint16_t */
typedef uint16_t Port;
#define SET_PORT(v, p) ((p) = (v))
@@ -347,8 +359,9 @@ typedef struct Packet_
uint8_t *payload;
uint16_t payload_len;
- /* storage: maximum ip packet size + link header */
- uint8_t pkt[IPV6_HEADER_LEN + 65536 + 28];
+ /* storage: set to DFLT_PAYLOAD_SIZE and extended via allocation if necessary */
+ uint8_t pkt[DFLT_PAYLOAD_SIZE];
+ uint8_t *ext_pkt;
uint32_t pktlen;
PacketAlerts alerts;
@@ -634,6 +647,8 @@ typedef struct DecodeThreadVars_
void DecodeRegisterPerfCounters(DecodeThreadVars *, ThreadVars *);
Packet *PacketPseudoPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto);
Packet *PacketGetFromQueueOrAlloc(void);
+int CopyDataToPacket(Packet *p, uint8_t *pktdata, int pktlen);
+int CopyDataToPacketOffset(Packet *p, int offset, uint8_t *data, int datalen);
DecodeThreadVars *DecodeThreadVarsAlloc();
diff --git a/src/tmqh-packetpool.c b/src/tmqh-packetpool.c
index 1cc028b..adc9310 100644
--- a/src/tmqh-packetpool.c
+++ b/src/tmqh-packetpool.c
@@ -186,6 +186,11 @@ void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
/* we're done with the tunnel root now as well */
if (proot == 1) {
SCLogDebug("getting rid of root pkt... alloc'd %s", p->root->flags & PKT_ALLOC ? "true" : "false");
+ /* if p->root uses extended data, free them */
+ if (p->root->ext_pkt) {
+ SCFree(p->root->ext_pkt);
+ p->root->ext_pkt = NULL;
+ }
if (p->root->flags & PKT_ALLOC) {
PACKET_CLEANUP(p->root);
SCFree(p->root);
@@ -196,6 +201,12 @@ void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
}
}
+ /* if p uses extended data, free them */
+ if (p->ext_pkt) {
+ SCFree(p->ext_pkt);
+ p->ext_pkt = NULL;
+ }
+
SCLogDebug("getting rid of tunnel pkt... alloc'd %s (root %p)", p->flags & PKT_ALLOC ? "true" : "false", p->root);
if (p->flags & PKT_ALLOC) {
PACKET_CLEANUP(p);
--
1.7.1
More information about the Oisf-devel
mailing list