aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmo-pcap/osmo_pcap_client.h8
-rw-r--r--src/osmo_client_core.c55
-rw-r--r--src/osmo_client_main.c3
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 = {