[MERGED] libosmo-netif[master]: tests: osmo-pcap: Allow different l2 pkts

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Wed Aug 9 09:55:32 UTC 2017


Harald Welte has submitted this change and it was merged.

Change subject: tests: osmo-pcap: Allow different l2 pkts
......................................................................


tests: osmo-pcap: Allow different l2 pkts

Before this patch, ETH was assumed and other types were not supported.
This patch also adds Linux cooked packet support for L2.

Change-Id: Ie62fa0a8e45e1e141edb64b116dad185ad9c7a5f
---
M tests/osmo-pcap-test/Makefile.am
A tests/osmo-pcap-test/l2_eth.c
A tests/osmo-pcap-test/l2_sll.c
M tests/osmo-pcap-test/l3_ipv4.c
M tests/osmo-pcap-test/l4_tcp.c
M tests/osmo-pcap-test/l4_udp.c
M tests/osmo-pcap-test/pcap.c
M tests/osmo-pcap-test/proto.c
M tests/osmo-pcap-test/proto.h
9 files changed, 189 insertions(+), 50 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/tests/osmo-pcap-test/Makefile.am b/tests/osmo-pcap-test/Makefile.am
index a256005..3e5bdf1 100644
--- a/tests/osmo-pcap-test/Makefile.am
+++ b/tests/osmo-pcap-test/Makefile.am
@@ -3,6 +3,8 @@
 check_PROGRAMS = osmo-pcap-test
 
 osmo_pcap_test_SOURCES = proto.c		\
+			 l2_eth.c		\
+			 l2_sll.c		\
 			 l3_ipv4.c		\
 			 l4_tcp.c		\
 			 l4_udp.c		\
diff --git a/tests/osmo-pcap-test/l2_eth.c b/tests/osmo-pcap-test/l2_eth.c
new file mode 100644
index 0000000..3171fd7
--- /dev/null
+++ b/tests/osmo-pcap-test/l2_eth.c
@@ -0,0 +1,48 @@
+/*
+ * (C) 2012 by Pablo Neira Ayuso <pablo at gnumonks.org>
+ * (C) 2012 by On Waves ehf <http://www.on-waves.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later vers
+ */
+
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <linux/if_ether.h>
+#include <pcap/dlt.h>
+
+#include "proto.h"
+
+#define PRINT_CMP(...)
+
+static int unsigned l2_eth_pkt_l3proto_num(const uint8_t *pkt)
+{
+	const struct ethhdr *eh = (const struct ethhdr *)pkt;
+	switch(ntohs(eh->h_proto)) {
+	case ETH_P_IP:
+		return htons(AF_INET);
+	default:
+		return eh->h_proto;
+	}
+}
+
+static unsigned int l2_eth_pkt_l2hdr_len(const uint8_t *pkt)
+{
+
+	return ETH_HLEN;
+}
+
+static struct osmo_pcap_proto_l2 eth = {
+	//.l2protonum	= ETH_P_IP,
+	.l2protonum	= DLT_EN10MB,
+	.l2pkt_hdr_len	= l2_eth_pkt_l2hdr_len,
+	.l3pkt_proto	= l2_eth_pkt_l3proto_num,
+};
+
+void l2_eth_init(void)
+{
+	osmo_pcap_proto_l2_register(&eth);
+}
diff --git a/tests/osmo-pcap-test/l2_sll.c b/tests/osmo-pcap-test/l2_sll.c
new file mode 100644
index 0000000..5a600ff
--- /dev/null
+++ b/tests/osmo-pcap-test/l2_sll.c
@@ -0,0 +1,47 @@
+/*
+ * (C) 2012 by Pablo Neira Ayuso <pablo at gnumonks.org>
+ * (C) 2012 by On Waves ehf <http://www.on-waves.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later vers
+ */
+
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <linux/if_ether.h>
+#include <pcap/sll.h>
+#include <pcap/dlt.h>
+
+#include "proto.h"
+
+#define PRINT_CMP(...)
+
+static unsigned int l2_sll_pkt_l3proto_num(const uint8_t *pkt)
+{
+	const struct sll_header *lh = (const struct sll_header *)pkt;
+	switch(ntohs(lh->sll_protocol)) {
+	case ETH_P_IP:
+		return htons(AF_INET);
+	default:
+		return lh->sll_protocol;
+	}
+}
+
+static unsigned int l2_sll_pkt_l2hdr_len(const uint8_t *pkt)
+{
+
+	return SLL_HDR_LEN;
+}
+
+static struct osmo_pcap_proto_l2 sll = {
+	.l2protonum	= DLT_LINUX_SLL,
+	.l2pkt_hdr_len	= l2_sll_pkt_l2hdr_len,
+	.l3pkt_proto	= l2_sll_pkt_l3proto_num,
+};
+
+void l2_sll_init(void)
+{
+	osmo_pcap_proto_l2_register(&sll);
+}
diff --git a/tests/osmo-pcap-test/l3_ipv4.c b/tests/osmo-pcap-test/l3_ipv4.c
index 83e3479..521a803 100644
--- a/tests/osmo-pcap-test/l3_ipv4.c
+++ b/tests/osmo-pcap-test/l3_ipv4.c
@@ -16,29 +16,27 @@
 
 #define PRINT_CMP(...)
 
-static int l3_ipv4_pkt_l4proto_num(const uint8_t *pkt)
+static unsigned int l3_ipv4_pkt_l4proto_num(const uint8_t *pkt)
 {
 	const struct iphdr *iph = (const struct iphdr *)pkt;
 
 	return iph->protocol;
 }
 
-static int l3_ipv4_pkt_l3hdr_len(const uint8_t *pkt)
+static unsigned int l3_ipv4_pkt_l3hdr_len(const uint8_t *pkt)
 {
 	const struct iphdr *iph = (const struct iphdr *)pkt;
 
 	return iph->ihl << 2;
 }
 
-static struct osmo_pcap_proto_l2l3 ipv4 = {
-	.l2protonum	= ETH_P_IP,
+static struct osmo_pcap_proto_l3 ipv4 = {
 	.l3protonum	= AF_INET,
-	.l2hdr_len	= ETH_HLEN,
 	.l3pkt_hdr_len	= l3_ipv4_pkt_l3hdr_len,
 	.l4pkt_proto	= l3_ipv4_pkt_l4proto_num,
 };
 
-void l2l3_ipv4_init(void)
+void l3_ipv4_init(void)
 {
-	osmo_pcap_proto_l2l3_register(&ipv4);
+	osmo_pcap_proto_l3_register(&ipv4);
 }
diff --git a/tests/osmo-pcap-test/l4_tcp.c b/tests/osmo-pcap-test/l4_tcp.c
index 1e024b5..f7aedbd 100644
--- a/tests/osmo-pcap-test/l4_tcp.c
+++ b/tests/osmo-pcap-test/l4_tcp.c
@@ -13,14 +13,14 @@
 
 #include "proto.h"
 
-static int l4_tcp_pkt_hdr_len(const uint8_t *pkt)
+static unsigned int l4_tcp_pkt_hdr_len(const uint8_t *pkt)
 {
 	const struct tcphdr *tcph = (const struct tcphdr *)pkt;
 
 	return tcph->doff << 2;
 }
 
-static int l4_tcp_pkt_no_data(const uint8_t *pkt)
+static unsigned int l4_tcp_pkt_no_data(const uint8_t *pkt)
 {
 	const struct tcphdr *tcph = (const struct tcphdr *)pkt;
 	return tcph->syn || tcph->fin || tcph->rst || !tcph->psh;
diff --git a/tests/osmo-pcap-test/l4_udp.c b/tests/osmo-pcap-test/l4_udp.c
index 9ffa77b..1733908 100644
--- a/tests/osmo-pcap-test/l4_udp.c
+++ b/tests/osmo-pcap-test/l4_udp.c
@@ -13,12 +13,12 @@
 
 #include "proto.h"
 
-static int l4_udp_pkt_hdr_len(const uint8_t *pkt)
+static unsigned int l4_udp_pkt_hdr_len(const uint8_t *pkt)
 {
 	return sizeof(struct udphdr);
 }
 
-static int l4_udp_pkt_no_data(const uint8_t *pkt)
+static unsigned int l4_udp_pkt_no_data(const uint8_t *pkt)
 {
 	/* UDP has no control packets. */
 	return 0;
diff --git a/tests/osmo-pcap-test/pcap.c b/tests/osmo-pcap-test/pcap.c
index 61408f8..f9304b9 100644
--- a/tests/osmo-pcap-test/pcap.c
+++ b/tests/osmo-pcap-test/pcap.c
@@ -34,6 +34,7 @@
 	uint32_t pkts;
 	uint32_t skip;
 	uint32_t processed;
+	uint32_t unsupported_l2;
 	uint32_t unsupported_l3;
 	uint32_t unsupported_l4;
 } osmo_pcap_test_stats;
@@ -41,21 +42,22 @@
 static int
 osmo_pcap_process_packet(struct msgb **msgptr,
 			 const uint8_t *pkt, uint32_t pktlen,
-			 struct osmo_pcap_proto_l2l3 *l3h,
+			 struct osmo_pcap_proto_l2 *l2h,
+			 struct osmo_pcap_proto_l3 *l3h,
 			 struct osmo_pcap_proto_l4 *l4h,
 			 int (*cb)(struct msgb *msgb))
 {
-	unsigned int l3hdr_len, skip_hdr_len;
+	unsigned int l2hdr_len, l3hdr_len, skip_hdr_len;
 	struct msgb *msgb;
-	int ret;
 
 	/* skip layer 2, 3 and 4 headers */
-	l3hdr_len = l3h->l3pkt_hdr_len(pkt + ETH_HLEN);
-	skip_hdr_len = l3h->l2hdr_len + l3hdr_len +
-			l4h->l4pkt_hdr_len(pkt + ETH_HLEN + l3hdr_len);
+	l2hdr_len = l2h->l2pkt_hdr_len(pkt);
+	l3hdr_len = l3h->l3pkt_hdr_len(pkt + l2hdr_len);
+	skip_hdr_len = l2hdr_len + l3hdr_len +
+			l4h->l4pkt_hdr_len(pkt + l2hdr_len + l3hdr_len);
 
 	/* This packet contains no data, skip it. */
-	if (l4h->l4pkt_no_data(pkt + l3hdr_len + ETH_HLEN)) {
+	if (l4h->l4pkt_no_data(pkt + l2hdr_len + l3hdr_len)) {
 		osmo_pcap_test_stats.skip++;
 		return -1;
 	}
@@ -101,10 +103,11 @@
 int
 osmo_pcap_test_run(struct osmo_pcap *p, uint8_t pnum, int (*cb)(struct msgb *msgb))
 {
-	struct osmo_pcap_proto_l2l3 *l3h;
+	struct osmo_pcap_proto_l2 *l2h;
+	struct osmo_pcap_proto_l3 *l3h;
 	struct osmo_pcap_proto_l4 *l4h;
 	struct pcap_pkthdr pcaph;
-	const u_char *pkt;
+	const u_char *l2pkt, *l3pkt;
 	struct timeval res;
 	uint8_t l4protonum;
 
@@ -115,26 +118,34 @@
 	}
 
 retry:
-	pkt = pcap_next(p->h, &pcaph);
-	if (pkt == NULL)
+	l2pkt = pcap_next(p->h, &pcaph);
+	if (l2pkt == NULL)
 		return -1;
 
 	osmo_pcap_test_stats.pkts++;
 
-	l3h = osmo_pcap_proto_l2l3_find(pkt);
+	int linktype = pcap_datalink(p->h);
+	l2h = osmo_pcap_proto_l2_find(linktype);
+	if (l2h == NULL) {
+		osmo_pcap_test_stats.unsupported_l2++;
+		goto retry;
+	}
+
+	l3h = osmo_pcap_proto_l3_find(l2h->l3pkt_proto(l2pkt));
 	if (l3h == NULL) {
 		osmo_pcap_test_stats.unsupported_l3++;
 		goto retry;
 	}
-	l4protonum = l3h->l4pkt_proto(pkt + ETH_HLEN);
 
+	l3pkt = l2pkt + l2h->l2pkt_hdr_len(l2pkt);
+	l4protonum = l3h->l4pkt_proto(l3pkt);
 	/* filter l4 protocols we are not interested in */
 	if (l4protonum != pnum) {
 		osmo_pcap_test_stats.skip++;
 		goto retry;
 	}
 
-	l4h = osmo_pcap_proto_l4_find(pkt, l4protonum);
+	l4h = osmo_pcap_proto_l4_find(l4protonum);
 	if (l4h == NULL) {
 		osmo_pcap_test_stats.unsupported_l4++;
 		goto retry;
@@ -145,7 +156,7 @@
 		memcpy(&p->last, &pcaph.ts, sizeof(struct timeval));
 
 	/* retry with next packet if this has been skipped. */
-	if (osmo_pcap_process_packet(&p->deliver_msg, pkt, pcaph.caplen, l3h, l4h, cb) < 0)
+	if (osmo_pcap_process_packet(&p->deliver_msg, l2pkt, pcaph.caplen, l2h, l3h, l4h, cb) < 0)
 		goto retry;
 
 	/* calculate waiting time */
@@ -161,19 +172,22 @@
 
 void osmo_pcap_stats_printf(void)
 {
-	printf("pkts=%d processed=%d skip=%d "
+	printf("pkts=%d processed=%d skip=%d unsupported_l2=%d "
 		"unsupported_l3=%d unsupported_l4=%d\n",
 		osmo_pcap_test_stats.pkts,
 		osmo_pcap_test_stats.processed,
 		osmo_pcap_test_stats.skip,
+		osmo_pcap_test_stats.unsupported_l2,
 		osmo_pcap_test_stats.unsupported_l3,
 		osmo_pcap_test_stats.unsupported_l4);
 }
 
 void osmo_pcap_init(void)
 {
-	/* Initialization of supported layer 3 and 4 protocols here. */
-	l2l3_ipv4_init();
+	/* Initialization of supported layer 2, 3 and 4 protocols here. */
+	l2_eth_init();
+	l2_sll_init();
+	l3_ipv4_init();
 	l4_tcp_init();
 	l4_udp_init();
 }
diff --git a/tests/osmo-pcap-test/proto.c b/tests/osmo-pcap-test/proto.c
index f90f07c..085ca25 100644
--- a/tests/osmo-pcap-test/proto.c
+++ b/tests/osmo-pcap-test/proto.c
@@ -15,28 +15,46 @@
 #include <osmocom/core/linuxlist.h>
 #include "proto.h"
 
-static LLIST_HEAD(l2l3_proto_list);
+static LLIST_HEAD(l2_proto_list);
+static LLIST_HEAD(l3_proto_list);
 static LLIST_HEAD(l4_proto_list);
+#include <stdio.h>
 
-struct osmo_pcap_proto_l2l3 *osmo_pcap_proto_l2l3_find(const uint8_t *pkt)
+struct osmo_pcap_proto_l2 *osmo_pcap_proto_l2_find(unsigned int pcap_linktype)
 {
-	const struct ethhdr *eh = (const struct ethhdr *)pkt;
-	struct osmo_pcap_proto_l2l3 *cur;
+	struct osmo_pcap_proto_l2 *cur;
 
-	llist_for_each_entry(cur, &l2l3_proto_list, head) {
-		if (ntohs(cur->l2protonum) == eh->h_proto)
+	llist_for_each_entry(cur, &l2_proto_list, head) {
+		if (cur->l2protonum == pcap_linktype)
 			return cur;
 	}
 	return NULL;
 }
 
-void osmo_pcap_proto_l2l3_register(struct osmo_pcap_proto_l2l3 *h)
+void osmo_pcap_proto_l2_register(struct osmo_pcap_proto_l2 *h)
 {
-	llist_add(&h->head, &l2l3_proto_list);
+	llist_add(&h->head, &l2_proto_list);
+}
+
+
+struct osmo_pcap_proto_l3 *osmo_pcap_proto_l3_find(unsigned int l3protocol)
+{
+	struct osmo_pcap_proto_l3 *cur;
+
+	llist_for_each_entry(cur, &l3_proto_list, head) {
+		if (ntohs(cur->l3protonum) == l3protocol)
+			return cur;
+	}
+	return NULL;
+}
+
+void osmo_pcap_proto_l3_register(struct osmo_pcap_proto_l3 *h)
+{
+	llist_add(&h->head, &l3_proto_list);
 }
 
 struct osmo_pcap_proto_l4 *
-osmo_pcap_proto_l4_find(const uint8_t *pkt, unsigned int l4protocol)
+osmo_pcap_proto_l4_find(unsigned int l4protocol)
 {
 	struct osmo_pcap_proto_l4 *cur;
 
diff --git a/tests/osmo-pcap-test/proto.h b/tests/osmo-pcap-test/proto.h
index 8cb41ed..2580058 100644
--- a/tests/osmo-pcap-test/proto.h
+++ b/tests/osmo-pcap-test/proto.h
@@ -10,30 +10,42 @@
 
 	unsigned int		l4protonum;
 
-	int	(*l4pkt_hdr_len)(const uint8_t *pkt);
-	int	(*l4pkt_no_data)(const uint8_t *pkt);
+	unsigned int	(*l4pkt_hdr_len)(const uint8_t *pkt);
+	unsigned int	(*l4pkt_no_data)(const uint8_t *pkt);
 };
 
-struct osmo_pcap_proto_l2l3 {
+struct osmo_pcap_proto_l3 {
 	struct llist_head	head;
-
-	unsigned int		l2protonum;
-	unsigned int		l2hdr_len;
 
 	unsigned int		l3protonum;
 
-	int	(*l3pkt_hdr_len)(const uint8_t *pkt);
-	int	(*l4pkt_proto)(const uint8_t *pkt);
+	unsigned int	(*l3pkt_hdr_len)(const uint8_t *pkt);
+	unsigned int	(*l4pkt_proto)(const uint8_t *pkt);
 };
 
-struct osmo_pcap_proto_l2l3 *osmo_pcap_proto_l2l3_find(const uint8_t *pkt);
-void osmo_pcap_proto_l2l3_register(struct osmo_pcap_proto_l2l3 *h);
+struct osmo_pcap_proto_l2 {
+	struct llist_head	head;
 
-struct osmo_pcap_proto_l4 *osmo_pcap_proto_l4_find(const uint8_t *pkt, unsigned int l4protonum);
+	unsigned int		l2protonum;
+
+	unsigned int	(*l2pkt_hdr_len)(const uint8_t *pkt);
+	unsigned int	(*l3pkt_proto)(const uint8_t *pkt);
+};
+
+
+struct osmo_pcap_proto_l2 *osmo_pcap_proto_l2_find(unsigned int pcap_linktype);
+void osmo_pcap_proto_l2_register(struct osmo_pcap_proto_l2 *h);
+
+struct osmo_pcap_proto_l3 *osmo_pcap_proto_l3_find(unsigned int l3protonum);
+void osmo_pcap_proto_l3_register(struct osmo_pcap_proto_l3 *h);
+
+struct osmo_pcap_proto_l4 *osmo_pcap_proto_l4_find(unsigned int l4protonum);
 void osmo_pcap_proto_l4_register(struct osmo_pcap_proto_l4 *h);
 
 /* Initialization of supported protocols here. */
-void l2l3_ipv4_init(void);
+void l2_sll_init(void);
+void l2_eth_init(void);
+void l3_ipv4_init(void);
 void l4_tcp_init(void);
 void l4_udp_init(void);
 

-- 
To view, visit https://gerrit.osmocom.org/3064
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ie62fa0a8e45e1e141edb64b116dad185ad9c7a5f
Gerrit-PatchSet: 2
Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-Owner: Pau Espin Pedrol <pespin at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list