|  | /** @file | 
|  | * @brief Network packet capture definitions | 
|  | * | 
|  | * Definitions for capturing network packets. | 
|  | */ | 
|  |  | 
|  | /* | 
|  | * Copyright (c) 2021 Intel Corporation | 
|  | * | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  |  | 
|  | #ifndef ZEPHYR_INCLUDE_NET_CAPTURE_H_ | 
|  | #define ZEPHYR_INCLUDE_NET_CAPTURE_H_ | 
|  |  | 
|  | #include <zephyr.h> | 
|  |  | 
|  | #ifdef __cplusplus | 
|  | extern "C" { | 
|  | #endif | 
|  |  | 
|  | /** | 
|  | * @brief Network packet capture support functions | 
|  | * @defgroup capture Network packet capture | 
|  | * @ingroup networking | 
|  | * @{ | 
|  | */ | 
|  |  | 
|  | /** @cond INTERNAL_HIDDEN */ | 
|  |  | 
|  | struct net_if; | 
|  |  | 
|  | struct net_capture_interface_api { | 
|  | /** Cleanup the setup. This will also disable capturing. After this | 
|  | * call, the setup function can be called again. | 
|  | */ | 
|  | int (*cleanup)(const struct device *dev); | 
|  |  | 
|  | /** Enable / start capturing data */ | 
|  | int (*enable)(const struct device *dev, struct net_if *iface); | 
|  |  | 
|  | /** Disable / stop capturing data */ | 
|  | int (*disable)(const struct device *dev); | 
|  |  | 
|  | /** Is capturing enabled (returns true) or disabled (returns false). | 
|  | */ | 
|  | bool (*is_enabled)(const struct device *dev); | 
|  |  | 
|  | /** Send captured data */ | 
|  | int (*send)(const struct device *dev, struct net_if *iface, | 
|  | struct net_pkt *pkt); | 
|  | }; | 
|  |  | 
|  | /** @endcond */ | 
|  |  | 
|  | /** | 
|  | * @brief Setup network packet capturing support. | 
|  | * | 
|  | * @param remote_addr The value tells the tunnel remote/outer endpoint | 
|  | *        IP address. The IP address can be either IPv4 or IPv6 address. | 
|  | *        This address is used to select the network interface where the tunnel | 
|  | *        is created. | 
|  | * @param my_local_addr The local/inner IP address of the tunnel. Can contain | 
|  | *        also port number which is used as UDP source port. | 
|  | * @param peer_addr The peer/inner IP address of the tunnel. Can contain | 
|  | *        also port number which is used as UDP destination port. | 
|  | * @param dev Network capture device. This is returned to the caller. | 
|  | * | 
|  | * @return 0 if ok, <0 if network packet capture setup failed | 
|  | */ | 
|  | int net_capture_setup(const char *remote_addr, const char *my_local_addr, | 
|  | const char *peer_addr, const struct device **dev); | 
|  |  | 
|  | /** | 
|  | * @brief Cleanup network packet capturing support. | 
|  | * | 
|  | * @details This should be called after the capturing is done and resources | 
|  | *          can be released. | 
|  | * | 
|  | * @param dev Network capture device. User must allocate using the | 
|  | *            net_capture_setup() function. | 
|  | * | 
|  | * @return 0 if ok, <0 if network packet capture cleanup failed | 
|  | */ | 
|  | static inline int net_capture_cleanup(const struct device *dev) | 
|  | { | 
|  | #if defined(CONFIG_NET_CAPTURE) | 
|  | const struct net_capture_interface_api *api = | 
|  | (const struct net_capture_interface_api *)dev->api; | 
|  |  | 
|  | return api->cleanup(dev); | 
|  | #else | 
|  | ARG_UNUSED(dev); | 
|  |  | 
|  | return -ENOTSUP; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @brief Enable network packet capturing support. | 
|  | * | 
|  | * @details This creates tunnel network interface where all the | 
|  | * captured packets are pushed. The captured network packets are | 
|  | * placed in UDP packets that are sent to tunnel peer. | 
|  | * | 
|  | * @param dev Network capture device | 
|  | * @param iface Network interface we are starting to capture packets. | 
|  | * | 
|  | * @return 0 if ok, <0 if network packet capture enable failed | 
|  | */ | 
|  | static inline int net_capture_enable(const struct device *dev, | 
|  | struct net_if *iface) | 
|  | { | 
|  | #if defined(CONFIG_NET_CAPTURE) | 
|  | const struct net_capture_interface_api *api = | 
|  | (const struct net_capture_interface_api *)dev->api; | 
|  |  | 
|  | return api->enable(dev, iface); | 
|  | #else | 
|  | ARG_UNUSED(dev); | 
|  | ARG_UNUSED(iface); | 
|  |  | 
|  | return -ENOTSUP; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @brief Is network packet capture enabled or disabled. | 
|  | * | 
|  | * @param dev Network capture device | 
|  | * | 
|  | * @return True if enabled, False if network capture is disabled. | 
|  | */ | 
|  | static inline bool net_capture_is_enabled(const struct device *dev) | 
|  | { | 
|  | #if defined(CONFIG_NET_CAPTURE) | 
|  | const struct net_capture_interface_api *api = | 
|  | (const struct net_capture_interface_api *)dev->api; | 
|  |  | 
|  | return api->is_enabled(dev); | 
|  | #else | 
|  | ARG_UNUSED(dev); | 
|  |  | 
|  | return -ENOTSUP; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @brief Disable network packet capturing support. | 
|  | * | 
|  | * @param dev Network capture device | 
|  | * | 
|  | * @return 0 if ok, <0 if network packet capture disable failed | 
|  | */ | 
|  | static inline int net_capture_disable(const struct device *dev) | 
|  | { | 
|  | #if defined(CONFIG_NET_CAPTURE) | 
|  | const struct net_capture_interface_api *api = | 
|  | (const struct net_capture_interface_api *)dev->api; | 
|  |  | 
|  | return api->disable(dev); | 
|  | #else | 
|  | ARG_UNUSED(dev); | 
|  |  | 
|  | return -ENOTSUP; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @brief Send captured packet. | 
|  | * | 
|  | * @param dev Network capture device | 
|  | * @param iface Network interface the packet is being sent | 
|  | * @param pkt The network packet that is sent | 
|  | * | 
|  | * @return 0 if ok, <0 if network packet capture send failed | 
|  | */ | 
|  | static inline int net_capture_send(const struct device *dev, | 
|  | struct net_if *iface, | 
|  | struct net_pkt *pkt) | 
|  | { | 
|  | #if defined(CONFIG_NET_CAPTURE) | 
|  | const struct net_capture_interface_api *api = | 
|  | (const struct net_capture_interface_api *)dev->api; | 
|  |  | 
|  | return api->send(dev, iface, pkt); | 
|  | #else | 
|  | ARG_UNUSED(dev); | 
|  | ARG_UNUSED(iface); | 
|  | ARG_UNUSED(pkt); | 
|  |  | 
|  | return -ENOTSUP; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /** @cond INTERNAL_HIDDEN */ | 
|  |  | 
|  | /** | 
|  | * @brief Check if the network packet needs to be captured or not. | 
|  | *        This is called for every network packet being sent. | 
|  | * | 
|  | * @param iface Network interface the packet is being sent | 
|  | * @param pkt The network packet that is sent | 
|  | * | 
|  | * @return 0 if ok, <0 if network packet capture failed | 
|  | */ | 
|  | #if defined(CONFIG_NET_CAPTURE) | 
|  | void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt); | 
|  | #else | 
|  | static inline void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt) | 
|  | { | 
|  | ARG_UNUSED(iface); | 
|  | ARG_UNUSED(pkt); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | struct net_capture_info { | 
|  | const struct device *capture_dev; | 
|  | struct net_if *capture_iface; | 
|  | struct net_if *tunnel_iface; | 
|  | struct sockaddr *peer; | 
|  | struct sockaddr *local; | 
|  | bool is_enabled; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @typedef net_capture_cb_t | 
|  | * @brief Callback used while iterating over capture devices | 
|  | * | 
|  | * @param info Information about capture device | 
|  | * @param user_data A valid pointer to user data or NULL | 
|  | */ | 
|  | typedef void (*net_capture_cb_t)(struct net_capture_info *info, | 
|  | void *user_data); | 
|  |  | 
|  | /** | 
|  | * @brief Go through all the capture devices in order to get | 
|  | *        information about them. This is mainly useful in | 
|  | *        net-shell to print data about currently active | 
|  | *        captures. | 
|  | * | 
|  | * @param cb Callback to call for each capture device | 
|  | * @param user_data User supplied data | 
|  | */ | 
|  | #if defined(CONFIG_NET_CAPTURE) | 
|  | void net_capture_foreach(net_capture_cb_t cb, void *user_data); | 
|  | #else | 
|  | static inline void net_capture_foreach(net_capture_cb_t cb, void *user_data) | 
|  | { | 
|  | ARG_UNUSED(cb); | 
|  | ARG_UNUSED(user_data); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /** @endcond */ | 
|  |  | 
|  | /** | 
|  | * @} | 
|  | */ | 
|  |  | 
|  | #ifdef __cplusplus | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #endif /* ZEPHYR_INCLUDE_NET_CAPTURE_H_ */ |