mirror of
https://github.com/saymrwulf/uhd.git
synced 2026-05-16 21:10:10 +00:00
229 lines
7.6 KiB
C
229 lines
7.6 KiB
C
//
|
|
// Copyright 2013-2014 Ettus Research LLC
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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);
|
|
}
|
|
|