blob: 4b4dc37aee30c86c1870f6c4ca12d49bb62e4c1f [file] [log] [blame]
Harald Welted46bcd22017-08-08 23:27:22 +02001#pragma once
2
Pau Espin Pedrole2b09612020-04-15 15:09:30 +02003#include <stdbool.h>
4
5#include <osmocom/core/msgb.h>
6#include <osmocom/core/endian.h>
7
Harald Welted46bcd22017-08-08 23:27:22 +02008#include "../gtp/gtp.h"
9#include "../gtp/pdp.h"
10
Pau Espin Pedrole2b09612020-04-15 15:09:30 +020011#define ICMPv6_OPT_TYPE_PREFIX_INFO 0x03
12
13#define foreach_icmpv6_opt(icmpv6_pkt, icmpv6_len, opt_hdr) \
14 for (opt_hdr = (struct icmpv6_opt_hdr *)(icmpv6_pkt)->options; \
15 (uint8_t*)(opt_hdr) + sizeof(struct icmpv6_opt_hdr) <= (((uint8_t*)(icmpv6_pkt)) + (icmpv6_len)); \
16 opt_hdr = (struct icmpv6_opt_hdr*)((uint8_t*)(opt_hdr) + (opt_hdr)->len) \
17 )
18
19struct icmpv6_hdr {
20 uint8_t type;
21 uint8_t code;
22 uint16_t csum;
23} __attribute__ ((packed));
24
Pau Espin Pedrol96214602020-04-14 19:39:09 +020025struct icmpv6_echo_hdr {
26 struct icmpv6_hdr hdr;
27 uint16_t ident; /* Identifier */
28 uint16_t seq; /* Sequence number */
29 uint8_t data[0]; /* Data */
30} __attribute__ ((packed));
31
Pau Espin Pedrole2b09612020-04-15 15:09:30 +020032/* RFC4861 Section 4.1 */
33struct icmpv6_rsol_hdr {
34 struct icmpv6_hdr hdr;
35 uint32_t reserved;
36 uint8_t options[0];
37} __attribute__ ((packed));
38
39/* RFC4861 Section 4.2 */
40struct icmpv6_radv_hdr {
41 struct icmpv6_hdr hdr;
42 uint8_t cur_ho_limit;
43#if OSMO_IS_LITTLE_ENDIAN
44 uint8_t res:6,
45 m:1,
46 o:1;
47#else
48 uint8_t m:1,
49 o:1,
50 res:6;
51#endif
52 uint16_t router_lifetime;
53 uint32_t reachable_time;
54 uint32_t retrans_timer;
55 uint8_t options[0];
56} __attribute__ ((packed));
57
58
59/* RFC4861 Section 4.6 */
60struct icmpv6_opt_hdr {
61 uint8_t type;
62 /* length in units of 8 octets, including type+len! */
63 uint8_t len;
64 uint8_t data[0];
65} __attribute__ ((packed));
66
67/* RFC4861 Section 4.6.2 */
68struct icmpv6_opt_prefix {
69 struct icmpv6_opt_hdr hdr;
70 uint8_t prefix_len;
71#if OSMO_IS_LITTLE_ENDIAN
72 uint8_t res:6,
73 a:1,
74 l:1;
75#else
76 uint8_t l:1,
77 a:1,
78 res:6;
79#endif
80 uint32_t valid_lifetime;
81 uint32_t preferred_lifetime;
82 uint32_t res2;
83 uint8_t prefix[16];
84} __attribute__ ((packed));
85
Pau Espin Pedrol96214602020-04-14 19:39:09 +020086uint16_t icmpv6_prepend_ip6hdr(struct msgb *msg, const struct in6_addr *saddr,
87 const struct in6_addr *daddr);
88
Pau Espin Pedrole2b09612020-04-15 15:09:30 +020089struct msgb *icmpv6_construct_rs(const struct in6_addr *saddr);
90
Pau Espin Pedrol7d54ed42018-01-25 20:09:16 +010091int handle_router_mcast(struct gsn_t *gsn, struct pdp_t *pdp,
92 const struct in6_addr *pdp_prefix,
93 const struct in6_addr *own_ll_addr,
Harald Weltef85fe972017-09-24 20:00:34 +080094 const uint8_t *pack, unsigned len);
Pau Espin Pedrole2b09612020-04-15 15:09:30 +020095
96struct icmpv6_radv_hdr *icmpv6_validate_router_adv(const uint8_t *pack, unsigned len);
97
98
99/* RFC3307 link-local scope multicast address */
100extern const struct in6_addr all_router_mcast_addr;