rb-wartslib 0.9.10 → 0.9.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/scdump CHANGED
@@ -3,7 +3,24 @@
3
3
  #############################################################################
4
4
  ## Ruby version of sc_analsysis_dump.
5
5
  ##
6
- ## $Id: scdump,v 1.11 2007/11/29 20:39:13 youngh Exp $
6
+ ## --------------------------------------------------------------------------
7
+ ## Copyright (C) 2007 The Regents of the University of California.
8
+ ##
9
+ ## This program is free software; you can redistribute it and/or modify
10
+ ## it under the terms of the GNU General Public License as published by
11
+ ## the Free Software Foundation; either version 2 of the License, or
12
+ ## (at your option) any later version.
13
+ ##
14
+ ## This program is distributed in the hope that it will be useful,
15
+ ## but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ ## GNU General Public License for more details.
18
+ ##
19
+ ## You should have received a copy of the GNU General Public License
20
+ ## along with this program; if not, write to the Free Software
21
+ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
+ ##
23
+ ## $Id: scdump,v 1.12 2007/11/29 23:57:41 youngh Exp $
7
24
  #############################################################################
8
25
 
9
26
  require 'rubygems'
@@ -0,0 +1,275 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #############################################################################
4
+ ## Selects traces from input files based on a set of conditions and either
5
+ ## writes matching traces to an output warts file or prints out a textual
6
+ ## representation.
7
+ ##
8
+ ## --------------------------------------------------------------------------
9
+ ## Copyright (C) 2007 The Regents of the University of California.
10
+ ##
11
+ ## This program is free software; you can redistribute it and/or modify
12
+ ## it under the terms of the GNU General Public License as published by
13
+ ## the Free Software Foundation; either version 2 of the License, or
14
+ ## (at your option) any later version.
15
+ ##
16
+ ## This program is distributed in the hope that it will be useful,
17
+ ## but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ ## GNU General Public License for more details.
20
+ ##
21
+ ## You should have received a copy of the GNU General Public License
22
+ ## along with this program; if not, write to the Free Software
23
+ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
+ ##
25
+ ## $Id: select-traces,v 1.1 2007/11/30 01:14:48 youngh Exp $
26
+ #############################################################################
27
+
28
+ require 'rubygems'
29
+ require 'ostruct'
30
+ require 'optparse'
31
+
32
+ require 'wartslib'
33
+
34
+ $options = OpenStruct.new
35
+ $options.skip_traces = 0
36
+
37
+ opts = OptionParser.new
38
+ opts.banner = "Usage: select-traces [options] <warts-file-1> <warts-file-2> ..."
39
+
40
+ opts.on("-r", "--responding", TrueClass,
41
+ "if destination responded") do |v|
42
+ $options.responding = v
43
+ end
44
+
45
+ opts.on("-c", "--complete", TrueClass,
46
+ "if dest and all intermediate hops responded") do |v|
47
+ $options.complete = v
48
+ end
49
+
50
+ opts.on("-s", "--stop-reasons", Array, "=NUM-LIST",
51
+ "comma-separated numeric stop reason(s)") do |v|
52
+ $options.stop_reasons = v
53
+ end
54
+
55
+ opts.on("-m", "--methods", Array, "=STR-LIST",
56
+ "comma-separated traceroute method(s): udp,udp-paris,icmp,icmp-paris,tcp") do |v|
57
+ $options.trace_methods = v
58
+ end
59
+
60
+ opts.on("--length", Integer, "=NUM",
61
+ "if path length is equal to N") do |v|
62
+ $options.length = v
63
+ end
64
+
65
+ opts.on("--length-ge", Integer, "=NUM",
66
+ "if path length is >= N") do |v|
67
+ $options.length_ge = v
68
+ end
69
+
70
+ opts.on("--length-le", Integer, "=NUM",
71
+ "if path length is <= N") do |v|
72
+ $options.length_le = v
73
+ end
74
+
75
+ opts.on("-S", "--skip-traces", Integer, "=NUM",
76
+ "number of leading traces to skip") do |v|
77
+ $options.skip_traces = v
78
+ end
79
+
80
+ opts.on("-N", "--num-traces", Integer, "=NUM",
81
+ "# traces to examine after skipping traces") do |v|
82
+ $options.num_traces = v
83
+ end
84
+
85
+ opts.on("-o", "--output", "=FILE", "output warts file") do |v|
86
+ $options.output_file = v
87
+ end
88
+
89
+ opts.on("-p", "--print-stats", TrueClass, "print trace stats") do |v|
90
+ $options.print_stats = v
91
+ end
92
+
93
+ opts.on("-d", "--dump-traces", TrueClass,
94
+ "dump traces in text to stdout") do |v|
95
+ $options.dump_traces = v
96
+ end
97
+
98
+ opts.on("-v", "--[no-]verbose", TrueClass, "show detailed progress") do |v|
99
+ $options.verbose = v
100
+ end
101
+
102
+ begin
103
+ ARGV.replace opts.parse(*ARGV)
104
+ rescue OptionParser::ParseError
105
+ $stderr.puts "ERROR: " + $!
106
+ $stderr.puts opts
107
+ exit 1
108
+ end
109
+
110
+ if $options.stop_reasons
111
+ $options.stop_reasons = $options.stop_reasons.map { |s|
112
+ unless s =~ /^\d+$/
113
+ $stderr.puts "ERROR: invalid stop reason '#{s}': must be an integer"
114
+ exit 1
115
+ end
116
+ s.to_i
117
+ }
118
+ end
119
+
120
+ if $options.trace_methods
121
+ trace_type = {
122
+ "icmp" => Warts::Trace::TYPE_ICMP_ECHO,
123
+ "udp" => Warts::Trace::TYPE_UDP,
124
+ "tcp" => Warts::Trace::TYPE_TCP,
125
+ "icmp-paris" => Warts::Trace::TYPE_ICMP_ECHO_PARIS,
126
+ "udp-paris" => Warts::Trace::TYPE_UDP_PARIS
127
+ }
128
+
129
+ $options.trace_type = $options.trace_methods.map { |s|
130
+ type = trace_type[s]
131
+ unless type
132
+ $stderr.puts "ERROR: invalid trace method '#{s}': must be one of " +
133
+ trace_type.keys.sort.join(", ")
134
+ exit 1
135
+ end
136
+ type
137
+ }
138
+ end
139
+
140
+ unless $options.output_file || $options.print_stats || $options.dump_traces
141
+ $options.print_stats = true
142
+ end
143
+
144
+ #===========================================================================
145
+
146
+ class Stats
147
+ attr_accessor :traces, :responding, :complete, :stop_reason
148
+ attr_accessor :hop_histogram, :zero_dead
149
+
150
+ def initialize
151
+ @traces = 0
152
+ @responding = 0
153
+ @complete = 0
154
+ @stop_reason = Hash.new 0
155
+
156
+ # from scamper_trace.h:SCAMPER_TRACE_STOP_*
157
+ @stop_text = {
158
+ 0 => "none (null reason)",
159
+ 1 => "completed (got an ICMP port unreach)",
160
+ 2 => "unreach (got an other ICMP unreach code)",
161
+ 3 => "icmp (got an ICMP msg, not unreach)",
162
+ 4 => "loop (loop detected)",
163
+ 5 => "dead (unresponsive target)",
164
+ 6 => "error (sendto error)"
165
+ }
166
+ @stop_text.default = "<<UNKNOWN STOP CODE>>"
167
+
168
+ @hop_histogram = Hash.new 0
169
+ @zero_dead = 0
170
+ end
171
+
172
+ def print
173
+ puts "%8d traces" % [@traces]
174
+ puts "%8d responding (%.1f%%)" % [@responding, pct(@responding, @traces)]
175
+ puts "%8d complete (%.1f%%)" % [@complete, pct(@complete, @traces)]
176
+ puts "%8d dead traces with zero hop count (%.1f%%)" %
177
+ [ @zero_dead, pct(@zero_dead, @traces) ]
178
+ puts
179
+ stop_reason.to_a.sort.each do |k, v|
180
+ puts "%8d stop reason %d, %s" % [v, k, @stop_text[k]]
181
+ end
182
+ puts
183
+ @hop_histogram.to_a.sort.each do |k, v|
184
+ puts "%8d %d hops" % [v, k]
185
+ end
186
+ end
187
+
188
+ def add(other)
189
+ @traces += other.traces
190
+ @responding += other.responding
191
+ @complete += other.complete
192
+ other.stop_reason.each { |k,v| @stop_reason[k] += v }
193
+ other.hop_histogram.each { |k,v| @hop_histogram[k] += v }
194
+ @zero_dead += other.zero_dead
195
+ end
196
+
197
+ def pct(x, y)
198
+ return 100.0 if y == 0
199
+ x.quo(y) * 100.0
200
+ end
201
+ end
202
+
203
+
204
+ #############################################################################
205
+ # Main
206
+ #############################################################################
207
+
208
+ if $options.output_file
209
+ $options.output = Warts::File.open $options.output_file, "w",
210
+ Warts::File::WARTS
211
+ unless $options.output
212
+ $stderr.puts "ERROR: couldn't open output file '#{$options.output_file}'"
213
+ exit 1
214
+ end
215
+ end
216
+
217
+ total = Stats.new
218
+
219
+ trace_index = 0
220
+ ARGV.each do |path|
221
+ stats = Stats.new
222
+ $stderr.puts "Examining #{path} ..." if $options.verbose
223
+ file = Warts::File.open path
224
+ unless file
225
+ $stderr.puts "ERROR: couldn't open input file '#{path}'; aborting"
226
+ exit 1
227
+ end
228
+
229
+ file.add_filters Warts::File::TRACE
230
+ file.read do |trace|
231
+ trace_index += 1
232
+ next if trace_index <= $options.skip_traces
233
+ if $options.num_traces &&
234
+ trace_index - $options.skip_traces > $options.num_traces
235
+ exit 0
236
+ end
237
+
238
+ next if $options.responding && !trace.dest_responded?
239
+ next if $options.complete && !trace.complete?
240
+ next if $options.stop_reasons &&
241
+ !$options.stop_reasons.include?(trace.stop_reason)
242
+ next if $options.trace_type && !$options.trace_type.include?(trace.type)
243
+ next if $options.length && trace.path_length != $options.length
244
+ next if $options.length_ge && trace.path_length < $options.length_ge
245
+ next if $options.length_le && trace.path_length > $options.length_le
246
+
247
+ if $options.print_stats
248
+ stats.traces += 1
249
+ stats.responding += 1 if trace.dest_responded?
250
+ stats.complete += 1 if trace.complete?
251
+ stats.stop_reason[trace.stop_reason] += 1
252
+ stats.hop_histogram[trace.path_length] += 1
253
+ stats.zero_dead += 1 if trace.stop_reason == 5 && trace.hop_count == 0
254
+ end
255
+
256
+ puts trace.dump if $options.dump_traces
257
+ $options.output.write trace if $options.output
258
+ end
259
+
260
+ if $options.print_stats
261
+ puts "\n"
262
+ puts("-" * 70)
263
+ puts path
264
+ stats.print
265
+
266
+ total.add stats
267
+ end
268
+ end
269
+
270
+ if $options.print_stats && ARGV.length > 1
271
+ puts "\n"
272
+ puts("=" * 70)
273
+ puts "total"
274
+ total.print
275
+ end
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #############################################################################
4
+ ## Prints out information about cycle start/stop/def records in the input
5
+ ## warts files.
6
+ ##
7
+ ## --------------------------------------------------------------------------
8
+ ## Copyright (C) 2007 The Regents of the University of California.
9
+ ##
10
+ ## This program is free software; you can redistribute it and/or modify
11
+ ## it under the terms of the GNU General Public License as published by
12
+ ## the Free Software Foundation; either version 2 of the License, or
13
+ ## (at your option) any later version.
14
+ ##
15
+ ## This program is distributed in the hope that it will be useful,
16
+ ## but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ ## GNU General Public License for more details.
19
+ ##
20
+ ## You should have received a copy of the GNU General Public License
21
+ ## along with this program; if not, write to the Free Software
22
+ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
+ ##
24
+ ## $Id: show-cycles,v 1.1 2007/11/30 01:14:48 youngh Exp $
25
+ #############################################################################
26
+
27
+ require "rubygems"
28
+ require 'wartslib'
29
+
30
+ def cycle_type(element)
31
+ case element.element_type
32
+ when Warts::File::CYCLE_START: "START"
33
+ when Warts::File::CYCLE_DEF: "DEF"
34
+ when Warts::File::CYCLE_STOP: "STOP"
35
+ end
36
+ end
37
+
38
+ def ts_date(timestamp)
39
+ timestamp > 0 ? " (" + Time.at(timestamp).to_s + ")" : ""
40
+ end
41
+
42
+ ARGV.each do |path|
43
+ puts ">> #{path}"
44
+ Warts::File::open(path) do |file|
45
+ file.add_filters Warts::File::CYCLE_START, Warts::File::CYCLE_DEF,
46
+ Warts::File::CYCLE_STOP
47
+ file.read do |c|
48
+ start_date = ts_date c.start_time
49
+ stop_date = ts_date c.stop_time
50
+ puts sprintf("%5s: id=%d\n start=%d%s\n stop=%d%s",
51
+ cycle_type(c), c.id, c.start_time, start_date,
52
+ c.stop_time, stop_date)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #############################################################################
4
+ ## Utility for splitting traces into multiple files based on the probe
5
+ ## method (e.g., UDP, ICMP-paris).
6
+ ##
7
+ ## --------------------------------------------------------------------------
8
+ ## Copyright (C) 2007 The Regents of the University of California.
9
+ ##
10
+ ## This program is free software; you can redistribute it and/or modify
11
+ ## it under the terms of the GNU General Public License as published by
12
+ ## the Free Software Foundation; either version 2 of the License, or
13
+ ## (at your option) any later version.
14
+ ##
15
+ ## This program is distributed in the hope that it will be useful,
16
+ ## but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ ## GNU General Public License for more details.
19
+ ##
20
+ ## You should have received a copy of the GNU General Public License
21
+ ## along with this program; if not, write to the Free Software
22
+ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
+ ##
24
+ ## $Id: split-traces-by-type,v 1.1 2007/11/30 01:14:48 youngh Exp $
25
+ #############################################################################
26
+
27
+ require 'rubygems'
28
+ require 'fileutils'
29
+ require 'wartslib'
30
+
31
+ #---------------------------------------------------------------------------
32
+
33
+ class SplitFiles
34
+ def initialize(filename)
35
+ @basename = File.basename filename, ".gz"
36
+ @basename += ".warts" unless @basename.include? ".warts"
37
+ @output_files = {}
38
+ end
39
+
40
+ def sort_trace(trace)
41
+ open_output_file trace
42
+ @output_files[trace.type].write trace
43
+ end
44
+
45
+ def close_all
46
+ @output_files.each_value do |file|
47
+ file.close
48
+ end
49
+ @output_files.clear
50
+ end
51
+
52
+ private
53
+
54
+ def open_output_file(trace)
55
+ unless @output_files.has_key? trace.type
56
+ type_name = trace_type_name trace.type
57
+ filename = @basename.sub(/\.warts/, "-" + type_name + ".warts")
58
+ file = Warts::File::open filename, "w", Warts::File::WARTS
59
+ @output_files[trace.type] = file
60
+ end
61
+ end
62
+
63
+ def trace_type_name(type)
64
+ case type
65
+ when Warts::Trace::TYPE_ICMP_ECHO: "icmp"
66
+ when Warts::Trace::TYPE_UDP: "udp"
67
+ when Warts::Trace::TYPE_TCP: "tcp"
68
+ when Warts::Trace::TYPE_ICMP_ECHO_PARIS: "icmp-paris"
69
+ when Warts::Trace::TYPE_UDP_PARIS: "udp-paris"
70
+ else fail "unknown trace type #{trace.type}"
71
+ end
72
+ end
73
+ end
74
+
75
+
76
+ #############################################################################
77
+ # MAIN
78
+ #############################################################################
79
+
80
+ if ARGV.length > 0
81
+ ARGV.each do |filename|
82
+ puts "splitting " + filename
83
+ split = SplitFiles.new filename
84
+
85
+ Warts::File::open(filename) do |file|
86
+ file.add_filters Warts::File::TRACE
87
+ file.read do |element|
88
+ split.sort_trace element
89
+ end
90
+ end
91
+
92
+ split.close_all
93
+ end
94
+ else
95
+ $stderr.puts "no files specified; nothing to do"
96
+ exit 0
97
+ end