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,
* 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,

View File

@ -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;

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);