diff options
Diffstat (limited to 'tools/uhd_dump/chdr_log.c')
-rw-r--r-- | tools/uhd_dump/chdr_log.c | 212 |
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); +} + |