From 7a880b129de8f439324ab0c04a20417af022a29c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 19 Apr 2020 16:36:47 +0300 Subject: [PATCH] l2_packet: Allow initialization without RX handling This can be used to minimize resource use when receive path is not needed. Signed-off-by: Jouni Malinen --- src/l2_packet/l2_packet.h | 4 ++++ src/l2_packet/l2_packet_freebsd.c | 2 +- src/l2_packet/l2_packet_linux.c | 6 ++++-- src/l2_packet/l2_packet_ndis.c | 3 ++- src/l2_packet/l2_packet_none.c | 4 ++-- src/l2_packet/l2_packet_pcap.c | 4 ++-- src/l2_packet/l2_packet_privsep.c | 3 ++- src/l2_packet/l2_packet_winpcap.c | 3 +++ 8 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/l2_packet/l2_packet.h b/src/l2_packet/l2_packet.h index 53871774b..6a862806f 100644 --- a/src/l2_packet/l2_packet.h +++ b/src/l2_packet/l2_packet.h @@ -61,6 +61,10 @@ enum l2_packet_filter_type { * points to len bytes of the payload after the layer 2 header and similarly, * TX buffers start with payload. This behavior can be changed by setting * l2_hdr=1 to include the layer 2 header in the data buffer. + * + * IF rx_callback is NULL, receive operation is not opened at all, i.e., only + * the TX path and additional helper functions for fetching MAC and IP + * addresses can be used. */ struct l2_packet_data * l2_packet_init( const char *ifname, const u8 *own_addr, unsigned short protocol, diff --git a/src/l2_packet/l2_packet_freebsd.c b/src/l2_packet/l2_packet_freebsd.c index aa8364827..60de9fe6b 100644 --- a/src/l2_packet/l2_packet_freebsd.c +++ b/src/l2_packet/l2_packet_freebsd.c @@ -84,7 +84,7 @@ static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) packet = pcap_next(pcap, &hdr); - if (packet == NULL || hdr.caplen < sizeof(*ethhdr)) + if (!l2->rx_callback || !packet || hdr.caplen < sizeof(*ethhdr)) return; ethhdr = (struct l2_ethhdr *) packet; diff --git a/src/l2_packet/l2_packet_linux.c b/src/l2_packet/l2_packet_linux.c index 138dcafcf..7897bc026 100644 --- a/src/l2_packet/l2_packet_linux.c +++ b/src/l2_packet/l2_packet_linux.c @@ -312,7 +312,8 @@ struct l2_packet_data * l2_packet_init( ll.sll_family = PF_PACKET; ll.sll_ifindex = ifr.ifr_ifindex; ll.sll_protocol = htons(protocol); - if (bind(l2->fd, (struct sockaddr *) &ll, sizeof(ll)) < 0) { + if (rx_callback && + bind(l2->fd, (struct sockaddr *) &ll, sizeof(ll)) < 0) { wpa_printf(MSG_ERROR, "%s: bind[PF_PACKET]: %s", __func__, strerror(errno)); close(l2->fd); @@ -329,7 +330,8 @@ struct l2_packet_data * l2_packet_init( } os_memcpy(l2->own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); - eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); + if (rx_callback) + eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); return l2; } diff --git a/src/l2_packet/l2_packet_ndis.c b/src/l2_packet/l2_packet_ndis.c index 716778164..4a4b639fd 100644 --- a/src/l2_packet/l2_packet_ndis.c +++ b/src/l2_packet/l2_packet_ndis.c @@ -294,7 +294,8 @@ static void l2_packet_callback(struct l2_packet_data *l2) } rx_src = ethhdr->h_source; - l2->rx_callback(l2->rx_callback_ctx, rx_src, rx_buf, rx_len); + if (l2->rx_callback) + l2->rx_callback(l2->rx_callback_ctx, rx_src, rx_buf, rx_len); #ifndef _WIN32_WCE l2_ndisuio_start_read(l2, 1); #endif /* _WIN32_WCE */ diff --git a/src/l2_packet/l2_packet_none.c b/src/l2_packet/l2_packet_none.c index 307fc6daa..bc7a4e82d 100644 --- a/src/l2_packet/l2_packet_none.c +++ b/src/l2_packet/l2_packet_none.c @@ -84,7 +84,7 @@ struct l2_packet_data * l2_packet_init( * TODO: open connection for receiving frames */ l2->fd = -1; - if (l2->fd >= 0) + if (rx_callback && l2->fd >= 0) eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); return l2; @@ -112,7 +112,7 @@ void l2_packet_deinit(struct l2_packet_data *l2) eloop_unregister_read_sock(l2->fd); /* TODO: close connection */ } - + os_free(l2); } diff --git a/src/l2_packet/l2_packet_pcap.c b/src/l2_packet/l2_packet_pcap.c index 423c099fd..c2b17fcf8 100644 --- a/src/l2_packet/l2_packet_pcap.c +++ b/src/l2_packet/l2_packet_pcap.c @@ -127,7 +127,7 @@ static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) packet = pcap_next(pcap, &hdr); - if (packet == NULL || hdr.caplen < sizeof(*ethhdr)) + if (!l2->rx_callback || !packet || hdr.caplen < sizeof(*ethhdr)) return; ethhdr = (struct l2_ethhdr *) packet; @@ -152,7 +152,7 @@ static void l2_packet_receive_cb(u_char *user, const struct pcap_pkthdr *hdr, unsigned char *buf; size_t len; - if (pkt_data == NULL || hdr->caplen < sizeof(*ethhdr)) + if (!l2->rx_callback || !pkt_data || hdr->caplen < sizeof(*ethhdr)) return; ethhdr = (struct l2_ethhdr *) pkt_data; diff --git a/src/l2_packet/l2_packet_privsep.c b/src/l2_packet/l2_packet_privsep.c index ce86802c2..014a45f34 100644 --- a/src/l2_packet/l2_packet_privsep.c +++ b/src/l2_packet/l2_packet_privsep.c @@ -216,7 +216,8 @@ struct l2_packet_data * l2_packet_init( } os_memcpy(l2->own_addr, reply, ETH_ALEN); - eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); + if (rx_callback) + eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); return l2; diff --git a/src/l2_packet/l2_packet_winpcap.c b/src/l2_packet/l2_packet_winpcap.c index 74085a316..3452051f5 100644 --- a/src/l2_packet/l2_packet_winpcap.c +++ b/src/l2_packet/l2_packet_winpcap.c @@ -224,6 +224,9 @@ struct l2_packet_data * l2_packet_init( return NULL; } + if (!rx_callback) + return l2; + l2->rx_avail = CreateEvent(NULL, TRUE, FALSE, NULL); l2->rx_done = CreateEvent(NULL, TRUE, FALSE, NULL); l2->rx_notify = CreateEvent(NULL, TRUE, FALSE, NULL);