Till now headers were used only for packet creation at compile time
only, which does not allow to handle dynamic fields update at runtime.
It needs that proto_hdr entries will be not freed after compile is done.

Signed-off-by: Vadim Kochan <vadi...@gmail.com>
---
 trafgen_conf.h   |  6 ++++++
 trafgen_parser.y | 17 ++++++++++++++---
 trafgen_proto.c  | 40 +++++++++++++++++++---------------------
 trafgen_proto.h  |  2 ++
 4 files changed, 41 insertions(+), 24 deletions(-)

diff --git a/trafgen_conf.h b/trafgen_conf.h
index efce29c..934f8fe 100644
--- a/trafgen_conf.h
+++ b/trafgen_conf.h
@@ -5,6 +5,10 @@
 #include <stdio.h>
 #include <sys/types.h>
 
+#include "trafgen_proto.h"
+
+#define PROTO_MAX_LAYERS       16
+
 #define TYPE_INC       0
 #define TYPE_DEC       1
 
@@ -34,6 +38,8 @@ struct csum16 {
 struct packet {
        uint8_t *payload;
        size_t len;
+       struct proto_hdr *headers[PROTO_MAX_LAYERS];
+       size_t headers_count;
 };
 
 struct packet_dyn {
diff --git a/trafgen_parser.y b/trafgen_parser.y
index a286e6b..091dee9 100644
--- a/trafgen_parser.y
+++ b/trafgen_parser.y
@@ -1004,11 +1004,22 @@ static void dump_conf(void)
 
 void cleanup_packets(void)
 {
-       size_t i;
+       size_t i, j;
 
        for (i = 0; i < plen; ++i) {
-               if (packets[i].len > 0)
-                       xfree(packets[i].payload);
+               struct packet *pkt = &packets[i];
+
+               if (pkt->len > 0)
+                       xfree(pkt->payload);
+
+               for (j = 0; j < pkt->headers_count; j++) {
+                       struct proto_hdr *hdr = pkt->headers[j];
+
+                       if (hdr->fields)
+                               xfree(hdr->fields);
+
+                       xfree(hdr);
+               }
        }
 
        free(packets);
diff --git a/trafgen_proto.c b/trafgen_proto.c
index e5b1ad3..a1d56cf 100644
--- a/trafgen_proto.c
+++ b/trafgen_proto.c
@@ -24,15 +24,23 @@
 
 static struct proto_ctx ctx;
 
-#define PROTO_MAX_LAYERS       16
+static struct proto_hdr *registered;
 
-static struct proto_hdr *headers[PROTO_MAX_LAYERS];
-static size_t headers_count;
+static inline struct proto_hdr *proto_current_header(void)
+{
+       struct proto_hdr **headers = &current_packet()->headers[0];
+       size_t headers_count = current_packet()->headers_count;
 
-static struct proto_hdr *registered;
+       if (headers_count > 0)
+               return headers[headers_count - 1];
+
+       bug();
+}
 
 struct proto_hdr *proto_lower_header(struct proto_hdr *hdr)
 {
+       struct proto_hdr **headers = &current_packet()->headers[0];
+       size_t headers_count = current_packet()->headers_count;
        struct proto_hdr *lower = NULL;
        size_t i;
 
@@ -128,10 +136,11 @@ bool proto_field_is_set(struct proto_hdr *hdr, uint32_t 
fid)
 
 struct proto_hdr *proto_header_init(enum proto_id pid)
 {
+       struct proto_hdr **headers = &current_packet()->headers[0];
        struct proto_hdr *hdr = proto_header_by_id(pid);
        struct proto_hdr *new_hdr;
 
-       bug_on(headers_count >= PROTO_MAX_LAYERS);
+       bug_on(current_packet()->headers_count >= PROTO_MAX_LAYERS);
 
        new_hdr = xmalloc(sizeof(*new_hdr));
        memcpy(new_hdr, hdr, sizeof(*new_hdr));
@@ -141,7 +150,7 @@ struct proto_hdr *proto_header_init(enum proto_id pid)
        if (new_hdr->header_init)
                new_hdr->header_init(new_hdr);
 
-       headers[headers_count++] = new_hdr;
+       headers[current_packet()->headers_count++] = new_hdr;
        return new_hdr;
 }
 
@@ -156,8 +165,8 @@ struct proto_hdr *proto_lower_default_add(struct proto_hdr 
*hdr,
 {
        struct proto_hdr *current;
 
-       if (headers_count > 0) {
-               current = headers[headers_count - 1];
+       if (current_packet()->headers_count > 0) {
+               current = proto_current_header();
 
                if (current->layer >= proto_header_by_id(pid)->layer)
                        goto set_proto;
@@ -418,6 +427,8 @@ void protos_init(const char *dev)
 
 void proto_packet_finish(void)
 {
+       struct proto_hdr **headers = &current_packet()->headers[0];
+       size_t headers_count = current_packet()->headers_count;
        ssize_t i;
 
        /* Go down from upper layers to do last calculations (checksum) */
@@ -427,17 +438,4 @@ void proto_packet_finish(void)
                if (p->packet_finish)
                        p->packet_finish(p);
        }
-
-       for (i = 0; i < headers_count; i++) {
-               struct proto_hdr *p = headers[i];
-
-               if (p->fields) {
-                       xfree(p->fields);
-                       p->fields_count = 0;
-               }
-
-               xfree(headers[i]);
-       }
-
-       headers_count = 0;
 }
diff --git a/trafgen_proto.h b/trafgen_proto.h
index d2fde62..41e5b76 100644
--- a/trafgen_proto.h
+++ b/trafgen_proto.h
@@ -5,6 +5,8 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#include "trafgen_conf.h"
+
 struct proto_ctx {
        const char *dev;
 };
-- 
2.6.3

-- 
You received this message because you are subscribed to the Google Groups 
"netsniff-ng" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to netsniff-ng+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to