aboutsummaryrefslogtreecommitdiffstats
path: root/tools/uhd_dump/chdr_log.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/uhd_dump/chdr_log.c')
-rw-r--r--tools/uhd_dump/chdr_log.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/tools/uhd_dump/chdr_log.c b/tools/uhd_dump/chdr_log.c
new file mode 100644
index 000000000..9a0834e9b
--- /dev/null
+++ b/tools/uhd_dump/chdr_log.c
@@ -0,0 +1,212 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcap.h>
+#include <netinet/in.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "uhd_dump.h"
+
+//#define DEBUG 1
+
+void usage()
+{
+ fprintf(stderr,"Usage: chdr_dump [-h host_ip] filename.pcap\n");
+ exit(2);
+}
+
+int main(int argc, char *argv[])
+{
+ struct pbuf_info *packet_buffer; // Store all packets of interest here
+ struct in_addr host_addr; // Apparent Host IP addr in this capture
+ struct in_addr usrp_addr; // Apparent USRP IP addr in this capture
+ struct timeval *origin_ts; // Timestamp of first packet in file.
+ long long origin_ts_in_us;
+ int direction; // Flag to show direction of packet flow. 0=H->U, 1=U->H.
+ int packet_count[2]; // Number of packets that match filter
+ double size_average[2]; // Average size of packets Host to USRP
+ int size_histogram[90][2]; // Array captures histogram of packet sizes Host to USRP in 100 byte bins
+ int x; // Local integer scratch variables
+ char *conversion_error[1];
+ int c;
+ char buffer[26]; // Buffer to format GMT time stamp strings for output
+ double time_since_start; // Time elapsed in seconds since start
+
+ const struct ip_header *ip_header;
+
+ u32 *dump_header;
+
+
+ host_addr.s_addr = 0x0;
+ //usrp_addr.s_addr = 0x0;
+
+ while ((c = getopt(argc, argv, "h:u:")) != -1) {
+ switch(c) {
+ case 'h':
+ // Explicit IP address for host on command line
+ if (*optarg == '\0')
+ usage();
+ host_addr.s_addr = strtol(strtok(optarg,"."),conversion_error,10) ;
+ if (**conversion_error != '\0')
+ usage();
+ host_addr.s_addr = host_addr.s_addr | strtol(strtok(NULL,"."),conversion_error,10) << 8;
+ if (**conversion_error != '\0')
+ usage();
+ host_addr.s_addr = host_addr.s_addr | strtol(strtok(NULL,"."),conversion_error,10) << 16;
+ if (**conversion_error != '\0')
+ usage();
+ host_addr.s_addr = host_addr.s_addr | strtol(strtok(NULL,"\0"),conversion_error,10) << 24;
+ if (**conversion_error != '\0')
+ usage();
+ break;
+ case 'u':
+ // Explicit IP address for USRP on command line
+ if (*optarg == '\0')
+ usage();
+ usrp_addr.s_addr = strtol(strtok(optarg,"."),conversion_error,10) ;
+ if (**conversion_error != '\0')
+ usage();
+ usrp_addr.s_addr = usrp_addr.s_addr | strtol(strtok(NULL,"."),conversion_error,10) << 8;
+ if (**conversion_error != '\0')
+ usage();
+ usrp_addr.s_addr = usrp_addr.s_addr | strtol(strtok(NULL,"."),conversion_error,10) << 16;
+ if (**conversion_error != '\0')
+ usage();
+ usrp_addr.s_addr = usrp_addr.s_addr | strtol(strtok(NULL,"\0"),conversion_error,10) << 24;
+ if (**conversion_error != '\0')
+ usage();
+ break;
+
+ case'?':
+ default:
+ usage();
+ }
+ }
+
+ argc -= (optind - 1);
+ argv += (optind -1);
+
+
+ // Just a mandatory pcap filename for now, better parser and options later.
+ if (argc != 2) {
+ usage();
+ }
+
+
+ // Init packet buffer
+ packet_buffer = malloc(sizeof(struct pbuf_info));
+
+ // Init origin timestamp
+ origin_ts = malloc(sizeof(struct timeval));
+
+ // Go read matching packets from capture file into memory
+ get_udp_port_from_file(CHDR_PORT,argv[1],packet_buffer,origin_ts);
+
+ // Extract origin tome of first packet and convert to uS.
+ origin_ts_in_us = origin_ts->tv_sec * 1000000 + origin_ts->tv_usec;
+
+
+ // Count number of packets in capture
+ packet_buffer->current = packet_buffer->start;
+ x = 0;
+
+ while (packet_buffer->current != NULL) {
+ x++;
+ packet_buffer->current = packet_buffer->current->next;
+ }
+
+ fprintf(stdout,"\n===================================================================\n");
+ fprintf(stdout,"\n Total matching packet count in capture file: %d\n",x);
+ fprintf(stdout,"\n===================================================================\n\n");
+
+ // If no packets were CHDR then just exit now
+ if (x == 0) {
+ exit(0);
+ }
+
+ // Determine host and USRP IP addresses so that we can classify direction of packet flow later.
+ if (host_addr.s_addr == 0x0)
+ get_connection_endpoints(packet_buffer,&host_addr,&usrp_addr);
+
+ // Count packets in list.
+ // Build histogram of packet sizes
+ // Build histogram of Stream ID's
+ packet_buffer->current = packet_buffer->start;
+
+ for (x=0;x<90;x+=1)
+ size_histogram[x][H2U] = size_histogram[x][U2H] = 0;
+
+ size_average[H2U] = size_average[U2H] = 0;
+ packet_count[H2U] = packet_count[U2H] = 0;
+
+ while (packet_buffer->current != NULL) {
+
+ // Overlay IP header on packet payload
+ ip_header = (struct ip_header *)(packet_buffer->current->payload+ETH_SIZE);
+
+ // Identify packet direction
+ if (ip_header->ip_src.s_addr == host_addr.s_addr)
+ direction = H2U;
+ else
+ direction = U2H;
+
+ packet_count[direction]++;
+ size_average[direction]+=(double)packet_buffer->current->size;
+ if ((x=packet_buffer->current->size) > 9000)
+ fprintf(stderr,"Current packet size = %d at absolute time %s, relative time %f, exceeds MTU! Skip counting.",
+ x,format_gmt(&packet_buffer->current->ts,buffer),(relative_time(&packet_buffer->current->ts,origin_ts)));
+ else
+ size_histogram[x/100][direction]++;
+
+ packet_buffer->current = packet_buffer->current->next;
+
+ }
+
+ fprintf(stdout,"\n===================================================================\n");
+ fprintf(stdout,"\n Average packet size Host -> USRP: %d\n",(int)(size_average[H2U]/packet_count[H2U]));
+ fprintf(stdout,"\n Average packet size USRP -> Host: %d\n",(int)(size_average[U2H]/packet_count[U2H]));
+ fprintf(stdout,"\n===================================================================\n\n");
+
+ //
+ // Now produce packet by packet log
+ //
+ packet_buffer->current = packet_buffer->start;
+ x = 0;
+
+ while (packet_buffer->current != NULL) {
+ x++;
+
+ // Calculate time offset of this packet from start
+ time_since_start = ((double) packet_buffer->current->ts.tv_sec * 1000000 + packet_buffer->current->ts.tv_usec - origin_ts_in_us)/1000000;
+
+
+ dump_header = (u32 *) (packet_buffer->current->payload+ETH_SIZE+IP_SIZE+UDP_SIZE);
+
+ /* fprintf(stdout,"DUMP: %08x %08x %08x %08x %08x %08x\n", */
+ /* swapint((int) *(dump_header)), */
+ /* swapint((int) *(dump_header+1)), */
+ /* swapint((int) *(dump_header+2)), */
+ /* swapint((int) *(dump_header+3)), */
+ /* swapint((int) *(dump_header+4)), */
+ /* swapint((int) *(dump_header+5))); */
+
+ // Extract the device portion of the SID to see which packet flow this belongs in
+
+ fprintf(stdout,"%8d %f \t",x,time_since_start);
+ print_direction(packet_buffer,&host_addr,&usrp_addr);
+ fprintf(stdout,"\t");
+ print_size(packet_buffer);
+ fprintf(stdout,"\t");
+ print_sid(packet_buffer);
+ fprintf(stdout,"\t");
+ print_vita_header(packet_buffer,&host_addr);
+ fprintf(stdout,"\n");
+
+ packet_buffer->current = packet_buffer->current->next;
+
+ }
+ // Normal Exit
+ return(0);
+}
+