/** @file * @brief Promiscuous mode support * * Allow user to receive all network packets that are seen by a * network interface. This requires that network device driver * supports promiscuous mode. */ /* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include LOG_MODULE_REGISTER(net_promisc, CONFIG_NET_PROMISC_LOG_LEVEL); #include #include #include #include #include static K_FIFO_DEFINE(promiscuous_queue); static atomic_t enabled = ATOMIC_INIT(0); struct net_pkt *net_promisc_mode_wait_data(k_timeout_t timeout) { return k_fifo_get(&promiscuous_queue, timeout); } int net_promisc_mode_on(struct net_if *iface) { int ret; if (!iface) { return -EINVAL; } ret = net_if_set_promisc(iface); if (!ret) { atomic_inc(&enabled); } return ret; } static void flush_queue(void) { struct net_pkt *pkt; while (1) { pkt = k_fifo_get(&promiscuous_queue, K_NO_WAIT); if (!pkt) { return; } net_pkt_unref(pkt); } } int net_promisc_mode_off(struct net_if *iface) { atomic_val_t prev; bool ret; ret = net_if_is_promisc(iface); if (ret) { net_if_unset_promisc(iface); prev = atomic_dec(&enabled); if (prev == 1) { atomic_clear(&enabled); flush_queue(); } return 0; } return -EALREADY; } enum net_verdict net_promisc_mode_input(struct net_pkt *pkt) { if (!pkt) { return NET_CONTINUE; } if (!atomic_get(&enabled)) { return NET_DROP; } k_fifo_put(&promiscuous_queue, pkt); return NET_OK; }