summaryrefslogtreecommitdiff
path: root/proto_ip_authentication_hdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto_ip_authentication_hdr.c')
-rw-r--r--proto_ip_authentication_hdr.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/proto_ip_authentication_hdr.c b/proto_ip_authentication_hdr.c
new file mode 100644
index 0000000..2d5f57c
--- /dev/null
+++ b/proto_ip_authentication_hdr.c
@@ -0,0 +1,87 @@
+/*
+ * netsniff-ng - the packet sniffing beast
+ * Copyright 2012 Markus Amend <markus@netsniff-ng.org>, Deutsche Flugsicherung GmbH
+ * Subject to the GPL, version 2.
+ *
+ * IP Authentication Header described in RFC4302
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <netinet/in.h> /* for ntohs() */
+
+#include "proto.h"
+#include "protos.h"
+#include "dissector_eth.h"
+#include "built_in.h"
+#include "pkt_buff.h"
+
+struct auth_hdr {
+ uint8_t h_next_header;
+ uint8_t h_payload_len;
+ uint16_t h_reserved;
+ uint32_t h_spi;
+ uint32_t h_snf;
+} __packed;
+
+static void auth_hdr(struct pkt_buff *pkt)
+{
+ ssize_t hdr_len;
+ size_t i;
+ struct auth_hdr *auth_ops;
+
+ auth_ops = (struct auth_hdr *) pkt_pull(pkt, sizeof(*auth_ops));
+ if (auth_ops == NULL)
+ return;
+
+ hdr_len = (auth_ops->h_payload_len * 4) + 8;
+
+ tprintf(" [ Authentication Header ");
+ tprintf("NextHdr (%u), ", auth_ops->h_next_header);
+ if (hdr_len > pkt_len(pkt) || hdr_len < 0){
+ tprintf("HdrLen (%u, %zd Bytes %s), ",
+ auth_ops->h_payload_len, hdr_len,
+ colorize_start_full(black, red)
+ "invalid" colorize_end());
+ return;
+ }
+ tprintf("HdrLen (%u, %zd Bytes), ",auth_ops->h_payload_len, hdr_len);
+ tprintf("Reserved (0x%x), ", ntohs(auth_ops->h_reserved));
+ /* TODO
+ * Upgrade for Extended (64-bit) Sequence Number
+ * http://tools.ietf.org/html/rfc4302#section-2.5.1
+ */
+ tprintf("SPI (0x%x), ", ntohl(auth_ops->h_spi));
+ tprintf("SNF (0x%x), ", ntohl(auth_ops->h_snf));
+ tprintf("ICV 0x");
+ for (i = sizeof(struct auth_hdr); i < hdr_len; i++)
+ tprintf("%02x", *pkt_pull(pkt, 1));
+ tprintf(" ]\n");
+
+ pkt_set_proto(pkt, &eth_lay3, auth_ops->h_next_header);
+}
+
+static void auth_hdr_less(struct pkt_buff *pkt)
+{
+ ssize_t hdr_len;
+ struct auth_hdr *auth_ops;
+
+ auth_ops = (struct auth_hdr *) pkt_pull(pkt, sizeof(*auth_ops));
+ if (auth_ops == NULL)
+ return;
+
+ hdr_len = (auth_ops->h_payload_len * 4) + 8;
+ if (hdr_len > pkt_len(pkt) || hdr_len < 0)
+ return;
+
+ tprintf(" AH");
+
+ pkt_pull(pkt, hdr_len - sizeof(*auth_ops));
+ pkt_set_proto(pkt, &eth_lay3, auth_ops->h_next_header);
+}
+
+struct protocol ip_auth_ops = {
+ .key = 0x33,
+ .print_full = auth_hdr,
+ .print_less = auth_hdr_less,
+};