From f02fcdbd2cb4dc041783def773e446c179bd57f1 Mon Sep 17 00:00:00 2001 From: Vadim Kochan Date: Mon, 8 Feb 2016 08:01:51 +0200 Subject: [PATCH] trafgen: proto: Fix bad field masking Current logic does OR of existing field value & shift-masked specified value, which is not enough as 0s bits from the specified value will be not set (be cause of OR), so fixed it by reseting original field value by AND with reverted field mask, in otherwords - bits part of original field value is reset to 0s and only after OR-ed with specified shift-masked value. Signed-off-by: Vadim Kochan Signed-off-by: Tobias Klauser --- trafgen_proto.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/trafgen_proto.c b/trafgen_proto.c index efa8fceb..214547e9 100644 --- a/trafgen_proto.c +++ b/trafgen_proto.c @@ -182,7 +182,9 @@ static void __proto_field_set_bytes(struct proto_hdr *hdr, uint32_t fid, uint8_t *bytes, bool is_default, bool is_be) { struct proto_field *field; - uint8_t *payload; + uint8_t *payload, *p8; + uint16_t *p16; + uint32_t *p32; uint32_t v32; uint16_t v16; uint8_t v8; @@ -195,18 +197,32 @@ static void __proto_field_set_bytes(struct proto_hdr *hdr, uint32_t fid, payload = ¤t_packet()->payload[field->pkt_offset]; if (field->len == 1) { + p8 = payload; + *p8 = field->mask ? *p8 & ~field->mask : *p8; + v8 = field_shift_and_mask(field, *bytes); - v8 = field->mask ? (v8 | *payload) : v8; + v8 = field->mask ? (v8 | *p8) : v8; + bytes = &v8; } else if (field->len == 2) { + p16 = (uint16_t *)payload; + *p16 = be16_to_cpu(*p16); + *p16 = cpu_to_be16(field->mask ? *p16 & ~field->mask : *p16); + v16 = field_shift_and_mask(field, *(uint16_t *)bytes); v16 = is_be ? cpu_to_be16(v16) : v16; - v16 = field->mask ? (v16 | *(uint16_t *)payload) : v16; + v16 = field->mask ? (v16 | *p16) : v16; + bytes = (uint8_t *)&v16; } else if (field->len == 4) { + p32 = (uint32_t *)payload; + *p32 = be32_to_cpu(*p32); + *p32 = cpu_to_be32(field->mask ? *p32 & ~field->mask : *p32); + v32 = field_shift_and_mask(field, *(uint32_t *)bytes); v32 = is_be ? cpu_to_be32(v32) : v32; - v32 = field->mask ? (v32 | *(uint32_t *)payload) : v32; + v32 = field->mask ? (v32 | *p32) : v32; + bytes = (uint8_t *)&v32; } -- 2.11.4.GIT