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.orgHarald 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(ð); +} 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