1 /** @file 2 * @brief Promiscuous mode support 3 * 4 * Allow user to receive all network packets that are seen by a 5 * network interface. This requires that network device driver 6 * supports promiscuous mode. 7 */ 8 9 /* 10 * Copyright (c) 2018 Intel Corporation 11 * 12 * SPDX-License-Identifier: Apache-2.0 13 */ 14 15 #include <zephyr/logging/log.h> 16 LOG_MODULE_REGISTER(net_promisc, CONFIG_NET_PROMISC_LOG_LEVEL); 17 18 #include <zephyr/kernel.h> 19 #include <errno.h> 20 21 #include <zephyr/net/net_if.h> 22 #include <zephyr/net/net_core.h> 23 #include <zephyr/net/net_pkt.h> 24 25 static K_FIFO_DEFINE(promiscuous_queue); 26 static atomic_t enabled = ATOMIC_INIT(0); 27 net_promisc_mode_wait_data(k_timeout_t timeout)28struct net_pkt *net_promisc_mode_wait_data(k_timeout_t timeout) 29 { 30 return k_fifo_get(&promiscuous_queue, timeout); 31 } 32 net_promisc_mode_on(struct net_if * iface)33int net_promisc_mode_on(struct net_if *iface) 34 { 35 int ret; 36 37 if (!iface) { 38 return -EINVAL; 39 } 40 41 ret = net_if_set_promisc(iface); 42 if (!ret) { 43 atomic_inc(&enabled); 44 } 45 46 return ret; 47 } 48 flush_queue(void)49static void flush_queue(void) 50 { 51 struct net_pkt *pkt; 52 53 while (1) { 54 pkt = k_fifo_get(&promiscuous_queue, K_NO_WAIT); 55 if (!pkt) { 56 return; 57 } 58 59 net_pkt_unref(pkt); 60 } 61 } 62 net_promisc_mode_off(struct net_if * iface)63int net_promisc_mode_off(struct net_if *iface) 64 { 65 atomic_val_t prev; 66 bool ret; 67 68 ret = net_if_is_promisc(iface); 69 if (ret) { 70 net_if_unset_promisc(iface); 71 72 prev = atomic_dec(&enabled); 73 if (prev == 1) { 74 atomic_clear(&enabled); 75 76 flush_queue(); 77 } 78 79 return 0; 80 } 81 82 return -EALREADY; 83 } 84 net_promisc_mode_input(struct net_pkt * pkt)85enum net_verdict net_promisc_mode_input(struct net_pkt *pkt) 86 { 87 if (!pkt) { 88 return NET_CONTINUE; 89 } 90 91 if (!atomic_get(&enabled)) { 92 return NET_DROP; 93 } 94 95 k_fifo_put(&promiscuous_queue, pkt); 96 97 return NET_OK; 98 } 99