Skip to content

Commit

Permalink
C: Refactor options parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiasl committed Jan 25, 2016
1 parent 13386af commit e78852e
Showing 1 changed file with 56 additions and 53 deletions.
109 changes: 56 additions & 53 deletions c/save_to_pcap.c
Expand Up @@ -139,9 +139,11 @@ typedef struct {
// RAN probe has 64
#define MAX_SPANS 64

// How many MTP-2 channels can we run at the same time? (Also limited by
// hardware)
#define MAX_MTP2_CHANNELS 72
// How many channels can we run at the same time?
//
// The hardware also has a limit; if we go over that we'll get an error
// back via the API.
#define MAX_CHANNELS 96

typedef struct {
u16 tag;
Expand All @@ -154,14 +156,33 @@ typedef struct {
enum PCap_format { PCAP_CLASSIC, PCAP_NG };

// Link types, defined in PCap-NG spec appendix C
#define LINK_TYPE_MTP2 140
enum Protocols {
LINK_TYPE_MTP2 = 140
};

typedef struct {
char *span;
int timeslots[MAX_TIMESLOTS];
int n_timeslots;
} Channel_t;

// Command-line options provided by the user
struct Options {
int monitoring;
int verbose;
int n_sus_per_file;
int duration_per_file;
int drop_fisus;
int esnf;
char *hostname;
Channel_t channels[MAX_CHANNELS];
int n_channels;
char *base_filename;
enum PCap_format format;
enum Protocols protocol;
};


//----------------------------------------------------------------------
void
usage() {
Expand All @@ -172,7 +193,7 @@ usage() {
"\n\nSave decoded MTP-2 signal units to a file in libpcap format, "
"\nsuitable for examining with wireshark, tshark or other network"
"\nanalyser software.\n"
"\n<options>: [-c] [-f fisu=no] [-m] [-n <rotation>] [-v]"
"\n<options>: [-c] [-f <option>] [-m] [-n <rotation>] [-v]"
"\n-c: save in the classic Pcap format (default is the newer Pcap-NG)"
"\n-f fisu=no: remove all MTP-2 FISUs"
"\n-f esnf=yes: use MTP-2 extended sequence numbers"
Expand Down Expand Up @@ -1102,7 +1123,7 @@ arguments_to_channels(int argc,

for (i = 0; i < n_spans; i++)
{
if (*n_channels >= MAX_MTP2_CHANNELS)
if (*n_channels >= MAX_CHANNELS)
die("Attempted to start too many signalling channels. Abort.");

channels[*n_channels].span = spans[i];
Expand All @@ -1129,20 +1150,20 @@ arguments_to_channels(int argc,
//
// It's possible to specify multiple, separate -n arguments.
static void
parse_rotation(char *arg, int *n_sus_per_file, int *duration_per_file)
parse_rotation(char *arg, struct Options *opts)
{
int n;

if (sscanf(arg, "packets:%d", &n) == 1
|| sscanf(arg, "%d", &n) == 1)
{
*n_sus_per_file = n;
opts->n_sus_per_file = n;
return;
}

if (sscanf(arg, "duration:%d", &n) == 1)
{
*duration_per_file = n;
opts->duration_per_file = n;
return;
}

Expand All @@ -1153,49 +1174,39 @@ parse_rotation(char *arg, int *n_sus_per_file, int *duration_per_file)
static void
process_arguments(char **argv,
int argc,
int *monitoring,
int *verbose,
int *n_sus_per_file,
int *duration_per_file,
int *drop_fisus,
int *esnf,
char **hostname,
Channel_t channels[],
int *n_channels,
char **base_filename,
enum PCap_format *format)
struct Options *options)
{
int current_arg;

while (argc > 1 && argv[1][0] == '-') {
switch (argv[1][1]) {
case 'c': *format = PCAP_CLASSIC; break;
case 'c': options->format = PCAP_CLASSIC; break;

case 'f':
if (argc < 3) {
usage();
}
if (!strcmp("fisu=no", argv[2])) {
*drop_fisus = 1;
options->drop_fisus = 1;
} else if (!strcmp("esnf=yes", argv[2])) {
*esnf = 1;
options->esnf = 1;
}
argc--;
argv++;
break;

case 'm': *monitoring = 1; break;
case 'm': options->monitoring = 1; break;

case 'n':
if (argc < 3) {
usage();
}
parse_rotation(argv[2], n_sus_per_file, duration_per_file);
parse_rotation(argv[2], options);
argc--;
argv++;
break;

case 'v': *verbose = 1; break;
case 'v': options->verbose = 1; break;

default: usage();
}
Expand All @@ -1207,19 +1218,21 @@ process_arguments(char **argv,
usage();
}

*hostname = argv[1];
options->hostname = argv[1];

argv += 2;
argc -= 2;

current_arg = arguments_to_channels(argc, argv, channels, n_channels);
if (!n_channels){
current_arg = arguments_to_channels(argc, argv,
options->channels,
&(options->n_channels));
if (!options->n_channels){
die("No timeslots given (or, perhaps, no output filename given).");
}

print_channels(channels, *n_channels);
print_channels(options->channels, options->n_channels);

*base_filename = argv[current_arg];
options->base_filename = argv[current_arg];
}

// Entry point
Expand All @@ -1230,51 +1243,41 @@ main(int argc, char **argv)
int data_socket = -1;
int result;
int monitoring = 0;
int verbose = 0;
Channel_t channels[MAX_MTP2_CHANNELS];
int i;
int n_channels = 0;
int n_sus_per_file = 0;
int duration_per_file = 0;
int drop_fisus = 0;
int esnf = 0;
int listen_port = 0;
int listen_socket = -1;
enum PCap_format format = PCAP_NG;
char *hostname;
char *base_filename;
struct Options options;

// Check a couple of assumptions about type size.
assert(sizeof(u32) == 4);
assert(sizeof(u16) == 2);

win32_specific_startup();

process_arguments(argv, argc,
&monitoring, &verbose, &n_sus_per_file, &duration_per_file,
&drop_fisus, &esnf, &hostname, channels, &n_channels,
&base_filename, &format);
result = gth_connect(&api, hostname, verbose);
memset(&options, 0, sizeof(options));
process_arguments(argv, argc, &options);
result = gth_connect(&api, options.hostname, options.verbose);
if (result != 0) {
die("Unable to connect to the GTH. Giving up.");
}

read_hw_description(&api, hostname);
enable_l1(&api, channels, n_channels, monitoring);
read_hw_description(&api, options.hostname);
enable_l1(&api, options.channels, options.n_channels, monitoring);

listen_socket = gth_make_listen_socket(&listen_port);
for (i = 0; i < n_channels; i++){
monitor_mtp2(&api, channels + i,
i, drop_fisus, esnf, listen_port);
for (i = 0; i < options.n_channels; i++){
monitor_mtp2(&api, options.channels + i,
i, options.drop_fisus, options.esnf, listen_port);
if (i == 0) {
data_socket = gth_wait_for_accept(listen_socket);
}
}

fprintf(stderr, "capturing packets, press ^C to abort\n");
convert_to_pcap(&api, data_socket, base_filename,
n_sus_per_file, duration_per_file,
channels, n_channels, format);
convert_to_pcap(&api, data_socket, options.base_filename,
options.n_sus_per_file, options.duration_per_file,
options.channels, options.n_channels, format);

return 0; // not reached
}
Expand Down

0 comments on commit e78852e

Please sign in to comment.