summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Kochan <vadim4j@gmail.com>2016-07-16 12:39:43 +0300
committerTobias Klauser <tklauser@distanz.ch>2016-07-18 14:43:45 +0200
commit9ad5ccd66e89778e33cd1be3cd8887ec4a03d177 (patch)
treec4e804dd8f4f6795ca505ccd0b0ee69acf1dfe7c
parentc11d67bf8ce5666b454ba34c004c264d5cfae24a (diff)
trafgen: ipv4: Do not use user-provided 'ihl' field to calculate csum
It is potentially dangerous to use the user specified IHL field for csum calculation, as it might lead to read buffer overflows. Instead introduce and use the len field in struct proto_hdr which is calculated automatically after the header is built. Signed-off-by: Vadim Kochan <vadim4j@gmail.com> [tk: reword commit message] Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r--trafgen_l3.c4
-rw-r--r--trafgen_proto.c4
-rw-r--r--trafgen_proto.h1
3 files changed, 5 insertions, 4 deletions
diff --git a/trafgen_l3.c b/trafgen_l3.c
index 012321f..ad58270 100644
--- a/trafgen_l3.c
+++ b/trafgen_l3.c
@@ -53,10 +53,8 @@ static void ipv4_packet_finish(struct proto_hdr *hdr)
if (!proto_field_is_set(hdr, IP4_CSUM)) {
uint16_t csum;
- uint8_t ihl;
- ihl = proto_field_get_u8(hdr, IP4_IHL);
- csum = htons(calc_csum(&pkt->payload[hdr->pkt_offset], ihl * 4));
+ csum = htons(calc_csum(&pkt->payload[hdr->pkt_offset], hdr->len));
proto_field_set_u16(hdr, IP4_CSUM, bswap_16(csum));
}
}
diff --git a/trafgen_proto.c b/trafgen_proto.c
index 1babba5..cb0c6ae 100644
--- a/trafgen_proto.c
+++ b/trafgen_proto.c
@@ -100,8 +100,10 @@ void proto_header_fields_add(struct proto_hdr *hdr,
f->mask = fields[i].mask;
f->pkt_offset = hdr->pkt_offset + fields[i].offset;
- if (f->pkt_offset + f->len > pkt->len)
+ if (f->pkt_offset + f->len > pkt->len) {
+ hdr->len += f->len;
set_fill(0, (f->pkt_offset + f->len) - pkt->len);
+ }
}
}
diff --git a/trafgen_proto.h b/trafgen_proto.h
index 822d841..72cd9f7 100644
--- a/trafgen_proto.h
+++ b/trafgen_proto.h
@@ -51,6 +51,7 @@ struct proto_hdr {
uint16_t pkt_offset;
struct proto_field *fields;
size_t fields_count;
+ size_t len;
void (*header_init)(struct proto_hdr *hdr);
void (*header_finish)(struct proto_hdr *hdr);