Handle 'field_changed' callback to check if IPv4 csum is needed to be recalculated, if so - update it on 'packet_update' event.
Added 'is_csum_valid' to proto_hdr struct to check if csum needs to be updated. Signed-off-by: Vadim Kochan <vadi...@gmail.com> --- trafgen_l3.c | 33 +++++++++++++++++++++++++++------ trafgen_proto.h | 2 ++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/trafgen_l3.c b/trafgen_l3.c index 1cdd041..8db7e5d 100644 --- a/trafgen_l3.c +++ b/trafgen_l3.c @@ -43,6 +43,30 @@ static void ipv4_header_init(struct proto_hdr *hdr) proto_field_set_default_dev_ipv4(hdr, IP4_SADDR); } +static void ipv4_field_changed(struct proto_hdr *hdr, struct proto_field *field) +{ + hdr->is_csum_valid = false; +} + +static void ipv4_csum_update(struct proto_hdr *hdr) +{ + struct packet *pkt; + uint16_t csum; + + if (proto_field_is_set(hdr, IP4_CSUM)) + return; + if (hdr->is_csum_valid) + return; + + pkt = packet_get(hdr->pkt_id); + + proto_field_set_default_u16(hdr, IP4_CSUM, 0); + csum = htons(calc_csum(&pkt->payload[hdr->pkt_offset], hdr->len)); + proto_field_set_default_u16(hdr, IP4_CSUM, bswap_16(csum)); + + hdr->is_csum_valid = true; +} + static void ipv4_packet_finish(struct proto_hdr *hdr) { struct packet *pkt = current_packet(); @@ -51,12 +75,7 @@ static void ipv4_packet_finish(struct proto_hdr *hdr) total_len = pkt->len - hdr->pkt_offset; proto_field_set_default_be16(hdr, IP4_LEN, total_len); - if (!proto_field_is_set(hdr, IP4_CSUM)) { - uint16_t csum; - - csum = htons(calc_csum(&pkt->payload[hdr->pkt_offset], hdr->len)); - proto_field_set_u16(hdr, IP4_CSUM, bswap_16(csum)); - } + ipv4_csum_update(hdr); } static void ipv4_set_next_proto(struct proto_hdr *hdr, enum proto_id pid) @@ -90,6 +109,8 @@ static struct proto_hdr ipv4_hdr = { .id = PROTO_IP4, .layer = PROTO_L3, .header_init = ipv4_header_init, + .packet_update = ipv4_csum_update, + .field_changed = ipv4_field_changed, .packet_finish = ipv4_packet_finish, .set_next_proto = ipv4_set_next_proto, }; diff --git a/trafgen_proto.h b/trafgen_proto.h index c7b5909..ddf9fb4 100644 --- a/trafgen_proto.h +++ b/trafgen_proto.h @@ -71,6 +71,8 @@ struct proto_hdr { size_t fields_count; size_t len; + bool is_csum_valid; + void (*header_init)(struct proto_hdr *hdr); void (*header_finish)(struct proto_hdr *hdr); void (*field_changed)(struct proto_hdr *hdr, struct proto_field *field); -- 2.9.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.