1 /** @file 2 @brief ICMPv6 handler 3 4 This is not to be included by the application. 5 */ 6 7 /* 8 * Copyright (c) 2016 Intel Corporation 9 * 10 * SPDX-License-Identifier: Apache-2.0 11 */ 12 13 #ifndef __ICMPV6_H 14 #define __ICMPV6_H 15 16 #include <zephyr/sys/slist.h> 17 #include <zephyr/types.h> 18 19 #include <zephyr/net/net_ip.h> 20 #include <zephyr/net/net_pkt.h> 21 22 struct net_icmpv6_ns_hdr { 23 uint32_t reserved; 24 uint8_t tgt[NET_IPV6_ADDR_SIZE]; 25 } __packed; 26 27 struct net_icmpv6_nd_opt_hdr { 28 uint8_t type; 29 uint8_t len; 30 } __packed; 31 32 struct net_icmpv6_na_hdr { 33 uint8_t flags; 34 uint8_t reserved[3]; 35 uint8_t tgt[NET_IPV6_ADDR_SIZE]; 36 } __packed; 37 38 struct net_icmpv6_rs_hdr { 39 uint32_t reserved; 40 } __packed; 41 42 struct net_icmpv6_ra_hdr { 43 uint8_t cur_hop_limit; 44 uint8_t flags; 45 uint16_t router_lifetime; 46 uint32_t reachable_time; 47 uint32_t retrans_timer; 48 } __packed; 49 50 struct net_icmpv6_nd_opt_mtu { 51 uint16_t reserved; 52 uint32_t mtu; 53 } __packed; 54 55 struct net_icmpv6_nd_opt_prefix_info { 56 uint8_t prefix_len; 57 uint8_t flags; 58 uint32_t valid_lifetime; 59 uint32_t preferred_lifetime; 60 uint32_t reserved; 61 uint8_t prefix[NET_IPV6_ADDR_SIZE]; 62 } __packed; 63 64 struct net_icmpv6_nd_opt_6co { 65 uint8_t context_len; 66 uint8_t flag; /*res:3,c:1,cid:4 */ 67 uint16_t reserved; 68 uint16_t lifetime; 69 uint8_t prefix[NET_IPV6_ADDR_SIZE]; 70 } __packed; 71 72 /* RFC 4191, ch. 2.3 */ 73 struct net_icmpv6_nd_opt_route_info { 74 uint8_t prefix_len; 75 struct { 76 #ifdef CONFIG_LITTLE_ENDIAN 77 uint8_t reserved_2 :3; 78 uint8_t prf :2; 79 uint8_t reserved_1 :3; 80 #else 81 uint8_t reserved_1 :3; 82 uint8_t prf :2; 83 uint8_t reserved_2 :3; 84 #endif 85 } flags; 86 uint32_t route_lifetime; 87 /* Variable-length prefix field follows, can be 0, 8 or 16 bytes 88 * depending on the option length. 89 */ 90 } __packed; 91 92 struct net_icmpv6_nd_opt_rdnss { 93 uint16_t reserved; 94 uint32_t lifetime; 95 /* Variable-length DNS server address follows, 96 * depending on the option length. 97 */ 98 } __packed; 99 100 struct net_icmpv6_echo_req { 101 uint16_t identifier; 102 uint16_t sequence; 103 } __packed; 104 105 struct net_icmpv6_mld_query { 106 uint16_t max_response_code; 107 uint16_t reserved; 108 uint8_t mcast_address[NET_IPV6_ADDR_SIZE]; 109 uint16_t flagg; /*S, QRV & QQIC */ 110 uint16_t num_sources; 111 } __packed; 112 113 struct net_icmpv6_mld_mcast_record { 114 uint8_t record_type; 115 uint8_t aux_data_len; 116 uint16_t num_sources; 117 uint8_t mcast_address[NET_IPV6_ADDR_SIZE]; 118 } __packed; 119 120 121 #define NET_ICMPV6_ND_O_FLAG(flag) ((flag) & 0x40) 122 #define NET_ICMPV6_ND_M_FLAG(flag) ((flag) & 0x80) 123 124 #define NET_ICMPV6_ND_OPT_SLLAO 1 125 #define NET_ICMPV6_ND_OPT_TLLAO 2 126 #define NET_ICMPV6_ND_OPT_PREFIX_INFO 3 127 #define NET_ICMPV6_ND_OPT_MTU 5 128 #define NET_ICMPV6_ND_OPT_ROUTE 24 129 #define NET_ICMPV6_ND_OPT_RDNSS 25 130 #define NET_ICMPV6_ND_OPT_DNSSL 31 131 #define NET_ICMPV6_ND_OPT_6CO 34 132 133 #define NET_ICMPV6_OPT_TYPE_OFFSET 0 134 #define NET_ICMPV6_OPT_LEN_OFFSET 1 135 #define NET_ICMPV6_OPT_DATA_OFFSET 2 136 137 #define NET_ICMPV6_NA_FLAG_ROUTER 0x80 138 #define NET_ICMPV6_NA_FLAG_SOLICITED 0x40 139 #define NET_ICMPV6_NA_FLAG_OVERRIDE 0x20 140 #define NET_ICMPV6_RA_FLAG_ONLINK 0x80 141 #define NET_ICMPV6_RA_FLAG_AUTONOMOUS 0x40 142 143 #define NET_ICMPV6_DST_UNREACH 1 /* Destination unreachable */ 144 #define NET_ICMPV6_PACKET_TOO_BIG 2 /* Packet too big */ 145 #define NET_ICMPV6_TIME_EXCEEDED 3 /* Time exceeded */ 146 #define NET_ICMPV6_PARAM_PROBLEM 4 /* IPv6 header is bad */ 147 #define NET_ICMPV6_MLD_QUERY 130 /* Multicast Listener Query */ 148 #define NET_ICMPV6_RS 133 /* Router Solicitation */ 149 #define NET_ICMPV6_RA 134 /* Router Advertisement */ 150 #define NET_ICMPV6_NS 135 /* Neighbor Solicitation */ 151 #define NET_ICMPV6_NA 136 /* Neighbor Advertisement */ 152 #define NET_ICMPV6_MLDv2 143 /* Multicast Listener Report v2 */ 153 154 /* Codes for ICMPv6 Destination Unreachable message */ 155 #define NET_ICMPV6_DST_UNREACH_NO_ROUTE 0 /* No route to destination */ 156 #define NET_ICMPV6_DST_UNREACH_ADMIN 1 /* Admin prohibited communication */ 157 #define NET_ICMPV6_DST_UNREACH_SCOPE 2 /* Beyond scope of source address */ 158 #define NET_ICMPV6_DST_UNREACH_NO_ADDR 3 /* Address unreachable */ 159 #define NET_ICMPV6_DST_UNREACH_NO_PORT 4 /* Port unreachable */ 160 #define NET_ICMPV6_DST_UNREACH_SRC_ADDR 5 /* Source address failed */ 161 #define NET_ICMPV6_DST_UNREACH_REJ_ROUTE 6 /* Reject route to destination */ 162 163 /* Codes for ICMPv6 Parameter Problem message */ 164 #define NET_ICMPV6_PARAM_PROB_HEADER 0 /* Erroneous header field */ 165 #define NET_ICMPV6_PARAM_PROB_NEXTHEADER 1 /* Unrecognized next header */ 166 #define NET_ICMPV6_PARAM_PROB_OPTION 2 /* Unrecognized option */ 167 168 /* ICMPv6 header has 4 unused bytes that must be zero, RFC 4443 ch 3.1 */ 169 #define NET_ICMPV6_UNUSED_LEN 4 170 171 const char *net_icmpv6_type2str(int icmpv6_type); 172 173 /** 174 * @brief Send ICMPv6 error message. 175 * @param pkt Network packet that this error is related to. 176 * @param type Type of the error message. 177 * @param code Code of the type of the error message. 178 * @param param Optional parameter value for this error. Depending on type 179 * and code this gives extra information to the recipient. Set 0 if unsure 180 * what value to use. 181 * @return Return 0 if the sending succeed, <0 otherwise. 182 */ 183 int net_icmpv6_send_error(struct net_pkt *pkt, uint8_t type, uint8_t code, 184 uint32_t param); 185 186 #if defined(CONFIG_NET_NATIVE_IPV6) 187 enum net_verdict net_icmpv6_input(struct net_pkt *pkt, 188 struct net_ipv6_hdr *ip_hdr); 189 190 int net_icmpv6_create(struct net_pkt *pkt, uint8_t icmp_type, uint8_t icmp_code); 191 int net_icmpv6_finalize(struct net_pkt *pkt, bool force_chksum); 192 193 void net_icmpv6_init(void); 194 #else 195 #define net_icmpv6_init(...) 196 #endif 197 198 #endif /* __ICMPV6_H */ 199