[netsniff-ng] [PATCH 3/7] trafgen: proto: Rename proto_field_xxx -> proto_hdr_field_xxx

2016-12-17 Thread Vadim Kochan
Rename all proto_field_xxx(...) functions to proto_hdr_field(...).

It is good for 2 reasons:
1) proto_hdr_field_xxx naming is more consistent as
   it is related to proto_hdr API.

2) It makes possible to introduce proto_field_xxx API
   which will operate only with struct proto_field.

Signed-off-by: Vadim Kochan 
---
 trafgen_l2.c |  44 -
 trafgen_l3.c |  24 +-
 trafgen_l4.c |  28 +--
 trafgen_parser.y |  64 -
 trafgen_proto.c  | 144 ---
 trafgen_proto.h  |  52 ++--
 6 files changed, 179 insertions(+), 177 deletions(-)

diff --git a/trafgen_l2.c b/trafgen_l2.c
index b27c9dd..5fc0a0d 100644
--- a/trafgen_l2.c
+++ b/trafgen_l2.c
@@ -40,14 +40,14 @@ static uint16_t pid_to_eth(enum proto_id pid)
 
 static void eth_set_next_proto(struct proto_hdr *hdr, enum proto_id pid)
 {
-   proto_field_set_default_be16(hdr, ETH_TYPE, pid_to_eth(pid));
+   proto_hdr_field_set_default_be16(hdr, ETH_TYPE, pid_to_eth(pid));
 }
 
 static void eth_header_init(struct proto_hdr *hdr)
 {
proto_header_fields_add(hdr, eth_fields, array_size(eth_fields));
 
-   proto_field_set_default_dev_mac(hdr, ETH_SRC_ADDR);
+   proto_hdr_field_set_default_dev_mac(hdr, ETH_SRC_ADDR);
 }
 
 static const struct proto_ops eth_proto_ops = {
@@ -69,10 +69,10 @@ static void pause_header_init(struct proto_hdr *hdr)
struct proto_hdr *lower;
 
lower = proto_lower_default_add(hdr, PROTO_ETH);
-   proto_field_set_default_bytes(lower, ETH_DST_ADDR, eth_dst);
+   proto_hdr_field_set_default_bytes(lower, ETH_DST_ADDR, eth_dst);
 
proto_header_fields_add(hdr, pause_fields, array_size(pause_fields));
-   proto_field_set_default_be16(hdr, PAUSE_OPCODE, 0x1);
+   proto_hdr_field_set_default_be16(hdr, PAUSE_OPCODE, 0x1);
 }
 
 static struct proto_ops pause_proto_ops = {
@@ -109,10 +109,10 @@ static void pfc_header_init(struct proto_hdr *hdr)
struct proto_hdr *lower;
 
lower = proto_lower_default_add(hdr, PROTO_ETH);
-   proto_field_set_default_bytes(lower, ETH_DST_ADDR, eth_dst);
+   proto_hdr_field_set_default_bytes(lower, ETH_DST_ADDR, eth_dst);
 
proto_header_fields_add(hdr, pfc_fields, array_size(pfc_fields));
-   proto_field_set_default_be16(hdr, PFC_OPCODE, 0x0101);
+   proto_hdr_field_set_default_be16(hdr, PFC_OPCODE, 0x0101);
 }
 
 static struct proto_ops pfc_proto_ops = {
@@ -140,18 +140,18 @@ static void vlan_header_init(struct proto_hdr *hdr)
proto_header_fields_add(hdr, vlan_fields, array_size(vlan_fields));
 
if (lower->ops->id == PROTO_ETH)
-   lower_etype = proto_field_get_u16(lower, ETH_TYPE);
+   lower_etype = proto_hdr_field_get_u16(lower, ETH_TYPE);
else if (lower->ops->id == PROTO_VLAN)
-   lower_etype = proto_field_get_u16(lower, VLAN_ETYPE);
+   lower_etype = proto_hdr_field_get_u16(lower, VLAN_ETYPE);
 
-   proto_field_set_be16(hdr, VLAN_ETYPE, lower_etype);
-   proto_field_set_default_be16(hdr, VLAN_TPID, pid_to_eth(hdr->ops->id));
+   proto_hdr_field_set_be16(hdr, VLAN_ETYPE, lower_etype);
+   proto_hdr_field_set_default_be16(hdr, VLAN_TPID, 
pid_to_eth(hdr->ops->id));
 }
 
 static void vlan_set_next_proto(struct proto_hdr *hdr, enum proto_id pid)
 {
if (pid != PROTO_VLAN)
-   proto_field_set_be16(hdr, VLAN_ETYPE, pid_to_eth(pid));
+   proto_hdr_field_set_be16(hdr, VLAN_ETYPE, pid_to_eth(pid));
 }
 
 static const struct proto_ops vlan_proto_ops = {
@@ -180,20 +180,20 @@ static void arp_header_init(struct proto_hdr *hdr)
if (lower->ops->id == PROTO_ETH) {
const uint8_t bcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
-   proto_field_set_default_bytes(lower, ETH_DST_ADDR, bcast);
+   proto_hdr_field_set_default_bytes(lower, ETH_DST_ADDR, bcast);
}
 
proto_header_fields_add(hdr, arp_fields, array_size(arp_fields));
 
/* Generate Announce request by default */
-   proto_field_set_default_be16(hdr, ARP_HTYPE, ARPHRD_ETHER);
-   proto_field_set_default_be16(hdr, ARP_PTYPE, ETH_P_IP);
-   proto_field_set_default_u8(hdr, ARP_HLEN, 6);
-   proto_field_set_default_u8(hdr, ARP_PLEN, 4);
-   proto_field_set_default_be16(hdr, ARP_OPER, ARPOP_REQUEST);
-   proto_field_set_default_dev_mac(hdr, ARP_SHA);
-   proto_field_set_default_dev_ipv4(hdr, ARP_SPA);
-   proto_field_set_default_dev_ipv4(hdr, ARP_TPA);
+   proto_hdr_field_set_default_be16(hdr, ARP_HTYPE, ARPHRD_ETHER);
+   proto_hdr_field_set_default_be16(hdr, ARP_PTYPE, ETH_P_IP);
+   proto_hdr_field_set_default_u8(hdr, ARP_HLEN, 6);
+   proto_hdr_field_set_default_u8(hdr, ARP_PLEN, 4);
+   proto_hdr_field_set_default_be16(hdr, ARP_OPER, ARPOP_REQUEST);
+   

[netsniff-ng] [PATCH 2/7] trafgen: proto: Change __proto_field_set_bytes(...) to take field

2016-12-17 Thread Vadim Kochan
Change __proto_field_set_bytes(...) function to take struct proto_field
instead of do looup by hdr & fid.

It is needed to able use this function with some custom
modified struct proto_field (len, pkt_offset).

Signed-off-by: Vadim Kochan 
---
 trafgen_proto.c | 50 +-
 1 file changed, 33 insertions(+), 17 deletions(-)

diff --git a/trafgen_proto.c b/trafgen_proto.c
index 62ac831..05fccb2 100644
--- a/trafgen_proto.c
+++ b/trafgen_proto.c
@@ -181,11 +181,10 @@ set_proto:
return current;
 }
 
-static void __proto_field_set_bytes(struct proto_hdr *hdr, uint32_t fid,
+static void __proto_field_set_bytes(struct proto_field *field,
const uint8_t *bytes, bool is_default,
bool is_be)
 {
-   struct proto_field *field;
uint8_t *payload, *p8;
uint16_t *p16;
uint32_t *p32;
@@ -193,12 +192,10 @@ static void __proto_field_set_bytes(struct proto_hdr 
*hdr, uint32_t fid,
uint16_t v16;
uint8_t v8;
 
-   field = proto_field_by_id(hdr, fid);
-
if (is_default && field->is_set)
return;
 
-   payload = _get(hdr->pkt_id)->payload[field->pkt_offset];
+   payload = _get(field->hdr->pkt_id)->payload[field->pkt_offset];
 
if (field->len == 1) {
p8 = payload;
@@ -239,7 +236,7 @@ static void __proto_field_set_bytes(struct proto_hdr *hdr, 
uint32_t fid,
 void proto_field_set_bytes(struct proto_hdr *hdr, uint32_t fid,
   const uint8_t *bytes)
 {
-   __proto_field_set_bytes(hdr, fid, bytes, false, false);
+   __proto_field_set_bytes(proto_field_by_id(hdr, fid), bytes, false, 
false);
 }
 
 static uint8_t *__proto_field_get_bytes(struct proto_field *field)
@@ -289,47 +286,64 @@ uint32_t proto_field_get_u32(struct proto_hdr *hdr, 
uint32_t fid)
 void proto_field_set_default_bytes(struct proto_hdr *hdr, uint32_t fid,
   const uint8_t *bytes)
 {
-   __proto_field_set_bytes(hdr, fid, bytes, true, false);
+   struct proto_field *field = proto_field_by_id(hdr, fid);
+
+   __proto_field_set_bytes(field, bytes, true, false);
 }
 
 void proto_field_set_default_u8(struct proto_hdr *hdr, uint32_t fid, uint8_t 
val)
 {
-   __proto_field_set_bytes(hdr, fid, (uint8_t *), true, false);
+   struct proto_field *field = proto_field_by_id(hdr, fid);
+
+   __proto_field_set_bytes(field, (uint8_t *), true, false);
 }
 
 void proto_field_set_default_u16(struct proto_hdr *hdr, uint32_t fid, uint16_t 
val)
 {
-   __proto_field_set_bytes(hdr, fid, (uint8_t *), true, false);
+   struct proto_field *field = proto_field_by_id(hdr, fid);
+
+   __proto_field_set_bytes(field, (uint8_t *), true, false);
 }
 
 void proto_field_set_default_u32(struct proto_hdr *hdr, uint32_t fid, uint32_t 
val)
 {
-   __proto_field_set_bytes(hdr, fid, (uint8_t *), true, false);
+   struct proto_field *field = proto_field_by_id(hdr, fid);
+
+   __proto_field_set_bytes(field, (uint8_t *), true, false);
 }
 
 void proto_field_set_be16(struct proto_hdr *hdr, uint32_t fid, uint16_t val)
 {
-   __proto_field_set_bytes(hdr, fid, (uint8_t *), false, true);
+   struct proto_field *field = proto_field_by_id(hdr, fid);
+
+   __proto_field_set_bytes(field, (uint8_t *), false, true);
 }
 
 void proto_field_set_be32(struct proto_hdr *hdr, uint32_t fid, uint32_t val)
 {
-   __proto_field_set_bytes(hdr, fid, (uint8_t *), false, true);
+   struct proto_field *field = proto_field_by_id(hdr, fid);
+
+   __proto_field_set_bytes(field, (uint8_t *), false, true);
 }
 
 void proto_field_set_default_be16(struct proto_hdr *hdr, uint32_t fid, 
uint16_t val)
 {
-   __proto_field_set_bytes(hdr, fid, (uint8_t *), true, true);
+   struct proto_field *field = proto_field_by_id(hdr, fid);
+
+   __proto_field_set_bytes(field, (uint8_t *), true, true);
 }
 
 void proto_field_set_default_be32(struct proto_hdr *hdr, uint32_t fid, 
uint32_t val)
 {
-   __proto_field_set_bytes(hdr, fid, (uint8_t *), true, true);
+   struct proto_field *field = proto_field_by_id(hdr, fid);
+
+   __proto_field_set_bytes(field, (uint8_t *), true, true);
 }
 
 static void __proto_field_set_dev_mac(struct proto_hdr *hdr, uint32_t fid,
  bool is_default)
 {
+   struct proto_field *field = proto_field_by_id(hdr, fid);
uint8_t mac[ETH_ALEN];
int ret;
 
@@ -340,7 +354,7 @@ static void __proto_field_set_dev_mac(struct proto_hdr 
*hdr, uint32_t fid,
if (ret < 0)
panic("Could not get device hw address\n");
 
-   __proto_field_set_bytes(hdr, fid, mac, is_default, false);
+   __proto_field_set_bytes(field, mac, is_default, false);
 }
 
 void proto_field_set_dev_mac(struct proto_hdr *hdr, uint32_t fid)
@@ -356,6 +370,7 @@ void proto_field_set_default_dev_mac(struct 

[netsniff-ng] [PATCH 0/7] trafgen: Allow set proto field value at specific offset

2016-12-17 Thread Vadim Kochan
Extend field expression with the following syntax:

[] | [:]

which allows to specify value or function at specified offset relative to the
field's offset within a header.

The trick to implement this was to use copies of proto_field instances
in the packet_dyn->fields array which allows to specify different functions
for the same field and with different offsets.

Vadim Kochan (7):
  trafgen: parser: Rename field_expr -> field_value_expr rule
  trafgen: proto: Change __proto_field_set_bytes(...) to take field
  trafgen: proto: Rename proto_field_xxx -> proto_hdr_field_xxx
  trafgen: proto: Add proto field only setters/getters
  trafgen: parser: Parse IPv6 address by strict match pattern
  trafgen: parser: Allow to set value/func at field offset
  man: trafgen: Add short description about field offset using

 trafgen.8|  25 +++
 trafgen_l2.c |  44 +--
 trafgen_l3.c |  24 +++---
 trafgen_l4.c |  28 +++
 trafgen_lexer.l  |  51 -
 trafgen_parser.y | 164 +
 trafgen_proto.c  | 217 +++
 trafgen_proto.h  |  64 +---
 8 files changed, 412 insertions(+), 205 deletions(-)

-- 
2.10.2

-- 
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.


[netsniff-ng] [PATCH 1/7] trafgen: parser: Rename field_expr -> field_value_expr rule

2016-12-17 Thread Vadim Kochan
Rename field_expr rule to field_value_expr to indicate the rule
relates to field value part in case if there will be added field_expr
rule to indicate field expression syntax.

Signed-off-by: Vadim Kochan 
---
 trafgen_parser.y | 30 +++---
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/trafgen_parser.y b/trafgen_parser.y
index 1e20cff..7e22a1d 100644
--- a/trafgen_parser.y
+++ b/trafgen_parser.y
@@ -718,7 +718,7 @@ proto
| tcp_proto { }
;
 
-field_expr
+field_value_expr
: number { field_expr.type = FIELD_EXPR_NUMB;
   field_expr.val.number = $1; }
| mac { field_expr.type = FIELD_EXPR_MAC;
@@ -783,7 +783,7 @@ eth_field
| eth_type { proto_field_set(ETH_TYPE); }
 
 eth_expr
-   : eth_field skip_white '=' skip_white field_expr
+   : eth_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
;
 
@@ -807,7 +807,7 @@ pause_field
;
 
 pause_expr
-   : pause_field skip_white '=' skip_white field_expr
+   : pause_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
;
 
@@ -843,7 +843,7 @@ pfc_field
;
 
 pfc_expr
-   : pfc_field skip_white '=' skip_white field_expr
+   : pfc_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
;
 
@@ -875,7 +875,7 @@ vlan_field
;
 
 vlan_expr
-   : vlan_field skip_white '=' skip_white field_expr
+   : vlan_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
| K_1Q
{ proto_field_set_be16(hdr, VLAN_TPID, ETH_P_8021Q); }
@@ -910,7 +910,7 @@ mpls_field
;
 
 mpls_expr
-   : mpls_field skip_white '=' skip_white field_expr
+   : mpls_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
 
 arp_proto
@@ -939,9 +939,9 @@ arp_field
;
 
 arp_expr
-   : arp_field skip_white '=' skip_white field_expr
+   : arp_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
-   | K_OPER skip_white '=' skip_white field_expr
+   | K_OPER skip_white '=' skip_white field_value_expr
{ proto_field_set(ARP_OPER);
  proto_field_expr_eval(); }
| K_OPER skip_white '=' skip_white K_REQUEST
@@ -985,7 +985,7 @@ ip4_field
;
 
 ip4_expr
-   : ip4_field skip_white '=' skip_white field_expr
+   : ip4_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
| K_DF  { proto_field_set_be16(hdr, IP4_DF, 1); }
| K_MF  { proto_field_set_be16(hdr, IP4_MF, 1); }
@@ -1022,7 +1022,7 @@ ip6_field
;
 
 ip6_expr
-   : ip6_field skip_white '=' skip_white field_expr
+   : ip6_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
;
 
@@ -1050,7 +1050,7 @@ icmp4_field
;
 
 icmp4_expr
-   : icmp4_field skip_white '=' skip_white field_expr
+   : icmp4_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
| K_ECHO_REQUEST
{ proto_field_set_u8(hdr, ICMPV4_TYPE, ICMP_ECHO);
@@ -1079,9 +1079,9 @@ icmp6_field
;
 
 icmp6_expr
-   : icmp6_field skip_white '=' skip_white field_expr
+   : icmp6_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
-   | K_TYPE skip_white '=' skip_white field_expr
+   | K_TYPE skip_white '=' skip_white field_value_expr
{ proto_field_set(ICMPV6_TYPE);
  proto_field_expr_eval(); }
| K_TYPE skip_white '=' K_ECHO_REQUEST
@@ -1115,7 +1115,7 @@ udp_field
;
 
 udp_expr
-   : udp_field skip_white '=' skip_white field_expr
+   : udp_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
;
 
@@ -1145,7 +1145,7 @@ tcp_field
;
 
 tcp_expr
-   : tcp_field skip_white '=' skip_white field_expr
+   : tcp_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
| K_CWR { proto_field_set_be16(hdr, TCP_CWR, 1); }
| K_ECE { proto_field_set_be16(hdr, TCP_ECE, 1); }
-- 
2.10.2

-- 
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.


[netsniff-ng] [PATCH 6/7] trafgen: parser: Allow to set value/func at field offset

2016-12-17 Thread Vadim Kochan
Extend proto field expression to:

proto_field[{index}:{len}] = {func}

which allows to specify function/value on the part of the field via index
and value length (default is 1 - 1 byte). This rule is optional.

It was needed to keep of proto_field's copies in packet_dyn->fields
instead of original fields which allows to scpecify different functions
on the different parts of same field, also the copy of original
proto_field allows to set custom length/pkt_offset which makes such
field behave as virtual sub-field of the original one with different
length/pkt_offset but point to the same piece of header.

Signed-off-by: Vadim Kochan 
---
 trafgen_parser.y | 96 +++-
 trafgen_proto.c  | 27 +++-
 trafgen_proto.h  |  8 +++--
 3 files changed, 98 insertions(+), 33 deletions(-)

diff --git a/trafgen_parser.y b/trafgen_parser.y
index a1b8b0c..4d570e0 100644
--- a/trafgen_parser.y
+++ b/trafgen_parser.y
@@ -387,20 +387,30 @@ static void proto_add(enum proto_id pid)
 
 static void proto_field_set(uint32_t fid)
 {
+   memset(_expr, 0, sizeof(field_expr));
field_expr.field = proto_hdr_field_by_id(hdr, fid);
 }
 
 static void proto_field_func_setup(struct proto_field *field, struct 
proto_field_func *func)
 {
+   struct proto_field *field_copy;
struct packet_dyn *pkt_dyn;
 
-   proto_hdr_field_func_add(field->hdr, field->id, func);
+   field_copy = xmalloc(sizeof(*field));
+   memcpy(field_copy, field, sizeof(*field));
+
+   field_copy->pkt_offset += func->offset;
+   if (func->len)
+   field_copy->len = func->len;
+
+   proto_field_func_add(field_copy, func);
 
pkt_dyn = _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;
+
+   pkt_dyn->fields[pkt_dyn->flen - 1] = field_copy;
 }
 
 static void proto_field_expr_eval(void)
@@ -450,6 +460,19 @@ static void proto_field_expr_eval(void)
memset(_expr, 0, sizeof(field_expr));
 }
 
+static void field_index_validate(struct proto_field *field, uint16_t index, 
size_t len)
+{
+   if (field_expr.field->len <= index) {
+   yyerror("Invalid [index] parameter");
+   panic("Index (%u) is bigger than field's length (%zu)\n",
+  index, field->len);
+   }
+   if (len != 1 && len != 2 && len != 4) {
+   yyerror("Invalid [index:len] parameter");
+   panic("Invalid index length - 1,2 or 4 is only allowed\n");
+   }
+}
+
 %}
 
 %union {
@@ -718,6 +741,17 @@ proto
| tcp_proto { }
;
 
+field_expr
+   : '[' skip_white number skip_white ']'
+   { field_index_validate(field_expr.field, $3, 1);
+ field_expr.val.func.offset = $3;
+ field_expr.val.func.len = 1; }
+   | '[' skip_white number skip_white ':' skip_white number skip_white ']'
+   { field_index_validate(field_expr.field, $3, $7);
+ field_expr.val.func.offset = $3;
+ field_expr.val.func.len = $7; }
+   ;
+
 field_value_expr
: number { field_expr.type = FIELD_EXPR_NUMB;
   field_expr.val.number = $1; }
@@ -783,7 +817,9 @@ eth_field
| eth_type { proto_field_set(ETH_TYPE); }
 
 eth_expr
-   : eth_field skip_white '=' skip_white field_value_expr
+   : eth_field field_expr skip_white '=' skip_white field_value_expr
+   { proto_field_expr_eval(); }
+   | eth_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
;
 
@@ -807,7 +843,9 @@ pause_field
;
 
 pause_expr
-   : pause_field skip_white '=' skip_white field_value_expr
+   : pause_field field_expr skip_white '=' skip_white field_value_expr
+   { proto_field_expr_eval(); }
+   | pause_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
;
 
@@ -843,7 +881,9 @@ pfc_field
;
 
 pfc_expr
-   : pfc_field skip_white '=' skip_white field_value_expr
+   : pfc_field field_expr skip_white '=' skip_white field_value_expr
+   { proto_field_expr_eval(); }
+   | pfc_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
;
 
@@ -875,7 +915,9 @@ vlan_field
;
 
 vlan_expr
-   : vlan_field skip_white '=' skip_white field_value_expr
+   : vlan_field field_expr skip_white '=' skip_white field_value_expr
+   { proto_field_expr_eval(); }
+   | vlan_field skip_white '=' skip_white field_value_expr
{ proto_field_expr_eval(); }
| K_1Q
{ proto_hdr_field_set_be16(hdr, VLAN_TPID, ETH_P_8021Q); }
@@ -910,7 +952,9 @@ mpls_field
;
 
 mpls_expr
-   

[netsniff-ng] [PATCH 5/7] trafgen: parser: Parse IPv6 address by strict match pattern

2016-12-17 Thread Vadim Kochan
Used IPv6 pattern from nftables project to match valid only IPv6
address to do not mess with MAC or other syntax patterns with ':' symbol.

Signed-off-by: Vadim Kochan 
---
 trafgen_lexer.l  | 51 +++
 trafgen_parser.y |  2 +-
 2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/trafgen_lexer.l b/trafgen_lexer.l
index 025fbfe..ad9dfe7 100644
--- a/trafgen_lexer.l
+++ b/trafgen_lexer.l
@@ -77,13 +77,56 @@ number_bin  ([0]?[b][0-1]+)
 number_dec (([0])|([1-9][0-9]*))
 number_ascii   ([a-zA-Z])
 
+hex4   ([[:xdigit:]]{1,4})
+v680   (({hex4}:){7}{hex4})
+v670   ((:)((:{hex4}){7}))
+v671   ((({hex4}:){1})((:{hex4}){6}))
+v672   ((({hex4}:){2})((:{hex4}){5}))
+v673   ((({hex4}:){3})((:{hex4}){4}))
+v674   ((({hex4}:){4})((:{hex4}){3}))
+v675   ((({hex4}:){5})((:{hex4}){2}))
+v676   ((({hex4}:){6})(:{hex4}{1}))
+v677   ((({hex4}:){7})(:))
+v67({v670}|{v671}|{v672}|{v673}|{v674}|{v675}|{v676}|{v677})
+v660   ((:)((:{hex4}){6}))
+v661   ((({hex4}:){1})((:{hex4}){5}))
+v662   ((({hex4}:){2})((:{hex4}){4}))
+v663   ((({hex4}:){3})((:{hex4}){3}))
+v664   ((({hex4}:){4})((:{hex4}){2}))
+v665   ((({hex4}:){5})((:{hex4}){1}))
+v666   ((({hex4}:){6})(:))
+v66({v660}|{v661}|{v662}|{v663}|{v664}|{v665}|{v666})
+v650   ((:)((:{hex4}){5}))
+v651   ((({hex4}:){1})((:{hex4}){4}))
+v652   ((({hex4}:){2})((:{hex4}){3}))
+v653   ((({hex4}:){3})((:{hex4}){2}))
+v654   ((({hex4}:){4})(:{hex4}{1}))
+v655   ((({hex4}:){5})(:))
+v65({v650}|{v651}|{v652}|{v653}|{v654}|{v655})
+v640   ((:)((:{hex4}){4}))
+v641   ((({hex4}:){1})((:{hex4}){3}))
+v642   ((({hex4}:){2})((:{hex4}){2}))
+v643   ((({hex4}:){3})((:{hex4}){1}))
+v644   ((({hex4}:){4})(:))
+v64({v640}|{v641}|{v642}|{v643}|{v644})
+v630   ((:)((:{hex4}){3}))
+v631   ((({hex4}:){1})((:{hex4}){2}))
+v632   ((({hex4}:){2})((:{hex4}){1}))
+v633   ((({hex4}:){3})(:))
+v63({v630}|{v631}|{v632}|{v633})
+v620   ((:)((:{hex4}){2}))
+v621   ((({hex4}:){1})((:{hex4}){1}))
+v622   ((({hex4}:){2})(:))
+v62({v620}|{v621}|{v622})
+v610   ((:)(:{hex4}{1}))
+v611   ((({hex4}:){1})(:))
+v61({v610}|{v611})
+v60(::)
+
 a_hex  ([a-fA-F0-9]+)
 mac({a_hex}:{a_hex}:{a_hex}:{a_hex}:{a_hex}:{a_hex})
 ip4_addr   ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)
-   /* We're very permissive about IPv6 addresses the grammar accepts, as
-* they can come in various different formats. In any case,
-* inet_pton(AF_INET6, ...) will reject the invalid ones later on. */
-ip6_addr   
(({a_hex}?:)?({a_hex}?:)?({a_hex}?:)?({a_hex}?:)?({a_hex}?:)?({a_hex}?:)?({a_hex}?:)?({a_hex})?)
+ip6_addr   ({v680}|{v67}|{v66}|{v65}|{v64}|{v63}|{v62}|{v61}|{v60})
 
 %%
 
diff --git a/trafgen_parser.y b/trafgen_parser.y
index bfeed2e..a1b8b0c 100644
--- a/trafgen_parser.y
+++ b/trafgen_parser.y
@@ -416,7 +416,7 @@ static void proto_field_expr_eval(void)
else if (field->len == 4)
proto_hdr_field_set_be32(hdr, field->id, 
field_expr.val.number);
else
-   bug();
+   proto_hdr_field_set_bytes(hdr, field->id, 
field_expr.val.bytes);
break;
 
case FIELD_EXPR_MAC:
-- 
2.10.2

-- 
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.


[netsniff-ng] [PATCH 7/7] man: trafgen: Add short description about field offset using

2016-12-17 Thread Vadim Kochan
Add short note about field offset syntax with an example.

Signed-off-by: Vadim Kochan 
---
 trafgen.8 | 25 +
 1 file changed, 25 insertions(+)

diff --git a/trafgen.8 b/trafgen.8
index 62716bb..c58d429 100644
--- a/trafgen.8
+++ b/trafgen.8
@@ -329,6 +329,31 @@ Example of using dynamic functions:
 .in -4
 
 .sp
+Field might be set with a value/function at a specific offset within a field:
+.sp
+.in +4
+[] | [:]
+.sp
+.in +4
+ - relative field's offset with range 0.. - 1
+.sp
+ - length/size of the value which will be set - 1,2 or 4 bytes 
(default: 1).
+.in -4
+.sp
+The  starts from the 1st field's byte in the network order.
+.sp
+Example of using field offset:
+.sp
+{
+.in +2
+eth(saddr=aa:bb:cc:dd:ee:ff, saddr[0]=dinc()),
+ipv4(saddr[0:2]=drnd()),
+udp(),
+.in -2
+}
+.in -4
+
+.sp
 All required lower layer headers will be filled automatically if they were not
 specified by the user. The headers will be filled in the order they were
 specified. Each header will be filled with some mimimum required set of fields.
-- 
2.10.2

-- 
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.