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/CHANGES +4 -0
- data/bin/count-traces +42 -0
- data/bin/create-aspath +169 -0
- data/bin/extract-trace-addrs +98 -0
- data/bin/modify-traces +137 -0
- data/bin/scdump +18 -1
- data/bin/select-traces +275 -0
- data/bin/show-cycles +55 -0
- data/bin/split-traces-by-type +97 -0
- data/bin/stat-traces +118 -0
- data/bin/trace-gap-size-hist +159 -0
- data/bin/trace-timestamps-hist +51 -0
- data/bin/w2tr +39 -0
- data/bin/wcat +73 -0
- data/bin/wdump +18 -1
- data/ext/scext.c +2 -2
- metadata +15 -4
- data/bin/analyze-order +0 -37
data/bin/scdump
CHANGED
@@ -3,7 +3,24 @@
|
|
3
3
|
#############################################################################
|
4
4
|
## Ruby version of sc_analsysis_dump.
|
5
5
|
##
|
6
|
-
##
|
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'
|
data/bin/select-traces
ADDED
@@ -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
|
data/bin/show-cycles
ADDED
@@ -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
|