From 6417651bf4ba217e6590f12e25f5fd48d76dc65a Mon Sep 17 00:00:00 2001 From: Martin Schwenke Date: Mon, 15 Aug 2022 10:51:47 +1000 Subject: [PATCH] ctdb-common: Support "any" interface for pcap-based capture This uses Linux cooked capture link-layer headers. See: https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL2.html The header type needs to be checked to ensure the protocol type (i.e. ether type, for the protocols we might be interested in) is meaningful. The size of the header needs to be known so it can be skipped, allowing the IP header to be found and parsed. It would be possible to define support for DLT_LINUX_SLL2 if it is missing. However, if a platform is missing support in the header file then it is almost certainly missing in the run-time library too. Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs (cherry picked from commit e5541a7e0220a88d59d574d501626b0598050c52) --- ctdb/common/system_socket.c | 50 ++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/ctdb/common/system_socket.c b/ctdb/common/system_socket.c index 51f5d030906..9f7ca07e098 100644 --- a/ctdb/common/system_socket.c +++ b/ctdb/common/system_socket.c @@ -967,12 +967,18 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data, #include +/* + * Assume this exists if pcap.h exists - it has been around for a + * while + */ +#include + int ctdb_sys_open_capture_socket(const char *iface, void **private_data) { char errbuf[PCAP_ERRBUF_SIZE]; pcap_t *pt; int pcap_packet_type; - const char *t; + const char *t = NULL; int fd; pt = pcap_open_live(iface, 100, 0, 0, errbuf); @@ -989,6 +995,14 @@ int ctdb_sys_open_capture_socket(const char *iface, void **private_data) case DLT_EN10MB: t = "DLT_EN10MB"; break; + case DLT_LINUX_SLL: + t = "DLT_LINUX_SLL"; + break; +#ifdef DLT_LINUX_SLL2 + case DLT_LINUX_SLL2: + t = "DLT_LINUX_SLL2"; + break; +#endif /* DLT_LINUX_SLL2 */ default: DBG_ERR("Unknown pcap packet type %d\n", pcap_packet_type); pcap_close(pt); @@ -1044,6 +1058,40 @@ int ctdb_sys_read_tcp_packet(int s, ll_hdr_len = sizeof(struct ether_header); break; } + case DLT_LINUX_SLL: { + const struct sll_header *sll = + (const struct sll_header *)buffer; + uint16_t arphrd_type = ntohs(sll->sll_hatype); + switch (arphrd_type) { + case ARPHRD_ETHER: + break; + default: + DBG_DEBUG("SLL: Unknown arphrd_type %"PRIu16"\n", + arphrd_type); + return EPROTONOSUPPORT; + } + ether_type = ntohs(sll->sll_protocol); + ll_hdr_len = SLL_HDR_LEN; + break; + } +#ifdef DLT_LINUX_SLL2 + case DLT_LINUX_SLL2: { + const struct sll2_header *sll2 = + (const struct sll2_header *)buffer; + uint16_t arphrd_type = ntohs(sll2->sll2_hatype); + switch (arphrd_type) { + case ARPHRD_ETHER: + break; + default: + DBG_DEBUG("SLL2: Unknown arphrd_type %"PRIu16"\n", + arphrd_type); + return EPROTONOSUPPORT; + } + ether_type = ntohs(sll2->sll2_protocol); + ll_hdr_len = SLL2_HDR_LEN; + break; + } +#endif /* DLT_LINUX_SLL2 */ default: DBG_DEBUG("Unknown pcap packet type %d\n", pcap_packet_type); return EPROTONOSUPPORT; -- 2.34.1