1#!/usr/local/bin/perl
2#
3#  Purpose:
4#  FlowViewer_Utilities.pm holds utility functions that are called
5#  by FlowViewer, FlowGrapher, and FlowMonitor scripts.
6#
7#  Description:
8#  Various conversion and formatting utility functions.
9#
10#  Input arguments:
11#  Name                 Description
12#  -----------------------------------------------------------------------
13#  None
14#
15#  Modification history:
16#  Author       Date            Vers.   Description
17#  -----------------------------------------------------------------------
18#  J. Loiacono  07/04/2005      1.0     Original version.
19#  J. Loiacono  01/01/2006      2.0     Added y_format for FlowGrapher
20#  J. Loiacono  04/15/2006      2.3     Added time_check for testing
21#  J. Loiacono  07/04/2006      3.0     Included new formatting and filter subs
22#                                       Permits host names (thanks Mark Foster)
23#  J. Loiacono  12/25/2006      3.1     Allow all network masks, port ranges
24#  J. Loiacono  02/22/2007      3.2     Moved create_flowmonitor_html here
25#  J. Loiacono  12/07/2007      3.3     Exporter, Next Hop, Sampling, Logo,
26#                                       Named IFs, Unit Conv. (thanks C. Kashimoto)
27#  J. Loiacono  01/26/2008      3.3.1   E. Lautenschlaeger fix for exporter names
28#  J. Loiacono  04/22/2008      3.3.1   Exporter appearing on FlowMonitor output
29#  J. Loiacono  06/14/2008      3.3.1   Fixed printing extraneous Interface Names
30#  J. Loiacono  03/17/2011      3.4     Now permits up to 20 source/dest networks
31#                                       Can exclude IP addresses from requested ranges
32#                                       Logo's now have links to Saved reports
33#  J. Loiacono  05/08/2012      4.0     Major upgrade for IPFIX/v9 using SiLK,
34#                                       New User Interface
35#  J. Loiacono  09/11/2013      4.2.1   New international date formatting
36#  J. Loiacono  09/28/2013      4.2.2   Fixed unitialized @temp_ports
37#  J. Loiacono  01/26/2014      4.3     Removed 16-bit limitation on AS
38#  J. Loiacono  07/04/2014      4.4     Fixed IP address field checks
39#  J. Loiacono  11/02/2014      4.5     Ability to use SiLK localtime
40#                                       SiLK IPset processing
41#                                       Fixed port=0 filter processing
42#
43#$Author$
44#$Date$
45#$Header$
46#
47###########################################################################
48#
49#               BEGIN EXECUTABLE STATEMENTS
50#
51
52use Time::Local;
53use Time::HiRes qw( usleep ualarm gettimeofday tv_interval );
54
55sub format_date {
56
57	my ($sec,$min,$hr,$date,$mnth,$yr) = @_;
58	$mnth++;
59	$yr += 1900;
60	if ($date<10) {$date = "0" . $date; }
61	if ($mnth<10) {$mnth = "0" . $mnth; }
62	if ($hr<10) {$hr = "0" . $hr; }
63	if ($min<10) {$min = "0" . $min; }
64	if ($sec<10) {$sec = "0" . $sec; }
65	$formatted_date = $mnth ."\/". $date ."\/". $yr ." ". $hr .":". $min .":". $sec;
66}
67
68sub format_number {
69
70	my ($number) = @_;
71	my $counter;
72        $formatted_number = "";
73        $length_number = length($number);
74        $counter = $length_number;
75        for ($digit=1;$digit<=$length_number;$digit++) {
76                $formatted_number = substr($number,$counter-1,1) . $formatted_number;
77                if (($digit>0) && ($digit%3 == 0)) { $formatted_number = "," . $formatted_number;}
78                $counter = $counter - 1;
79        }
80        if ( substr($formatted_number,0,1) eq ",") {
81                $formatted_number = substr($formatted_number,1,35); }
82
83	return $formatted_number;
84}
85
86sub date_to_epoch {
87
88	my ($in_date,$in_time,$time_zone)  = @_;
89
90	($mon,$day,$yr) = split(/\//,$in_date);
91	($hr, $min, $sec) = split(/:/,$in_time);
92	$date = $mon."/".$day."/".$yr." ".$hr.":".$min.":".$sec;
93	if ($time_zone eq "GMT") {
94		$epoch_date = timegm($sec,$min,$hr,$day,$mon-1,$yr); }
95	else {
96		$epoch_date = timelocal($sec,$min,$hr,$day,$mon-1,$yr); }
97	return $epoch_date;
98}
99
100sub epoch_to_date {
101
102	my ($epoch_date,$time_zone)  = @_;
103
104	if ($time_zone eq "GMT") {
105		($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = gmtime($epoch_date); }
106	else {
107		($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = localtime($epoch_date); }
108
109	$current_yr_date = $yr_date;
110	$mnth++;
111	$yr += 1900;
112	if ($date<10) {$date = "0" . $date; }
113	if ($mnth<10) {$mnth = "0" . $mnth; }
114	if ($hr<10) {$hr = "0" . $hr; }
115	if ($min<10) {$min = "0" . $min; }
116	if ($sec<10) {$sec = "0" . $sec; }
117	return $mnth ."\/". $date ."\/". $yr ." ". $hr .":". $min .":". $sec;
118}
119
120sub flow_date_time {
121
122        my ($flow_time,$time_zone) = @_;
123
124        $formatted = epoch_to_date($flow_time,$time_zone);
125        ($first_half,$second_half) = split(/ /,$formatted);
126        ($mnth,$date,$yr) = split(/\//,$first_half);
127        ($hr,$min,$sec) = split(/:/,$second_half);
128
129        if ((0 < $date) && ($date < 10)) { $date = substr($date,1,1); }
130        if ((0 < $hr) && ($hr < 10)) { $hr = substr($hr,1,1); }
131
132        if    ($mnth == 1)  { $month = "January"; }
133        elsif ($mnth == 2)  { $month = "February"; }
134        elsif ($mnth == 3)  { $month = "March"; }
135        elsif ($mnth == 4)  { $month = "April"; }
136        elsif ($mnth == 5)  { $month = "May"; }
137        elsif ($mnth == 6)  { $month = "June"; }
138        elsif ($mnth == 7)  { $month = "July"; }
139        elsif ($mnth == 8)  { $month = "August"; }
140        elsif ($mnth == 9)  { $month = "September"; }
141        elsif ($mnth == 10) { $month = "October"; }
142        elsif ($mnth == 11) { $month = "November"; }
143        elsif ($mnth == 12) { $month = "December"; }
144
145        return $month ." ". $date .", ". $yr ." ". $hr .":". $min .":". $sec;
146}
147
148sub day_of_week {
149
150	my ($day_number) = @_;
151
152	if    ($day_number == 0) { $day = "Sun"; }
153	elsif ($day_number == 1) { $day = "Mon"; }
154	elsif ($day_number == 2) { $day = "Tue"; }
155	elsif ($day_number == 3) { $day = "Wed"; }
156	elsif ($day_number == 4) { $day = "Thr"; }
157	elsif ($day_number == 5) { $day = "Fri"; }
158	elsif ($day_number == 6) { $day = "Sat"; }
159
160	return $day;
161}
162
163sub month_of_year {
164
165	my ($mnth) = @_;
166
167	if    ($mnth == 0)  { $month = "Jan"; }
168	elsif ($mnth == 1)  { $month = "Feb"; }
169	elsif ($mnth == 2)  { $month = "Mar"; }
170	elsif ($mnth == 3)  { $month = "Apr"; }
171	elsif ($mnth == 4)  { $month = "May"; }
172	elsif ($mnth == 5)  { $month = "Jun"; }
173	elsif ($mnth == 6)  { $month = "Jul"; }
174	elsif ($mnth == 7)  { $month = "Aug"; }
175	elsif ($mnth == 8)  { $month = "Sep"; }
176	elsif ($mnth == 9)  { $month = "Oct"; }
177	elsif ($mnth == 10) { $month = "Nov"; }
178	elsif ($mnth == 11) { $month = "Dec"; }
179
180	return $month;
181}
182
183sub full_month {
184
185	my ($mnth) = @_;
186
187        if    ($mnth == "01")  { $month = "January"; }
188        elsif ($mnth == "02")  { $month = "February"; }
189        elsif ($mnth == "03")  { $month = "March"; }
190        elsif ($mnth == "04")  { $month = "April"; }
191        elsif ($mnth == "05")  { $month = "May"; }
192        elsif ($mnth == "06")  { $month = "June"; }
193        elsif ($mnth == "07")  { $month = "July"; }
194        elsif ($mnth == "08")  { $month = "August"; }
195        elsif ($mnth == "09")  { $month = "September"; }
196        elsif ($mnth == "10")  { $month = "October"; }
197        elsif ($mnth == "11")  { $month = "November"; }
198        elsif ($mnth == "12")  { $month = "December"; }
199
200	return $month;
201}
202
203sub convert_month {
204
205	my ($mnth) = @_;
206
207	if    ($mnth eq "Jan") { $month = "01"; }
208	elsif ($mnth eq "Feb") { $month = "02"; }
209	elsif ($mnth eq "Mar") { $month = "03"; }
210	elsif ($mnth eq "Apr") { $month = "04"; }
211	elsif ($mnth eq "May") { $month = "05"; }
212	elsif ($mnth eq "Jun") { $month = "06"; }
213	elsif ($mnth eq "Jul") { $month = "07"; }
214	elsif ($mnth eq "Aug") { $month = "08"; }
215	elsif ($mnth eq "Sep") { $month = "09"; }
216	elsif ($mnth eq "Oct") { $month = "10"; }
217	elsif ($mnth eq "Nov") { $month = "11"; }
218	elsif ($mnth eq "Dec") { $month = "12"; }
219
220	return $month;
221}
222
223sub y_format {
224
225        my $value = shift;
226        my $ret;
227
228        if ($value >= 1000000) {
229                $ret = int ($value / 1000000) . " M"; }
230        else {
231                $ret = $value; }
232        return $ret;
233}
234
235sub get_suffix {
236
237	my $suffix;
238
239	($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = localtime(time);
240	$mnth++;
241	$yr += 1900;
242	if ((0 < $mnth) && ($mnth < 10)) { $mnth = "0" . $mnth; }
243	if ((0 < $date) && ($date < 10)) { $date = "0" . $date; }
244	if ((0 <= $hr)  && ($hr   < 10)) { $hr  = "0"  . $hr; }
245	if ((0 <= $min) && ($min  < 10)) { $min = "0"  . $min; }
246	if ((0 <= $sec) && ($sec  < 10)) { $sec = "0"  . $sec; }
247	$prefix = $yr . $mnth . $date ."_". $hr . $min . $sec;
248	$suffix = $hr . $min . $sec;
249
250	@letters=(A..Z);
251	$first_letter  = $letters[rand 26];
252	$second_letter = $letters[rand 26];
253
254	$suffix .= $first_letter . $second_letter;
255	return $suffix;
256}
257
258
259sub time_check {
260
261        my ($tc_event) = @_;
262
263        $tc_current_time = [gettimeofday];
264        $tc_elapsed_time = tv_interval( $tc_last_time, $tc_current_time );
265        if ($tc_last_event eq "") { $tc_elapsed_time = 0; }
266        $tc_total_time  += $tc_elapsed_time;
267
268        printf DEBUG "from: %-30s to: %-30s  elapsed seconds: %-3.6f  running: %-3.6f\n", $tc_last_event, $tc_event, $tc_elapsed_time, $tc_total_time;
269
270        $tc_last_time = $tc_current_time;
271        $tc_last_event = $tc_event;
272}
273
274sub create_filter_file {
275
276	my $new_filter_file;
277
278	# General parameters for generating Filter Files
279
280	my $device_name       = $FORM{'device_name'};
281	my $flow_select       = $FORM{'flow_select'};
282	my $start_date        = $FORM{'start_date'};
283	my $start_time        = $FORM{'start_time'};
284	my $end_date          = $FORM{'end_date'};
285	my $end_time          = $FORM{'end_time'};
286	my $source_addresses  = $FORM{'source_address'};
287	my $source_ports      = $FORM{'source_port'};
288	my $source_ifs        = $FORM{'source_if'};
289	my $sif_names         = $FORM{'sif_name'};
290	my $source_ases       = $FORM{'source_as'};
291	my $dest_addresses    = $FORM{'dest_address'};
292	my $dest_ports        = $FORM{'dest_port'};
293	my $dest_ifs          = $FORM{'dest_if'};
294	my $dif_names         = $FORM{'dif_name'};
295	my $dest_ases         = $FORM{'dest_as'};
296	my $protocols         = $FORM{'protocols'};
297	my $tos_fields        = $FORM{'tos_fields'};
298	my $tcp_flags         = $FORM{'tcp_flags'};
299	my $exporter          = $FORM{'exporter'};
300	my $nexthop_ips       = $FORM{'nexthop_ip'};
301
302	$new_filter_file      = "$filter_file";
303
304	if ($date_format eq "DMY") {
305	        ($temp_day_s,$temp_mnth_s,$temp_yr_s) = split(/\//,$start_date);
306	        ($temp_day_e,$temp_mnth_e,$temp_yr_e) = split(/\//,$end_date);
307	} elsif ($date_format eq "DMY2") {
308	        ($temp_day_s,$temp_mnth_s,$temp_yr_s) = split(/\./,$start_date);
309	        ($temp_day_e,$temp_mnth_e,$temp_yr_e) = split(/\./,$end_date);
310	} elsif ($date_format eq "YMD") {
311	        ($temp_yr_s,$temp_mnth_s,$temp_day_s) = split(/\-/,$start_date);
312	        ($temp_yr_e,$temp_mnth_e,$temp_day_e) = split(/\-/,$end_date);
313	} else {
314	        ($temp_mnth_s,$temp_day_s,$temp_yr_s) = split(/\//,$start_date);
315	        ($temp_mnth_e,$temp_day_e,$temp_yr_e) = split(/\//,$end_date);
316	}
317	$start_date = $temp_mnth_s ."/". $temp_day_s ."/". $temp_yr_s;
318	$end_date   = $temp_mnth_e ."/". $temp_day_e ."/". $temp_yr_e;
319
320	if ($start_date ne "") {
321		$epoch_start = date_to_epoch($start_date,$start_time,"LOCAL");
322		$flows_start = &flow_date_time($epoch_start,"LOCAL");
323	}
324
325	if ($end_date ne "") {
326		$epoch_end   = date_to_epoch($end_date,$end_time,"LOCAL");
327		$flows_end   = &flow_date_time($epoch_end,"LOCAL");
328	}
329
330	# Create the filter to match the input specifications
331
332	open (FILTER,">$new_filter_file") || die "cannot open Filter file for write: $new_filter_file";
333
334	$still_more = 1;
335
336	# Set up source address filtering, if any
337
338	if ($source_addresses ne "") {
339
340	        print FILTER "filter-primitive source_address\n";
341	        print FILTER "  type ip-address-prefix\n";
342
343	        $source_addresses =~ s/\s+//g;
344
345		$include = 0;  $exclude = 0;
346
347		while ($still_more) {
348
349	                ($source_address) = split(/,/,$source_addresses);
350
351	                $start_char = length($source_address) + 1;
352	                $source_addresses = substr($source_addresses,$start_char);
353
354			if ($source_address =~ /:/) { &print_error("Ranges not supported for this field."); last; }
355
356	                if (($source_address =~ m/^\s*-*\d+/) && (!($source_address =~ /[A-Za-z]/))) {
357		                $_ = $source_address;
358		                $num_dots = tr/\.//;
359		                if ($num_dots != 3) { &print_error("Not full address: $source_address Try: n.n.n.n/m"); last; }
360
361		                ($a,$b,$c,$d)    = split(/\./,$source_address);
362				($source_ip,$source_prefix) = split(/\//,$source_address);
363
364		                if (($source_prefix eq "") && ($d eq "0")) {
365		                        &print_error("Missing or improper IP address prefix.  Use (e.g.) : 192.168.10.0/24."); last; }
366		                if (($source_prefix < 0) || ($source_prefix > 32)) {
367					&print_error("Improper network mask (0 <= mask <= 32)"); last; }
368
369		                if ($a > 255 || $a eq "") { &print_error("Improper network: $source_address Try: n.n.n.n/m"); last; }
370		                if ($b > 255 || $b eq "") { &print_error("Improper network: $source_address Try: n.n.n.n/m"); last; }
371		                if ($c > 255 || $c eq "") { &print_error("Improper network: $source_address Try: n.n.n.n/m"); last; }
372		                if ($d > 255 || $d eq "") { &print_error("Improper network: $source_address Try: n.n.n.n/m"); last; }
373			}
374
375	                if (substr($source_address,0,1) eq "-") {
376	                        $source_address = substr($source_address,1);
377				print FILTER "  deny $source_address\n";
378	                        $exclude = 1; }
379	                else {
380	                        print FILTER "  permit $source_address\n";
381				$include = 1;
382	                }
383
384	                if ($source_addresses eq "") { last; }
385	        }
386
387	        if (($exclude) && (!$include)) {
388	                $exclude = 0;
389	                print FILTER "  default permit\n";
390		}
391	        if (($include) && (!$exclude)) {
392	                $include = 0;
393	                print FILTER "  default deny\n";
394	        }
395
396	        $save_file .= "_" . $source_address;
397	}
398
399	# Set up source interface filtering, if any
400
401	if ($sif_names ne "") {
402		if ($source_ifs eq "") {
403			$source_ifs = $sif_names;
404		} else {
405			$source_ifs = $source_ifs .",". $sif_names;
406		}
407	}
408
409	if ($source_ifs ne "") {
410
411	        print FILTER "filter-primitive source_if\n";
412	        print FILTER "  type ifindex\n";
413
414	        $source_ifs =~ s/\s+//g;
415
416		$include = 0;  $exclude = 0;
417
418		while ($still_more) {
419
420	                ($source_if) = split(/,/,$source_ifs);
421	                $start_char = length($source_if) + 1;
422	                $source_ifs = substr($source_ifs,$start_char);
423
424			if ($source_if =~ /:/)      { &print_error("Ranges not supported for this field."); last; }
425	                if (length($source_if) > 4) { &print_error("Improper interface index: $source_if Try: nnn"); last; }
426
427	                if (substr($source_if,0,1) eq "-") {
428	                        $source_if = substr($source_if,1,3);
429				if ($source_if =~ /[^0-9]/) { &print_error("Improper Source interface index: $source_if Try: nnn"); last; }
430	                        print FILTER "  deny $source_if\n";
431	                        $exclude = 1; }
432	                else {
433	                        print FILTER "  permit $source_if\n";
434				if ($source_if =~ /[^0-9]/) { &print_error("Improper Source interface index: $source_if Try: nnn"); last; }
435				$include = 1;
436	                }
437
438			if ($source_ifs eq "") { last; }
439	        }
440
441	        if (($exclude) && (!$include)) {
442	                $exclude = 0;
443	                print FILTER "  default permit\n";
444		}
445	        if (($include) && (!$exclude)) {
446	                $include = 0;
447	                print FILTER "  default deny\n";
448	        }
449
450	        $save_file .= "_" . $source_if;
451	}
452
453	# Set up source port filtering, if any
454
455	if ($source_ports ne "") {
456
457	        print FILTER "filter-primitive source_port\n";
458	        print FILTER "  type ip-port\n";
459
460	        $source_ports =~ s/\s+//g;
461
462		$include = 0;  $exclude = 0;
463
464		while ($still_more) {
465
466	                ($source_port) = split(/,/,$source_ports);
467	                $start_char = length($source_port) + 1;
468	                $source_ports = substr($source_ports,$start_char);
469
470			$range = 0;
471			if ($source_port =~ /:/) {
472				$range = 1;
473				($start_port,$end_port) = split(/:/,$source_port);
474			}
475
476			if ($range) {
477	                	if (($start_port < -65536) || ($start_port > 65536)) {
478					&print_error("Port out of range -65536 < port < 65536");
479					last;
480				}
481	                	if (($end_port < -65536) || ($end_port > 65536)) {
482					&print_error("Port out of range -65536 < port < 65536");
483					last;
484				}
485			}
486			else {
487	                	if (($source_port < -65536) || ($source_port > 65536)) {
488					&print_error("Port out of range -65536 < port < 65536");
489					last;
490				}
491			}
492
493			if ($range) {
494	                	if (substr($start_port,0,1) eq "-") {
495	                       		$start_port = substr($start_port,1,6);
496					for ($j=$start_port;$j<=$end_port;$j++) { $port_range .= "$j,"; }
497	                        	print FILTER "  deny $port_range\n";
498	                        	$exclude = 1; }
499	                	else {
500					for ($j=$start_port;$j<=$end_port;$j++) { $port_range .= "$j,"; }
501	                        	print FILTER "  permit $port_range\n";
502					$include = 1;
503	                	}
504			}
505			else {
506	                	if (substr($source_port,0,1) eq "-") {
507	                       		$source_port = substr($source_port,1,256);
508	                        	print FILTER "  deny $source_port\n";
509	                        	$exclude = 1; }
510	                	else {
511	                        	print FILTER "  permit $source_port\n";
512					$include = 1;
513	                	}
514	                }
515
516			$range = 0;
517
518	                if ($source_ports eq "") { last; }
519	        }
520
521	        if (($exclude) && (!$include)) {
522	                $exclude = 0;
523	                print FILTER "  default permit\n";
524		}
525	        if (($include) && (!$exclude)) {
526	                $include = 0;
527	                print FILTER "  default deny\n";
528	        }
529
530	        $save_file .= "_" . $source_port;
531	}
532
533	# Set up source AS filtering, if any
534
535	if ($source_ases ne "") {
536
537	        print FILTER "filter-primitive source_as\n";
538	        print FILTER "  type as\n";
539
540	        $source_ases =~ s/\s+//g;
541
542		$include = 0;  $exclude = 0;
543
544		while ($still_more) {
545
546	                ($source_as) = split(/,/,$source_ases);
547	                $start_char = length($source_as) + 1;
548	                $source_ases = substr($source_ases,$start_char);
549
550			if ($source_as =~ /:/) { &print_error("Ranges not supported for this field."); last; }
551
552	                if (substr($source_as,0,1) eq "-") {
553	                        $source_as = substr($source_as,1,6);
554	                        print FILTER "  deny $source_as\n";
555	                        $exclude = 1; }
556	                else {
557	                        print FILTER "  permit $source_as\n";
558				$include = 1;
559	                }
560
561	                if ($source_ases eq "") { last; }
562	        }
563
564	        if (($exclude) && (!$include)) {
565	                $exclude = 0;
566	                print FILTER "  default permit\n";
567		}
568	        if (($include) && (!$exclude)) {
569	                $include = 0;
570	                print FILTER "  default deny\n";
571	        }
572
573	        $save_file .= "_" . $source_as;
574	}
575
576	# Set up destination address filtering, if any
577
578	if ($dest_addresses ne "") {
579
580	        print FILTER "filter-primitive dest_address\n";
581	        print FILTER "  type ip-address-prefix\n";
582
583	        $dest_addresses =~ s/\s+//g;
584
585		$include = 0;  $exclude = 0;
586
587		while ($still_more) {
588
589	                ($dest_address) = split(/,/,$dest_addresses);
590	                $start_char = length($dest_address) + 1;
591	                $dest_addresses = substr($dest_addresses,$start_char);
592
593			if ($dest_address =~ /:/) { &print_error("Ranges not supported for this field."); last; }
594
595	                if (($dest_address =~ m/^\s*-*\d+/) && (!($dest_address =~ /[A-Za-z]/))) {
596		                $_ = $dest_address;
597		                $num_dots = tr/\.//;
598		                if ($num_dots != 3) { &print_error("Not full address: $dest_address Try: n.n.n.n/m"); last; }
599
600		                ($a,$b,$c,$d)    = split(/\./,$dest_address);
601				($dest_ip,$dest_prefix)     = split(/\//,$dest_address);
602
603		                if (($dest_prefix eq "") && ($d eq "0")) {
604		                        &print_error("Missing or improper IP address prefix.  Use (e.g.) : 192.168.10.0/24"); last; }
605		                if (($dest_prefix < 0) || ($dest_prefix > 32)) { &print_error("Improper network mask (0 <= mask <= 32)"); last; }
606
607		                if ($a > 255 || $a eq "") { &print_error("Improper network: $dest_address Try: n.n.n.n/m"); last; }
608		                if ($b > 255 || $b eq "") { &print_error("Improper network: $dest_address Try: n.n.n.n/m"); last; }
609		                if ($c > 255 || $c eq "") { &print_error("Improper network: $dest_address Try: n.n.n.n/m"); last; }
610		                if ($d > 255 || $d eq "") { &print_error("Improper network: $dest_address Try: n.n.n.n/m"); last; }
611			}
612
613	                if (substr($dest_address,0,1) eq "-") {
614	                        $dest_address = substr($dest_address,1);
615	                        print FILTER "  deny $dest_address\n";
616	                        $exclude = 1; }
617	                else {
618	                        print FILTER "  permit $dest_address\n";
619				$include = 1;
620	                }
621
622	                if ($dest_addresses eq "") { last; }
623	        }
624
625	        if (($exclude) && (!$include)) {
626	                $exclude = 0;
627	                print FILTER "  default permit\n";
628		}
629	        if (($include) && (!$exclude)) {
630	                $include = 0;
631	                print FILTER "  default deny\n";
632	        }
633
634	        $save_file .= "_" . $dest_address;
635	}
636
637	# Set up destination interface filtering, if any
638
639	if ($dif_names ne "") {
640		if ($dest_ifs eq "") {
641			$dest_ifs = $dif_names;
642		} else {
643			$dest_ifs = $dest_ifs .",". $dif_names;
644		}
645	}
646
647	if ($dest_ifs ne "") {
648
649	        print FILTER "filter-primitive dest_if\n";
650	        print FILTER "  type ifindex\n";
651
652	        $dest_ifs =~ s/\s+//g;
653
654		$include = 0;  $exclude = 0;
655
656		while ($still_more) {
657
658	                ($dest_if) = split(/,/,$dest_ifs);
659	                $start_char = length($dest_if) + 1;
660	                $dest_ifs = substr($dest_ifs,$start_char);
661
662			if ($dest_if =~ /:/)      { &print_error("Ranges not supported for this field."); last; }
663	                if (length($dest_if) > 4) { &print_error("Improper interface index: $dest_if Try: nnn"); last; }
664
665	                if (substr($dest_if,0,1) eq "-") {
666	                        $dest_if = substr($dest_if,1,3);
667				if ($dest_if =~ /[^0-9]/) { &print_error("Improper Destination interface index: $dest_if Try: nnn"); last; }
668	                        print FILTER "  deny $dest_if\n";
669	                        $exclude = 1; }
670	                else {
671				if ($dest_if =~ /[^0-9]/) { &print_error("Improper Destination interface index: $dest_if Try: nnn"); last; }
672	                        print FILTER "  permit $dest_if\n";
673				$include = 1;
674	                }
675
676	                if ($dest_ifs eq "") { last; }
677	        }
678
679	        if (($exclude) && (!$include)) {
680	                $exclude = 0;
681	                print FILTER "  default permit\n";
682		}
683	        if (($include) && (!$exclude)) {
684	                $include = 0;
685	                print FILTER "  default deny\n";
686	        }
687
688	        $save_file .= "_" . $dest_if;
689	}
690
691	# Set up destination port filtering, if any
692
693	if ($dest_ports ne "") {
694
695	        print FILTER "filter-primitive dest_port\n";
696	        print FILTER "  type ip-port\n";
697
698	        $dest_ports =~ s/\s+//g;
699
700		$include = 0;  $exclude = 0;
701
702		while ($still_more) {
703
704	                ($dest_port) = split(/,/,$dest_ports);
705	                $start_char = length($dest_port) + 1;
706	                $dest_ports = substr($dest_ports,$start_char);
707
708			$range = 0;
709			if ($dest_port =~ /:/) {
710				$range = 1;
711				($start_port,$end_port) = split(/:/,$dest_port);
712			}
713
714			if ($range) {
715	                	if (($start_port < -65536) || ($start_port > 65536)) {
716					&print_error("Port out of range -65536 < port < 65536");
717					last;
718				}
719	                	if (($end_port < -65536) || ($end_port > 65536)) {
720					&print_error("Port out of range -65536 < port < 65536");
721					last;
722				}
723			}
724			else {
725	                	if (($dest_port < -65536) || ($dest_port > 65536)) {
726					&print_error("Port out of range -65536 < port < 65536");
727					last;
728				}
729			}
730
731			if ($range) {
732	                	if (substr($start_port,0,1) eq "-") {
733	                       		$start_port = substr($start_port,1,6);
734					for ($j=$start_port;$j<=$end_port;$j++) { $port_range .= "$j,"; }
735	                        	print FILTER "  deny $port_range\n";
736	                        	$exclude = 1; }
737	                	else {
738					for ($j=$start_port;$j<=$end_port;$j++) { $port_range .= "$j,"; }
739	                        	print FILTER "  permit $port_range\n";
740	                        	$include = 1;
741	                	}
742			}
743			else {
744	                	if (substr($dest_port,0,1) eq "-") {
745	                       		$dest_port = substr($dest_port,1,256);
746	                        	print FILTER "  deny $dest_port\n";
747	                        	$exclude = 1; }
748	                	else {
749	                        	print FILTER "  permit $dest_port\n";
750	                        	$include = 1;
751	                	}
752	                }
753
754			$range = 0;
755
756	                if ($dest_ports eq "") { last; }
757	        }
758
759	        if (($exclude) && (!$include)) {
760	                $exclude = 0;
761	                print FILTER "  default permit\n";
762		}
763	        if (($include) && (!$exclude)) {
764	                $include = 0;
765	                print FILTER "  default deny\n";
766	        }
767
768	        $save_file .= "_" . $dest_port;
769	}
770
771	# Set up destination AS filtering, if any
772
773	if ($dest_ases ne "") {
774
775	        print FILTER "filter-primitive dest_as\n";
776	        print FILTER "  type as\n";
777
778	        $dest_ases =~ s/\s+//g;
779
780		$include = 0;  $exclude = 0;
781
782		while ($still_more) {
783
784	                ($dest_as) = split(/,/,$dest_ases);
785	                $start_char = length($dest_as) + 1;
786	                $dest_ases = substr($dest_ases,$start_char);
787
788			if ($dest_as =~ /:/) { &print_error("Ranges not supported for this field."); last; }
789
790	                if (substr($dest_as,0,1) eq "-") {
791	                        $dest_as = substr($dest_as,1,6);
792	                        print FILTER "  deny $dest_as\n";
793	                        $exclude = 1; }
794	                else {
795	                        print FILTER "  permit $dest_as\n";
796				$include = 1;
797	                }
798
799	                if ($dest_ases eq "") { last; }
800	        }
801
802	        if (($exclude) && (!$include)) {
803	                $exclude = 0;
804	                print FILTER "  default permit\n";
805		}
806	        if (($include) && (!$exclude)) {
807	                $include = 0;
808	                print FILTER "  default deny\n";
809	        }
810
811	        $save_file .= "_" . $dest_as;
812	}
813
814	# Set up Protocol filtering, if any
815
816	if ($protocols ne "") {
817
818	        print FILTER "filter-primitive protocol\n";
819	        print FILTER "  type ip-protocol\n";
820
821	        $protocols =~ s/\s+//g;
822
823		$include = 0;  $exclude = 0;
824
825		while ($still_more) {
826
827	                ($protocol) = split(/,/,$protocols);
828	                $start_char = length($protocol) + 1;
829	                $protocols = substr($protocols,$start_char);
830
831			if ($protocol =~ /:/) { &print_error("Ranges not supported for this field."); last; }
832	                if (($protocol < -255) || ($protocol > 255)) { &print_error("Protocol out of range 1 < Protocol < 255"); last; }
833
834	                if (substr($protocol,0,1) eq "-") {
835	                        $protocol = substr($protocol,1,3);
836	                        print FILTER "  deny $protocol\n";
837	                        $exclude = 1; }
838	                else {
839	                        print FILTER "  permit $protocol\n";
840				$include = 1;
841	                }
842
843	                if ($protocols eq "") { last; }
844	        }
845
846	        if (($exclude) && (!$include)) {
847	                $exclude = 0;
848	                print FILTER "  default permit\n";
849		}
850	        if (($include) && (!$exclude)) {
851	                $include = 0;
852	                print FILTER "  default deny\n";
853	        }
854
855	        $save_file .= "_" . $protocol;
856	}
857
858	# Set up TCP Flag filtering, if any
859
860	if ($tcp_flags ne "") {
861
862	        print FILTER "filter-primitive tcp_flag\n";
863	        print FILTER "  type ip-tcp-flags\n";
864
865	        $tcp_flags =~ s/\s+//g;
866
867		$include = 0;  $exclude = 0;
868
869		while ($still_more) {
870
871	                ($tcp_flag) = split(/,/,$tcp_flags);
872	                $start_char = length($tcp_flag) + 1;
873	                $tcp_flags = substr($tcp_flags,$start_char);
874
875			if ($tcp_flag =~ /:/) { &print_error("Ranges not supported for this field."); last; }
876	                if (length($tcp_flag) > 4) { &print_error("TCP Flag out of range: 0x00 < TCP Flag < 0xFF"); last; }
877
878			($tcp_flag,$tcp_mask) = split(/\//,$tcp_flag);
879
880	                if (substr($tcp_flag,0,1) eq "-") {
881	                        $tcp_flag = substr($tcp_flag,1,4);
882				if ($tcp_mask ne "") { print FILTER "  mask $tcp_mask\n"; }
883	                        print FILTER "  deny $tcp_flag\n";
884				$exclude = 1; }
885	                else {
886				if ($tcp_mask ne "") { print FILTER "  mask $tcp_mask\n"; }
887	                        print FILTER "  permit $tcp_flag\n";
888				$include = 1;
889	                }
890
891	                if ($tcp_flags eq "") { last; }
892	        }
893
894	        if (($exclude) && (!$include)) {
895	                $exclude = 0;
896	                print FILTER "  default permit\n";
897		}
898	        if (($include) && (!$exclude)) {
899	                $include = 0;
900	                print FILTER "  default deny\n";
901	        }
902
903	        $save_file .= "_" . $tcp_flag;
904	}
905
906	# Set up TOS Field filtering, if any
907
908	if ($tos_fields ne "") {
909
910	        print FILTER "filter-primitive tos_field\n";
911	        print FILTER "  type ip-tos\n";
912
913	        $tos_fields =~ s/\s+//g;
914
915		$include = 0;  $exclude = 0;
916
917		while ($still_more) {
918
919	                ($tos_field) = split(/,/,$tos_fields);
920	                $start_char = length($tos_field) + 1;
921	                $tos_fields = substr($tos_fields,$start_char);
922
923			if ($tos_field =~ /:/) { &print_error("Ranges not supported for this field."); last; }
924	                if (length($tos_field) > 4) { &print_error("TOS Field out of range: 0x00 < TOS Field < 0xFF"); last; }
925
926			($tos_field,$tos_mask) = split(/\//,$tos_field);
927
928	                if (substr($tos_field,0,1) eq "-") {
929	                        $tos_field = substr($tos_field,1,4);
930				if ($tos_mask ne "") { print FILTER "  mask $tos_mask\n"; }
931	                        print FILTER "  deny $tos_field\n";
932				$exclude = 1; }
933	                else {
934				if ($tos_mask ne "") { print FILTER "  mask $tos_mask\n"; }
935	                        print FILTER "  permit $tos_field\n";
936				$include = 1;
937	                }
938
939	                if ($tos_fields eq "") { last; }
940	        }
941
942	        if (($exclude) && (!$include)) {
943	                $exclude = 0;
944	                print FILTER "  default permit\n";
945		}
946	        if (($include) && (!$exclude)) {
947	                $include = 0;
948	                print FILTER "  default deny\n";
949	        }
950
951	        $save_file .= "_" . $tos_field;
952	}
953
954	# Set up exporter address filtering, if any
955
956	if ($exporter ne "") {
957
958	        print FILTER "filter-primitive exporter\n";
959	        print FILTER "  type ip-address-prefix\n";
960
961	        $exporter =~ s/\s+//g;
962
963		$include = 0;  $exclude = 0;
964
965		while ($still_more) {
966
967	                ($exporter_address) = split(/,/,$exporter);
968	                $start_char = length($exporter_address) + 1;
969	                $exporter = substr($exporter,$start_char);
970
971			if ($exporter_address =~ /:/) { &print_error("Ranges not supported for this field."); last; }
972
973	                if ($exporter_address =~ m/^\s*-*\d+/) {
974		                $_ = $exporter_address;
975		                $num_dots = tr/\.//;
976		                if ($num_dots != 3) { &print_error("Not full address: $exporter_address Try: n.n.n.n/m"); last; }
977
978		                ($a,$b,$c,$d)    = split(/\./,$exporter_address);
979				($exporter_ip,$exporter_prefix) = split(/\//,$exporter_address);
980
981		                if (($exporter_prefix eq "") && ($d eq "0")) {
982		                        &print_error("Missing or improper IP address prefix.  Use (e.g.) : 192.168.10.0/24."); last; }
983		                if (($exporter_prefix < 0) || ($exporter_prefix > 32)) {
984					&print_error("Improper network mask (0 <= mask <= 32)"); last; }
985
986		                if ($a > 255 || $a eq "") { &print_error("Improper network: $exporter_address Try: n.n.n.n/m"); last; }
987		                if ($b > 255 || $b eq "") { &print_error("Improper network: $exporter_address Try: n.n.n.n/m"); last; }
988		                if ($c > 255 || $c eq "") { &print_error("Improper network: $exporter_address Try: n.n.n.n/m"); last; }
989		                if ($d > 255 || $d eq "") { &print_error("Improper network: $exporter_address Try: n.n.n.n/m"); last; }
990			}
991
992	                if (substr($exporter_address,0,1) eq "-") {
993	                        $exporter_address = substr($exporter_address,1);
994				print FILTER "  deny $exporter_address\n";
995	                        $exclude = 1; }
996	                else {
997	                        print FILTER "  permit $exporter_address\n";
998				$include = 1;
999	                }
1000
1001	                if ($exporter eq "") { last; }
1002	        }
1003
1004	        if (($exclude) && (!$include)) {
1005	                $exclude = 0;
1006	                print FILTER "  default permit\n";
1007		}
1008	        if (($include) && (!$exclude)) {
1009	                $include = 0;
1010	                print FILTER "  default deny\n";
1011	        }
1012
1013	        $save_file .= "_" . $exporter_address;
1014	}
1015
1016	# Set up Next Hop Ip filtering, if any
1017
1018	if ($nexthop_ips ne "") {
1019
1020	        print FILTER "filter-primitive nexthop_ip\n";
1021	        print FILTER "  type ip-address-prefix\n";
1022
1023	        $nexthop_ips =~ s/\s+//g;
1024
1025		$include = 0;  $exclude = 0;
1026
1027		while ($still_more) {
1028
1029	                ($nexthop_address) = split(/,/,$nexthop_ips);
1030	                $start_char = length($nexthop_address) + 1;
1031	                $nexthop_ips = substr($nexthop_ips,$start_char);
1032
1033			if ($nexthop_address =~ /:/) { &print_error("Ranges not supported for this field."); last; }
1034
1035	                if ($nexthop_address =~ m/^\s*-*\d+/) {
1036		                $_ = $nexthop_address;
1037		                $num_dots = tr/\.//;
1038		                if ($num_dots != 3) { &print_error("Not full address: $nexthop_address Try: n.n.n.n/m"); last; }
1039
1040		                ($a,$b,$c,$d)    = split(/\./,$nexthop_address);
1041				($nexthop_ip,$nexthop_prefix) = split(/\//,$nexthop_address);
1042
1043		                if (($nexthop_prefix eq "") && ($d eq "0")) {
1044		                        &print_error("Missing or improper IP address prefix.  Use (e.g.) : 192.168.10.0/24."); last; }
1045		                if (($nexthop_prefix < 0) || ($nexthop_prefix > 32)) {
1046					&print_error("Improper network mask (0 <= mask <= 32)"); last; }
1047
1048		                if ($a > 255 || $a eq "") { &print_error("Improper network: $nexthop_address Try: n.n.n.n/m"); last; }
1049		                if ($b > 255 || $b eq "") { &print_error("Improper network: $nexthop_address Try: n.n.n.n/m"); last; }
1050		                if ($c > 255 || $c eq "") { &print_error("Improper network: $nexthop_address Try: n.n.n.n/m"); last; }
1051		                if ($d > 255 || $d eq "") { &print_error("Improper network: $nexthop_address Try: n.n.n.n/m"); last; }
1052			}
1053
1054	                if (substr($nexthop_address,0,1) eq "-") {
1055	                        $nexthop_address = substr($nexthop_address,1);
1056				print FILTER "  deny $nexthop_address\n";
1057	                        $exclude = 1; }
1058	                else {
1059	                        print FILTER "  permit $nexthop_address\n";
1060				$include = 1;
1061	                }
1062
1063	                if ($nexthop_ips eq "") { last; }
1064	        }
1065
1066	        if (($exclude) && (!$include)) {
1067	                $exclude = 0;
1068	                print FILTER "  default permit\n";
1069		}
1070	        if (($include) && (!$exclude)) {
1071	                $include = 0;
1072	                print FILTER "  default deny\n";
1073	        }
1074
1075	        $save_file .= "_" . $nexthop_address;
1076	}
1077
1078	# Write out the flow files filter
1079
1080	print FILTER "filter-primitive start_flows\n";
1081	print FILTER "  type time-date\n";
1082	print FILTER "  permit ge $flows_start\n";
1083	print FILTER "  default deny\n";
1084	print FILTER "filter-primitive end_flows\n";
1085	print FILTER "  type time-date\n";
1086	print FILTER "  permit lt $flows_end\n";
1087	print FILTER "  default deny\n";
1088	print FILTER " \n";
1089	print FILTER "filter-definition Flow_Filter\n";
1090	if ($source_address ne "") {
1091	        print FILTER "  match ip-source-address source_address\n";
1092	}
1093	if ($source_if ne "") {
1094	        print FILTER "  match input-interface source_if\n";
1095	}
1096	if ($source_port ne "") {
1097	        print FILTER "  match ip-source-port source_port\n";
1098	}
1099	if ($source_as ne "") {
1100	        print FILTER "  match source-as source_as\n";
1101	}
1102	if ($dest_address ne "") {
1103	        print FILTER "  match ip-destination-address dest_address\n";
1104	}
1105	if ($dest_if ne "") {
1106	        print FILTER "  match output-interface dest_if\n";
1107	}
1108	if ($dest_port ne "") {
1109	        print FILTER "  match ip-destination-port dest_port\n";
1110	}
1111	if ($dest_as ne "") {
1112	        print FILTER "  match destination-as dest_as\n";
1113	}
1114	if ($protocol ne "") {
1115	        print FILTER "  match ip-protocol protocol\n";
1116	}
1117	if ($tcp_flag ne "") {
1118	        print FILTER "  match ip-tcp-flags tcp_flag\n";
1119	}
1120	if ($tos_field ne "") {
1121	        print FILTER "  match ip-tos tos_field\n";
1122	}
1123	if ($exporter_address ne "") {
1124	        print FILTER "  match ip-exporter-address exporter\n";
1125	}
1126	if ($nexthop_address ne "") {
1127	        print FILTER "  match ip-nexthop-address nexthop_ip\n";
1128	}
1129
1130	if ($flow_select == 1) {
1131		print FILTER "  match end-time start_flows\n";
1132		print FILTER "  match start-time end_flows\n";
1133		$flow_select_manner = "Any part of flow in Time Period";
1134	}
1135	if ($flow_select == 2) {
1136		print FILTER "  match end-time start_flows\n";
1137		print FILTER "  match end-time end_flows\n";
1138		$flow_select_manner = "Flow end-time in Time Period";
1139	}
1140	if ($flow_select == 3) {
1141		print FILTER "  match start-time start_flows\n";
1142		print FILTER "  match start-time end_flows\n";
1143		$flow_select_manner = "Flow start-time in Time Period";
1144	}
1145	if ($flow_select == 4) {
1146		print FILTER "  match start-time start_flows\n";
1147		print FILTER "  match end-time end_flows\n";
1148		$flow_select_manner = "Flow entirely in Time Period";
1149	}
1150
1151	close (FILTER);
1152}
1153
1154sub create_ipfix_filter {
1155
1156	# General parameters for generating Filter Files
1157
1158	my $device_name       = $FORM{'device_name'};
1159	my $flow_select       = $FORM{'flow_select'};
1160	my $start_date        = $FORM{'start_date'};
1161	my $start_time        = $FORM{'start_time'};
1162	my $end_date          = $FORM{'end_date'};
1163	my $end_time          = $FORM{'end_time'};
1164	my $source_addresses  = $FORM{'source_address'};
1165	my $source_ports      = $FORM{'source_port'};
1166	my $source_ifs        = $FORM{'source_if'};
1167	my $sif_names         = $FORM{'sif_name'};
1168	my $source_ases       = $FORM{'source_as'};
1169	my $dest_addresses    = $FORM{'dest_address'};
1170	my $dest_ports        = $FORM{'dest_port'};
1171	my $dest_ifs          = $FORM{'dest_if'};
1172	my $dif_names         = $FORM{'dif_name'};
1173	my $dest_ases         = $FORM{'dest_as'};
1174	my $protocols         = $FORM{'protocols'};
1175	my $tos_fields        = $FORM{'tos_fields'};
1176	my $tcp_flags         = $FORM{'tcp_flags'};
1177	my $exporter          = $FORM{'exporter'};
1178	my $nexthop_ips       = $FORM{'nexthop_ip'};
1179
1180	if ($date_format eq "DMY") {
1181	        ($temp_day_s,$temp_mnth_s,$temp_yr_s) = split(/\//,$start_date);
1182	        ($temp_day_e,$temp_mnth_e,$temp_yr_e) = split(/\//,$end_date);
1183	} elsif ($date_format eq "DMY2") {
1184	        ($temp_day_s,$temp_mnth_s,$temp_yr_s) = split(/\./,$start_date);
1185	        ($temp_day_e,$temp_mnth_e,$temp_yr_e) = split(/\./,$end_date);
1186	} elsif ($date_format eq "YMD") {
1187	        ($temp_yr_s,$temp_mnth_s,$temp_day_s) = split(/\-/,$start_date);
1188	        ($temp_yr_e,$temp_mnth_e,$temp_day_e) = split(/\-/,$end_date);
1189	} else {
1190	        ($temp_mnth_s,$temp_day_s,$temp_yr_s) = split(/\//,$start_date);
1191	        ($temp_mnth_e,$temp_day_e,$temp_yr_e) = split(/\//,$end_date);
1192	}
1193	$start_date = $temp_mnth_s ."/". $temp_day_s ."/". $temp_yr_s;
1194	$end_date   = $temp_mnth_e ."/". $temp_day_e ."/". $temp_yr_e;
1195
1196	$scidr_field          = "";
1197	$not_scidr_field      = "";
1198	$sif_field            = "";
1199	$in_index_field       = "";
1200	$sport_field          = "";
1201	$sas_field            = "";
1202	$dcidr_field          = "";
1203	$not_dcidr_field      = "";
1204	$dif_field            = "";
1205	$out_index_field      = "";
1206	$dport_field          = "";
1207	$das_field            = "";
1208	$proto_field          = "";
1209	$tcp_flags_field      = "";
1210	$sensor_field         = "";
1211	$nhcidr_field         = "";
1212	$not_nhcidr_field     = "";
1213
1214	$still_more = 1;
1215
1216	# Set up source address filtering, if any
1217
1218	if ($source_addresses ne "") {
1219
1220	        $source_addresses  =~ s/\s+//g;
1221		$num_include_saddr = 0;
1222		$num_exclude_saddr = 0;
1223		$IPSET = 0;
1224
1225		if (substr($source_addresses,0,1) eq "/") {
1226			if (($print_report >= 12) && ($print_report <= 17)) {
1227				$sip_prefix_length = substr($source_addresses,1,3);
1228				if ((($print_report >= 12) && ($print_report <= 14)) && ($sip_prefix_length > 32)) {
1229					&print_error("This prefix ($source_addresses) is too long for IPv4 addresses. Please correct, or use one of the _v6 reports.");
1230					last;
1231				}
1232				$source_address = $source_addresses;
1233	        		$save_file .= "_" . $source_address;
1234				if (substr($dest_addresses,0,1) eq "/") {
1235					$dip_prefix_length = substr($dest_addresses,1,3);
1236					if ((($print_report >= 12) && ($print_report <= 14)) && ($dip_prefix_length > 32)) {
1237						&print_error("This prefix ($dest_addresses) is too long for IPv4 addresses. Please correct, or use one of the _v6 reports.");
1238						last;
1239					}
1240					$dest_address = $dest_addresses;
1241	        			$save_file .= "_" . $dest_address;
1242				}
1243			} else {
1244				&print_error("Improper network: $source_address. Network mask is applicable to Printed Prefix Aggregation reports only");
1245				last;
1246			}
1247
1248		} elsif ($source_addresses =~ /\.set$/) {
1249
1250			$IPSET = 1;
1251			$still_more = 0;
1252			if (substr($source_addresses,0,1) ne "-") {
1253				$source_ipset = $source_addresses;
1254			} else {
1255				$num_exclude_saddr = 1;
1256				$not_source_ipset = substr($source_addresses,1,255);
1257			}
1258		}
1259
1260		while ($still_more) {
1261
1262			$IPv4 = 0; $IPv6 = 0; $unresolved = 0;
1263
1264	                ($source_address) = split(/,/,$source_addresses);
1265	                $start_char = length($source_address) + 1;
1266	                $source_addresses = substr($source_addresses,$start_char);
1267
1268	                if ($source_address =~ m/^\s*-*\d+/) {
1269		                $_ = $source_address;
1270		                $num_dots   = tr/\.//; if ($num_dots   > 0) { $IPv4 = 1; }
1271		                $num_colons = tr/\://; if ($num_colons > 0) { $IPv6 = 1; }
1272
1273				if (($IPv4) && ($IPv6)) {
1274			                &print_error("Support for IPv4-IPv6 embedded addresses not available in this version. $source_address"); last;
1275				}
1276
1277				if ($IPv4) {
1278
1279			                if ($num_dots != 3) { &print_error("Not full IPv4 address: $source_address Try: n.n.n.n/m"); last; }
1280
1281			                ($a,$b,$c,$d)    = split(/\./,$source_address);
1282					($source_ip,$source_prefix) = split(/\//,$source_address);
1283
1284			                if (($source_prefix eq "") && ($d eq "0")) {
1285			                        &print_error("Missing or improper IP address prefix.  Use (e.g.) : 192.168.10.0/24."); last; }
1286			                if (($source_prefix < 0) || ($source_prefix > 32)) {
1287						&print_error("Improper network mask (0 <= mask <= 32)"); last; }
1288
1289			                if ($a > 255 || $a eq "") { &print_error("Improper IPv4 network: $source_address Try: n.n.n.n/m"); last; }
1290			                if ($b > 255 || $b eq "") { &print_error("Improper IPv4 network: $source_address Try: n.n.n.n/m"); last; }
1291			                if ($c > 255 || $c eq "") { &print_error("Improper IPv4 network: $source_address Try: n.n.n.n/m"); last; }
1292			                if ($d > 255 || $d eq "") { &print_error("Improper IPv4 network: $source_address Try: n.n.n.n/m"); last; }
1293				}
1294
1295				if ($IPv6) {
1296
1297			                if ($num_colons > 7) { &print_error("Improper IPv6 address: $source_address.  Too many address segments."); last; }
1298
1299					($source_ip,$source_prefix)   = split(/\//,$source_address);
1300			                ($a,$b,$c,$d,$e,$f,$g,$h) = split(/\:/,$source_address);
1301
1302	                		if ($source_address =~ /[h-zH-Z]/) { &print_error("Improper IPv6 network. Contains a non-Hex character: $source_address"); last; }
1303
1304			                if (($source_prefix < 0) || ($source_prefix > 128)) {
1305						&print_error("Improper IPv6 network mask (0 <= mask <= 128)"); last; }
1306
1307			                if (hex($a) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $a"); last; }
1308			                if (hex($b) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $b"); last; }
1309			                if (hex($c) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $c"); last; }
1310			                if (hex($d) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $d"); last; }
1311			                if (hex($e) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $e"); last; }
1312			                if (hex($f) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $f"); last; }
1313			                if (hex($g) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $g"); last; }
1314			                if (hex($h) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $h"); last; }
1315				}
1316
1317			} else {
1318				$unresolved = 1;
1319			}
1320
1321	                if (substr($source_address,0,1) eq "-") {
1322				$num_exclude_saddr++;
1323	                        $source_address   = substr($source_address,1);
1324                                if ($unresolved) {
1325					$source_ip = &dig_forward($source_address);
1326				} else {
1327					$source_ip = $source_address;
1328				}
1329				if ($num_exclude_saddr < 2) {
1330					$not_scidr_field .= $source_ip;
1331				} else {
1332					$not_scidr_field .= "," . $source_ip;
1333				}
1334	                } else {
1335				$num_include_saddr++;
1336                                if ($unresolved) {
1337					$source_ip = &dig_forward($source_address);
1338				} else {
1339					$source_ip = $source_address;
1340				}
1341				if ($num_include_saddr < 2) {
1342					$scidr_field .= $source_ip;
1343				} else {
1344					$scidr_field .= "," . $source_ip;
1345				}
1346	                }
1347
1348	                if ($source_addresses eq "") { last; }
1349	        }
1350
1351		if (!$IPSET) {
1352			$scidr_field      = " --scidr="      . $scidr_field;
1353			$not_scidr_field  = " --not-scidr="  . $not_scidr_field;
1354		} else {
1355			if ($num_exclude_saddr < 1) {
1356				$sipset_field     = " --sipset="     . $ipset_directory ."/". $source_ipset;
1357			} else {
1358				$not_sipset_field = " --not-sipset=" . $ipset_directory ."/". $not_source_ipset;
1359			}
1360			$still_more = 1;
1361		}
1362
1363	        $save_file .= "_" . $source_address;
1364	}
1365
1366	# Set up source interface filtering, if any
1367
1368	if ($sif_names ne "") {
1369		if ($source_ifs eq "") {
1370			$source_ifs = $sif_names;
1371		} else {
1372			$source_ifs = $source_ifs .",". $sif_names;
1373		}
1374	}
1375
1376	if ($source_ifs ne "") {
1377
1378	        $source_ifs =~ s/\s+//g;
1379		$num_include_sif = 0;
1380		$num_exclude_sif = 0;
1381
1382		while ($still_more) {
1383
1384	                ($source_if) = split(/,/,$source_ifs);
1385	                $start_char = length($source_if) + 1;
1386	                $source_ifs = substr($source_ifs,$start_char);
1387
1388                        $exclude = 0;
1389                        if (substr($source_if,0,1) eq "-") {
1390                                $source_if = substr($source_if,1,12);
1391                                $exclude = 1;
1392                        }
1393
1394			if ($source_if =~ /[^0-9]/) { &print_error("Improper Source interface index: $source_if Try: nnn"); last; }
1395
1396			$range = 0;
1397                        if (($source_if =~ /:/) || ($source_if =~ /[\-]/)) {
1398                                $range = 1;
1399                                if ($source_if =~ /:/)    { ($start_if,$end_if) = split(/:/,$source_if); }
1400                                if ($source_if =~ /[\-]/) { ($start_if,$end_if) = split(/[\-]/,$source_if); }
1401                                if ($end_if < $start_if) {
1402                                        &print_error("Interface range is backwards:  End IF:$end_if  <  Start IF:$start_if");
1403                                        last;
1404                                }
1405                        }
1406
1407                        if ($range) {
1408                                if (($start_if > 10000) || ($start_if > 10000)) {
1409                                        &print_error("Port out of range. Must be: -10000 <= $source_if <= 10000");
1410                                        last;
1411                                }
1412                                if (($end_if > 10000) || ($end_if > 10000)) {
1413                                        &print_error("Port out of range. Must be: -10000 <= $source_if <= 10000");
1414                                        last;
1415                                }
1416                        }
1417                        else {
1418                                if (($source_if > 10000) || ($source_if > 10000)) {
1419                                        &print_error("Port out of range. Must be: -10000 <= $source_if <= 10000");
1420                                        last;
1421                                }
1422                        }
1423
1424			if ($range) {
1425				if ($exclude) {
1426					$num_exclude_sif++;
1427					if ($num_exclude_sif < 2) {
1428						if ($start_if == 0) {
1429							$sif_range_start = $end_if + 1;
1430							$sif_range_end   = 10000;
1431							$sif_field .= $sif_range_start ."-". $sif_range_end;
1432						} elsif ($end_if == 10000) {
1433							$sif_range_start = 0;
1434							$sif_range_end   = $start_if - 1;
1435							$sif_field .= $sif_range_start ."-". $sif_range_end;
1436						} else {
1437							$sif_range_start = 0;
1438							$sif_range_end   = $start_if - 1;
1439							$sif_field .= $sif_range_start ."-". $sif_range_end;
1440							$sif_range_start = $end_if + 1;
1441							$sif_range_end   = 10000;
1442							$sif_field .= "," . $sif_range_start ."-". $sif_range_end;
1443						}
1444					} else {
1445						$last_comma = rindex($sif_field,","); if ($last_comma == -1) { $last_comma = 0; }
1446						if ($last_comma > 0) { $last_comma++; }
1447						$last_range = substr($sif_field,$last_comma,15);
1448						($last_start_if,$remaining) = split(/[\-]/,$last_range);
1449
1450						$first_range_start = $last_start_if;
1451						$first_range_end   = $start_if - 1;
1452						$first_range       = $first_range_start ."-". $first_range_end;
1453
1454						$second_range_start = $end_if + 1;
1455						$second_range_end   = 10000;
1456						$second_range       = $second_range_start ."-". $second_range_end;
1457
1458						$sif_field = substr($sif_field,0,$last_comma);
1459						if ($end_if == 10000) {
1460							$sif_field .= $first_range;
1461						} else {
1462							$sif_field .= $first_range .",". $second_range;
1463						}
1464					}
1465	                	} else {
1466					$num_include_sif++;
1467					if ($num_include_sif < 2) {
1468						$sif_field .= $start_if ."-". $end_if;
1469					} else {
1470						$sif_field .= "," . $start_if ."-". $end_if;
1471					}
1472	                	}
1473
1474			} else {
1475
1476				if ($exclude) {
1477					$num_exclude_sif++;
1478					if ($num_exclude_sif < 2) {
1479						if ($source_if == 0) {
1480							$sif_range_start = 1;
1481							$sif_range_end   = 10000;
1482							$sif_field = $sif_range_start ."-". $sif_range_end;
1483						} elsif ($source_if == 10000) {
1484							$sif_range_start = 0;
1485							$sif_range_end   = 9999;
1486							$sif_field = $sif_range_start ."-". $sif_range_end;
1487						} else {
1488							$sif_range_start = 0;
1489							$sif_range_end   = $source_if - 1;
1490							$sif_field = $sif_range_start ."-". $sif_range_end;
1491							$sif_range_start = $source_if + 1;
1492							$sif_range_end   = 10000;
1493							$sif_field .= "," . $sif_range_start ."-". $sif_range_end;
1494						}
1495					} else {
1496						$last_comma = rindex($sif_field,","); if ($last_comma == -1) { $last_comma = 0; }
1497						if ($last_comma > 0) { $last_comma++; }
1498						$last_range = substr($sif_field,$last_comma,15);
1499						($last_start_if,$remaining) = split(/[\-]/,$last_range);
1500
1501						$first_range_start = $last_start_if;
1502						$first_range_end   = $source_if - 1;
1503						$first_range       = $first_range_start ."-". $first_range_end;
1504
1505						$second_range_start = $source_if + 1;
1506						$second_range_end   = 10000;
1507						$second_range       = $second_range_start ."-". $second_range_end;
1508
1509						$sif_field = substr($sif_field,0,$last_comma);
1510						if ($first_range_end < $first_range_start) {
1511							$sif_field .= $second_range;
1512						} elsif ($second_range_end < $second_range_start) {
1513							$sif_field .= $first_range;
1514						} else {
1515							$sif_field .= $first_range .",". $second_range;
1516						}
1517					}
1518	                	} else {
1519					$num_include_sif++;
1520					if ($num_include_sif < 2) {
1521						$sif_field .= $source_if;
1522					} else {
1523						$sif_field .= "," . $source_if;
1524					}
1525	                	}
1526	                }
1527
1528			$range = 0;
1529
1530	                if ($source_ifs eq "") { last; }
1531	        }
1532
1533		$in_index_field  = " --input-index=" . $sif_field;
1534
1535	        $save_file .= "_" . $source_if;
1536	}
1537
1538	# Set up source port filtering, if any
1539
1540	if ($source_ports ne "") {
1541
1542		$sport_range_start = 0;
1543
1544	        $source_ports =~ s/\s+//g;
1545		$num_include_sport = 0;
1546		$num_exclude_sport = 0;
1547
1548		@temp_ports  = ();
1549		@temp_ranges = ();
1550		@unsorted_ports = split(/\,/,$source_ports);
1551		foreach $unsorted_port (@unsorted_ports) {
1552			$temp_port = $unsorted_port;
1553			if ($temp_port =~ /:/) { push (@temp_ranges,$temp_port); next; }
1554			if (substr($unsorted_port,0,1) eq "-") { $temp_port = substr($unsorted_port,1,5); }
1555			if (length($temp_port) == 1) { $temp_port = "0000" . $temp_port; }
1556			if (length($temp_port) == 2) { $temp_port = "000"  . $temp_port; }
1557			if (length($temp_port) == 3) { $temp_port = "00"   . $temp_port; }
1558			if (length($temp_port) == 4) { $temp_port = "0"    . $temp_port; }
1559			if (substr($unsorted_port,0,1) eq "-") { $temp_port = "-" . $temp_port; }
1560			push (@temp_ports,$temp_port);
1561		}
1562		@sorted_ports = sort (@temp_ports);
1563		$sorted_string = "";
1564		foreach $temp_range (@temp_ranges) { $sorted_string .= $temp_range .","; }
1565		foreach $sorted_port (@sorted_ports) {
1566			$temp_port = $sorted_port;
1567			if (substr($sorted_port,0,1) eq "-") { $temp_port = substr($sorted_port,1,5); }
1568			if ($temp_port ne "00000") {
1569				$temp_port =~ s/^0+//g;
1570			} else {
1571				$temp_port = 0;
1572			}
1573			if (substr($sorted_port,0,1) eq "-") { $temp_port = "-" . $temp_port; }
1574			$sorted_string .= $temp_port . ",";
1575		}
1576		chop $sorted_string;
1577		$source_ports = $sorted_string;
1578
1579		while ($still_more) {
1580
1581	                ($source_port) = split(/,/,$source_ports);
1582	                $start_char = length($source_port) + 1;
1583	                $source_ports = substr($source_ports,$start_char);
1584
1585                        $exclude = 0;
1586                        if (substr($source_port,0,1) eq "-") {
1587                                $source_port = substr($source_port,1,12);
1588                                $exclude = 1;
1589                        }
1590
1591			$range = 0;
1592                        if (($source_port =~ /:/) || ($source_port =~ /[\-]/)) {
1593                                $range = 1;
1594                                if ($source_port =~ /:/)    { ($start_port,$end_port) = split(/:/,$source_port); }
1595                                if ($source_port =~ /[\-]/) { ($start_port,$end_port) = split(/[\-]/,$source_port); }
1596                                if ($end_port < $start_port) {
1597                                        &print_error("Port range is backwards:  End port:$end_port  <  Start port:$start_port");
1598                                        last;
1599                                }
1600                        }
1601
1602                        if ($range) {
1603                                if (($start_port > 65535) || ($end_port > 65535)) {
1604                                        &print_error("Port out of range. Must be: $source_port <= 65535");
1605                                        last;
1606                                }
1607                        }
1608                        else {
1609                                if ($source_port > 65535) {
1610                                        &print_error("Port out of range. Must be: $source_port <= 65535");
1611                                        last;
1612                                }
1613                        }
1614
1615			if ($range) {
1616				if ($exclude) {
1617					$num_exclude_sport++;
1618					if ($num_exclude_sport < 2) {
1619						if ($start_port == 0) {
1620							$sport_range_start = $end_port + 1;
1621							$sport_range_end   = 65535;
1622							$sport_field .= $sport_range_start ."-". $sport_range_end;
1623						} elsif ($end_port == 65535) {
1624							$sport_range_start = 0;
1625							$sport_range_end   = $start_port - 1;
1626							$sport_field .= $sport_range_start ."-". $sport_range_end;
1627						} else {
1628							$sport_range_start = 0;
1629							$sport_range_end   = $start_port - 1;
1630							$sport_field .= $sport_range_start ."-". $sport_range_end;
1631							$sport_range_start = $end_port + 1;
1632							$sport_range_end   = 65535;
1633							$sport_field .= "," . $sport_range_start ."-". $sport_range_end;
1634						}
1635					} else {
1636						$last_comma = rindex($sport_field,","); if ($last_comma == -1) { $last_comma = 0; }
1637						if ($last_comma > 0) { $last_comma++; }
1638						$last_range = substr($sport_field,$last_comma,15);
1639						($last_start_port,$remaining) = split(/[\-]/,$last_range);
1640
1641						$first_range_start = $last_start_port;
1642						$first_range_end   = $start_port - 1;
1643						$first_range       = $first_range_start ."-". $first_range_end;
1644
1645						$second_range_start = $end_port + 1;
1646						$second_range_end   = 65535;
1647						$second_range       = $second_range_start ."-". $second_range_end;
1648
1649						$sport_field = substr($sport_field,0,$last_comma);
1650						if ($end_port == 65535) {
1651							$sport_field .= $first_range;
1652						} else {
1653							$sport_field .= $first_range .",". $second_range;
1654						}
1655					}
1656	                	} else {
1657					$num_include_sport++;
1658					if ($num_include_sport < 2) {
1659						$sport_field .= $start_port ."-". $end_port;
1660					} else {
1661						$sport_field .= "," . $start_port ."-". $end_port;
1662					}
1663	                	}
1664
1665			} else {
1666
1667				if ($exclude) {
1668					$num_exclude_sport++;
1669					if ($num_exclude_sport < 2) {
1670						if ($source_port == 0) {
1671							$sport_range_start = 1;
1672							$sport_range_end   = 65535;
1673							$sport_field = $sport_range_start ."-". $sport_range_end;
1674						} elsif ($source_port == 65535) {
1675							$sport_range_start = 0;
1676							$sport_range_end   = 65534;
1677							$sport_field = $sport_range_start ."-". $sport_range_end;
1678						} else {
1679							$sport_range_start = 0;
1680							$sport_range_end   = $source_port - 1;
1681							$sport_field = $sport_range_start ."-". $sport_range_end;
1682							$sport_range_start = $source_port + 1;
1683							$sport_range_end   = 65535;
1684							$sport_field .= "," . $sport_range_start ."-". $sport_range_end;
1685						}
1686					} else {
1687						$last_comma = rindex($sport_field,","); if ($last_comma == -1) { $last_comma = 0; }
1688						if ($last_comma > 0) { $last_comma++; }
1689						$last_range = substr($sport_field,$last_comma,15);
1690						($last_start_port,$remaining) = split(/[\-]/,$last_range);
1691
1692						$first_range_start = $last_start_port;
1693						$first_range_end   = $source_port - 1;
1694						$first_range       = $first_range_start ."-". $first_range_end;
1695
1696						$second_range_start = $source_port + 1;
1697						$second_range_end   = 65535;
1698						$second_range       = $second_range_start ."-". $second_range_end;
1699
1700						$sport_field = substr($sport_field,0,$last_comma);
1701						if ($first_range_end < $first_range_start) {
1702							$sport_field .= $second_range;
1703						} elsif ($second_range_end < $second_range_start) {
1704							$sport_field .= $first_range;
1705						} else {
1706							$sport_field .= $first_range .",". $second_range;
1707						}
1708					}
1709	                	} else {
1710					$num_include_sport++;
1711					if ($num_include_sport < 2) {
1712						$sport_field .= $source_port;
1713					} else {
1714						$sport_field .= "," . $source_port;
1715					}
1716	                	}
1717	                }
1718
1719			$range = 0;
1720
1721	                if ($source_ports eq "") { last; }
1722	        }
1723
1724		$sport_field  = " --sport=" . $sport_field;
1725
1726	        $save_file .= "_" . $source_port;
1727	}
1728
1729	# Set up source AS filtering, if any (not in SiLK v2.4.5)
1730
1731	if ($source_ases ne "") {
1732
1733	        $source_ases =~ s/\s+//g;
1734		$num_include_sases = 0;
1735
1736	  	&print_error("SiLK software does not support filtering on AS at this time: $source_ases"); last;
1737
1738		while ($still_more) {
1739
1740	                ($source_as) = split(/,/,$source_ases);
1741	                $start_char = length($source_as) + 1;
1742	                $source_ases = substr($source_ases,$start_char);
1743
1744	                if (($source_as < -65536) || ($source_as > 65536)) { &print_error("AS out of range -65536 < AS < 65536"); last; }
1745
1746	                if (substr($source_as,0,1) eq "-") {
1747	                        $source_as = substr($source_as,1,6);
1748	  			&print_error("SiLK software does not support exclusion of Autonomous Systems at this time: -$source_ases"); last;
1749	                } else {
1750				$num_include_sases++;
1751				if ($num_include_sases < 2) {
1752					$sas_field .= $source_as;
1753				} else {
1754					$sas_field .= "," . $source_as;
1755				}
1756                	}
1757
1758	                if ($source_ases eq "") { last; }
1759	        }
1760
1761		$sas_field  = " --sas=" . $sas_field;
1762
1763	        $save_file .= "_" . $source_as;
1764	}
1765
1766	# Set up destination address filtering, if any
1767
1768	if ($dest_addresses ne "") {
1769
1770	        $dest_addresses =~ s/\s+//g;
1771		$num_include_daddr = 0;
1772		$num_exclude_daddr = 0;
1773		$IPSET = 0;
1774
1775		if (substr($source_addresses,0,1) eq "/") {
1776			if (($print_report >= 12) && ($print_report <= 17)) {
1777				$sip_prefix_length = substr($source_addresses,1,3);
1778				if ((($print_report >= 12) && ($print_report <= 14)) && ($sip_prefix_length > 32)) {
1779					&print_error("This prefix ($source_addresses) is too long for IPv4 addresses. Please correct, or use one of the _v6 reports.");
1780					last;
1781				}
1782				$source_address = $source_addresses;
1783	        		$save_file .= "_" . $source_address;
1784				if (substr($dest_addresses,0,1) eq "/") {
1785					$dip_prefix_length = substr($dest_addresses,1,3);
1786					if ((($print_report >= 12) && ($print_report <= 14)) && ($dip_prefix_length > 32)) {
1787						&print_error("This prefix ($dest_addresses) is too long for IPv4 addresses. Please correct, or use one of the _v6 reports.");
1788						last;
1789					}
1790					$dest_address = $dest_addresses;
1791	        			$save_file .= "_" . $dest_address;
1792				}
1793			} else {
1794				&print_error("Improper network: $source_address. Network mask is applicable to Printed Prefix Aggregation reports only");
1795				last;
1796			}
1797		}
1798
1799		if (substr($dest_addresses,0,1) eq "/") {
1800			if (($print_report >= 12) && ($print_report <= 17)) {
1801				$dip_prefix_length = substr($dest_addresses,1,3);
1802				if ((($print_report >= 12) && ($print_report <= 14)) && ($dip_prefix_length > 32)) {
1803					&print_error("This prefix ($dest_addresses) is too long for IPv4 addresses. Please correct, or use one of the _v6 reports.");
1804					last;
1805				}
1806				$dest_address = $dest_addresses;
1807	        		$save_file .= "_" . $dest_address;
1808			} else {
1809				&print_error("Improper network: $dest_address. Network mask is applicable to Printed Prefix Aggregation reports only");
1810				last;
1811			}
1812
1813		} elsif ($dest_addresses =~ /\.set$/) {
1814
1815			$IPSET = 1;
1816			$still_more = 0;
1817			if (substr($dest_addresses,0,1) ne "-") {
1818				$dest_ipset = $dest_addresses;
1819			} else {
1820				$num_exclude_daddr = 1;
1821				$not_dest_ipset = substr($dest_addresses,1,255);
1822			}
1823		}
1824
1825		while ($still_more) {
1826
1827			$IPv4 = 0; $IPv6 = 0; $unresolved = 0;
1828
1829	                ($dest_address) = split(/,/,$dest_addresses);
1830	                $start_char = length($dest_address) + 1;
1831	                $dest_addresses = substr($dest_addresses,$start_char);
1832
1833	                if ($dest_address =~ m/^\s*-*\d+/) {
1834		                $_ = $dest_address;
1835		                $num_dots   = tr/\.//; if ($num_dots   > 0) { $IPv4 = 1; }
1836		                $num_colons = tr/\://; if ($num_colons > 0) { $IPv6 = 1; }
1837
1838				if (($IPv4) && ($IPv6)) {
1839			                &print_error("Support for IPv4-IPv6 embedded addresses not available in this version. $dest_address"); last;
1840				}
1841
1842				if ($IPv4) {
1843
1844			                if ($num_dots != 3) { &print_error("Not full IPv4 address: $dest_address Try: n.n.n.n/m"); last; }
1845
1846			                ($a,$b,$c,$d)    = split(/\./,$dest_address);
1847					($dest_ip,$dest_prefix) = split(/\//,$dest_address);
1848
1849			                if (($dest_prefix eq "") && ($d eq "0")) {
1850			                        &print_error("Missing or improper IP address prefix.  Use (e.g.) : 192.168.10.0/24."); last; }
1851			                if (($dest_prefix < 0) || ($dest_prefix > 32)) {
1852						&print_error("Improper network mask (0 <= mask <= 32)"); last; }
1853
1854			                if ($a > 255 || $a eq "") { &print_error("Improper IPv4 network: $dest_address Try: n.n.n.n/m"); last; }
1855			                if ($b > 255 || $b eq "") { &print_error("Improper IPv4 network: $dest_address Try: n.n.n.n/m"); last; }
1856			                if ($c > 255 || $c eq "") { &print_error("Improper IPv4 network: $dest_address Try: n.n.n.n/m"); last; }
1857			                if ($d > 255 || $d eq "") { &print_error("Improper IPv4 network: $dest_address Try: n.n.n.n/m"); last; }
1858				}
1859
1860				if ($IPv6) {
1861
1862			                if ($num_colons > 7) { &print_error("Improper IPv6 address: $dest_address.  Too many address segments."); last; }
1863
1864					($dest_ip,$dest_prefix)   = split(/\//,$dest_address);
1865			                ($a,$b,$c,$d,$e,$f,$g,$h) = split(/\:/,$dest_address);
1866
1867	                		if ($dest_address =~ /[h-zH-Z]/) { &print_error("Improper IPv6 network. Contains a non-Hex character: $dest_address"); last; }
1868
1869			                if (($dest_prefix < 0) || ($dest_prefix > 128)) {
1870						&print_error("Improper IPv6 network mask (0 <= mask <= 128)"); last; }
1871
1872			                if (hex($a) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $a"); last; }
1873			                if (hex($b) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $b"); last; }
1874			                if (hex($c) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $c"); last; }
1875			                if (hex($d) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $d"); last; }
1876			                if (hex($e) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $e"); last; }
1877			                if (hex($f) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $f"); last; }
1878			                if (hex($g) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $g"); last; }
1879			                if (hex($h) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $h"); last; }
1880				}
1881
1882			} else {
1883				$unresolved = 1;
1884			}
1885
1886	                if (substr($dest_address,0,1) eq "-") {
1887				$num_exclude_daddr++;
1888	                        $dest_address = substr($dest_address,1);
1889                                if ($unresolved) {
1890					$dest_ip = &dig_forward($dest_address);
1891				} else {
1892					$dest_ip = $dest_address;
1893				}
1894				if ($num_exclude_daddr < 2) {
1895					$not_dcidr_field .= $dest_ip;
1896				} else {
1897					$not_dcidr_field .= "," . $dest_ip;
1898				}
1899	                } else {
1900				$num_include_daddr++;
1901                                if ($unresolved) {
1902					$dest_ip = &dig_forward($dest_address);
1903				} else {
1904					$dest_ip = $dest_address;
1905				}
1906				if ($num_include_daddr < 2) {
1907					$dcidr_field .= $dest_ip;
1908				} else {
1909					$dcidr_field .= "," . $dest_ip;
1910				}
1911	                }
1912
1913	                if ($dest_addresses eq "") { last; }
1914	        }
1915
1916		if (!$IPSET) {
1917			$dcidr_field      = " --dcidr="      . $dcidr_field;
1918			$not_dcidr_field  = " --not-dcidr="  . $not_dcidr_field;
1919		} else {
1920			if ($num_exclude_daddr < 1) {
1921				$dipset_field     = " --dipset="     . $ipset_directory ."/". $dest_ipset;
1922			} else {
1923				$not_dipset_field = " --not-dipset=" . $ipset_directory ."/". $not_dest_ipset;
1924			}
1925			$still_more = 1;
1926		}
1927
1928	        $save_file .= "_" . $dest_address;
1929	}
1930
1931	# Set up destination interface filtering, if any
1932
1933	if ($dif_names ne "") {
1934		if ($dest_ifs eq "") {
1935			$dest_ifs = $dif_names;
1936		} else {
1937			$dest_ifs = $dest_ifs .",". $dif_names;
1938		}
1939	}
1940
1941	if ($dest_ifs ne "") {
1942
1943	        $dest_ifs =~ s/\s+//g;
1944		$num_include_dif = 0;
1945		$num_exclude_dif = 0;
1946
1947		while ($still_more) {
1948
1949	                ($dest_if) = split(/,/,$dest_ifs);
1950	                $start_char = length($dest_if) + 1;
1951	                $dest_ifs = substr($dest_ifs,$start_char);
1952
1953                        $exclude = 0;
1954                        if (substr($dest_if,0,1) eq "-") {
1955                                $dest_if = substr($dest_if,1,12);
1956                                $exclude = 1;
1957                        }
1958
1959			if ($dest_if =~ /[^0-9]/) { &print_error("Improper Destination interface index: $dest_if Try: nnn"); last; }
1960
1961			$range = 0;
1962                        if (($dest_if =~ /:/) || ($dest_if =~ /[\-]/)) {
1963                                $range = 1;
1964                                if ($dest_if =~ /:/)    { ($start_if,$end_if) = split(/:/,$dest_if); }
1965                                if ($dest_if =~ /[\-]/) { ($start_if,$end_if) = split(/[\-]/,$dest_if); }
1966                                if ($end_if < $start_if) {
1967                                        &print_error("Interface range is backwards:  End IF:$end_if  <  Start IF:$start_if");
1968                                        last;
1969                                }
1970                        }
1971
1972                        if ($range) {
1973                                if (($start_if > 10000) || ($start_if > 10000)) {
1974                                        &print_error("Port out of range. Must be: -10000 <= $dest_if <= 10000");
1975                                        last;
1976                                }
1977                                if (($end_if > 10000) || ($end_if > 10000)) {
1978                                        &print_error("Port out of range. Must be: -10000 <= $dest_if <= 10000");
1979                                        last;
1980                                }
1981                        }
1982                        else {
1983                                if (($dest_if > 10000) || ($dest_if > 10000)) {
1984                                        &print_error("Port out of range. Must be: -10000 <= $dest_if <= 10000");
1985                                        last;
1986                                }
1987                        }
1988
1989			if ($range) {
1990				if ($exclude) {
1991					$num_exclude_dif++;
1992					if ($num_exclude_dif < 2) {
1993						if ($start_if == 0) {
1994							$dif_range_start = $end_if + 1;
1995							$dif_range_end   = 10000;
1996							$dif_field .= $dif_range_start ."-". $dif_range_end;
1997						} elsif ($end_if == 10000) {
1998							$dif_range_start = 0;
1999							$dif_range_end   = $start_if - 1;
2000							$dif_field .= $dif_range_start ."-". $dif_range_end;
2001						} else {
2002							$dif_range_start = 0;
2003							$dif_range_end   = $start_if - 1;
2004							$dif_field .= $dif_range_start ."-". $dif_range_end;
2005							$dif_range_start = $end_if + 1;
2006							$dif_range_end   = 10000;
2007							$dif_field .= "," . $dif_range_start ."-". $dif_range_end;
2008						}
2009					} else {
2010						$last_comma = rindex($dif_field,","); if ($last_comma == -1) { $last_comma = 0; }
2011						if ($last_comma > 0) { $last_comma++; }
2012						$last_range = substr($dif_field,$last_comma,15);
2013						($last_start_if,$remaining) = split(/[\-]/,$last_range);
2014
2015						$first_range_start = $last_start_if;
2016						$first_range_end   = $start_if - 1;
2017						$first_range       = $first_range_start ."-". $first_range_end;
2018
2019						$second_range_start = $end_if + 1;
2020						$second_range_end   = 10000;
2021						$second_range       = $second_range_start ."-". $second_range_end;
2022
2023						$dif_field = substr($dif_field,0,$last_comma);
2024						if ($end_if == 10000) {
2025							$dif_field .= $first_range;
2026						} else {
2027							$dif_field .= $first_range .",". $second_range;
2028						}
2029					}
2030	                	} else {
2031					$num_include_dif++;
2032					if ($num_include_dif < 2) {
2033						$dif_field .= $start_if ."-". $end_if;
2034					} else {
2035						$dif_field .= "," . $start_if ."-". $end_if;
2036					}
2037	                	}
2038
2039			} else {
2040
2041				if ($exclude) {
2042					$num_exclude_dif++;
2043					if ($num_exclude_dif < 2) {
2044						if ($dest_if == 0) {
2045							$dif_range_start = 1;
2046							$dif_range_end   = 10000;
2047							$dif_field = $dif_range_start ."-". $dif_range_end;
2048						} elsif ($dest_if == 10000) {
2049							$dif_range_start = 0;
2050							$dif_range_end   = 9999;
2051							$dif_field = $dif_range_start ."-". $dif_range_end;
2052						} else {
2053							$dif_range_start = 0;
2054							$dif_range_end   = $dest_if - 1;
2055							$dif_field = $dif_range_start ."-". $dif_range_end;
2056							$dif_range_start = $dest_if + 1;
2057							$dif_range_end   = 10000;
2058							$dif_field .= "," . $dif_range_start ."-". $dif_range_end;
2059						}
2060					} else {
2061						$last_comma = rindex($dif_field,","); if ($last_comma == -1) { $last_comma = 0; }
2062						if ($last_comma > 0) { $last_comma++; }
2063						$last_range = substr($dif_field,$last_comma,15);
2064						($last_start_if,$remaining) = split(/[\-]/,$last_range);
2065
2066						$first_range_start = $last_start_if;
2067						$first_range_end   = $dest_if - 1;
2068						$first_range       = $first_range_start ."-". $first_range_end;
2069
2070						$second_range_start = $dest_if + 1;
2071						$second_range_end   = 10000;
2072						$second_range       = $second_range_start ."-". $second_range_end;
2073
2074						$dif_field = substr($dif_field,0,$last_comma);
2075						if ($first_range_end < $first_range_start) {
2076							$dif_field .= $second_range;
2077						} elsif ($second_range_end < $second_range_start) {
2078							$dif_field .= $first_range;
2079						} else {
2080							$dif_field .= $first_range .",". $second_range;
2081						}
2082					}
2083	                	} else {
2084					$num_include_dif++;
2085					if ($num_include_dif < 2) {
2086						$dif_field .= $dest_if;
2087					} else {
2088						$dif_field .= "," . $dest_if;
2089					}
2090	                	}
2091	                }
2092
2093			$range = 0;
2094
2095	                if ($dest_ifs eq "") { last; }
2096	        }
2097
2098		$out_index_field  = " --output-index=" . $dif_field;
2099
2100	        $save_file .= "_" . $dest_if;
2101	}
2102
2103	# Set up destination port filtering, if any
2104
2105	if ($dest_ports ne "") {
2106
2107print DEBUG "dest_ports: $dest_ports\n";
2108		$dport_range_start = 0;
2109
2110	        $dest_ports =~ s/\s+//g;
2111		$num_include_dport = 0;
2112		$num_exclude_dport = 0;
2113
2114		@temp_ports  = ();
2115		@temp_ranges = ();
2116		@unsorted_ports = split(/\,/,$dest_ports);
2117		foreach $unsorted_port (@unsorted_ports) {
2118			$temp_port = $unsorted_port;
2119			if ($temp_port =~ /:/) { push (@temp_ranges,$temp_port); next; }
2120			if (substr($unsorted_port,0,1) eq "-") { $temp_port = substr($unsorted_port,1,5); }
2121			if (length($temp_port) == 1) { $temp_port = "0000" . $temp_port; }
2122			if (length($temp_port) == 2) { $temp_port = "000"  . $temp_port; }
2123			if (length($temp_port) == 3) { $temp_port = "00"   . $temp_port; }
2124			if (length($temp_port) == 4) { $temp_port = "0"    . $temp_port; }
2125			if (substr($unsorted_port,0,1) eq "-") { $temp_port = "-" . $temp_port; }
2126			push (@temp_ports,$temp_port);
2127		}
2128		@sorted_ports = sort (@temp_ports);
2129		$sorted_string = "";
2130		foreach $temp_range (@temp_ranges) { $sorted_string .= $temp_range .","; }
2131		foreach $sorted_port (@sorted_ports) {
2132			$temp_port = $sorted_port;
2133			if (substr($sorted_port,0,1) eq "-") { $temp_port = substr($sorted_port,1,5); }
2134			if ($temp_port ne "00000") {
2135				$temp_port =~ s/^0+//g;
2136			} else {
2137				$temp_port = 0;
2138			}
2139			if (substr($sorted_port,0,1) eq "-") { $temp_port = "-" . $temp_port; }
2140			$sorted_string .= $temp_port . ",";
2141		}
2142		chop $sorted_string;
2143		$dest_ports = $sorted_string;
2144print DEBUG "after range calc, dest_ports: $dest_ports\n";
2145
2146		while ($still_more) {
2147
2148	                ($dest_port) = split(/,/,$dest_ports);
2149	                $start_char = length($dest_port) + 1;
2150	                $dest_ports = substr($dest_ports,$start_char);
2151
2152                        $exclude = 0;
2153                        if (substr($dest_port,0,1) eq "-") {
2154                                $dest_port = substr($dest_port,1,12);
2155                                $exclude = 1;
2156                        }
2157
2158			$range = 0;
2159                        if (($dest_port =~ /:/) || ($dest_port =~ /[\-]/)) {
2160                                $range = 1;
2161                                if ($dest_port =~ /:/)    { ($start_port,$end_port) = split(/:/,$dest_port); }
2162                                if ($dest_port =~ /[\-]/) { ($start_port,$end_port) = split(/[\-]/,$dest_port); }
2163                                if ($end_port < $start_port) {
2164                                        &print_error("Port range is backwards:  End port:$end_port  <  Start port:$start_port");
2165                                        last;
2166                                }
2167                        }
2168
2169                        if ($range) {
2170                                if (($start_port > 65535) || ($end_port > 65535)) {
2171                                        &print_error("Port out of range. Must be: $dest_port <= 65535");
2172                                        last;
2173                                }
2174                        }
2175                        else {
2176                                if ($dest_port > 65535) {
2177                                        &print_error("Port out of range. Must be: $dest_port <= 65535");
2178                                        last;
2179                                }
2180                        }
2181
2182			if ($range) {
2183	                	if ($exclude) {
2184					$num_exclude_dport++;
2185					if ($num_exclude_dport < 2) {
2186						if (abs($start_port) == 0) {
2187							$dport_range_start = $end_port + 1;
2188							$dport_range_end   = 65535;
2189							$dport_field .= $dport_range_start ."-". $dport_range_end;
2190						} elsif ($end_port == 65535) {
2191							$dport_range_start = 0;
2192							$dport_range_end   = $start_port - 1;
2193							$dport_field .= $dport_range_start ."-". $dport_range_end;
2194						} else {
2195							$dport_range_start = 0;
2196							$dport_range_end   = $start_port - 1;
2197							$dport_field .= $dport_range_start ."-". $dport_range_end;
2198							$dport_range_start = $end_port + 1;
2199							$dport_range_end   = 65535;
2200							$dport_field .= "," . $dport_range_start ."-". $dport_range_end;
2201						}
2202					} else {
2203						$last_comma = rindex($dport_field,","); if ($last_comma == -1) { $last_comma = 0; }
2204						if ($last_comma > 0) { $last_comma++; }
2205						$last_range = substr($dport_field,$last_comma,15);
2206						($last_start_port,$remaining) = split(/[\-]/,$last_range);
2207
2208						$first_range_start = $last_start_port;
2209						$first_range_end   = $start_port - 1;
2210						$first_range       = $first_range_start ."-". $first_range_end;
2211
2212						$second_range_start = $end_port + 1;
2213						$second_range_end   = 65535;
2214						$second_range       = $second_range_start ."-". $second_range_end;
2215
2216						$dport_field = substr($dport_field,0,$last_comma);
2217						if ($end_port == 65535) {
2218							$dport_field .= $first_range;
2219						} else {
2220							$dport_field .= $first_range .",". $second_range;
2221						}
2222					}
2223	                	} else {
2224					$num_include_dport++;
2225					if ($num_include_dport < 2) {
2226						$dport_field .= $start_port ."-". $end_port;
2227					} else {
2228						$dport_field .= "," . $start_port ."-". $end_port;
2229					}
2230	                	}
2231
2232			} else {
2233
2234	                	if ($exclude) {
2235					$num_exclude_dport++;
2236					if ($num_exclude_dport < 2) {
2237						if ($dest_port == 0) {
2238							$dport_range_start = 1;
2239							$dport_range_end   = 65535;
2240							$dport_field = $dport_range_start ."-". $dport_range_end;
2241						} elsif ($dest_port == 65535) {
2242							$dport_range_start = 0;
2243							$dport_range_end   = 65534;
2244							$dport_field = $dport_range_start ."-". $dport_range_end;
2245						} else {
2246							$dport_range_start = 0;
2247							$dport_range_end   = $dest_port - 1;
2248							$dport_field = $dport_range_start ."-". $dport_range_end;
2249							$dport_range_start = $dest_port + 1;
2250							$dport_range_end   = 65535;
2251							$dport_field .= "," . $dport_range_start ."-". $dport_range_end;
2252						}
2253					} else {
2254						$last_comma = rindex($dport_field,","); if ($last_comma == -1) { $last_comma = 0; }
2255						if ($last_comma > 0) { $last_comma++; }
2256						$last_range = substr($dport_field,$last_comma,15);
2257						($last_start_port,$remaining) = split(/[\-]/,$last_range);
2258
2259						$first_range_start = $last_start_port;
2260						$first_range_end   = $dest_port - 1;
2261						$first_range       = $first_range_start ."-". $first_range_end;
2262
2263						$second_range_start = $dest_port + 1;
2264						$second_range_end   = 65535;
2265						$second_range       = $second_range_start ."-". $second_range_end;
2266
2267						$dport_field = substr($dport_field,0,$last_comma);
2268						if ($first_range_end < $first_range_start) {
2269							$dport_field .= $second_range;
2270						} elsif ($second_range_end < $second_range_start) {
2271							$dport_field .= $first_range;
2272						} else {
2273							$dport_field .= $first_range .",". $second_range;
2274						}
2275					}
2276	                	} else {
2277					$num_include_dport++;
2278					if ($num_include_dport < 2) {
2279						$dport_field .= $dest_port;
2280					} else {
2281						$dport_field .= "," . $dest_port;
2282					}
2283	                	}
2284	                }
2285
2286			$range = 0;
2287
2288	                if ($dest_ports eq "") { last; }
2289	        }
2290
2291print DEBUG "dport_field: $dport_field\n";
2292		$dport_field  = " --dport=" . $dport_field;
2293
2294	        $save_file .= "_" . $dest_port;
2295	}
2296
2297	# Set up destination AS filtering, if any
2298
2299	if ($dest_ases ne "") {
2300
2301	        $dest_ases =~ s/\s+//g;
2302		$num_include_dases = 0;
2303
2304	  	&print_error("SiLK software does not support filtering on AS at this time: $dest_ases"); last;
2305
2306		while ($still_more) {
2307
2308	                ($dest_as) = split(/,/,$dest_ases);
2309	                $start_char = length($dest_as) + 1;
2310	                $dest_ases = substr($dest_ases,$start_char);
2311
2312	                if (($dest_as < -65536) || ($dest_as > 65536)) { &print_error("AS out of range -65536 < AS < 65536"); last; }
2313
2314	                if (substr($dest_as,0,1) eq "-") {
2315	                        $dest_as = substr($dest_as,1,6);
2316	  			&print_error("SiLK software does not support exclusion of ASes at this time: -$dest_as"); last;
2317	                } else {
2318				$num_include_dases++;
2319				if ($num_include_dases < 2) {
2320					$das_field .= $dest_as;
2321				} else {
2322					$das_field .= "," . $dest_as;
2323				}
2324                	}
2325
2326	                if ($dest_ases eq "") { last; }
2327	        }
2328
2329		$das_field  = " --das=" . $das_field;
2330
2331	        $save_file .= "_" . $dest_as;
2332	}
2333
2334	# Set up Protocol filtering, if any
2335
2336	if ($protocols ne "") {
2337
2338	        $protocols =~ s/\s+//g;
2339		$num_include_proto = 0;
2340
2341		while ($still_more) {
2342
2343	                ($protocol) = split(/,/,$protocols);
2344	                $start_char = length($protocol) + 1;
2345	                $protocols = substr($protocols,$start_char);
2346
2347	                if (($protocol < -255) || ($protocol > 255)) { &print_error("Protocol out of range 1 < Protocol < 255"); last; }
2348
2349	                if (substr($protocol,0,1) eq "-") {
2350	                        $protocol = substr($protocol,1,3);
2351	  			&print_error("SiLK software does not support exclusion of Protocols at this time: -$protocol"); last;
2352	                } else {
2353				$num_include_proto++;
2354				if ($num_include_proto < 2) {
2355					$proto_field .= $protocol;
2356				} else {
2357					$proto_field .= "," . $protocol;
2358				}
2359                	}
2360
2361	                if ($protocols eq "") { last; }
2362	        }
2363
2364		$proto_field  = " --protocol=" . $proto_field;
2365
2366	        $save_file .= "_" . $protocol;
2367	}
2368
2369	# Set up TCP Flag filtering, if any. Note: accepting only one TCP flag/mask pair for SiLK
2370
2371	if ($tcp_flags ne "") {
2372
2373	        $tcp_flags =~ s/\s+//g;
2374
2375		$num_flags = 0;
2376		while ($still_more) {
2377
2378			$num_flags++;
2379
2380			if ($num_flags == 2) { &print_error("SiLK accepts only one TCP flag and mask combination"); last; }
2381
2382	                ($tcp_flag) = split(/,/,$tcp_flags);
2383	                $start_char = length($tcp_flag) + 1;
2384	                $tcp_flags = substr($tcp_flags,$start_char);
2385
2386			($tcp_flag,$tcp_mask) = split(/\//,$tcp_flag);
2387
2388			$tcp_flag_dec = hex($tcp_flag);
2389			$tcp_mask_dec = hex($tcp_mask);
2390
2391			$tcp_flag_bin = dec2bin($tcp_flag_dec);
2392			$tcp_mask_bin = dec2bin($tcp_mask_dec);
2393
2394			for ($i=0;$i<8;$i++) {
2395			        if (substr($tcp_mask_bin,$i,1) == 1) {
2396			                if (substr($tcp_flag_bin,$i,1) == 1) { $tcp_flags_field .= high_flags($i); }
2397			                if (substr($tcp_flag_bin,$i,1) == 0) { $tcp_flags_field .=  low_flags($i); }
2398			        }
2399			}
2400
2401			if (substr($tcp_flags_field,0,1) eq ",") { $tcp_flags_field = substr($tcp_flags_field,1,35); }
2402
2403	                if ($tcp_flags eq "") { last; }
2404		}
2405
2406		$tcp_flags_field  = " --flags-all=" . $tcp_flags_field;
2407
2408	        $save_file .= "_" . $tcp_flag;
2409	}
2410
2411	# Set up TOS Field filtering, if any (SiLK v2.4.5 doe not support TOS field)
2412
2413	if ($tos_fields ne "") {
2414
2415		&print_error("SiLK does not currently support filtering on TOS field");
2416	}
2417
2418	# Set up exporter address filtering, if any
2419
2420	if ($exporter ne "") {
2421
2422	        $exporter =~ s/\s+//g;
2423		$num_include_probe = 0;
2424		@valid_probes = ();
2425
2426		# Get valid probes (exporters) from the sensor.conf file
2427
2428		$probe_command = "cat $sensor_config_file | grep probe > $work_directory/valid_probes_$suffix";
2429		system ($probe_command);
2430
2431		open (PROBES,"<$work_directory/valid_probes_$suffix");
2432		while (<PROBES>) {
2433			($probe_label,$probe) = split(/\s+/,$_);
2434			if ($probe_label eq "probe") { push (@valid_probes,$probe); }
2435		}
2436
2437		while ($still_more) {
2438
2439	                ($exporter_name) = split(/,/,$exporter);
2440	                $start_char = length($exporter_name) + 1;
2441	                $exporter = substr($exporter,$start_char);
2442
2443	                if (substr($exporter_name,0,1) eq "-") {
2444	  			&print_error("SiLK software does not support exclusion of Exporters (Sensors) at this time: -$exporter_name"); last;
2445	                } else {
2446                		foreach $probe (@valid_probes) {
2447					if ($exporter_name eq $probe) {
2448						$num_include_probe++;
2449						if ($num_include_probe < 2) {
2450							$sensor_field .= $exporter_name;
2451						} else {
2452							$sensor_field .= "," . $exporter_name;
2453						}
2454					}
2455				}
2456                	}
2457
2458	                if ($exporter eq "") { last; }
2459	        }
2460
2461		$sensor_field  = " --sensors=" . $sensor_field;
2462
2463	        $save_file .= "_" . $exporter_name;
2464	}
2465
2466	# Set up Next Hop IP filtering, if any
2467
2468	if ($nexthop_ips ne "") {
2469
2470	        $nexthop_ips =~ s/\s+//g;
2471		$num_include_next = 0;
2472		$num_exclude_next = 0;
2473
2474		if ($nexthop_ips =~ /\.set$/) {
2475
2476			$IPSET = 1;
2477			$still_more = 0;
2478			if (substr($nexthop_ips,0,1) ne "-") {
2479				$nh_ipset = $nexthop_ips;
2480			} else {
2481				$not_nh_ipset = substr($nexthop_ips,1,255);
2482			}
2483		}
2484
2485		while ($still_more) {
2486
2487			$IPv4 = 0; $IPv6 = 0;
2488
2489	                ($nexthop_address) = split(/,/,$nexthop_ips);
2490	                $start_char = length($nexthop_address) + 1;
2491	                $nexthop_ips = substr($nexthop_ips,$start_char);
2492
2493	                if ($nexthop_address =~ m/^\s*-*\d+/) {
2494		                $_ = $nexthop_address;
2495		                $num_dots   = tr/\.//; if ($num_dots   > 0) { $IPv4 = 1; }
2496		                $num_colons = tr/\://; if ($num_colons > 0) { $IPv6 = 1; }
2497			}
2498
2499			if (($IPv4) && ($IPv6)) {
2500		                &print_error("Support for IPv4-IPv6 embedded addresses not available in this version. $nexthop_address"); last;
2501			}
2502
2503			if ($IPv4) {
2504
2505		                if ($num_dots != 3) { &print_error("Not full IPv4 address: $nexthop_address Try: n.n.n.n/m"); last; }
2506
2507		                ($a,$b,$c,$d)    = split(/\./,$nexthop_address);
2508				($nexthop_ip,$nexthop_prefix) = split(/\//,$nexthop_address);
2509
2510		                if (($nexthop_prefix eq "") && ($d eq "0")) {
2511		                        &print_error("Missing or improper IP address prefix.  Use (e.g.) : 192.168.10.0/24."); last; }
2512		                if (($nexthop_prefix < 0) || ($nexthop_prefix > 32)) {
2513					&print_error("Improper network mask (0 <= mask <= 32)"); last; }
2514
2515		                if ($a > 255 || $a eq "") { &print_error("Improper IPv4 network: $nexthop_address Try: n.n.n.n/m"); last; }
2516		                if ($b > 255 || $b eq "") { &print_error("Improper IPv4 network: $nexthop_address Try: n.n.n.n/m"); last; }
2517		                if ($c > 255 || $c eq "") { &print_error("Improper IPv4 network: $nexthop_address Try: n.n.n.n/m"); last; }
2518		                if ($d > 255 || $d eq "") { &print_error("Improper IPv4 network: $nexthop_address Try: n.n.n.n/m"); last; }
2519			}
2520
2521			if ($IPv6) {
2522
2523		                if ($num_colons > 7) { &print_error("Improper IPv6 address: $nexthop_address.  Too many address segments."); last; }
2524
2525				($nexthop_ip,$nexthop_prefix)   = split(/\//,$nexthop_address);
2526		                ($a,$b,$c,$d,$e,$f,$g,$h) = split(/\:/,$nexthop_address);
2527
2528		                if (($nexthop_prefix < 0) || ($nexthop_prefix > 128)) {
2529					&print_error("Improper IPv6 network mask (0 <= mask <= 128)"); last; }
2530
2531		                if (hex($a) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $a"); last; }
2532		                if (hex($b) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $b"); last; }
2533		                if (hex($c) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $c"); last; }
2534		                if (hex($d) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $d"); last; }
2535		                if (hex($e) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $e"); last; }
2536		                if (hex($f) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $f"); last; }
2537		                if (hex($g) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $g"); last; }
2538		                if (hex($h) > 65535) { &print_error("Improper IPv6 network. Address segment too large: $h"); last; }
2539			}
2540
2541	                if (substr($nexthop_address,0,1) eq "-") {
2542	                        $nexthop_address   = substr($nexthop_address,1);
2543				$num_exclude_next++;
2544				if ($num_exclude_next < 2) {
2545					$not_nhcidr_field .= $nexthop_address;
2546				} else {
2547					$not_nhcidr_field .= "," . $nexthop_address;
2548				}
2549	                } else {
2550				$num_include_next++;
2551				if ($num_include_next < 2) {
2552					$nhcidr_field .= $nexthop_address;
2553				} else {
2554					$nhcidr_field .= "," . $nexthop_address;
2555				}
2556	                }
2557
2558	                if ($nexthop_ips eq "") { last; }
2559	        }
2560
2561		if (!$IPSET) {
2562			$nhcidr_field      = " --nhcidr="      . $nhcidr_field;
2563			$not_nhcidr_field  = " --not-nhcidr="  . $not_nhcidr_field;
2564		} else {
2565			$nhipset_field     = " --nhipset="     . $nh_ipset;
2566			$not_nhipset_field = " --not-nhipset=" . $not_nh_ipset;
2567			$still_more = 1;
2568		}
2569
2570	        $save_file .= "_" . $nexthop_address;
2571	}
2572
2573	$partitioning_switches = "";
2574	($field,$parameter) = split(/=/,$not_nhcidr_field);  if ($parameter ne "") { $partitioning_switches .= $not_nhcidr_field; }
2575	($field,$parameter) = split(/=/,$nhcidr_field);      if ($parameter ne "") { $partitioning_switches .= $nhcidr_field; }
2576	($field,$parameter) = split(/=/,$sensor_field);      if ($parameter ne "") { $partitioning_switches .= $sensor_field; }
2577	($field,$parameter) = split(/=/,$tcp_flags_field);   if ($parameter ne "") { $partitioning_switches .= $tcp_flags_field; }
2578	($field,$parameter) = split(/=/,$proto_field);       if ($parameter ne "") { $partitioning_switches .= $proto_field; }
2579	($field,$parameter) = split(/=/,$dport_field);       if ($parameter ne "") { $partitioning_switches .= $dport_field; }
2580	($field,$parameter) = split(/=/,$sport_field);       if ($parameter ne "") { $partitioning_switches .= $sport_field; }
2581	($field,$parameter) = split(/=/,$out_index_field);   if ($parameter ne "") { $partitioning_switches .= $out_index_field; }
2582	($field,$parameter) = split(/=/,$in_index_field);    if ($parameter ne "") { $partitioning_switches .= $in_index_field; }
2583	($field,$parameter) = split(/=/,$not_dcidr_field);   if ($parameter ne "") { $partitioning_switches .= $not_dcidr_field; }
2584	($field,$parameter) = split(/=/,$dcidr_field);       if ($parameter ne "") { $partitioning_switches .= $dcidr_field; }
2585	($field,$parameter) = split(/=/,$not_scidr_field);   if ($parameter ne "") { $partitioning_switches .= $not_scidr_field; }
2586	($field,$parameter) = split(/=/,$scidr_field);       if ($parameter ne "") { $partitioning_switches .= $scidr_field; }
2587	($field,$parameter) = split(/=/,$not_sipset_field);  if ($parameter ne "") { $partitioning_switches .= $not_sipset_field; }
2588	($field,$parameter) = split(/=/,$sipset_field);      if ($parameter ne "") { $partitioning_switches .= $sipset_field; }
2589	($field,$parameter) = split(/=/,$not_dipset_field);  if ($parameter ne "") { $partitioning_switches .= $not_dipset_field; }
2590	($field,$parameter) = split(/=/,$dipset_field);      if ($parameter ne "") { $partitioning_switches .= $dipset_field; }
2591	($field,$parameter) = split(/=/,$not_nhipset_field); if ($parameter ne "") { $partitioning_switches .= $not_nhipset_field; }
2592	($field,$parameter) = split(/=/,$nhipset_field);     if ($parameter ne "") { $partitioning_switches .= $nhipset_field; }
2593
2594	return $partitioning_switches;
2595}
2596
2597sub convert_octets2string {
2598
2599        my ($octets) = @_;
2600        my $res;
2601        my $unit=0;
2602
2603        $res = $octets;
2604        while ($res > 1024) {
2605               $res = $res/1024;
2606               $unit = $unit +1;
2607        }
2608
2609        if ($unit == 0) {
2610            $res = sprintf("%.0f" , $res);
2611        } elsif ($unit == 1) {
2612            $res = sprintf("%.2f KB" , $res);
2613        } elsif ($unit == 2) {
2614            $res = sprintf("%.2f MB" , $res);
2615        } elsif ($unit == 3) {
2616            $res = sprintf("%.2f GB" , $res);
2617        } elsif ($unit == 4) {
2618            $res = sprintf("%.2f TB" , $res);
2619        } else {
2620            $res = sprintf("%.2f PB" , $res);
2621        }
2622        return $res;
2623}
2624
2625sub dec2bin {
2626        my $str = unpack("B32", pack("N", shift));
2627        $str = substr($str,24,8);
2628	return $str;
2629}
2630
2631sub high_flags {
2632        if ($i == 0) { $flag_value = ",C/C"; }
2633        if ($i == 1) { $flag_value = ",E/E"; }
2634        if ($i == 2) { $flag_value = ",U/U"; }
2635        if ($i == 3) { $flag_value = ",A/A"; }
2636        if ($i == 4) { $flag_value = ",P/P"; }
2637        if ($i == 5) { $flag_value = ",R/R"; }
2638        if ($i == 6) { $flag_value = ",S/S"; }
2639        if ($i == 7) { $flag_value = ",F/F"; }
2640        return $flag_value;
2641}
2642
2643sub low_flags {
2644        if ($i == 0) { $flag_value = ",/C"; }
2645        if ($i == 1) { $flag_value = ",/E"; }
2646        if ($i == 2) { $flag_value = ",/U"; }
2647        if ($i == 3) { $flag_value = ",/A"; }
2648        if ($i == 4) { $flag_value = ",/P"; }
2649        if ($i == 5) { $flag_value = ",/R"; }
2650        if ($i == 6) { $flag_value = ",/S"; }
2651        if ($i == 7) { $flag_value = ",/F"; }
2652        return $flag_value;
2653}
2654
2655sub dig_forward {
2656        my ($host_name) = @_;
2657
2658        open(DIG,"$dig_forward $host_name 2>&1|");
2659        $answer_record = 0;
2660        while (<DIG>) {
2661                chop;
2662                if (/ANSWER SECTION/) {
2663                        $answer_record = 1;
2664                        next;
2665                }
2666                if ($answer_record) {
2667                        ($in_name,$rec_timeout,$rec_direction,$rec_type,$host_ip) = split(/\s+/,$_);
2668                        last;
2669                }
2670        }
2671        return $host_ip;
2672}
2673
2674return 1;
2675