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 <j@w1.fi>
This commit is contained in:
Jouni Malinen 2020-04-19 16:36:47 +03:00
parent 95cbf45090
commit 7a880b129d
8 changed files with 20 additions and 9 deletions

View file

@ -61,6 +61,10 @@ enum l2_packet_filter_type {
* points to len bytes of the payload after the layer 2 header and similarly, * 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 * 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. * 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( struct l2_packet_data * l2_packet_init(
const char *ifname, const u8 *own_addr, unsigned short protocol, const char *ifname, const u8 *own_addr, unsigned short protocol,

View file

@ -84,7 +84,7 @@ static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx)
packet = pcap_next(pcap, &hdr); packet = pcap_next(pcap, &hdr);
if (packet == NULL || hdr.caplen < sizeof(*ethhdr)) if (!l2->rx_callback || !packet || hdr.caplen < sizeof(*ethhdr))
return; return;
ethhdr = (struct l2_ethhdr *) packet; ethhdr = (struct l2_ethhdr *) packet;

View file

@ -312,7 +312,8 @@ struct l2_packet_data * l2_packet_init(
ll.sll_family = PF_PACKET; ll.sll_family = PF_PACKET;
ll.sll_ifindex = ifr.ifr_ifindex; ll.sll_ifindex = ifr.ifr_ifindex;
ll.sll_protocol = htons(protocol); 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", wpa_printf(MSG_ERROR, "%s: bind[PF_PACKET]: %s",
__func__, strerror(errno)); __func__, strerror(errno));
close(l2->fd); 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); 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; return l2;
} }

View file

@ -294,7 +294,8 @@ static void l2_packet_callback(struct l2_packet_data *l2)
} }
rx_src = ethhdr->h_source; 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 #ifndef _WIN32_WCE
l2_ndisuio_start_read(l2, 1); l2_ndisuio_start_read(l2, 1);
#endif /* _WIN32_WCE */ #endif /* _WIN32_WCE */

View file

@ -84,7 +84,7 @@ struct l2_packet_data * l2_packet_init(
* TODO: open connection for receiving frames * TODO: open connection for receiving frames
*/ */
l2->fd = -1; l2->fd = -1;
if (l2->fd >= 0) if (rx_callback && l2->fd >= 0)
eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL);
return l2; return l2;
@ -112,7 +112,7 @@ void l2_packet_deinit(struct l2_packet_data *l2)
eloop_unregister_read_sock(l2->fd); eloop_unregister_read_sock(l2->fd);
/* TODO: close connection */ /* TODO: close connection */
} }
os_free(l2); os_free(l2);
} }

View file

@ -127,7 +127,7 @@ static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx)
packet = pcap_next(pcap, &hdr); packet = pcap_next(pcap, &hdr);
if (packet == NULL || hdr.caplen < sizeof(*ethhdr)) if (!l2->rx_callback || !packet || hdr.caplen < sizeof(*ethhdr))
return; return;
ethhdr = (struct l2_ethhdr *) packet; 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; unsigned char *buf;
size_t len; size_t len;
if (pkt_data == NULL || hdr->caplen < sizeof(*ethhdr)) if (!l2->rx_callback || !pkt_data || hdr->caplen < sizeof(*ethhdr))
return; return;
ethhdr = (struct l2_ethhdr *) pkt_data; ethhdr = (struct l2_ethhdr *) pkt_data;

View file

@ -216,7 +216,8 @@ struct l2_packet_data * l2_packet_init(
} }
os_memcpy(l2->own_addr, reply, ETH_ALEN); 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; return l2;

View file

@ -224,6 +224,9 @@ struct l2_packet_data * l2_packet_init(
return NULL; return NULL;
} }
if (!rx_callback)
return l2;
l2->rx_avail = CreateEvent(NULL, TRUE, FALSE, NULL); l2->rx_avail = CreateEvent(NULL, TRUE, FALSE, NULL);
l2->rx_done = CreateEvent(NULL, TRUE, FALSE, NULL); l2->rx_done = CreateEvent(NULL, TRUE, FALSE, NULL);
l2->rx_notify = CreateEvent(NULL, TRUE, FALSE, NULL); l2->rx_notify = CreateEvent(NULL, TRUE, FALSE, NULL);