* 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,
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;
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);
}
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;
}
}
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 */
* 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;
eloop_unregister_read_sock(l2->fd);
/* TODO: close connection */
}
-
+
os_free(l2);
}
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;
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;
}
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 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);