client: Add pcap snaplen VTY cmd

Change-Id: I84fda9f27b725e031c218187ab679392dfa7ec3d
diff --git a/src/osmo_client_core.c b/src/osmo_client_core.c
index e19ae89..6414552 100644
--- a/src/osmo_client_core.c
+++ b/src/osmo_client_core.c
@@ -287,7 +287,9 @@
 		return 1;
 	}
 
-	client->handle = pcap_open_live(client->device, 9000, 0,
+	LOGP(DCLIENT, LOGL_INFO, "Opening device %s for capture with snaplen %zu\n",
+	     client->device, (size_t) client->snaplen);
+	client->handle = pcap_open_live(client->device, client->snaplen, 0,
 					1000, client->errbuf);
 	if (!client->handle) {
 		LOGP(DCLIENT, LOGL_ERROR,
@@ -346,6 +348,16 @@
 	conn->wqueue.bfd.fd = -1;
 }
 
+struct osmo_pcap_client *osmo_pcap_client_alloc(void *tall_ctx)
+{
+	struct osmo_pcap_client *client;
+	client = talloc_zero(tall_ctx, struct osmo_pcap_client);
+	if (!client)
+		return NULL;
+	client->fd.fd = -1;
+	client->snaplen = DEFAULT_SNAPLEN;
+	return client;
+}
 
 void osmo_client_free(struct osmo_pcap_client_conn *conn)
 {
diff --git a/src/osmo_client_main.c b/src/osmo_client_main.c
index f571b96..a28c4b7 100644
--- a/src/osmo_client_main.c
+++ b/src/osmo_client_main.c
@@ -212,12 +212,11 @@
 		exit(1);
 	}
 
-	pcap_client = talloc_zero(tall_cli_ctx, struct osmo_pcap_client);
+	pcap_client = osmo_pcap_client_alloc(tall_cli_ctx);
 	if (!pcap_client) {
 		LOGP(DCLIENT, LOGL_ERROR, "Failed to allocate osmo_pcap_client.\n");
 		exit(1);
 	}
-	pcap_client->fd.fd = -1;
 	vty_client_init(pcap_client);
 
 	/* initialize the queue */
diff --git a/src/osmo_client_network.c b/src/osmo_client_network.c
index e900ef4..7073d6c 100644
--- a/src/osmo_client_network.c
+++ b/src/osmo_client_network.c
@@ -169,14 +169,14 @@
 	struct msgb *msg;
 	int offset, ip_len;
 
-	if (in_hdr->caplen > 9000) {
+	if (in_hdr->len > in_hdr->caplen) {
 		LOGP(DCLIENT, LOGL_ERROR,
-			"Capture len too big %zu\n", (size_t) in_hdr->caplen);
+			"Recording truncated packet, len %zu > snaplen %zu\n",
+			(size_t) in_hdr->len, (size_t) in_hdr->caplen);
 		rate_ctr_inc(&conn->client->ctrg->ctr[CLIENT_CTR_2BIG]);
-		return;
 	}
 
-	msg = msgb_alloc(9000 + sizeof(*om_hdr) + sizeof(*hdr), "data-data");
+	msg = msgb_alloc(in_hdr->caplen + sizeof(*om_hdr) + sizeof(*hdr), "data-data");
 	if (!msg) {
 		LOGP(DCLIENT, LOGL_ERROR, "Failed to allocate.\n");
 		rate_ctr_inc(&conn->client->ctrg->ctr[CLIENT_CTR_NOMEM]);
@@ -239,7 +239,7 @@
 		return;
 	}
 
-	msg = msgb_alloc(9000 + sizeof(*om_hdr) + sizeof(*hdr), "link-data");
+	msg = msgb_alloc(conn->client->snaplen + sizeof(*om_hdr) + sizeof(*hdr), "link-data");
 	if (!msg) {
 		LOGP(DCLIENT, LOGL_ERROR, "Failed to allocate data.\n");
 		return;
@@ -256,7 +256,7 @@
 	hdr->version_minor = 4;
 	hdr->thiszone = 0;
 	hdr->sigfigs = 0;
-	hdr->snaplen = MAXIMUM_SNAPLEN;
+	hdr->snaplen = conn->client->snaplen;
 	hdr->linktype = pcap_datalink(conn->client->handle);
 
 	write_data(conn, msg);
diff --git a/src/osmo_client_vty.c b/src/osmo_client_vty.c
index e50099f..30158c5 100644
--- a/src/osmo_client_vty.c
+++ b/src/osmo_client_vty.c
@@ -125,7 +125,9 @@
 	if (pcap_client->device)
 		vty_out(vty, " pcap device %s%s",
 			pcap_client->device, VTY_NEWLINE);
-
+	if (pcap_client->snaplen != DEFAULT_SNAPLEN)
+		vty_out(vty, " pcap snaplen %d%s",
+			pcap_client->snaplen, VTY_NEWLINE);
 	if (pcap_client->filter_string)
 		vty_out(vty, " pcap filter %s%s",
 			pcap_client->filter_string, VTY_NEWLINE);
@@ -148,6 +150,19 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN(cfg_client_snaplen,
+      cfg_client_snaplen_cmd,
+	      "pcap snaplen <1-262144>", /* MAXIMUM_SNAPLEN */
+      PCAP_STRING "snapshot length\n" "Bytes\n")
+{
+	if (pcap_client->handle) {
+		vty_out(vty, "'pcap snaplen' must be set before 'pcap device' to take effect!%s", VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+	pcap_client->snaplen = atoi(argv[0]);
+	return CMD_SUCCESS;
+}
+
 DEFUN(cfg_client_add_gprs,
       cfg_client_add_gprs_cmd,
       "pcap add-filter gprs",
@@ -512,6 +527,7 @@
 	install_node(&server_node, config_write_server);
 
 	install_element(CLIENT_NODE, &cfg_client_device_cmd);
+	install_element(CLIENT_NODE, &cfg_client_snaplen_cmd);
 	install_element(CLIENT_NODE, &cfg_client_filter_cmd);
 	install_element(CLIENT_NODE, &cfg_client_loop_cmd);