blob: ee5ef297f7fe86f14577cf362940401173fe51b5 [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;
Vadim Yanitskiy99afe972023-02-26 15:43:10 +070047#elif OSMO_IS_BIG_ENDIAN
48/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
49 uint8_t o:1, m:1, res:6;
Pau Espin Pedrole2b09612020-04-15 15:09:30 +020050#endif
51 uint16_t router_lifetime;
52 uint32_t reachable_time;
53 uint32_t retrans_timer;
54 uint8_t options[0];
55} __attribute__ ((packed));
56
57
58/* RFC4861 Section 4.6 */
59struct icmpv6_opt_hdr {
60 uint8_t type;
61 /* length in units of 8 octets, including type+len! */
62 uint8_t len;
63 uint8_t data[0];
64} __attribute__ ((packed));
65
66/* RFC4861 Section 4.6.2 */
67struct icmpv6_opt_prefix {
68 struct icmpv6_opt_hdr hdr;
69 uint8_t prefix_len;
70#if OSMO_IS_LITTLE_ENDIAN
71 uint8_t res:6,
72 a:1,
73 l:1;
Vadim Yanitskiy99afe972023-02-26 15:43:10 +070074#elif OSMO_IS_BIG_ENDIAN
75/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
76 uint8_t l:1, a:1, res:6;
Pau Espin Pedrole2b09612020-04-15 15:09:30 +020077#endif
78 uint32_t valid_lifetime;
79 uint32_t preferred_lifetime;
80 uint32_t res2;
81 uint8_t prefix[16];
82} __attribute__ ((packed));
83
Pau Espin Pedrol96214602020-04-14 19:39:09 +020084uint16_t icmpv6_prepend_ip6hdr(struct msgb *msg, const struct in6_addr *saddr,
85 const struct in6_addr *daddr);
86
Pau Espin Pedrole2b09612020-04-15 15:09:30 +020087struct msgb *icmpv6_construct_rs(const struct in6_addr *saddr);
88
Pau Espin Pedrol7d54ed42018-01-25 20:09:16 +010089int handle_router_mcast(struct gsn_t *gsn, struct pdp_t *pdp,
90 const struct in6_addr *pdp_prefix,
91 const struct in6_addr *own_ll_addr,
Harald Weltef85fe972017-09-24 20:00:34 +080092 const uint8_t *pack, unsigned len);
Pau Espin Pedrole2b09612020-04-15 15:09:30 +020093
94struct icmpv6_radv_hdr *icmpv6_validate_router_adv(const uint8_t *pack, unsigned len);
95
96
97/* RFC3307 link-local scope multicast address */
98extern const struct in6_addr all_router_mcast_addr;