Line data Source code
1 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 1 : #define NET_ICMPV4_ECHO_REQUEST 8 /**< ICMPv4 Echo-Request */ 34 1 : #define NET_ICMPV4_ECHO_REPLY 0 /**< ICMPv4 Echo-Reply */ 35 1 : #define NET_ICMPV6_ECHO_REQUEST 128 /**< ICMPv6 Echo-Request */ 36 1 : #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 1 : 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 1 : 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 1 : struct net_icmp_ctx { 84 : /** List node */ 85 1 : sys_snode_t node; 86 : 87 : /** ICMP response handler */ 88 1 : net_icmp_handler_t handler; 89 : 90 : /** Network interface where the ICMP request was sent */ 91 1 : struct net_if *iface; 92 : 93 : /** Opaque user supplied data */ 94 1 : void *user_data; 95 : 96 : /** ICMP type of the response we are waiting */ 97 1 : uint8_t type; 98 : 99 : /** ICMP code of the response type we are waiting */ 100 1 : uint8_t code; 101 : }; 102 : 103 : /** 104 : * @brief Struct presents either IPv4 or IPv6 header in ICMP response message. 105 : */ 106 1 : struct net_icmp_ip_hdr { 107 : union { 108 : /** IPv4 header in response message. */ 109 1 : struct net_ipv4_hdr *ipv4; 110 : 111 : /** IPv6 header in response message. */ 112 1 : struct net_ipv6_hdr *ipv6; 113 0 : }; 114 : 115 : /** Is the header IPv4 or IPv6 one. Value of either AF_INET or AF_INET6 */ 116 1 : sa_family_t family; 117 : }; 118 : 119 : /** 120 : * @brief Struct presents parameters that are needed when sending 121 : * Echo-Request (ping) messages. 122 : */ 123 1 : struct net_icmp_ping_params { 124 : /** An identifier to aid in matching Echo Replies to this Echo Request. 125 : * May be zero. 126 : */ 127 1 : uint16_t identifier; 128 : 129 : /** A sequence number to aid in matching Echo Replies to this 130 : * Echo Request. May be zero. 131 : */ 132 1 : 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 1 : uint8_t tc_tos; 138 : 139 : /** Network packet priority. */ 140 1 : int priority; 141 : 142 : /** Arbitrary payload data that will be included in the Echo Reply 143 : * verbatim. May be NULL. 144 : */ 145 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : struct net_icmp_offload { 222 : /** List node */ 223 1 : 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 1 : net_icmp_handler_t handler; 231 : 232 : /** ICMP offloaded ping handler */ 233 1 : net_icmp_offload_ping_handler_t ping_handler; 234 : 235 : /** Offloaded network interface */ 236 1 : 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 1 : 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 1 : 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 1 : 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 : /**@} */