1 /* 2 * Copyright (c) 2023 Nordic Semiconductor ASA 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** @file icmp.h 8 * 9 * @brief ICMP sending and receiving. 10 * 11 * @defgroup icmp Send and receive IPv4 or IPv6 ICMP Echo Request messages. 12 * @since 3.5 13 * @version 0.8.0 14 * @ingroup networking 15 * @{ 16 */ 17 18 #ifndef ZEPHYR_INCLUDE_NET_ICMP_H_ 19 #define ZEPHYR_INCLUDE_NET_ICMP_H_ 20 21 #include <stddef.h> 22 23 #include <zephyr/kernel.h> 24 #include <zephyr/types.h> 25 #include <zephyr/net/net_ip.h> 26 #include <zephyr/net/net_if.h> 27 #include <zephyr/net/net_pkt.h> 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #define NET_ICMPV4_ECHO_REQUEST 8 /**< ICMPv4 Echo-Request */ 34 #define NET_ICMPV4_ECHO_REPLY 0 /**< ICMPv4 Echo-Reply */ 35 #define NET_ICMPV6_ECHO_REQUEST 128 /**< ICMPv6 Echo-Request */ 36 #define NET_ICMPV6_ECHO_REPLY 129 /**< ICMPv6 Echo-Reply */ 37 38 struct net_icmp_ctx; 39 struct net_icmp_ip_hdr; 40 struct net_icmp_ping_params; 41 42 /** 43 * @typedef net_icmp_handler_t 44 * @brief Handler function that is called when ICMP response is received. 45 * 46 * @param ctx ICMP context to use. 47 * @param pkt Received ICMP response network packet. 48 * @param ip_hdr IP header of the packet. 49 * @param icmp_hdr ICMP header of the packet. 50 * @param user_data A valid pointer to user data or NULL 51 */ 52 typedef int (*net_icmp_handler_t)(struct net_icmp_ctx *ctx, 53 struct net_pkt *pkt, 54 struct net_icmp_ip_hdr *ip_hdr, 55 struct net_icmp_hdr *icmp_hdr, 56 void *user_data); 57 58 /** 59 * @typedef net_icmp_offload_ping_handler_t 60 * @brief Handler function that is called when an Echo-Request is sent 61 * to offloaded device. This handler is typically setup by the 62 * device driver so that it can catch the ping request and send 63 * it to the offloaded device. 64 * 65 * @param ctx ICMP context used in this request. 66 * @param iface Network interface, can be set to NULL in which case the 67 * interface is selected according to destination address. 68 * @param dst IP address of the target host. 69 * @param params Echo-Request specific parameters. May be NULL in which case 70 * suitable default parameters are used. 71 * @param user_data User supplied opaque data passed to the handler. May be NULL. 72 * 73 */ 74 typedef int (*net_icmp_offload_ping_handler_t)(struct net_icmp_ctx *ctx, 75 struct net_if *iface, 76 struct sockaddr *dst, 77 struct net_icmp_ping_params *params, 78 void *user_data); 79 80 /** 81 * @brief ICMP context structure. 82 */ 83 struct net_icmp_ctx { 84 /** List node */ 85 sys_snode_t node; 86 87 /** ICMP response handler */ 88 net_icmp_handler_t handler; 89 90 /** Network interface where the ICMP request was sent */ 91 struct net_if *iface; 92 93 /** Opaque user supplied data */ 94 void *user_data; 95 96 /** ICMP type of the response we are waiting */ 97 uint8_t type; 98 99 /** ICMP code of the response type we are waiting */ 100 uint8_t code; 101 }; 102 103 /** 104 * @brief Struct presents either IPv4 or IPv6 header in ICMP response message. 105 */ 106 struct net_icmp_ip_hdr { 107 union { 108 /** IPv4 header in response message. */ 109 struct net_ipv4_hdr *ipv4; 110 111 /** IPv6 header in response message. */ 112 struct net_ipv6_hdr *ipv6; 113 }; 114 115 /** Is the header IPv4 or IPv6 one. Value of either AF_INET or AF_INET6 */ 116 sa_family_t family; 117 }; 118 119 /** 120 * @brief Struct presents parameters that are needed when sending 121 * Echo-Request (ping) messages. 122 */ 123 struct net_icmp_ping_params { 124 /** An identifier to aid in matching Echo Replies to this Echo Request. 125 * May be zero. 126 */ 127 uint16_t identifier; 128 129 /** A sequence number to aid in matching Echo Replies to this 130 * Echo Request. May be zero. 131 */ 132 uint16_t sequence; 133 134 /** Can be either IPv4 Type-of-service field value, or IPv6 Traffic 135 * Class field value. Represents combined DSCP and ECN values. 136 */ 137 uint8_t tc_tos; 138 139 /** Network packet priority. */ 140 int priority; 141 142 /** Arbitrary payload data that will be included in the Echo Reply 143 * verbatim. May be NULL. 144 */ 145 const void *data; 146 147 /** Size of the Payload Data in bytes. May be zero. In case data 148 * pointer is NULL, the function will generate the payload up to 149 * the requested size. 150 */ 151 size_t data_size; 152 }; 153 154 /** 155 * @brief Initialize the ICMP context structure. Must be called before 156 * ICMP messages can be sent. This will register handler to the 157 * system. 158 * 159 * @param ctx ICMP context used in this request. 160 * @param type Type of ICMP message we are handling. 161 * @param code Code of ICMP message we are handling. 162 * @param handler Callback function that is called when a response is received. 163 */ 164 int net_icmp_init_ctx(struct net_icmp_ctx *ctx, uint8_t type, uint8_t code, 165 net_icmp_handler_t handler); 166 167 /** 168 * @brief Cleanup the ICMP context structure. This will unregister the ICMP handler 169 * from the system. 170 * 171 * @param ctx ICMP context used in this request. 172 */ 173 int net_icmp_cleanup_ctx(struct net_icmp_ctx *ctx); 174 175 /** 176 * @brief Send ICMP echo request message. 177 * 178 * @param ctx ICMP context used in this request. 179 * @param iface Network interface, can be set to NULL in which case the 180 * interface is selected according to destination address. 181 * @param dst IP address of the target host. 182 * @param params Echo-Request specific parameters. May be NULL in which case 183 * suitable default parameters are used. 184 * @param user_data User supplied opaque data passed to the handler. May be NULL. 185 * 186 * @return Return 0 if the sending succeed, <0 otherwise. 187 */ 188 int net_icmp_send_echo_request(struct net_icmp_ctx *ctx, 189 struct net_if *iface, 190 struct sockaddr *dst, 191 struct net_icmp_ping_params *params, 192 void *user_data); 193 194 /** 195 * @brief Send ICMP echo request message without waiting during send. 196 * 197 * @details This function can be used to send ICMP Echo-Request from a system 198 * workqueue handler which should not have any sleeps or waits. 199 * This variant will do the net_buf allocations with K_NO_WAIT. 200 * This will avoid a warning message in the log about the timeout. 201 * 202 * @param ctx ICMP context used in this request. 203 * @param iface Network interface, can be set to NULL in which case the 204 * interface is selected according to destination address. 205 * @param dst IP address of the target host. 206 * @param params Echo-Request specific parameters. May be NULL in which case 207 * suitable default parameters are used. 208 * @param user_data User supplied opaque data passed to the handler. May be NULL. 209 * 210 * @return Return 0 if the sending succeed, <0 otherwise. 211 */ 212 int net_icmp_send_echo_request_no_wait(struct net_icmp_ctx *ctx, 213 struct net_if *iface, 214 struct sockaddr *dst, 215 struct net_icmp_ping_params *params, 216 void *user_data); 217 218 /** 219 * @brief ICMP offload context structure. 220 */ 221 struct net_icmp_offload { 222 /** List node */ 223 sys_snode_t node; 224 225 /** 226 * ICMP response handler. Currently there is only one handler. 227 * This means that one offloaded ping request/response can be going 228 * on at the same time. 229 */ 230 net_icmp_handler_t handler; 231 232 /** ICMP offloaded ping handler */ 233 net_icmp_offload_ping_handler_t ping_handler; 234 235 /** Offloaded network interface */ 236 struct net_if *iface; 237 }; 238 239 /** 240 * @brief Register a handler function that is called when an Echo-Request 241 * is sent to the offloaded device. This function is typically 242 * called by a device driver so that it can do the actual offloaded 243 * ping call. 244 * 245 * @param ctx ICMP offload context used for this interface. 246 * @param iface Network interface of the offloaded device. 247 * @param ping_handler Function to be called when offloaded ping request is done. 248 * 249 * @return Return 0 if the register succeed, <0 otherwise. 250 */ 251 int net_icmp_register_offload_ping(struct net_icmp_offload *ctx, 252 struct net_if *iface, 253 net_icmp_offload_ping_handler_t ping_handler); 254 255 /** 256 * @brief Unregister the offload handler. 257 * 258 * @param ctx ICMP offload context used for this interface. 259 * 260 * @return Return 0 if the call succeed, <0 otherwise. 261 */ 262 int net_icmp_unregister_offload_ping(struct net_icmp_offload *ctx); 263 264 /** 265 * @brief Get a ICMP response handler function for an offloaded device. 266 * When a ping response is received by the driver, it should call 267 * the handler function with proper parameters so that the ICMP response 268 * is received by the net stack. 269 * 270 * @param ctx ICMP offload context used in this request. 271 * @param resp_handler Function to be called when offloaded ping response 272 * is received by the offloaded driver. The ICMP response handler 273 * function is returned and the caller should call it when appropriate. 274 * 275 * @return Return 0 if the call succeed, <0 otherwise. 276 */ 277 int net_icmp_get_offload_rsp_handler(struct net_icmp_offload *ctx, 278 net_icmp_handler_t *resp_handler); 279 280 #ifdef __cplusplus 281 } 282 #endif 283 284 #endif /* ZEPHYR_INCLUDE_NET_ICMP_H */ 285 286 /**@} */ 287