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