Add ICMPv4 protocol header creating with minimum field set: type, code, checksum & unused field.
Checksum is calculated by default if the 'csum' field is not set. It is allowed to specify such fields like: type, code, checksum, unused, sequence, identifier, mtu, redirect address Signed-off-by: Vadim Kochan <vadi...@gmail.com> --- trafgen_l3.c | 3 +++ trafgen_l4.c | 42 ++++++++++++++++++++++++++++++++++++++++++ trafgen_l4.h | 10 ++++++++++ trafgen_proto.h | 1 + 4 files changed, 56 insertions(+) diff --git a/trafgen_l3.c b/trafgen_l3.c index cbdbe6c..ae3f136 100644 --- a/trafgen_l3.c +++ b/trafgen_l3.c @@ -69,6 +69,9 @@ static void ipv4_set_next_proto(struct proto_hdr *hdr, enum proto_id pid) case PROTO_IP4: ip_proto = IPPROTO_IPIP; break; + case PROTO_ICMP4: + ip_proto = IPPROTO_ICMP; + break; case PROTO_UDP: ip_proto = IPPROTO_UDP; break; diff --git a/trafgen_l4.c b/trafgen_l4.c index 886e2b2..c109675 100644 --- a/trafgen_l4.c +++ b/trafgen_l4.c @@ -138,6 +138,47 @@ static struct proto_hdr tcp_hdr = { .packet_finish = tcp_packet_finish, }; +static struct proto_field icmpv4_fields[] = { + { .id = ICMPV4_TYPE, .len = 1, .offset = 0 }, + { .id = ICMPV4_CODE, .len = 1, .offset = 1 }, + { .id = ICMPV4_CSUM, .len = 2, .offset = 2 }, + /* Echo/Ping fields */ + { .id = ICMPV4_ID, .len = 2, .offset = 4 }, + { .id = ICMPV4_SEQ, .len = 2, .offset = 6 }, + /* Redirect field */ + { .id = ICMPV4_REDIR_ADDR, .len = 4, .offset = 4 }, + /* Next-hop MTU */ + { .id = ICMPV4_MTU, .len = 2, .offset = 6 }, +}; + +static void icmpv4_header_init(struct proto_hdr *hdr) +{ + proto_lower_default_add(hdr, PROTO_IP4); + + proto_header_fields_add(hdr, icmpv4_fields, array_size(icmpv4_fields)); +} + +static void icmpv4_packet_finish(struct proto_hdr *hdr) +{ + struct packet *pkt; + uint16_t csum; + + if (proto_field_is_set(hdr, ICMPV4_CSUM)) + return; + + pkt = current_packet(); + + csum = htons(calc_csum(proto_header_ptr(hdr), pkt->len - hdr->pkt_offset)); + proto_field_set_u16(hdr, ICMPV4_CSUM, bswap_16(csum)); +} + +static struct proto_hdr icmpv4_hdr = { + .id = PROTO_ICMP4, + .layer = PROTO_L4, + .header_init = icmpv4_header_init, + .packet_finish = icmpv4_packet_finish, +}; + static struct proto_field icmpv6_fields[] = { { .id = ICMPV6_TYPE, .len = 1, .offset = 0 }, { .id = ICMPV6_CODE, .len = 1, .offset = 1 }, @@ -190,5 +231,6 @@ void protos_l4_init(void) { proto_header_register(&udp_hdr); proto_header_register(&tcp_hdr); + proto_header_register(&icmpv4_hdr); proto_header_register(&icmpv6_hdr); } diff --git a/trafgen_l4.h b/trafgen_l4.h index e94ff23..9537cbf 100644 --- a/trafgen_l4.h +++ b/trafgen_l4.h @@ -27,6 +27,16 @@ enum tcp_field { TCP_URG_PTR, }; +enum icmpv4_field { + ICMPV4_TYPE, + ICMPV4_CODE, + ICMPV4_CSUM, + ICMPV4_ID, + ICMPV4_SEQ, + ICMPV4_REDIR_ADDR, + ICMPV4_MTU, +}; + enum icmpv6_field { ICMPV6_TYPE, ICMPV6_CODE, diff --git a/trafgen_proto.h b/trafgen_proto.h index 5528704..822d841 100644 --- a/trafgen_proto.h +++ b/trafgen_proto.h @@ -16,6 +16,7 @@ enum proto_id { PROTO_ARP, PROTO_MPLS, PROTO_IP4, + PROTO_ICMP4, PROTO_IP6, PROTO_ICMP6, PROTO_UDP, -- 2.6.3 -- 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.