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