aboutsummaryrefslogtreecommitdiffstats
path: root/lib/icmpv6.h
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2020-04-15 15:09:30 +0200
committerpespin <pespin@sysmocom.de>2020-04-21 14:39:42 +0000
commite2b0961f18c1ba9204013b831797ad94604352ef (patch)
tree61f374d096242c01fdd223287b7bdf0b54788a32 /lib/icmpv6.h
parentff2ebee03baf92609dc14bb1324cd069bf5c8323 (diff)
sgsnemu: Handle IPv6 SLAAC in tun iface manually
Disable IPv6 automatic SLAAC by linux kernel and handle it manually. This allows us gaining control on local address acquisition and set addresses and routing properly. It will also allow us to run in ping mode without a tun iface. Related: OS#4434 Change-Id: Iae59cf6ffb181357e10b3080a5c751bd454f4a1f
Diffstat (limited to 'lib/icmpv6.h')
-rw-r--r--lib/icmpv6.h81
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/icmpv6.h b/lib/icmpv6.h
index bf91e27..44b9b73 100644
--- a/lib/icmpv6.h
+++ b/lib/icmpv6.h
@@ -1,9 +1,90 @@
#pragma once
+#include <stdbool.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/endian.h>
+
#include "../gtp/gtp.h"
#include "../gtp/pdp.h"
+#define ICMPv6_OPT_TYPE_PREFIX_INFO 0x03
+
+#define foreach_icmpv6_opt(icmpv6_pkt, icmpv6_len, opt_hdr) \
+ for (opt_hdr = (struct icmpv6_opt_hdr *)(icmpv6_pkt)->options; \
+ (uint8_t*)(opt_hdr) + sizeof(struct icmpv6_opt_hdr) <= (((uint8_t*)(icmpv6_pkt)) + (icmpv6_len)); \
+ opt_hdr = (struct icmpv6_opt_hdr*)((uint8_t*)(opt_hdr) + (opt_hdr)->len) \
+ )
+
+struct icmpv6_hdr {
+ uint8_t type;
+ uint8_t code;
+ uint16_t csum;
+} __attribute__ ((packed));
+
+/* RFC4861 Section 4.1 */
+struct icmpv6_rsol_hdr {
+ struct icmpv6_hdr hdr;
+ uint32_t reserved;
+ uint8_t options[0];
+} __attribute__ ((packed));
+
+/* RFC4861 Section 4.2 */
+struct icmpv6_radv_hdr {
+ struct icmpv6_hdr hdr;
+ uint8_t cur_ho_limit;
+#if OSMO_IS_LITTLE_ENDIAN
+ uint8_t res:6,
+ m:1,
+ o:1;
+#else
+ uint8_t m:1,
+ o:1,
+ res:6;
+#endif
+ uint16_t router_lifetime;
+ uint32_t reachable_time;
+ uint32_t retrans_timer;
+ uint8_t options[0];
+} __attribute__ ((packed));
+
+
+/* RFC4861 Section 4.6 */
+struct icmpv6_opt_hdr {
+ uint8_t type;
+ /* length in units of 8 octets, including type+len! */
+ uint8_t len;
+ uint8_t data[0];
+} __attribute__ ((packed));
+
+/* RFC4861 Section 4.6.2 */
+struct icmpv6_opt_prefix {
+ struct icmpv6_opt_hdr hdr;
+ uint8_t prefix_len;
+#if OSMO_IS_LITTLE_ENDIAN
+ uint8_t res:6,
+ a:1,
+ l:1;
+#else
+ uint8_t l:1,
+ a:1,
+ res:6;
+#endif
+ uint32_t valid_lifetime;
+ uint32_t preferred_lifetime;
+ uint32_t res2;
+ uint8_t prefix[16];
+} __attribute__ ((packed));
+
+struct msgb *icmpv6_construct_rs(const struct in6_addr *saddr);
+
int handle_router_mcast(struct gsn_t *gsn, struct pdp_t *pdp,
const struct in6_addr *pdp_prefix,
const struct in6_addr *own_ll_addr,
const uint8_t *pack, unsigned len);
+
+struct icmpv6_radv_hdr *icmpv6_validate_router_adv(const uint8_t *pack, unsigned len);
+
+
+/* RFC3307 link-local scope multicast address */
+extern const struct in6_addr all_router_mcast_addr;