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, sequence, identifier, mtu, redirect
address
Signed-off-by: Vadim Kochan <[email protected]>
---
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 [email protected].
For more options, visit https://groups.google.com/d/optout.