diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2016-08-19 20:27:35 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2016-08-19 20:28:21 +0200 |
commit | fa5572e2afc01903b2e5dd260f475d1f73ded74a (patch) | |
tree | 30409e19fb936cef49a594eb8980c0c31fb05925 | |
parent | 99526a6ad07c02e40e0831fd952974c5b7446f31 (diff) |
client: Use pcap_stats and export them as statistics
Attempt to write code that detects the wrap and is doing the
right thing when it happens.
Change-Id: I501ebc49d3e86b0605ec1fbe2f62aee3f362aa36
-rw-r--r-- | include/osmo-pcap/osmo_pcap_client.h | 8 | ||||
-rw-r--r-- | src/osmo_client_core.c | 55 | ||||
-rw-r--r-- | src/osmo_client_main.c | 3 |
3 files changed, 66 insertions, 0 deletions
diff --git a/include/osmo-pcap/osmo_pcap_client.h b/include/osmo-pcap/osmo_pcap_client.h index 90cd5ad..ee81e50 100644 --- a/include/osmo-pcap/osmo_pcap_client.h +++ b/include/osmo-pcap/osmo_pcap_client.h @@ -38,6 +38,9 @@ enum { CLIENT_CTR_QERR, CLIENT_CTR_PERR, CLIENT_CTR_WERR, + CLIENT_CTR_P_RECV, + CLIENT_CTR_P_DROP, + CLIENT_CTR_P_IFDROP, }; struct osmo_pcap_client { @@ -45,6 +48,11 @@ struct osmo_pcap_client { pcap_t *handle; char errbuf[PCAP_ERRBUF_SIZE]; + u_int last_ps_recv; + u_int last_ps_drop; + u_int last_ps_ifdrop; + struct osmo_timer_list pcap_stat_timer; + struct bpf_program bpf; char *filter_string; int filter_itself; diff --git a/src/osmo_client_core.c b/src/osmo_client_core.c index 4455c95..abef787 100644 --- a/src/osmo_client_core.c +++ b/src/osmo_client_core.c @@ -171,6 +171,56 @@ static int pcap_read_cb(struct osmo_fd *fd, unsigned int what) return 0; } +static inline u_int P_CAP_UINT_MAX() +{ + u_int val = 0; + return ~val; +} + +static void add_psbl_wrapped_ctr(struct osmo_pcap_client *client, + u_int *old_val, u_int new_val, int ctr) +{ + /* + * Wrapped.. + * So let's at from N to XYZ_MAX + * and then from 0 to new_val + * Only issue is we don't know sizeof(u_int) + */ + if (*old_val > new_val) { + rate_ctr_add(&client->ctrg->ctr[ctr], P_CAP_UINT_MAX() - *old_val); + rate_ctr_add(&client->ctrg->ctr[ctr], new_val); + *old_val = new_val; + return; + } + + /* Just increment it */ + rate_ctr_add(&client->ctrg->ctr[ctr], new_val - *old_val); + *old_val = new_val; +} + +static void pcap_check_stats_cb(void *_client) +{ + struct pcap_stat stat; + struct osmo_pcap_client *client = _client; + int rc; + + /* reschedule */ + osmo_timer_schedule(&client->pcap_stat_timer, 10, 0); + + memset(&stat, 0, sizeof(stat)); + rc = pcap_stats(client->handle, &stat); + if (rc != 0) { + LOGP(DCLIENT, LOGL_ERROR, "Failed to query pcap stats: %s\n", + pcap_geterr(client->handle)); + rate_ctr_inc(&client->ctrg->ctr[CLIENT_CTR_PERR]); + return; + } + + add_psbl_wrapped_ctr(client, &client->last_ps_recv, stat.ps_recv, CLIENT_CTR_P_RECV); + add_psbl_wrapped_ctr(client, &client->last_ps_drop, stat.ps_drop, CLIENT_CTR_P_DROP); + add_psbl_wrapped_ctr(client, &client->last_ps_ifdrop, stat.ps_ifdrop, CLIENT_CTR_P_IFDROP); +} + static int osmo_install_filter(struct osmo_pcap_client *client) { int rc; @@ -216,6 +266,7 @@ static void free_all(struct osmo_pcap_client *client) } pcap_close(client->handle); + osmo_timer_del(&client->pcap_stat_timer); client->handle = NULL; } @@ -260,6 +311,10 @@ int osmo_client_capture(struct osmo_pcap_client *client, const char *device) return 4; } + client->pcap_stat_timer.data = client; + client->pcap_stat_timer.cb = pcap_check_stats_cb; + pcap_check_stats_cb(client); + osmo_client_send_link(client); if (client->filter_string) { diff --git a/src/osmo_client_main.c b/src/osmo_client_main.c index 0b53939..f5ba41a 100644 --- a/src/osmo_client_main.c +++ b/src/osmo_client_main.c @@ -62,6 +62,9 @@ static const struct rate_ctr_desc pcap_client_ctr_desc[] = { [CLIENT_CTR_QERR] = { "client.queue_err", "Can not queue data " }, [CLIENT_CTR_PERR] = { "client.pcap_err", "libpcap error " }, [CLIENT_CTR_WERR] = { "client.write_err", "Write error " }, + [CLIENT_CTR_P_RECV] = { "pcap.recv", "PCAP received packets " }, + [CLIENT_CTR_P_DROP] = { "pcap.drop", "PCAP dropped packets " }, + [CLIENT_CTR_P_IFDROP] = { "pcap.ifdrop", "iface dropped packets " }, }; static const struct rate_ctr_group_desc pcap_client_ctr_group_desc = { |