aboutgitcodebugslistschat
path: root/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'util.c')
-rw-r--r--util.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/util.c b/util.c
index aee41a0..7dd0db1 100644
--- a/util.c
+++ b/util.c
@@ -7,8 +7,11 @@
*
*/
+#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
+#include <linux/ipv6.h>
+#include <arpa/inet.h>
/**
* csum_fold() - Fold long sum for IP and TCP checksum
@@ -46,3 +49,39 @@ uint16_t csum_ip4(void *buf, size_t len)
return ~csum_fold(sum);
}
+
+unsigned char *ipv6_l4hdr(struct ipv6hdr *ip6h, uint8_t *proto)
+{
+ int offset, len, hdrlen;
+ struct ipv6_opt_hdr *o;
+ uint8_t nh;
+
+ len = ntohs(ip6h->payload_len);
+ offset = 0;
+
+ while (offset < len) {
+ if (!offset) {
+ nh = ip6h->nexthdr;
+ hdrlen = sizeof(struct ipv6hdr);
+ } else {
+ nh = o->nexthdr;
+ hdrlen = (o->hdrlen + 1) * 8;
+ }
+
+ if (nh == 59)
+ return NULL;
+
+ if (nh == 0 || nh == 43 || nh == 44 || nh == 50 ||
+ nh == 51 || nh == 60 || nh == 135 || nh == 139 ||
+ nh == 140 || nh == 253 || nh == 254) {
+ offset += hdrlen;
+ o = (struct ipv6_opt_hdr *)(unsigned char *)ip6h +
+ offset;
+ } else {
+ *proto = nh;
+ return (unsigned char *)(ip6h + 1) + offset;
+ }
+ }
+
+ return NULL;
+}