abw_conf.c 31.7 KB
Newer Older
's avatar
committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
 * Copyright (c) 2006, CESNET
 * All rights reserved.
 *
 * LICENSE TERMS
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the company nor the names of its contributors 
 *       may be used to endorse or promote products derived from this 
 *       software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
 * THE COMPANY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

34
35
36
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
37
38
#include <unistd.h>
#include <math.h>
39
40
#define __USE_XOPEN
#include <time.h>
's avatar
committed
41
42
43
44
#define _GNU_SOURCE
#include <getopt.h>
#include <readline/readline.h>
#include <readline/history.h>
45

46
47
#include "../../src/common/parseconf.h"
#include "abw_common.h"
48
49
#include "abw_conf.h"

50
extern int debug;
51

52
53
configuration_t configuration;

54
55
56
57
void usage() {
	char *progname="abw";

	fprintf(stderr, "%s: Usage: %s [options] [header_filter]\n", progname, progname);
's avatar
committed
58

59
	fprintf(stderr, "  -f or --conf_filename <filename>   read configuration from file\n");
's avatar
committed
60
	fprintf(stderr, "\nGeneral options:\n");
61
62
63
64
65
66
67
	fprintf(stderr, "  -h                             print this help message\n");
	fprintf(stderr, "  -D or --debug[=n]              set debug level to n\n");
	fprintf(stderr, "                                 (n can be specified with --debug only)\n");
	fprintf(stderr, "  -q or --no_stdout              do not print results on stdout\n");
	fprintf(stderr, "  --stdout_simple                print results as numbers only\n");
	fprintf(stderr, "  --no_measure                   do not start measurements\n");
	fprintf(stderr, "                                 (use with -D or --debug to check configuration)\n");
's avatar
committed
68
69
70
71
	fprintf(stderr, "\nSubject options:\n");
	fprintf(stderr, "  -n or --hostname <hostname>    hostname or IP address of measurement station\n");
	fprintf(stderr, "                                 (default localhost)\n");
	fprintf(stderr, "  -d or --device <device>        device on measurement station\n");
's avatar
committed
72
	fprintf(stderr, "                                 (e.g., /dev/combosix/0, /dev/dag0,\n");
73
	fprintf(stderr, "                                 default %s)\n", DEFAULT_INTERFACE);
74
	fprintf(stderr, "  --port <n>                     port on device, default is all ports together\n");
's avatar
committed
75
76
77
	fprintf(stderr, "  --mpls                         link uses MPLS\n");
	fprintf(stderr, "  -l or --link_mbps <mbps>       link installed bandwidth (default %d)\n", DEFAULT_LINK_MBPS);
	fprintf(stderr, "\nParameters options:\n");
's avatar
committed
78
	fprintf(stderr, "  -m or --sau_mode {d | b | p}   sampling mode (default deterministic)\n");
79
80
81
	fprintf(stderr, "      d - deterministic\n");
	fprintf(stderr, "      b - byte deterministic\n");
	fprintf(stderr, "      p - probabilistic\n");
's avatar
committed
82
	fprintf(stderr, "  -r or --sau_threshold <threshold>  pass packet when threshold is reached\n");
83
	fprintf(stderr, "      number of packets for d, number of bytes for b and\n");
's avatar
committed
84
	fprintf(stderr, "      pass probability for p (default 1 for all modes)\n");
's avatar
committed
85
	fprintf(stderr, "  -w or --payload_string <word>  word to be searched in payload,\n");
86
	fprintf(stderr, "                                 for multiple -w, packet passes when at least\n");
's avatar
committed
87
	fprintf(stderr, "                                 one word matches\n");
's avatar
committed
88
89
	fprintf(stderr, "  -i or --interval <interval>    seconds between measurements (default 1)\n");
	fprintf(stderr, "\nMeasurement options:\n");
's avatar
committed
90
	fprintf(stderr, "  --protocols <protocols>        comma-separated list of protocols\n");
91
92
	fprintf(stderr, "                                 (default all, which means all packets)\n");

93
94
95
	exit(-1);
} /* usage() */

96
int read_command_line(int argc, char *argv[], configuration_t *configuration) {
97
98
99
100
101

	int payload_strings_no;
	double interval;
	int direct_flow;
	int opt;
's avatar
committed
102
	int opt_idx;
103
104
105
106
107

	if (configuration==NULL) {
		fprintf(stderr, "%s: configuration argument is NULL\n", __func__);
		return -1;
	}
108
109
110
111

	payload_strings_no=0;
	direct_flow=0;

's avatar
committed
112
	while ((opt=getopt_long(argc, argv, ARGS, long_options, &opt_idx)) != -1) {
113
  	switch(opt) {
's avatar
committed
114

's avatar
committed
115
		/* General options */
116
117
118
		case 'h':
			usage();
			exit(0);
119
120
121
122
123
124
125
		case 'D':
		case LO_DEBUG:
			if (optarg)
				debug=atoi(optarg);
			else
				debug=1;
			break;
126
127
128
		case LO_NO_MEASURE:
         configuration->global->no_measure=1;
         break;
129
		case 'q':
's avatar
committed
130
		case LO_NO_STDOUT:
131
			configuration->global->no_stdout=1;
132
			break;
133
		case LO_STDOUT_SIMPLE:
134
			configuration->global->stdout_simple=1;
's avatar
committed
135
			break;
's avatar
committed
136

's avatar
committed
137
		/* Subject options */
's avatar
committed
138
139
140
		case 'n':
		case LO_HOSTNAME:
			direct_flow=1;
141
			configuration->subject->hostname=optarg;
's avatar
committed
142
			break;
143
		case 'd':
's avatar
committed
144
		case LO_INTERFACE:
145
			direct_flow=1;
146
	  		configuration->subject->interface=optarg;
147
		  	break;
148
149
150
151
152
153
154
155
		case LO_PORT:
			/* check here, because -1 given here would look as correct default 
				value for check_conf() */
			if (atoi(optarg)<0) {
				fprintf(stderr, "%s: port number must be >= 0\n", __func__);
				return -1;
			}
			configuration->subject->port=atoi(optarg);
's avatar
committed
156
157
158
		case 'l':
		case LO_LINK_MBPS:
			direct_flow=1;
159
160
161
162
			configuration->subject->link_mbps=atoi(optarg);
			if (configuration->subject->link_mbps<=0) {
				fprintf(stderr, "%s: link installed bandwidth must be positive\n", 
					__func__);
's avatar
committed
163
164
165
				return -1;
			}
			break;
166
167
168
169
		case LO_MPLS:
			direct_flow=1;
			configuration->subject->mpls=1;
			break;
's avatar
committed
170
171

		/* Parameters options */
172
		case 'm':
's avatar
committed
173
		case LO_SAU_MODE:
174
175
176
177
178
			direct_flow=1;
			if (strlen(optarg)>1) {
				fprintf(stderr, "%s: sampling mode must be d, b or p\n", __func__);
				return -1;
			}
179
			configuration->parameters->sau_mode=optarg[0];
180
181
			break;
		case 'r':
's avatar
committed
182
		case LO_SAU_THRESHOLD:
183
			direct_flow=1;
184
			configuration->parameters->sau_threshold=atof(optarg);
185
186
			break;
		case 'w':
's avatar
committed
187
		case LO_PAYLOAD_STRING:
's avatar
committed
188
189
190
			/* We let user to specify more payload strings on a command-line
				(each as a word without spaces), but current implementation
				passes only the first string to searching mechanism */
191
192
			direct_flow=1;
			if (payload_strings_no >= MAX_PAYLOAD_STRINGS) {
's avatar
committed
193
194
				fprintf(stderr, "%s: max. %d strings can be searched in payload\n",
					 __func__, MAX_PAYLOAD_STRINGS);
195
196
197
198
199
200
				return -1;
			}
			if (strlen(optarg) > MAX_PAYLOAD_STRING) {
				fprintf(stderr, "%s: max. %d characters long strings can be searched in payload\n", __func__, MAX_PAYLOAD_STRING);
				return -1;
			}
201
			if ((configuration->parameters->payload_strings[payload_strings_no]=
's avatar
committed
202
					malloc(strlen(optarg)+1))==NULL) {
203
204
205
				fprintf(stderr, "%s: malloc() failed\n", __func__);
				return -1;
			}
206
			strcpy(configuration->parameters->payload_strings[payload_strings_no], 
's avatar
committed
207
				optarg);
208
209
210
			payload_strings_no++;
			break;
		case 'i':
's avatar
committed
211
		case LO_INTERVAL:
212
213
214
215
216
217
			direct_flow=1;
			interval=atof(optarg);
			if (interval<=0) {
				fprintf(stderr, "%s: interval must be positive\n", __func__);
				return -1;
			}
218
219
220
			configuration->parameters->interval.tv_sec=floor(interval);
			configuration->parameters->interval.tv_usec=
				(int)floor((interval - configuration->parameters->interval.tv_sec) * 1000000);
221
			break;
's avatar
committed
222
223
224

		/* Measurement options */
		case LO_PROTOCOLS:
225
			configuration->measurement->protocols=optarg;
's avatar
committed
226
			break;
's avatar
committed
227
228
229

		/* Read flow configuration from configuration file */
		case 'f':
230
231
		case LO_CONF_FILENAME:
			configuration->global->conf_filename=optarg;
's avatar
committed
232
233
			break;

234
235
236
237
238
239
		default:
			usage();
			return -1;
	  }
  }

240
241
	if (direct_flow && configuration->global->conf_filename) {
		fprintf(stderr, "%s: configuration can be read from one source only - command line or configuration file\n", __func__);
's avatar
committed
242
243
244
		return -1;
	}

's avatar
committed
245
246
247
	/* If we do not specify any command-line arguments, use direct flow
		with default subject and parameters */

248
	if (argc==1) {
's avatar
committed
249
		direct_flow=1;
250
251
252
		configuration->subject->hostname=DEFAULT_HOSTNAME;
		configuration->subject->interface=DEFAULT_INTERFACE;
	}
's avatar
committed
253

254
255
256
257
258
259
260
261
262
	if (direct_flow) {
		configuration->subject->id=1;
		configuration->scope->id=1;
		configuration->scope->subject_ids="1";
		configuration->parameters->id=1;
		configuration->measurement->id=1;
		configuration->measurement->scope_id=1;
		configuration->measurement->parameters_id=1;
	}
's avatar
committed
263

264
265
266
	return 0;
} /* read_command_line() */

267
int read_conf_file(configuration_t *configuration)
268
{
269
   conf_category_entry_t *cat;
's avatar
committed
270
   conf_parameter_t *param;
271
	int payload_strings_no;
272
273
274
275
	subject_t **subject;
	scope_t **scope;
	parameters_t **parameters;
	measurement_t **measurement;
276

277
   if (configuration==NULL || configuration->global->conf_filename==NULL) {
278
279
280
281
282
      fprintf(stderr, "%s: some of the required arguments were not specified\n",
			__func__);
      return -1;
   }

283
284
	/* Parse configuration file and load its content into a sequence of
		structures representing categories and their items in the file */
285
   if (pc_load(configuration->global->conf_filename)!=1) {
286
      fprintf(stderr, "%s: pc_load() did not load file %s\n", __func__,
287
         configuration->global->conf_filename);
288
289
290
      return -1;
   }

's avatar
committed
291
	/* Go over all categories */
292
293
294
295
	subject=&(configuration->subject);
	scope=&(configuration->scope);
	parameters=&(configuration->parameters);
	measurement=&(configuration->measurement);
296
297
298

	cat=pc_get_category("global");
	if (cat) {
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

		param=cat->params;
		while (param) {
			param=param->next;
		}
	}

	cat=pc_get_category("subject");
	while (cat) {

		if (*subject==NULL) {
			if ((*subject=new_subject())==NULL) {
				fprintf(stderr, "%s: new_subject() failed\n", __func__);
				return -1;
			}
		}

316
317
318
		param=cat->params;
		while (param) {

319
320
321
322
323
			if (!strcmp(param->name, "id"))
            (*subject)->id=atoi(param->value);

			else if (!strcmp(param->name, "hostname")) {
				if (((*subject)->hostname=malloc(strlen(param->value)+1))==NULL) {
's avatar
committed
324
325
326
					fprintf(stderr, "%s: malloc() failed\n", __func__);
					return -1;
				}
327
				strcpy((*subject)->hostname, param->value);
's avatar
committed
328
			}
329
330
331
332
333
334
335
336
337

			else if (!strcmp(param->name, "interface")) {
				if (((*subject)->interface=malloc(strlen(param->value)+1))==NULL) {
					fprintf(stderr, "%s: malloc() failed\n", __func__);
					return -1;
				}
				strcpy((*subject)->interface, param->value);
			}

338
339
340
341
342
343
344
345
346
347
			else if (!strcmp(param->name, "port")) {
				/* check here, because -1 given here would look as correct default
               value for check_conf() */
				if (atoi(param->value) < 0) {
					fprintf(stderr, "%s: port number must be >= 0\n", __func__);
					return -1;
				}
        		(*subject)->port=atoi(param->value);
			}

348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
			else if (!strcmp(param->name, "link_mbps"))
        		(*subject)->link_mbps=atoi(param->value);

			else if (!strcmp(param->name, "mpls")) {
				if (!strcmp(param->value, "yes"))
					(*subject)->mpls=1;
				else if (!strcmp(param->value, "no"))
					(*subject)->mpls=0;
				else {
					fprintf(stderr, "%s: mpls must be \"yes\" or \"no\"\n", 
						__func__);
					return -1;
				}
			}

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
			else if (!strcmp(param->name, "label")) {
				if (((*subject)->label=malloc(strlen(param->value)+1))==NULL) {
					fprintf(stderr, "%s: malloc() failed\n", __func__);
					return -1;
				}
				strcpy((*subject)->label, param->value);
			}

			else if (!strcmp(param->name, "description")) {
				if (((*subject)->description=malloc(strlen(param->value)+1))==NULL) {
					fprintf(stderr, "%s: malloc() failed\n", __func__);
					return -1;
				}
				strcpy((*subject)->description, param->value);
			}
		
			else if (!strcmp(param->name, "direction")) {
				if (!strcmp(param->value, "out"))
					(*subject)->out=1;
				else if (!strcmp(param->value, "in"))
					(*subject)->out=0; /* default, just for sure */
				else {
					fprintf(stderr, "%s: direction must be in or out\n", __func__);
					return -1;
				}
			}

390
			param=param->next;
391
392
393
394
395
396
397
398
399
400
401
402
403
		} /* while (param) */
		cat=cat->next;
		subject=&((*subject)->next);
	} /* while (cat) "subject" */
		
	cat=pc_get_category("scope");
	while (cat) {

		if (*scope==NULL) {
			if ((*scope=new_scope())==NULL) {
				fprintf(stderr, "%s: new_subject() failed\n", __func__);
				return -1;
			}
404
405
		}

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
		param=cat->params;
		while (param) {

			if (!strcmp(param->name, "id"))
            (*scope)->id=atoi(param->value);

			else if (!strcmp(param->name, "subject_ids")) {
				if (((*scope)->subject_ids=malloc(strlen(param->value)+1))==NULL) {
					fprintf(stderr, "%s: malloc() failed\n", __func__);
					return -1;
				}
				strcpy((*scope)->subject_ids, param->value);
			}

			param=param->next;
		} /* while (param) */
		cat=cat->next;
		scope=&((*scope)->next);
	} /* while (cat) "scope" */
		
426
	cat=pc_get_category("parameters");
427
	while (cat) {
428

429
430
		if (*parameters==NULL) {
			if ((*parameters=new_parameters())==NULL) {
431
				fprintf(stderr, "%s: new_parameters() failed\n", __func__);
432
433
				return -1;
			}
434
435
436
437
438
439
440
		}

		payload_strings_no=0;
		param=cat->params;
		while (param) {

			if (!strcmp(param->name, "id"))
441
				(*parameters)->id=atoi(param->value);
442

443
444
445
			else if (!strcmp(param->name, "header_filter")) {
				if (strlen(param->value)>=MAX_HEADER_FILTER) {
					fprintf(stderr, "%s: header filter string must not be longer than %d characters\n", __func__, MAX_HEADER_FILTER);
446
447
					return -1;
				}
448
449
450
451
				if (((*parameters)->header_filter=
					malloc(strlen(param->value)+1))==NULL) {
						fprintf(stderr, "%s: malloc() failed\n", __func__);
						return -1;
452
				}
453
				strcpy((*parameters)->header_filter, param->value);
454
			}
455

456
			else if (!strcmp(param->name, "sau_mode"))
457
				(*parameters)->sau_mode=param->value[0];
458
459

			else if (!strcmp(param->name, "sau_threshold"))
460
				(*parameters)->sau_threshold=atof(param->value);
461

's avatar
committed
462
			else if (!strcmp(param->name, "payload_string")) {
463
464
465
466
467
468
469
470
				if (payload_strings_no >= MAX_PAYLOAD_STRINGS) {
           		fprintf(stderr, "%s: max. %d strings can be searched in payload\n", __func__, MAX_PAYLOAD_STRINGS);
           		return -1;
        		}
        		if (strlen(param->value) > MAX_PAYLOAD_STRING) {
           		fprintf(stderr, "%s: max. %d characters long strings can be searched in payload\n", __func__, MAX_PAYLOAD_STRING);
           		return -1;
        		}
471
        		if (((*parameters)->payload_strings[payload_strings_no]=
472
473
474
475
              	malloc(strlen(param->value)+1))==NULL) {
           		fprintf(stderr, "%s: malloc() failed\n", __func__);
           		return -1;
        		}
476
477
        		strcpy((*parameters)->payload_strings[payload_strings_no], 
					param->value);
478
479
        		payload_strings_no++;
			}
's avatar
committed
480
				
481
			else if (!strcmp(param->name, "interval_sec"))
482
				(*parameters)->interval.tv_sec=atoi(param->value);
483

484
			else if (!strcmp(param->name, "interval_usec"))
485
				(*parameters)->interval.tv_usec=atoi(param->value);
's avatar
committed
486

487
488
489
			param=param->next;
		} /* while (param) */
		cat=cat->next;
490
		parameters=&((*parameters)->next);
491
	} /* while (cat) "parameters" */
's avatar
committed
492

493
494
	cat=pc_get_category("measurement");
	while (cat) {
's avatar
committed
495

496
497
498
		if (*measurement==NULL) {
			if ((*measurement=new_measurement())==NULL) {
				fprintf(stderr, "%s: new_measurement() failed\n", __func__);
499
				return -1;
's avatar
committed
500
			}
501
		}
's avatar
committed
502

503
504
		param=cat->params;
		while (param) {
's avatar
committed
505

506
			if (!strcmp(param->name, "id"))
507
              (*measurement)->id=atoi(param->value);
508

509
510
			if (!strcmp(param->name, "scope_id"))
              (*measurement)->scope_id=atoi(param->value);
's avatar
committed
511

512
			else if (!strcmp(param->name, "parameters_id"))
513
              (*measurement)->parameters_id=atoi(param->value);
514

515
			else if (!strcmp(param->name, "protocols")) {
516
				if ((*measurement)->protocols) {
517
518
					fprintf(stderr, "%s: only one protocols string can be specified\n", __func__);
					return -1;
519
				}
520
521
522
523
				if (strlen(param->value) > MAX_PROTOCOLS_STRING) {
               fprintf(stderr, "%s: max. %d characters long protocols string can be specified\n", __func__, MAX_PROTOCOLS_STRING);
               return -1;
            }
524
525
            if (((*measurement)->protocols=
						malloc(strlen(param->value)+1))==NULL) {
526
527
528
               fprintf(stderr, "%s: malloc() failed\n", __func__);
               return -1;
            }
529
				strcpy((*measurement)->protocols, param->value);
's avatar
committed
530
531
			}

532
533
			param=param->next;
		} /* while (param) */
534
		cat=cat->next;
535
		measurement=&((*measurement)->next);
536
	} /* while (cat) "measurement" */
537

's avatar
committed
538
539
	pc_close();

540
541
542
	return 0;
} /* read_conf_file() */

543
int read_const_conf_file(configuration_t *configuration)
's avatar
committed
544
545
{
   conf_category_entry_t *cat;
546
	subject_t *subject;
's avatar
committed
547
548
	char *hostname, *interface, *mpls, *link_mbps;

549
   if (configuration==NULL) {
's avatar
committed
550
551
552
553
554
      fprintf(stderr, "%s: some of the required arguments were not specified\n",
			__func__);
      return -1;
   }

555
556
	/* 
	 * Parse configuration file and load its content into a sequence of
557
558
559
560
561
	 * structures representing categories and their items in the file.
    * This file is optional, if we cannot load it, just return. 
	 */
   if (pc_load(ABW_CONST_CFG)!=1) 
		return 0;
's avatar
committed
562
563
564
565
566
567
568
569
570
571
572
573

	/* Go over all [subject] sections */
	
	cat=pc_get_category("subject");
	while (cat) {

		hostname=pc_get_param(cat, "hostname");
		interface=pc_get_param(cat, "interface");

		mpls=pc_get_param(cat, "mpls");
		link_mbps=pc_get_param(cat, "link_mbps");

574
575
		/* 
		 * If this [subject] section does not include hostname or interface
's avatar
committed
576
577
578
579
580
581
582
583
584
585
586
		 * (which are both needed to identify subject) or if it does not
		 * include any information about subject to be stored in configuration
		 * then skip this [subject] section.
		 */

		if (hostname==NULL || interface==NULL ||
			 (mpls==NULL && link_mbps==NULL)) {
			cat=cat->next;
			continue;
		}

587
588
589
590
		subject=configuration->subject;
		while (subject) {
			if (subject->hostname && !strcmp(subject->hostname, hostname) && 
				 subject->interface && !strcmp(subject->interface, interface)) {
's avatar
committed
591
				if (mpls && !strcmp(mpls, "yes"))
592
					subject->mpls=1;
's avatar
committed
593
				if (link_mbps)
594
					subject->link_mbps=atoi(link_mbps);
's avatar
committed
595
596
				break;
			}
597
			subject=subject->next;
's avatar
committed
598
599
600
601
602
603
604
605
		}

		cat=cat->next;
	} /* while (cat) "subject" */
		
	pc_close();

	return 0;
606
} /* read_const_conf_file() */
's avatar
committed
607

608
609
/* Note that readline() uses malloc() to allocate memory */
/* int read_password(global_spec_t *global_spec) {
610

's avatar
committed
611
	if (global_spec->conf_from_mysql || global_spec->conf_to_mysql ||
's avatar
committed
612
		 global_spec->clear_conf || global_spec->db) {
's avatar
committed
613
614
		if  (!global_spec->db || !global_spec->user) {
			fprintf(stderr, "%s: if MySQL operation is requested, you also have to specify MySQL database name, username and password\n", __func__);
615
616
			return -1;
		}
's avatar
committed
617
		if (!global_spec->passwd) {
's avatar
committed
618
			if ((global_spec->passwd=readline("MySQL password: "))==NULL) {
's avatar
committed
619
620
621
622
				fprintf(stderr, "%s: Invalid MySQL password\n", __func__);
				return -1;
			}
		}
623
	}
624
	return 0;
625
} */ /* read_password() */
626

627
628
629
630
631
632
633
int check_conf(configuration_t *configuration) {
	subject_t *subject;
	scope_t *scope;
	parameters_t *parameters;
	measurement_t *measurement;

	int subject_no;
634
635
	int protocols_no;

636
	int i;
637

638
	if (configuration==NULL) {
639
640
641
		fprintf(stderr, "%s: empty configuration\n", __func__);
		return -1;
	}
642

's avatar
committed
643
644
	/* Check subjects */

645
646
   subject=configuration->subject;
   while (subject) {
's avatar
committed
647

648
		if (subject->id <= 0) {
's avatar
committed
649
			fprintf(stderr, "%s: id in [subject] section must be greater than zero\n and is %d", __func__, subject->id);
's avatar
committed
650
651
			return -1;
		}
's avatar
committed
652
	
653
654
655
656
657
658
659
660
661
662
		if (subject->hostname == NULL) {
			fprintf(stderr, "%s: you must specify hostname\n", __func__);
			return -1;
		}

		if (subject->interface == NULL) {
			fprintf(stderr, "%s: you must specify interface\n", __func__);
			return -1;
		}

663
664
665
666
667
		if (subject->label == NULL) {
			fprintf(stderr, "%s: you must specify label\n", __func__);
			return -1;
		}

668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
		subject=subject->next;
	} /* while (subject) */

	/* Check scopes */

   scope=configuration->scope;
   while (scope) {

		if (scope->id <= 0) {
			fprintf(stderr, "%s: id in [scope] section must be greater than zero\n", __func__);
			return -1;
		}
	
		if (scope->subject_ids == NULL) {
			fprintf(stderr, "%s: you must specify subject_ids in [scope] section\n", __func__);
			return -1;
		}

		if ((subject_no=split_strings(scope->subject_ids, MAX_SUBJECTS,
				scope->subject_array))<=0) {
			fprintf(stderr, "%s: split_strings() failed\n", __func__);
			return -1;
		}

		for (i=0; i<subject_no; i++) {
693
694
			int mpls, port;

695
696
697
698
699
700
701
			subject=configuration->subject;
			while (subject) {
				if (subject->id == atoi(scope->subject_array[i])) {
					scope->subject[i]=subject;
					break;
				}
				subject=subject->next;
's avatar
committed
702
			}
703
704
705
706
707
708
			if (!(scope->subject[i])) {
         	fprintf(stderr, 
					"%s: cannot find subject %d refered by scope %d\n",
            		__func__, atoi(scope->subject_array[i]), scope->id);
         	return -1;
      	}
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

			if (i==0) {
				mpls=scope->subject[i]->mpls;
				port=scope->subject[i]->port;
			}
			else {
				if (mpls != scope->subject[i]->mpls) {
					fprintf(stderr, "%s: mpls must be the same in all subjects in a scope\n", __func__);
					return -1;
				}
				if (port != scope->subject[i]->port) {
					fprintf(stderr, "%s: port must be the same in all subjects in a scope\n", __func__);
					return -1;
				}
			}
's avatar
committed
724
		}
725
726
727
728
729

		scope->subject_no = subject_no;

		scope=scope->next;
	} /* while (scope) */
's avatar
committed
730
731
732

	/* Check parameters */

733
734
   parameters=configuration->parameters;
   while (parameters) {
's avatar
committed
735

736
		if (parameters->id <= 0) {
's avatar
committed
737
738
739
740
         fprintf(stderr, "%s: id in [parameters] section must be greater than zero\n", __func__);
         return -1;
      }

741
742
743
		if (parameters->sau_mode!='d' && parameters->sau_mode!='b' && 
			 parameters->sau_mode!='p') {
			fprintf(stderr, "%s: sampling mode must be d, b or p\n", __func__);
744
745
746
	  		return -1;
		}

747
748
749
750
		if (parameters->sau_mode=='p') {
			if (parameters->sau_threshold<0 || parameters->sau_threshold>1) {
		  			fprintf(stderr, "%s: pass probability must be between 0 and 1\n",
						 __func__);
751
752
	  	  			return -1;
	  			}
753
754
755
	  		parameters->sau_threshold=
				(floor)(0xFFFFFFFF * (1 - parameters->sau_threshold));
	  		parameters->sau_mode_encoded=COMBO6_PROBABILISTIC;
's avatar
committed
756
  		}
757
758
759
760
  		else if (parameters->sau_mode=='b') {
	  		if (parameters->sau_threshold<0) {
	  			fprintf(stderr, "%s: byte threshold cannot be negative\n", 
					__func__);
's avatar
committed
761
	  			return -1;
762
  			}
763
764
			parameters->sau_threshold=(floor)(parameters->sau_threshold);
  			parameters->sau_mode_encoded=COMBO6_LENGTH_DETERMINISTIC;
's avatar
committed
765
766
		}
  		else {
767
768
769
  			if (parameters->sau_threshold<0) {
	  			fprintf(stderr, "%s: packet threshold cannot be negative\n", 
					__func__);
's avatar
committed
770
	  			return -1;
771
  			}
772
773
		   parameters->sau_threshold=(floor)(parameters->sau_threshold);
  			parameters->sau_mode_encoded=COMBO6_DETERMINISTIC;
774
		}
775

776
777
		if (parameters->sau_mode=='b') {
			fprintf(stderr, "%s: byte probabilistic sampling is not supported in this version\n", __func__);
's avatar
committed
778
779
780
			return -1;
		}

781
		if (parameters->payload_strings[1]) {
's avatar
committed
782
783
784
785
			fprintf(stderr, "%s: payload searching for multiple strings is not supported in this version\n", __func__);
			return -1;
		}

786
787
788
		if (parameters->interval.tv_sec<0 || parameters->interval.tv_usec<0 || 
			 parameters->interval.tv_usec>=1000000 ||
			 (parameters->interval.tv_sec==0 && parameters->interval.tv_usec==0)) {
's avatar
committed
789
790
791
792
			fprintf(stderr, "%s: incorrect interval value\n", __func__);
			return -1;
		}

793
794
		parameters=parameters->next;
	} /* while (parameters) */
's avatar
committed
795

796
	/* Check measurements */
's avatar
committed
797

798
799
	measurement=configuration->measurement; 
	while (measurement) {
's avatar
committed
800

801
802
803
804
805
806
		if (measurement->id <= 0) {
         fprintf(stderr, "%s: id in [measurement] section must be greater than zero\n", __func__);
         return -1;
      }
		if (measurement->scope_id <= 0) {
			fprintf(stderr, "%s: scope_id in [measurement] section must be greater than zero\n", __func__);
's avatar
committed
807
808
			return -1;
		}
809
810
		if (measurement->parameters_id <= 0) {
			fprintf(stderr, "%s: parameters_id in [measurement] section must be greater than zero\n", __func__);
's avatar
committed
811
812
			return -1;
		}
's avatar
committed
813

's avatar
committed
814
815
		/* Set default protocol string */

816
817
		if (!(measurement->protocols)) {
			if ((measurement->protocols=malloc(strlen("all")+1))==NULL) {
's avatar
committed
818
819
820
				fprintf(stderr, "%s: malloc() failed\n", __func__);
				return -1;
			}
821
			strcpy(measurement->protocols, "all");
's avatar
committed
822
823
824
		}

		/* Split protocol string into individual protocols */
's avatar
committed
825

826
827
828
		if ((protocols_no=split_strings(measurement->protocols, MAX_PROTOCOLS,
				measurement->protocols_array))<0) {
			fprintf(stderr, "%s: split_strings() failed\n", __func__);
's avatar
committed
829
830
831
			return -1;
		}

's avatar
committed
832
		/* Sort individual protocols alphabetically */
's avatar
committed
833

834
835
		qsort(measurement->protocols_array, protocols_no, (size_t)sizeof(char *),
			 compstr);
's avatar
committed
836

's avatar
committed
837
		/* Replace protocols string with the sorted one */
's avatar
committed
838

839
840
841
842
		free(measurement->protocols);
		if (concat_strings(&(measurement->protocols), MAX_PROTOCOLS,
				measurement->protocols_array)<0) {
			fprintf(stderr, "%s: concat_strings() failed\n", __func__);
's avatar
committed
843
844
845
			return -1;
		}
	
846
		/* Check references and set pointers */
's avatar
committed
847

848
849
850
851
		scope=configuration->scope;
		while (scope) {
			if (scope->id == measurement->scope_id) {
				measurement->scope=scope;
's avatar
committed
852
853
				break;
			}
854
			scope=scope->next;
's avatar
committed
855
		}
856
857
858
		if (!(measurement->scope)) {
			fprintf(stderr, "%s: cannot find scope refered by measurement %d\n",
				__func__, measurement->id);
859
860
861
			return -1;
		}

862
863
864
865
		parameters=configuration->parameters;
		while (parameters) {
			if (parameters->id == measurement->parameters_id) {
				measurement->parameters=parameters;
's avatar
committed
866
867
				break;
			}
868
			parameters=parameters->next;
's avatar
committed
869
		}
870
871
872
		if (!(measurement->parameters)) {
			fprintf(stderr, "%s: cannot find parameters refered by measurement %d\n",
				__func__, measurement->id);
873
874
875
			return -1;
		}

876
877
		measurement=measurement->next;
	} /* while (measurement) */
878
879
880
881

	return 0;
} /* check_conf() */

882
883
int print_conf(configuration_t *configuration) {
	measurement_t *measurement;
's avatar
committed
884
	char *ch, **chch;
885
886
   int i, j;

887
	if (configuration==NULL) {
's avatar
committed
888
889
890
		fprintf(stderr, "%s: empty configuration\n", __func__);	
		return -1;
	}
891

892
893
	/* Print global configuration */

894
895
	if (configuration->global->conf_filename)
		printf("global->conf_filename: %s\n", configuration->global->conf_filename);
896
	else
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
		printf("global->conf_filename: unspecified\n");

	printf("global->no_measure: %d\n", configuration->global->no_measure);
	printf("global->no_stdout: %d\n", configuration->global->no_stdout);
	printf("global->stdout_simple: %d\n", configuration->global->stdout_simple);

	/* Print measurements */

	measurement=configuration->measurement;
   while (measurement) {

		printf("\nmeasurement:\n");
		printf("id: %d\n", measurement->id);
		printf("scope_id: %d\n", measurement->scope_id);
		printf("parameters_id: %d\n", measurement->parameters_id);
		printf("protocols: %s\n", measurement->protocols); 

		/* Print subjects */

		i=0;
		while (i<MAX_SUBJECTS && measurement->scope->subject[i]) {
			printf("subject:\n");
			printf("id: %d\n", measurement->scope->subject[i]->id);
			printf("hostname: %s\n", measurement->scope->subject[i]->hostname);
			printf("interface: %s\n", measurement->scope->subject[i]->interface);
922
			printf("port: %d\n", measurement->scope->subject[i]->port);
923
924
			printf("mpls: %d\n", measurement->scope->subject[i]->mpls);
  			printf("link_mbps: %d\n", measurement->scope->subject[i]->link_mbps);
925
926
927
928
929
930
931
			printf("label: %s\n", measurement->scope->subject[i]->label);
			if (measurement->scope->subject[i]->description)
  				printf("description: %s\n", measurement->scope->subject[i]->description);
			else
				printf("description: unspecified\n");
			printf("direction: %s\n", (measurement->scope->subject[i]->out)?
				"out":"in");
932
933
			i++;
		}
's avatar
committed
934
935
936
	
		/* Print parameters */

937
938
939
		printf("parameters:\n");
		if (measurement->parameters->header_filter)
			printf("header_filter: %s\n", measurement->parameters->header_filter);
's avatar
committed
940
941
		else
			printf("header_filter: unspecified\n");
942
943
944
945
946
947

		printf("sau_mode: %c, sau_threshold: %u\n", 
			measurement->parameters->sau_mode, 
			(unsigned int)(floor(measurement->parameters->sau_threshold)));

		chch=measurement->parameters->payload_strings; 
's avatar
committed
948
		j=0;
's avatar
committed
949
   	if (*chch) {
950
			printf("payload_strings:");
's avatar
committed
951
952
			while (j<MAX_PAYLOAD_STRINGS && *chch) {
				ch=*chch;
953
954
      		if (j>0)
         		printf(",");
's avatar
committed
955
956
      		printf(" |%s|", ch);
				chch++; j++;
957
958
959
			}
   		printf("\n");
		}
's avatar
committed
960
961
		else
			printf("payload_strings: unspecified\n");
962
963
 
  		printf("interval.tv_sec: %d, interval.tv_usec: %d\n", 
964
965
			(int)(measurement->parameters->interval.tv_sec), 
			(int)(measurement->parameters->interval.tv_usec));
966

967
968
		measurement=measurement->next;
	} /* while (measurement) */
's avatar
committed
969
970

	return 0;
971
} /* print_conf() */
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000

int read_header_filter(int argc, char *argv[], char **p) {
	char header_filter[MAX_HEADER_FILTER+1];
	int i;

	header_filter[0]='\0';
	*p=NULL;

  	for (i=optind; i<argc; i++) {
  		if ((strlen(header_filter) + strlen(argv[i])) < MAX_HEADER_FILTER) {
	  		if (i>optind)
		  		strcat(header_filter, " ");
	  		strcat(header_filter, argv[i]);
	  	}
	  	else {
			fprintf(stderr, "%s: header filter string must not be longer than %d characters\n", __func__, MAX_HEADER_FILTER);
	  		exit(-1);
		}
  	}

	if (header_filter[0]) {
		if ((*p=malloc(strlen(header_filter)+1))==NULL) {
			fprintf(stderr, "%s: malloc() failed\n", __func__);
			return -1;
		}
		strcpy(*p, header_filter);
	}
	return 0;
} /* read_header_filter() */
For faster browsing, not all history is shown. View entire blame