summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Kochan <vadim4j@gmail.com>2016-08-13 02:11:21 +0300
committerTobias Klauser <tklauser@distanz.ch>2016-09-21 09:58:49 +0200
commit958149795f680f77f73ca44f78279f55265728c0 (patch)
treee2fd819fae5d9bde7844dc8f1b04acaa9f090319
parent68e2a5ab4122bb826c99dfb784fa38c1c661411a (diff)
trafgen: parser: Add support of 'dinc' function for proto fields
Add 'dinc()' function in 'field_expr' rules to be used for dynamically incrementing of any specified field: SYNTAX := dinc() | dinc(step) | dinc(min, max) | dinc(min, max, step) EXAMPLES: { udp(sport=dinc() } { udp(sport=dinc(1) } { udp(sport=dinc(100, 125, 5) } Signed-off-by: Vadim Kochan <vadim4j@gmail.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r--trafgen_parser.y53
1 files changed, 53 insertions, 0 deletions
diff --git a/trafgen_parser.y b/trafgen_parser.y
index 1e7bd5c..9b313d1 100644
--- a/trafgen_parser.y
+++ b/trafgen_parser.y
@@ -75,6 +75,7 @@ enum field_expr_type_t {
FIELD_EXPR_MAC,
FIELD_EXPR_IP4_ADDR,
FIELD_EXPR_IP6_ADDR,
+ FIELD_EXPR_INC,
};
struct proto_field_expr {
@@ -86,6 +87,7 @@ struct proto_field_expr {
struct in6_addr ip6_addr;
long long int number;
uint8_t bytes[256];
+ struct proto_field_func func;
} val;
};
@@ -126,6 +128,12 @@ static inline void __init_new_csum_slot(struct packet_dyn *slot)
slot->slen = 0;
}
+static inline void __init_new_fields_slot(struct packet_dyn *slot)
+{
+ slot->fields = NULL;
+ slot->flen = 0;
+}
+
static inline void __setup_new_counter(struct counter *c, uint8_t start,
uint8_t stop, uint8_t stepping,
int type)
@@ -168,6 +176,7 @@ static void realloc_packet(void)
__init_new_counter_slot(&packet_dyn[packetd_last]);
__init_new_randomizer_slot(&packet_dyn[packetd_last]);
__init_new_csum_slot(&packet_dyn[packetd_last]);
+ __init_new_fields_slot(&packet_dyn[packetd_last]);
}
struct packet *current_packet(void)
@@ -377,6 +386,19 @@ static void proto_field_set(uint32_t fid)
field_expr.field = proto_field_by_id(hdr, fid);
}
+static void proto_field_func_setup(struct proto_field *field, struct proto_field_func *func)
+{
+ struct packet_dyn *pkt_dyn;
+
+ proto_field_func_add(field->hdr, field->id, func);
+
+ pkt_dyn = &packet_dyn[packetd_last];
+ pkt_dyn->flen++;
+ pkt_dyn->fields = xrealloc(pkt_dyn->fields, pkt_dyn->flen *
+ sizeof(struct proto_field *));
+ pkt_dyn->fields[pkt_dyn->flen - 1] = field;
+}
+
static void proto_field_expr_eval(void)
{
struct proto_field *field = field_expr.field;
@@ -406,6 +428,15 @@ static void proto_field_expr_eval(void)
(uint8_t *)&field_expr.val.ip6_addr.s6_addr);
break;
+ case FIELD_EXPR_INC:
+ if (field_expr.val.func.min
+ && field_expr.val.func.min >= field_expr.val.func.max)
+ panic("dinc(): min(%u) can't be >= max(%u)\n",
+ field_expr.val.func.min, field_expr.val.func.max);
+
+ proto_field_func_setup(field, &field_expr.val.func);
+ break;
+
case FIELD_EXPR_UNKNOWN:
default:
bug();
@@ -686,6 +717,27 @@ field_expr
field_expr.val.ip4_addr = $1; }
| ip6_addr { field_expr.type = FIELD_EXPR_IP6_ADDR;
field_expr.val.ip6_addr = $1; }
+ | K_DINC '(' ')' { field_expr.type = FIELD_EXPR_INC;
+ field_expr.val.func.type = PROTO_FIELD_FUNC_INC;
+ field_expr.val.func.inc = 1; }
+ | K_DINC '(' number ')'
+ { field_expr.type = FIELD_EXPR_INC;
+ field_expr.val.func.type = PROTO_FIELD_FUNC_INC;
+ field_expr.val.func.inc = $3; }
+ | K_DINC '(' number delimiter number ')'
+ { field_expr.type = FIELD_EXPR_INC;
+ field_expr.val.func.type = PROTO_FIELD_FUNC_INC;
+ field_expr.val.func.type |= PROTO_FIELD_FUNC_MIN;
+ field_expr.val.func.min = $3;
+ field_expr.val.func.max = $5;
+ field_expr.val.func.inc = 1; }
+ | K_DINC '(' number delimiter number delimiter number ')'
+ { field_expr.type = FIELD_EXPR_INC;
+ field_expr.val.func.type = PROTO_FIELD_FUNC_INC;
+ field_expr.val.func.type |= PROTO_FIELD_FUNC_MIN;
+ field_expr.val.func.min = $3;
+ field_expr.val.func.max = $5;
+ field_expr.val.func.inc = $7; }
;
eth_proto
@@ -1096,6 +1148,7 @@ void cleanup_packets(void)
for (i = 0; i < dlen; ++i) {
free(packet_dyn[i].cnt);
free(packet_dyn[i].rnd);
+ free(packet_dyn[i].fields);
}
free(packet_dyn);