rb-wartslib 0.9.11 → 0.9.12
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 +6 -0
- data/bin/extract-trace-addrs +3 -3
- data/bin/scdump +7 -7
- data/bin/stat-traces +86 -3
- data/bin/wdump +5 -5
- data/docs/gen-code-html +107 -0
- data/docs/gen-output-html +9 -0
- data/docs/gen-tut-html +4 -0
- data/docs/index.html +221 -0
- data/docs/layout.css +40 -0
- data/docs/reference.html +229 -0
- data/docs/ruby.css +34 -0
- data/docs/samples.html +48 -0
- data/docs/style.css +222 -0
- data/docs/tut-1-count.rb +13 -0
- data/docs/tut-10-list2.rb +22 -0
- data/docs/tut-11-cycle.rb +20 -0
- data/docs/tut-12-cycle2.rb +36 -0
- data/docs/tut-13-write.rb +17 -0
- data/docs/tut-14-write2.rb +22 -0
- data/docs/tut-15-write3.rb +15 -0
- data/docs/tut-16-write4.rb +13 -0
- data/docs/tut-17-modify.rb +28 -0
- data/docs/tut-18-modify2.rb +29 -0
- data/docs/tut-2-count-block.rb +10 -0
- data/docs/tut-3-count-resp.rb +16 -0
- data/docs/tut-4-path-length.rb +44 -0
- data/docs/tut-5-hop-addr.rb +14 -0
- data/docs/tut-6-hop-addr2.rb +14 -0
- data/docs/tut-7-hop-addr3.rb +22 -0
- data/docs/tut-8-hop-addr4.rb +15 -0
- data/docs/tut-9-list.rb +16 -0
- data/docs/tutorial.html +950 -0
- data/ext/scext.c +2 -2
- data/ext/scfile.c +1 -1
- data/ext/sctrace.c +43 -39
- metadata +32 -5
data/docs/tut-1-count.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
num_traces = 0
|
7
|
+
Warts::File.open(ARGV[0]) do |file|
|
8
|
+
file.add_filters Warts::File::TRACE, Warts::File::LIST
|
9
|
+
file.read do |element|
|
10
|
+
case element.element_type
|
11
|
+
when Warts::File::TRACE
|
12
|
+
num_traces += 1
|
13
|
+
when Warts::File::LIST
|
14
|
+
puts " id: " + element.id.to_s
|
15
|
+
puts " name: " + element.name
|
16
|
+
puts " descr: " + element.descr
|
17
|
+
puts "monitor: " + element.monitor
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
puts "# traces: " + num_traces.to_s
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
def t(timestamp)
|
7
|
+
timestamp.to_s + " (" + Time.at(timestamp).to_s + ")"
|
8
|
+
end
|
9
|
+
|
10
|
+
Warts::File.open(ARGV[0]) do |file|
|
11
|
+
file.add_filters Warts::File::TRACE
|
12
|
+
trace = file.read
|
13
|
+
if trace
|
14
|
+
cycle = trace.cycle
|
15
|
+
puts " id: " + cycle.id.to_s
|
16
|
+
puts "start_time: " + t(cycle.start_time)
|
17
|
+
puts " stop_time: " + t(cycle.stop_time)
|
18
|
+
puts " hostname: " + cycle.hostname
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
CYCLE_TYPE = {
|
7
|
+
Warts::File::CYCLE_START => "start",
|
8
|
+
Warts::File::CYCLE_STOP => "stop",
|
9
|
+
Warts::File::CYCLE_DEF => "def"
|
10
|
+
}
|
11
|
+
|
12
|
+
def t(timestamp)
|
13
|
+
timestamp.to_s + " (" + Time.at(timestamp).to_s + ")"
|
14
|
+
end
|
15
|
+
|
16
|
+
num_traces = 0
|
17
|
+
Warts::File.open(ARGV[0]) do |file|
|
18
|
+
file.add_filters Warts::File::TRACE, Warts::File::CYCLE_START,
|
19
|
+
Warts::File::CYCLE_STOP, Warts::File::CYCLE_DEF
|
20
|
+
|
21
|
+
file.read do |element|
|
22
|
+
case element.element_type
|
23
|
+
when Warts::File::TRACE
|
24
|
+
num_traces += 1
|
25
|
+
when Warts::File::CYCLE_START, Warts::File::CYCLE_STOP,
|
26
|
+
Warts::File::CYCLE_DEF
|
27
|
+
puts "\n===> cycle " + CYCLE_TYPE[element.element_type]
|
28
|
+
puts " id: " + element.id.to_s
|
29
|
+
puts "start_time: " + t(element.start_time)
|
30
|
+
puts " stop_time: " + t(element.stop_time)
|
31
|
+
puts " hostname: " + element.hostname
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
puts "# traces: " + num_traces.to_s
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
out = Warts::File::open "out.warts", "w"
|
7
|
+
|
8
|
+
Warts::File::open(ARGV[0]) do |file|
|
9
|
+
file.add_filters Warts::File::TRACE
|
10
|
+
file.read do |trace|
|
11
|
+
if trace.dest_responded? && trace.path_length > 5
|
12
|
+
out.write trace
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
out.close
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
out = Warts::File::open "out.warts", "w"
|
7
|
+
|
8
|
+
Warts::File::open(ARGV[0]) do |file|
|
9
|
+
file.add_filters Warts::File::TRACE, Warts::File::CYCLE_START,
|
10
|
+
Warts::File::CYCLE_STOP
|
11
|
+
file.read do |element|
|
12
|
+
if element.element_type == Warts::File::TRACE
|
13
|
+
if element.dest_responded? && element.path_length > 5
|
14
|
+
out.write element
|
15
|
+
end
|
16
|
+
else
|
17
|
+
out.write element
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
out.close
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
out = Warts::File::open "out.txt", "w", Warts::File::TRACEROUTE
|
7
|
+
|
8
|
+
Warts::File::open(ARGV[0]) do |file|
|
9
|
+
file.add_filters Warts::File::TRACE
|
10
|
+
file.read do |trace|
|
11
|
+
out.write trace
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
out.close
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
out = Warts::File::open $stdout, "w", Warts::File::TRACEROUTE
|
7
|
+
|
8
|
+
Warts::File::open(ARGV[0]) do |file|
|
9
|
+
file.add_filters Warts::File::TRACE
|
10
|
+
file.read do |trace|
|
11
|
+
out.write trace
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
out = Warts::File::open "out.warts", "w"
|
7
|
+
|
8
|
+
cycle = nil
|
9
|
+
Warts::File.open(ARGV[0]) do |file|
|
10
|
+
file.add_all_filters
|
11
|
+
file.read do |element|
|
12
|
+
case element.element_type
|
13
|
+
when Warts::File::TRACE
|
14
|
+
element.cycle = cycle
|
15
|
+
|
16
|
+
when Warts::File::CYCLE_START, Warts::File::CYCLE_DEF,
|
17
|
+
Warts::File::CYCLE_STOP
|
18
|
+
element = element.derive(:id => 5, :hostname => "foo.bar.com")
|
19
|
+
unless element.element_type == Warts::File::CYCLE_STOP
|
20
|
+
cycle = element
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
out.write element
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
out.close
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
out = Warts::File::open "out.warts", "w"
|
7
|
+
|
8
|
+
cycle = nil
|
9
|
+
Warts::File.open(ARGV[0]) do |file|
|
10
|
+
file.add_all_filters
|
11
|
+
file.read do |element|
|
12
|
+
case element.element_type
|
13
|
+
when Warts::File::TRACE
|
14
|
+
element.cycle = cycle
|
15
|
+
|
16
|
+
when Warts::File::CYCLE_START, Warts::File::CYCLE_DEF,
|
17
|
+
Warts::File::CYCLE_STOP
|
18
|
+
list = element.list.derive(:name => "dnssurvey")
|
19
|
+
element = element.derive(:id => 5, :list => list)
|
20
|
+
unless element.element_type == Warts::File::CYCLE_STOP
|
21
|
+
cycle = element
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
out.write element
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
out.close
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'wartslib'
|
3
|
+
|
4
|
+
Warts::File::open(ARGV[0]) do |file|
|
5
|
+
file.add_filters Warts::File::TRACE
|
6
|
+
|
7
|
+
count = 0
|
8
|
+
file.read do |trace|
|
9
|
+
if trace.dest_responded? && trace.path_length > 5
|
10
|
+
print trace.start, " ", trace.dst, " ", trace.path_length, "\n"
|
11
|
+
count += 1
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
puts count
|
16
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
num_traces = 0
|
7
|
+
num_responding = 0
|
8
|
+
stop_reason = Hash.new 0
|
9
|
+
hop_histogram = Hash.new 0
|
10
|
+
|
11
|
+
Warts::File.open(ARGV[0]) do |file|
|
12
|
+
file.add_filters Warts::File::TRACE
|
13
|
+
file.read do |trace|
|
14
|
+
num_traces += 1
|
15
|
+
num_responding += 1 if trace.dest_responded?
|
16
|
+
stop_reason[trace.stop_reason] += 1
|
17
|
+
hop_histogram[trace.path_length] += 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
puts "%8d traces" % [num_traces]
|
22
|
+
puts "%8d responding" % [num_responding]
|
23
|
+
|
24
|
+
# from scamper_trace.h:SCAMPER_TRACE_STOP_*
|
25
|
+
stop_text = {
|
26
|
+
0 => "none (null reason)",
|
27
|
+
1 => "completed (got an ICMP port unreach)",
|
28
|
+
2 => "unreach (got an other ICMP unreach code)",
|
29
|
+
3 => "icmp (got an ICMP msg, not unreach)",
|
30
|
+
4 => "loop (loop detected)",
|
31
|
+
5 => "dead (unresponsive target)",
|
32
|
+
6 => "error (sendto error)"
|
33
|
+
}
|
34
|
+
stop_text.default = "<<UNKNOWN STOP CODE>>"
|
35
|
+
|
36
|
+
puts
|
37
|
+
stop_reason.to_a.sort.each do |k, v|
|
38
|
+
puts "%8d stop reason %d, %s" % [v, k, stop_text[k]]
|
39
|
+
end
|
40
|
+
|
41
|
+
puts
|
42
|
+
hop_histogram.to_a.sort.each do |k, v|
|
43
|
+
puts "%8d %d hops" % [v, k]
|
44
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
Warts::File.open(ARGV[0]) do |file|
|
7
|
+
file.add_filters Warts::File::TRACE
|
8
|
+
file.read do |trace|
|
9
|
+
puts "trace to " + trace.dst
|
10
|
+
(0 ... trace.hop_count).each do |i|
|
11
|
+
puts " #{i+1} " + (trace.hop_addr(i) || "*")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
Warts::File.open(ARGV[0]) do |file|
|
7
|
+
file.add_filters Warts::File::TRACE
|
8
|
+
file.read do |trace|
|
9
|
+
puts "trace to " + trace.dst
|
10
|
+
trace.each_hop do |i, exists|
|
11
|
+
puts " #{i+1} " + (exists ? trace.hop_addr(i) : "*")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
Warts::File.open(ARGV[0]) do |file|
|
7
|
+
file.add_filters Warts::File::TRACE
|
8
|
+
file.read do |trace|
|
9
|
+
puts "trace to " + trace.dst
|
10
|
+
trace.each_hop do |hop, exists|
|
11
|
+
print " #{hop+1}"
|
12
|
+
if exists
|
13
|
+
trace.each_response(hop) do |response|
|
14
|
+
print " ", trace.hop_addr(hop, response)
|
15
|
+
end
|
16
|
+
puts
|
17
|
+
else
|
18
|
+
puts " *"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
Warts::File.open(ARGV[0]) do |file|
|
7
|
+
file.add_filters Warts::File::TRACE
|
8
|
+
file.read do |trace|
|
9
|
+
puts "trace to " + trace.dst
|
10
|
+
trace.each_hop_and_response do |hop, response, hop_exists|
|
11
|
+
printf " hop=%d, resp=%d: %s\n", hop, response,
|
12
|
+
(hop_exists ? trace.hop_addr(hop, response) : "*")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/docs/tut-9-list.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wartslib'
|
5
|
+
|
6
|
+
Warts::File.open(ARGV[0]) do |file|
|
7
|
+
file.add_filters Warts::File::TRACE
|
8
|
+
trace = file.read
|
9
|
+
if trace
|
10
|
+
list = trace.list
|
11
|
+
puts " id: " + list.id.to_s
|
12
|
+
puts " name: " + list.name
|
13
|
+
puts " descr: " + list.descr
|
14
|
+
puts "monitor: " + list.monitor
|
15
|
+
end
|
16
|
+
end
|
data/docs/tutorial.html
ADDED
@@ -0,0 +1,950 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>rb-wartslib: Tutorial</title>
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
6
|
+
<link rel="stylesheet" type="text/css" href="layout.css">
|
7
|
+
<link rel="stylesheet" type="text/css" href="style.css">
|
8
|
+
<link rel="stylesheet" type="text/css" href="ruby.css">
|
9
|
+
</head>
|
10
|
+
|
11
|
+
<body>
|
12
|
+
|
13
|
+
<div class="twikiTopBar">
|
14
|
+
<div class="twikiTopBarContents">
|
15
|
+
<h1 class="pagetitle">rb-wartslib: Ruby Warts Library</h1>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<a name="PageTop"></a>
|
20
|
+
<div class="twikiLeftBar">
|
21
|
+
<div class="twikiLeftBarContents">
|
22
|
+
<ul>
|
23
|
+
<li> <a href="index.html">Project Home Page</a></li>
|
24
|
+
<li> <a href="http://rubyforge.org/projects/rb-wartslib/">RubyForge Page</a></li>
|
25
|
+
</ul>
|
26
|
+
<hr>
|
27
|
+
<ul>
|
28
|
+
<li> <a href="index.html#installation">Installation</a></li>
|
29
|
+
<li> <a href="tutorial.html"><b>Tutorial</b></a></li>
|
30
|
+
<li> <a href="#basic_usage"> • Basic Usage</a></li>
|
31
|
+
<li> <a href="#trace_attributes"> • Trace Attributes</a></li>
|
32
|
+
<li> <a href="#hop_attributes"> • Hop Attributes</a></li>
|
33
|
+
<li> <a href="#list_attributes"> • List Attributes</a></li>
|
34
|
+
<li> <a href="#cycle_attributes"> • Cycle Attributes</a></li>
|
35
|
+
<li> <a href="#writing_files"> • Writing Files</a></li>
|
36
|
+
<li> <a href="#modifying_data"> • Modifying Data</a></li>
|
37
|
+
<li> <a href="reference.html">Class Reference</a></li>
|
38
|
+
<li> <a href="samples.html">Sample Scripts</a></li>
|
39
|
+
</ul>
|
40
|
+
<hr>
|
41
|
+
<ul>
|
42
|
+
<li> <a href="index.html#contact">Contact</a></li>
|
43
|
+
<li> <a href="index.html#license">License</a></li>
|
44
|
+
</ul>
|
45
|
+
</div></div>
|
46
|
+
|
47
|
+
<div class="twikiMain">
|
48
|
+
<div class="twikiTopic">
|
49
|
+
<h1>Tutorial</h1>
|
50
|
+
|
51
|
+
<h2><a name="basic_usage"></a>Basic Usage</h2>
|
52
|
+
<p>
|
53
|
+
Only a minimal amount of code is needed to use <i>rb-wartslib</i>, as the
|
54
|
+
following script shows. This script counts the number of traces in a file.
|
55
|
+
</p>
|
56
|
+
|
57
|
+
<!-- 1. count =========================================================== -->
|
58
|
+
<pre class="ruby snippet">
|
59
|
+
<span class="comment">#!/usr/bin/env ruby</span>
|
60
|
+
|
61
|
+
<span class="ident">require</span> <span class="punct">'</span><span class="string">rubygems</span><span class="punct">'</span>
|
62
|
+
<span class="ident">require</span> <span class="punct">'</span><span class="string">wartslib</span><span class="punct">'</span>
|
63
|
+
|
64
|
+
<span class="ident">file</span> <span class="punct">=</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span> <span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">]</span>
|
65
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
66
|
+
|
67
|
+
<span class="ident">count</span> <span class="punct">=</span> <span class="number">0</span>
|
68
|
+
<span class="keyword">while</span> <span class="punct">(</span><span class="ident">trace</span> <span class="punct">=</span> <span class="ident">file</span><span class="punct">.</span><span class="ident">read</span><span class="punct">)</span>
|
69
|
+
<span class="ident">count</span> <span class="punct">+=</span> <span class="number">1</span>
|
70
|
+
<span class="keyword">end</span>
|
71
|
+
|
72
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">close</span>
|
73
|
+
<span class="ident">puts</span> <span class="ident">count</span>
|
74
|
+
</pre>
|
75
|
+
|
76
|
+
<p>
|
77
|
+
You use the warts library in your scripts with the statement <code>require
|
78
|
+
'wartslib'</code>. There are no other <code>require</code> statements
|
79
|
+
(other than <code>require 'rubygems'</code>) or other setup work you need
|
80
|
+
to worry about. As you can see, everything is contained inside
|
81
|
+
the <code>Warts</code> top-level module. The library is small, so there
|
82
|
+
are only a handful of classes inside the <code>Warts</code> module.
|
83
|
+
</p>
|
84
|
+
|
85
|
+
<p>
|
86
|
+
The Ruby binding has transparent support for reading (but not writing)
|
87
|
+
files compressed with <a href="http://www.gzip.org/">gzip</a>,
|
88
|
+
<a href="http://www.bzip.org/">bzip2</a>, or
|
89
|
+
<a href="http://www.lzop.org/">lzop</a>. In fact,
|
90
|
+
the above example script (call it <code>count-traces</code>) will
|
91
|
+
automatically work as-is on compressed files; for example:
|
92
|
+
</p>
|
93
|
+
|
94
|
+
<pre class="snippet">
|
95
|
+
<span class="shell_command">$ ./count-traces 00024353.hourly.l7.t1.20071031-19.mnl-ph.warts.gz</span>
|
96
|
+
<span class="command_output">17496</span>
|
97
|
+
</pre>
|
98
|
+
|
99
|
+
<p>
|
100
|
+
You can manually specify the input file type with a parameter to
|
101
|
+
the <code>Warts::File::open</code> method, but it is often easier to just
|
102
|
+
let the library figure it out; for example, the above script works unchanged
|
103
|
+
on an <a href="http://www.caida.org/tools/utilities/arts/">arts++</a> file:
|
104
|
+
</p>
|
105
|
+
|
106
|
+
<pre class="snippet">
|
107
|
+
<span class="shell_command">$ ./count-traces l006.mwest.20070404_000.arts</span>
|
108
|
+
<span class="command_output">155830</span>
|
109
|
+
</pre>
|
110
|
+
|
111
|
+
<p>
|
112
|
+
Another convenient feature of the library is its support of Ruby blocks.
|
113
|
+
For example, we can minimize the above script even further by rewriting it
|
114
|
+
to use blocks (from now on, we will leave out the two <code>require</code>
|
115
|
+
lines in code listings):
|
116
|
+
</p>
|
117
|
+
|
118
|
+
<!-- 2. count+blocks ==================================================== -->
|
119
|
+
<pre class="ruby snippet">
|
120
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span><span class="punct">(<span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">]</span>)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
121
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
122
|
+
|
123
|
+
<span class="ident">count</span> <span class="punct">=</span> <span class="number">0</span>
|
124
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="punct">{</span> <span class="ident">count</span> <span class="punct">+=</span> <span class="number">1</span> <span class="punct">}</span>
|
125
|
+
<span class="ident">puts</span> <span class="ident">count</span>
|
126
|
+
<span class="keyword">end</span>
|
127
|
+
</pre>
|
128
|
+
|
129
|
+
<p>
|
130
|
+
The advantage to using a block for <code>Warts::File::open</code> is that
|
131
|
+
the file is closed for you when the block finishes or if an exception occurs.
|
132
|
+
</p>
|
133
|
+
|
134
|
+
|
135
|
+
<h2><a name="trace_attributes"></a>Accessing Trace Attributes</h2>
|
136
|
+
|
137
|
+
<p>
|
138
|
+
Trace objects are instances of <code>Warts::Trace</code>. Once you get a
|
139
|
+
trace from <code>Warts::File#read</code>, you can use accessor methods to
|
140
|
+
examine both the data and the metadata of a traceroute
|
141
|
+
path. <code>Warts::Trace</code> also provides a number of convenience methods.
|
142
|
+
</p>
|
143
|
+
|
144
|
+
<p>
|
145
|
+
For example, the following script gives a count of the traces that have
|
146
|
+
both a responding destination and a path length greater than 5. For these
|
147
|
+
traces, it prints out the trace timestamp, destination IP address, and the
|
148
|
+
path length.
|
149
|
+
</p>
|
150
|
+
|
151
|
+
<!--- 3. count+resp ------------------------------------------------------>
|
152
|
+
<pre class="ruby snippet">
|
153
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span><span class="punct">(<span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">]</span>)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
154
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
155
|
+
|
156
|
+
<span class="ident">count</span> <span class="punct">=</span> <span class="number">0</span>
|
157
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">trace</span><span class="punct">|</span>
|
158
|
+
<span class="keyword">if</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">dest_responded?</span> <span class="punct">&&</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">path_length</span> <span class="punct">></span> <span class="number">5</span>
|
159
|
+
<span class="ident">print</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">start</span><span class="punct">,</span> <span class="punct">"</span><span class="string"> </span><span class="punct">",</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">dst</span><span class="punct">,</span> <span class="punct">"</span><span class="string"> </span><span class="punct">",</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">path_length</span><span class="punct">,</span> <span class="punct">"</span><span class="string"><span class="escape">\n</span></span><span class="punct">"</span>
|
160
|
+
<span class="ident">count</span> <span class="punct">+=</span> <span class="number">1</span>
|
161
|
+
<span class="keyword">end</span>
|
162
|
+
<span class="keyword">end</span>
|
163
|
+
|
164
|
+
<span class="ident">puts</span> <span class="ident">count</span>
|
165
|
+
<span class="keyword">end</span>
|
166
|
+
</pre>
|
167
|
+
|
168
|
+
<pre class="snippet">
|
169
|
+
<span class="shell_command">$ ./count-traces3 traces.warts</span>
|
170
|
+
<span class="command_output">1169577966 10.205.150.148 17</span>
|
171
|
+
<span class="command_output">1169577964 10.198.133.11 18</span>
|
172
|
+
<span class="command_output">2</span>
|
173
|
+
</pre>
|
174
|
+
|
175
|
+
<p>
|
176
|
+
It doesn't take much additional code to turn the above script into the
|
177
|
+
beginnings of a full-featured trace statistics script; for example:
|
178
|
+
</p>
|
179
|
+
|
180
|
+
<!-- 4. stat-traces ====================================================== -->
|
181
|
+
<pre class="ruby snippet">
|
182
|
+
<span class="ident">num_traces</span> <span class="punct">=</span> <span class="number">0</span>
|
183
|
+
<span class="ident">num_responding</span> <span class="punct">=</span> <span class="number">0</span>
|
184
|
+
<span class="ident">stop_reason</span> <span class="punct">=</span> <span class="constant">Hash</span><span class="punct">.</span><span class="ident">new</span> <span class="number">0</span>
|
185
|
+
<span class="ident">hop_histogram</span> <span class="punct">=</span> <span class="constant">Hash</span><span class="punct">.</span><span class="ident">new</span> <span class="number">0</span>
|
186
|
+
|
187
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
188
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
189
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">trace</span><span class="punct">|</span>
|
190
|
+
<span class="ident">num_traces</span> <span class="punct">+=</span> <span class="number">1</span>
|
191
|
+
<span class="ident">num_responding</span> <span class="punct">+=</span> <span class="number">1</span> <span class="keyword">if</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">dest_responded?</span>
|
192
|
+
<span class="ident">stop_reason</span><span class="punct">[</span><span class="ident">trace</span><span class="punct">.</span><span class="ident">stop_reason</span><span class="punct">]</span> <span class="punct">+=</span> <span class="number">1</span>
|
193
|
+
<span class="ident">hop_histogram</span><span class="punct">[</span><span class="ident">trace</span><span class="punct">.</span><span class="ident">path_length</span><span class="punct">]</span> <span class="punct">+=</span> <span class="number">1</span>
|
194
|
+
<span class="keyword">end</span>
|
195
|
+
<span class="keyword">end</span>
|
196
|
+
|
197
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">%8d traces</span><span class="punct">"</span> <span class="punct">%</span> <span class="punct">[</span><span class="ident">num_traces</span><span class="punct">]</span>
|
198
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">%8d responding</span><span class="punct">"</span> <span class="punct">%</span> <span class="punct">[</span><span class="ident">num_responding</span><span class="punct">]</span>
|
199
|
+
|
200
|
+
<span class="comment"># from scamper_trace.h:SCAMPER_TRACE_STOP_*</span>
|
201
|
+
<span class="ident">stop_text</span> <span class="punct">=</span> <span class="punct">{</span>
|
202
|
+
<span class="number">0</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">none (null reason)</span><span class="punct">",</span>
|
203
|
+
<span class="number">1</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">completed (got an ICMP port unreach)</span><span class="punct">",</span>
|
204
|
+
<span class="number">2</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">unreach (got an other ICMP unreach code)</span><span class="punct">",</span>
|
205
|
+
<span class="number">3</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">icmp (got an ICMP msg, not unreach)</span><span class="punct">",</span>
|
206
|
+
<span class="number">4</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">loop (loop detected)</span><span class="punct">",</span>
|
207
|
+
<span class="number">5</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">dead (unresponsive target)</span><span class="punct">",</span>
|
208
|
+
<span class="number">6</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">error (sendto error)</span><span class="punct">"</span>
|
209
|
+
<span class="punct">}</span>
|
210
|
+
<span class="ident">stop_text</span><span class="punct">.</span><span class="ident">default</span> <span class="punct">=</span> <span class="punct">"</span><span class="string"><<UNKNOWN STOP CODE>></span><span class="punct">"</span>
|
211
|
+
|
212
|
+
<span class="ident">puts</span>
|
213
|
+
<span class="ident">stop_reason</span><span class="punct">.</span><span class="ident">to_a</span><span class="punct">.</span><span class="ident">sort</span><span class="punct">.</span><span class="ident">each</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">k</span><span class="punct">,</span> <span class="ident">v</span><span class="punct">|</span>
|
214
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">%8d stop reason %d, %s</span><span class="punct">"</span> <span class="punct">%</span> <span class="punct">[</span><span class="ident">v</span><span class="punct">,</span> <span class="ident">k</span><span class="punct">,</span> <span class="ident">stop_text</span><span class="punct">[</span><span class="ident">k</span><span class="punct">]]</span>
|
215
|
+
<span class="keyword">end</span>
|
216
|
+
|
217
|
+
<span class="ident">puts</span>
|
218
|
+
<span class="ident">hop_histogram</span><span class="punct">.</span><span class="ident">to_a</span><span class="punct">.</span><span class="ident">sort</span><span class="punct">.</span><span class="ident">each</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">k</span><span class="punct">,</span> <span class="ident">v</span><span class="punct">|</span>
|
219
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">%8d %d hops</span><span class="punct">"</span> <span class="punct">%</span> <span class="punct">[</span><span class="ident">v</span><span class="punct">,</span> <span class="ident">k</span><span class="punct">]</span>
|
220
|
+
<span class="keyword">end</span>
|
221
|
+
</pre>
|
222
|
+
|
223
|
+
<pre class="snippet">
|
224
|
+
<span class="shell_command">$ ./stat-traces traces.warts</span>
|
225
|
+
<span class="command_output"> 49 traces</span>
|
226
|
+
<span class="command_output"> 2 responding</span>
|
227
|
+
<span class="command_output"></span>
|
228
|
+
<span class="command_output"> 2 stop reason 1, completed (got an ICMP port unreach)</span>
|
229
|
+
<span class="command_output"> 13 stop reason 2, unreach (got an other ICMP unreach code)</span>
|
230
|
+
<span class="command_output"> 17 stop reason 4, loop (loop detected)</span>
|
231
|
+
<span class="command_output"> 17 stop reason 5, dead (unresponsive target)</span>
|
232
|
+
<span class="command_output"></span>
|
233
|
+
<span class="command_output"> 3 2 hops</span>
|
234
|
+
<span class="command_output"> 1 4 hops</span>
|
235
|
+
<span class="command_output"> 1 6 hops</span>
|
236
|
+
<span class="command_output"> 11 7 hops</span>
|
237
|
+
<span class="command_output"> 5 8 hops</span>
|
238
|
+
<span class="command_output"> 2 9 hops</span>
|
239
|
+
<span class="command_output"> 1 10 hops</span>
|
240
|
+
<span class="command_output"> ...</span>
|
241
|
+
</pre>
|
242
|
+
|
243
|
+
<h2><a name="hop_attributes"></a>Accessing Hop Attributes</h2>
|
244
|
+
|
245
|
+
<p>
|
246
|
+
You access information about a hop via the <code>Warts::Trace</code>
|
247
|
+
object returned by <code>Warts::File#read</code>. (Note: There isn't a
|
248
|
+
separate class for trace hops, unlike in the underlying <i>scamper</i>
|
249
|
+
implementation).
|
250
|
+
</p>
|
251
|
+
|
252
|
+
<p>
|
253
|
+
Each accessor method for hop data is named with a <code>hop_</code> prefix;
|
254
|
+
for example, <code>hop_addr</code> to obtain the IP address of a hop,
|
255
|
+
and <code>hop_rtt</code> to obtain the RTT. You pass an index to these
|
256
|
+
hop accessor methods to indicate which hop to examine. For example,
|
257
|
+
<code>trace.hop_addr(0)</code> returns the address of the first hop (using
|
258
|
+
zero-based indexing).
|
259
|
+
</p>
|
260
|
+
|
261
|
+
<p>
|
262
|
+
If <i>scamper</i> did not receive a response at a given hop, then no hop
|
263
|
+
data will be available in the trace object at that hop, and all of the hop
|
264
|
+
accessor methods will return <code>nil</code> for that hop. (The accessor
|
265
|
+
methods will also return <code>nil</code> if the index you provide exceeds
|
266
|
+
the highest available hop.) You can also use the
|
267
|
+
method <code>Warts::Trace#hop_exists?</code> to determine whether there is
|
268
|
+
any hop data at a given index.
|
269
|
+
</p>
|
270
|
+
|
271
|
+
<p>
|
272
|
+
Use the method <code>Warts::Trace#hop_count</code> to determine the upper
|
273
|
+
bound on the hop indexes; in particular, all valid hop indexes must be
|
274
|
+
strictly less than this value. However, you shouldn't ascribe too much
|
275
|
+
meaning to <code>hop_count</code>. This value is not necessarily equal to
|
276
|
+
the path length (you should use <code>Warts::Trace#path_length</code> to
|
277
|
+
compute that) because of possible unresponsive hops at the end of a trace.
|
278
|
+
This also means that there may be missing hop data at indexes leading up
|
279
|
+
to <code>hop_count</code>.
|
280
|
+
</p>
|
281
|
+
|
282
|
+
<p>
|
283
|
+
The following script prints out the IP path of each trace using hop
|
284
|
+
accessor methods.
|
285
|
+
</p>
|
286
|
+
|
287
|
+
<!-- 5. hop-addr ========================================================= -->
|
288
|
+
<pre class="ruby snippet">
|
289
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
290
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
291
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">trace</span><span class="punct">|</span>
|
292
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">trace to </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">dst</span>
|
293
|
+
<span class="punct">(</span><span class="number">0</span> <span class="punct">...</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">hop_count</span><span class="punct">).</span><span class="ident">each</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">i</span><span class="punct">|</span>
|
294
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> <span class="expr">#{i+1}</span> </span><span class="punct">"</span> <span class="punct">+</span> <span class="punct">(</span><span class="ident">trace</span><span class="punct">.</span><span class="ident">hop_addr</span><span class="punct">(</span><span class="ident">i</span><span class="punct">)</span> <span class="punct">||</span> <span class="punct">"</span><span class="string">*</span><span class="punct">")</span>
|
295
|
+
<span class="keyword">end</span>
|
296
|
+
<span class="keyword">end</span>
|
297
|
+
<span class="keyword">end</span>
|
298
|
+
</pre>
|
299
|
+
|
300
|
+
<pre class="snippet">
|
301
|
+
<span class="shell_command">$ hop-addr traces.warts</span>
|
302
|
+
<span class="command_output">trace to 10.72.146.120</span>
|
303
|
+
<span class="command_output"> 1 10.172.226.1</span>
|
304
|
+
<span class="command_output"> 2 10.17.46.8</span>
|
305
|
+
<span class="command_output"> 3 10.164.24.205</span>
|
306
|
+
<span class="command_output"> 4 10.71.128.5</span>
|
307
|
+
<span class="command_output"> 5 10.68.102.97</span>
|
308
|
+
<span class="command_output"> 6 10.68.128.157</span>
|
309
|
+
<span class="command_output"> 7 10.68.121.194</span>
|
310
|
+
<span class="command_output"> 8 10.68.110.162</span>
|
311
|
+
<span class="command_output"> 9 10.171.214.137</span>
|
312
|
+
<span class="command_output"> 10 *</span>
|
313
|
+
<span class="command_output"> 11 10.171.14.170</span>
|
314
|
+
<span class="command_output"> 12 10.115.84.234</span>
|
315
|
+
<span class="command_output">trace to 10.252.182.175</span>
|
316
|
+
<span class="command_output"> 1 10.172.226.1</span>
|
317
|
+
<span class="command_output"> 2 10.17.46.8</span>
|
318
|
+
<span class="command_output"> 3 10.164.24.157</span>
|
319
|
+
<span class="command_output"> 4 10.164.22.231</span>
|
320
|
+
<span class="command_output"> 5 *</span>
|
321
|
+
<span class="command_output"> 6 *</span>
|
322
|
+
<span class="command_output"> 7 *</span>
|
323
|
+
<span class="command_output"> 8 *</span>
|
324
|
+
<span class="command_output"> 9 *</span>
|
325
|
+
<span class="command_output">trace to 10.98.198.154</span>
|
326
|
+
<span class="command_output"> ...</span>
|
327
|
+
</pre>
|
328
|
+
|
329
|
+
<p>
|
330
|
+
In the second trace above, there are five consecutive unresponsive hops
|
331
|
+
at the end of the trace. Therefore, <code>Trace#path_length</code>
|
332
|
+
will return 4, while <code>Trace#hop_count</code> will return 9.
|
333
|
+
As you can see, <code>path_length</code> indicates the highest
|
334
|
+
<b>responding</b> hop, while <code>hop_count</code> indicates the
|
335
|
+
highest <b>attempted</b> hop.
|
336
|
+
</p>
|
337
|
+
|
338
|
+
<p>
|
339
|
+
<code>Warts::Trace#each_hop</code> provides a more succinct way of
|
340
|
+
iterating over all hops and, at the same time, getting an indication of hop
|
341
|
+
existence, as demonstrated in the following script:
|
342
|
+
</p>
|
343
|
+
|
344
|
+
<!-- 6. hop-addr2 ======================================================== -->
|
345
|
+
<pre class="ruby snippet">
|
346
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
347
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
348
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">trace</span><span class="punct">|</span>
|
349
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">trace to </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">dst</span>
|
350
|
+
<span class="ident">trace</span><span class="punct">.</span><span class="ident">each_hop</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">i</span><span class="punct">,</span> <span class="ident">exists</span><span class="punct">|</span>
|
351
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> <span class="expr">#{i+1}</span> </span><span class="punct">"</span> <span class="punct">+</span> <span class="punct">(</span><span class="ident">exists</span> <span class="punct">?</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">hop_addr</span><span class="punct">(</span><span class="ident">i</span><span class="punct">)</span> <span class="punct">:</span> <span class="punct">"</span><span class="string">*</span><span class="punct">")</span>
|
352
|
+
<span class="keyword">end</span>
|
353
|
+
<span class="keyword">end</span>
|
354
|
+
<span class="keyword">end</span>
|
355
|
+
</pre>
|
356
|
+
|
357
|
+
<h3>Multiple Hop Responses</h3>
|
358
|
+
|
359
|
+
<p>
|
360
|
+
All sample scripts so far have assumed that a hop can only have one
|
361
|
+
response, if it has a response at all. This is the case most of the time,
|
362
|
+
and making this assumption simplifies the analysis with usually only a
|
363
|
+
slight loss of information. However, <i>scamper</i> may store as many
|
364
|
+
as <i>N</i> different responses at a given hop, depending on <i>scamper</i>
|
365
|
+
settings and the responsiveness of intermediate hops during probing. With
|
366
|
+
the default settings, <i>scamper</i> makes up to 2 attempts per hop; that
|
367
|
+
is, if the first probe to a hop doesn't elicit a response within some
|
368
|
+
timeout period, then <i>scamper</i> will send out a second probe. As a
|
369
|
+
result, a hop can have 0, 1, or 2 recorded responses, although the case of
|
370
|
+
2 recorded responses will only happen under a rare scenario--namely, when
|
371
|
+
the response to the first attempt is delayed and arrives after the second
|
372
|
+
attempt is made. Of course, if you increase the setting for the maximum
|
373
|
+
number of attempts per hop, then the chance of getting multiple responses
|
374
|
+
at a hop will also increase.
|
375
|
+
</p>
|
376
|
+
|
377
|
+
<p>
|
378
|
+
You are much more likely to encounter multiple responses at a hop if you
|
379
|
+
explicitly configure <i>scamper</i> to always try <i>N</i> attempts at each
|
380
|
+
hop, regardless of responsiveness, and to store all received responses.
|
381
|
+
This is the way that <code>traceroute</code> is normally run, with it
|
382
|
+
always making 3 attempts at each hop.
|
383
|
+
</p>
|
384
|
+
|
385
|
+
<p>
|
386
|
+
Fortunately, working with multiple responses at a hop is easy. Every hop
|
387
|
+
accessor method, like <code>hop_addr</code>, can actually take two
|
388
|
+
parameters. The first parameter is the hop index, as you've already seen.
|
389
|
+
The second parameter is the <b>response</b> index, beginning with 0 for the
|
390
|
+
first response. The response parameter has a default value of 0, which is
|
391
|
+
the reason we were able to leave it out in the sample code so far. Hence,
|
392
|
+
the call <code>hop_addr(i)</code> is equivalent to <code>hop_addr(i,
|
393
|
+
0)</code>. One way to iterate over all responses at a given hop is to
|
394
|
+
use <code>Warts::Trace#each_response</code>, as illustrated by the
|
395
|
+
following script, which prints out the IP address of all responses at all
|
396
|
+
hops:
|
397
|
+
</p>
|
398
|
+
|
399
|
+
<!-- 7. hop-addr3 ======================================================== -->
|
400
|
+
<pre class="ruby snippet">
|
401
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
402
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
403
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">trace</span><span class="punct">|</span>
|
404
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">trace to </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">dst</span>
|
405
|
+
<span class="ident">trace</span><span class="punct">.</span><span class="ident">each_hop</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">hop</span><span class="punct">,</span> <span class="ident">exists</span><span class="punct">|</span>
|
406
|
+
<span class="ident">print</span> <span class="punct">"</span><span class="string"> <span class="expr">#{hop+1}</span></span><span class="punct">"</span>
|
407
|
+
<span class="keyword">if</span> <span class="ident">exists</span>
|
408
|
+
<span class="ident">trace</span><span class="punct">.</span><span class="ident">each_response</span><span class="punct">(</span><span class="ident">hop</span><span class="punct">)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">response</span><span class="punct">|</span>
|
409
|
+
<span class="ident">print</span> <span class="punct">"</span><span class="string"> </span><span class="punct">",</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">hop_addr</span><span class="punct">(</span><span class="ident">hop</span><span class="punct">,</span> <span class="ident">response</span><span class="punct">)</span>
|
410
|
+
<span class="keyword">end</span>
|
411
|
+
<span class="ident">puts</span>
|
412
|
+
<span class="keyword">else</span>
|
413
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> *</span><span class="punct">"</span>
|
414
|
+
<span class="keyword">end</span>
|
415
|
+
<span class="keyword">end</span>
|
416
|
+
<span class="keyword">end</span>
|
417
|
+
<span class="keyword">end</span>
|
418
|
+
</pre>
|
419
|
+
|
420
|
+
<pre class="snippet">
|
421
|
+
<span class="shell_command">$ hop-response traces.warts</span>
|
422
|
+
<span class="command_output">trace to 10.72.146.120</span>
|
423
|
+
<span class="command_output"> 1 10.172.226.1</span>
|
424
|
+
<span class="command_output"> 2 10.17.46.8 10.17.46.10</span>
|
425
|
+
<span class="command_output"> 3 10.164.24.205 10.164.24.207</span>
|
426
|
+
<span class="command_output"> 4 *</span>
|
427
|
+
<span class="command_output"> 5 10.68.121.194</span>
|
428
|
+
<span class="command_output"> 6 10.72.146.120</span>
|
429
|
+
</pre>
|
430
|
+
|
431
|
+
<p>
|
432
|
+
You can iterate over both hops and responses at the same time with
|
433
|
+
<code>Warts::Trace#each_hop_and_response</code> (or more simply
|
434
|
+
<code>Warts::Trace#each</code>). The following script prints out the
|
435
|
+
IP address of all responses of all hops:
|
436
|
+
</p>
|
437
|
+
|
438
|
+
<!-- 8. hop-addr4 ======================================================== -->
|
439
|
+
<pre class="ruby snippet">
|
440
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
441
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
442
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">trace</span><span class="punct">|</span>
|
443
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">trace to </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">dst</span>
|
444
|
+
<span class="ident">trace</span><span class="punct">.</span><span class="ident">each_hop_and_response</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">hop</span><span class="punct">,</span> <span class="ident">response</span><span class="punct">,</span> <span class="ident">hop_exists</span><span class="punct">|</span>
|
445
|
+
<span class="ident">printf</span> <span class="punct">"</span><span class="string"> hop=%d, resp=%d: %s<span class="escape">\n</span></span><span class="punct">",</span> <span class="ident">hop</span><span class="punct">,</span> <span class="ident">response</span><span class="punct">,</span>
|
446
|
+
<span class="punct">(</span><span class="ident">hop_exists</span> <span class="punct">?</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">hop_addr</span><span class="punct">(</span><span class="ident">hop</span><span class="punct">,</span> <span class="ident">response</span><span class="punct">)</span> <span class="punct">:</span> <span class="punct">"</span><span class="string">*</span><span class="punct">")</span>
|
447
|
+
<span class="keyword">end</span>
|
448
|
+
<span class="keyword">end</span>
|
449
|
+
<span class="keyword">end</span>
|
450
|
+
</pre>
|
451
|
+
|
452
|
+
<pre class="snippet">
|
453
|
+
<span class="shell_command">$ hop-response2 traces.warts</span>
|
454
|
+
<span class="command_output">trace to 10.72.146.120</span>
|
455
|
+
<span class="command_output"> hop=0, resp=0: 10.172.226.1</span>
|
456
|
+
<span class="command_output"> hop=1, resp=0: 10.17.46.8</span>
|
457
|
+
<span class="command_output"> hop=1, resp=1: 10.17.46.10</span>
|
458
|
+
<span class="command_output"> hop=2, resp=0: 10.164.24.205</span>
|
459
|
+
<span class="command_output"> hop=2, resp=1: 10.164.24.207</span>
|
460
|
+
<span class="command_output"> hop=3, resp=0: *</span>
|
461
|
+
<span class="command_output"> hop=4, resp=0: 10.68.121.194</span>
|
462
|
+
<span class="command_output"> hop=5, resp=0: 10.72.146.120</span>
|
463
|
+
</pre>
|
464
|
+
|
465
|
+
|
466
|
+
<h2><a name="list_attributes"></a>Accessing List Attributes</h2>
|
467
|
+
|
468
|
+
<p>
|
469
|
+
In the terminology of <i>scamper</i>, a <b>list</b> is a set of destination
|
470
|
+
addresses. You typically store a list in a file, and give the name of the
|
471
|
+
file to <i>scamper</i> on the command line. A list has some logical
|
472
|
+
identity, and for the purposes of keeping track of which list a trace
|
473
|
+
belongs to, it is helpful to record the list ID number, name, and/or a
|
474
|
+
description in a trace file. <i>scamper</i> itself doesn't need or use
|
475
|
+
this sort of descriptive information about a list, but it can store this
|
476
|
+
information in generated trace files on your behalf.
|
477
|
+
</p>
|
478
|
+
|
479
|
+
<p>
|
480
|
+
Given a warts file, you can examine any recorded information about lists in
|
481
|
+
one of two ways. The first way is to use the accessor
|
482
|
+
method <code>Warts::Trace#list</code> to get information about the list to
|
483
|
+
which a particular trace belongs (a warts file can contain traces from more
|
484
|
+
than one list, but a given trace can only belong to a single list). The
|
485
|
+
list information is returned in the form of a <code>Warts::List</code>
|
486
|
+
object, which has accessors for the list ID, name, and description.
|
487
|
+
(<code>Warts::List</code> also stores the canonical name of the measurement
|
488
|
+
monitor.) For example, the following script prints out the list
|
489
|
+
information for the first trace in a warts file:
|
490
|
+
</p>
|
491
|
+
|
492
|
+
<!-- 9. list =========================================================== -->
|
493
|
+
<pre class="ruby snippet">
|
494
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
495
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
496
|
+
<span class="ident">trace</span> <span class="punct">=</span> <span class="ident">file</span><span class="punct">.</span><span class="ident">read</span>
|
497
|
+
<span class="keyword">if</span> <span class="ident">trace</span>
|
498
|
+
<span class="ident">list</span> <span class="punct">=</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">list</span>
|
499
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> id: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">list</span><span class="punct">.</span><span class="ident">id</span><span class="punct">.</span><span class="ident">to_s</span>
|
500
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> name: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">list</span><span class="punct">.</span><span class="ident">name</span>
|
501
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> descr: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">list</span><span class="punct">.</span><span class="ident">descr</span>
|
502
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">monitor: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">list</span><span class="punct">.</span><span class="ident">monitor</span>
|
503
|
+
<span class="keyword">end</span>
|
504
|
+
<span class="keyword">end</span>
|
505
|
+
</pre>
|
506
|
+
|
507
|
+
<pre class="snippet">
|
508
|
+
<span class="shell_command">$ ./list-info traces.warts</span>
|
509
|
+
<span class="command_output"> id: 2</span>
|
510
|
+
<span class="command_output"> name: allpref24</span>
|
511
|
+
<span class="command_output"> descr: One randomly-selected address in every routed /24.</span>
|
512
|
+
<span class="command_output">monitor: mnl-ph</span>
|
513
|
+
</pre>
|
514
|
+
|
515
|
+
<p>
|
516
|
+
The second way to examine list information is to directly retrieve the
|
517
|
+
<code>Warts::List</code> objects stored in a warts file rather than
|
518
|
+
accessing them indirectly via a <code>Warts::Trace</code> object. For
|
519
|
+
example, the following script examines all list and trace objects in a
|
520
|
+
warts file, printing out the details of each encountered list object and
|
521
|
+
counting encountered traces (note the
|
522
|
+
additional <code>Warts::File::LIST</code> passed
|
523
|
+
to <code>File#add_filters</code>):
|
524
|
+
</p>
|
525
|
+
|
526
|
+
<!-- 10. list2 ========================================================== -->
|
527
|
+
<pre class="ruby snippet">
|
528
|
+
<span class="ident">num_traces</span> <span class="punct">=</span> <span class="number">0</span>
|
529
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
530
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span><span class="punct">,</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">LIST</span>
|
531
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">element</span><span class="punct">|</span>
|
532
|
+
<span class="keyword">case</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">element_type</span>
|
533
|
+
<span class="keyword">when</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
534
|
+
<span class="ident">num_traces</span> <span class="punct">+=</span> <span class="number">1</span>
|
535
|
+
<span class="keyword">when</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">LIST</span>
|
536
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> id: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">id</span><span class="punct">.</span><span class="ident">to_s</span>
|
537
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> name: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">name</span>
|
538
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> descr: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">descr</span>
|
539
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">monitor: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">monitor</span>
|
540
|
+
<span class="keyword">end</span>
|
541
|
+
<span class="keyword">end</span>
|
542
|
+
<span class="keyword">end</span>
|
543
|
+
|
544
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"># traces: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">num_traces</span><span class="punct">.</span><span class="ident">to_s</span>
|
545
|
+
</pre>
|
546
|
+
|
547
|
+
<pre class="snippet">
|
548
|
+
<span class="shell_command">$ ./list-info2 traces.warts</span>
|
549
|
+
<span class="command_output"> id: 2</span>
|
550
|
+
<span class="command_output"> name: allpref24</span>
|
551
|
+
<span class="command_output"> descr: One randomly-selected address in every routed /24.</span>
|
552
|
+
<span class="command_output">monitor: mnl-ph</span>
|
553
|
+
<span class="command_output"> id: 3</span>
|
554
|
+
<span class="command_output"> name: dnssurvey</span>
|
555
|
+
<span class="command_output"> descr: Top 500 DNS servers.</span>
|
556
|
+
<span class="command_output">monitor: mnl-ph</span>
|
557
|
+
<span class="command_output"># traces: 17496</span>
|
558
|
+
</pre>
|
559
|
+
|
560
|
+
|
561
|
+
<h2><a name="cycle_attributes"></a>Accessing Cycle Attributes</h2>
|
562
|
+
|
563
|
+
<p>
|
564
|
+
In the terminology of <i>scamper</i>, a <b>cycle</b> is a single pass
|
565
|
+
through a destination list. A single warts file can contain multiple
|
566
|
+
cycles of data.
|
567
|
+
</p>
|
568
|
+
|
569
|
+
<p>
|
570
|
+
Just as for list information, there are two ways of getting at cycle
|
571
|
+
information stored in a warts file. The first way is to use the accessor
|
572
|
+
method <code>Warts::Trace#cycle</code> to get information about the cycle
|
573
|
+
in which a trace was collected. The cycle information is returned in the
|
574
|
+
form of a <code>Warts::Cycle</code> object, which has accessors for the
|
575
|
+
cycle ID, start time, and stop time. (<code>Warts::Cycle</code> also
|
576
|
+
stores the hostname of the measurement monitor at the start of the cycle,
|
577
|
+
and you can get the associated list with <code>Warts::Cycle#list</code>.)
|
578
|
+
For example, the following script prints out the cycle information for the
|
579
|
+
first trace in a warts file:
|
580
|
+
</p>
|
581
|
+
|
582
|
+
<!-- 11. cycle ========================================================== -->
|
583
|
+
<pre class="ruby snippet">
|
584
|
+
<span class="keyword">def </span><span class="method">t</span><span class="punct">(</span><span class="ident">timestamp</span><span class="punct">)</span>
|
585
|
+
<span class="ident">timestamp</span><span class="punct">.</span><span class="ident">to_s</span> <span class="punct">+</span> <span class="punct">"</span><span class="string"> (</span><span class="punct">"</span> <span class="punct">+</span> <span class="constant">Time</span><span class="punct">.</span><span class="ident">at</span><span class="punct">(</span><span class="ident">timestamp</span><span class="punct">).</span><span class="ident">to_s</span> <span class="punct">+</span> <span class="punct">"</span><span class="string">)</span><span class="punct">"</span>
|
586
|
+
<span class="keyword">end</span>
|
587
|
+
|
588
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
589
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
590
|
+
<span class="ident">trace</span> <span class="punct">=</span> <span class="ident">file</span><span class="punct">.</span><span class="ident">read</span>
|
591
|
+
<span class="keyword">if</span> <span class="ident">trace</span>
|
592
|
+
<span class="ident">cycle</span> <span class="punct">=</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">cycle</span>
|
593
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> id: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">cycle</span><span class="punct">.</span><span class="ident">id</span><span class="punct">.</span><span class="ident">to_s</span>
|
594
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">start_time: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">t</span><span class="punct">(</span><span class="ident">cycle</span><span class="punct">.</span><span class="ident">start_time</span><span class="punct">)</span>
|
595
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> stop_time: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">t</span><span class="punct">(</span><span class="ident">cycle</span><span class="punct">.</span><span class="ident">stop_time</span><span class="punct">)</span>
|
596
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> hostname: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">cycle</span><span class="punct">.</span><span class="ident">hostname</span>
|
597
|
+
<span class="keyword">end</span>
|
598
|
+
<span class="keyword">end</span>
|
599
|
+
</pre>
|
600
|
+
|
601
|
+
<p>
|
602
|
+
The second way to examine cycle information is to directly retrieve
|
603
|
+
the <code>Warts::Cycle</code> objects stored in a warts file rather than
|
604
|
+
accessing them indirectly via a <code>Warts::Trace</code> object. There
|
605
|
+
are actually three types of cycle objects: cycle <b>start</b>, cycle
|
606
|
+
<b>stop</b>, and cycle <b>def</b>. However, all three types of objects are
|
607
|
+
represented with the same class. You can determine the cycle type
|
608
|
+
with <code>Warts::Cycle#element_type</code>.
|
609
|
+
</p>
|
610
|
+
|
611
|
+
<p>
|
612
|
+
<i>scamper</i> writes out cycle-start and cycle-stop records at the
|
613
|
+
beginning and end of a cycle, as you would expect. <i>scamper</i> writes
|
614
|
+
out a cycle-def record only when needed and only when the traces in a cycle
|
615
|
+
are stored across multiple files. The following figure should help clarify
|
616
|
+
the role of cycle-def records. Because the traces of the second cycle
|
617
|
+
spill over from <code>trace1.warts</code>
|
618
|
+
to <code>trace2.warts</code>, <i>scamper</i> writes out a cycle-def record
|
619
|
+
at the beginning of the latter file.
|
620
|
+
</p>
|
621
|
+
|
622
|
+
<pre>
|
623
|
+
+====================+
|
624
|
+
| cycle <span class="fig_green">start</span> record | <span class="fig_blue">trace1.warts</span>
|
625
|
+
+--------------------+
|
626
|
+
| trace 1 |
|
627
|
+
| trace 2 |
|
628
|
+
| ... |
|
629
|
+
| trace n |
|
630
|
+
+--------------------+
|
631
|
+
| cycle <span class="fig_green">stop</span> record |
|
632
|
+
+--------------------+
|
633
|
+
| cycle <span class="fig_green">start</span> record |
|
634
|
+
+--------------------+
|
635
|
+
| trace 1 |
|
636
|
+
| trace 2 |
|
637
|
+
| ... |
|
638
|
+
| trace k < n |
|
639
|
+
+====================+
|
640
|
+
|
641
|
+
+====================+
|
642
|
+
| cycle <span class="fig_red">def</span> record | <span class="fig_blue">trace2.warts</span>
|
643
|
+
+--------------------+
|
644
|
+
| trace k + 1 |
|
645
|
+
| trace k + 2 |
|
646
|
+
| ... |
|
647
|
+
| trace n |
|
648
|
+
+--------------------+
|
649
|
+
| cycle <span class="fig_green">stop</span> record |
|
650
|
+
+====================+
|
651
|
+
</pre>
|
652
|
+
|
653
|
+
<p>
|
654
|
+
The following script examines all cycle and trace objects in a warts file,
|
655
|
+
printing out the details of each encountered cycle object and counting
|
656
|
+
encountered traces (note the additional <code>Warts::File::CYCLE_xxx</code>
|
657
|
+
values passed to <code>File#add_filters</code>):
|
658
|
+
</p>
|
659
|
+
|
660
|
+
<!-- 12. cycle2 ========================================================== -->
|
661
|
+
<pre class="ruby snippet">
|
662
|
+
<span class="constant">CYCLE_TYPE</span> <span class="punct">=</span> <span class="punct">{</span>
|
663
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_START</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">start</span><span class="punct">",</span>
|
664
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_STOP</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">stop</span><span class="punct">",</span>
|
665
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_DEF</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">def</span><span class="punct">"</span>
|
666
|
+
<span class="punct">}</span>
|
667
|
+
|
668
|
+
<span class="keyword">def </span><span class="method">t</span><span class="punct">(</span><span class="ident">timestamp</span><span class="punct">)</span>
|
669
|
+
<span class="ident">timestamp</span><span class="punct">.</span><span class="ident">to_s</span> <span class="punct">+</span> <span class="punct">"</span><span class="string"> (</span><span class="punct">"</span> <span class="punct">+</span> <span class="constant">Time</span><span class="punct">.</span><span class="ident">at</span><span class="punct">(</span><span class="ident">timestamp</span><span class="punct">).</span><span class="ident">to_s</span> <span class="punct">+</span> <span class="punct">"</span><span class="string">)</span><span class="punct">"</span>
|
670
|
+
<span class="keyword">end</span>
|
671
|
+
|
672
|
+
<span class="ident">num_traces</span> <span class="punct">=</span> <span class="number">0</span>
|
673
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
674
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span><span class="punct">,</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_START</span><span class="punct">,</span>
|
675
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_STOP</span><span class="punct">,</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_DEF</span>
|
676
|
+
|
677
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">element</span><span class="punct">|</span>
|
678
|
+
<span class="keyword">case</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">element_type</span>
|
679
|
+
<span class="keyword">when</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
680
|
+
<span class="ident">num_traces</span> <span class="punct">+=</span> <span class="number">1</span>
|
681
|
+
<span class="keyword">when</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_START</span><span class="punct">,</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_STOP</span><span class="punct">,</span>
|
682
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_DEF</span>
|
683
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"><span class="escape">\n</span>===> cycle </span><span class="punct">"</span> <span class="punct">+</span> <span class="constant">CYCLE_TYPE</span><span class="punct">[</span><span class="ident">element</span><span class="punct">.</span><span class="ident">element_type</span><span class="punct">]</span>
|
684
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> id: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">id</span><span class="punct">.</span><span class="ident">to_s</span>
|
685
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string">start_time: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">t</span><span class="punct">(</span><span class="ident">element</span><span class="punct">.</span><span class="ident">start_time</span><span class="punct">)</span>
|
686
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> stop_time: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">t</span><span class="punct">(</span><span class="ident">element</span><span class="punct">.</span><span class="ident">stop_time</span><span class="punct">)</span>
|
687
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"> hostname: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">hostname</span>
|
688
|
+
<span class="keyword">end</span>
|
689
|
+
<span class="keyword">end</span>
|
690
|
+
<span class="keyword">end</span>
|
691
|
+
|
692
|
+
<span class="ident">puts</span> <span class="punct">"</span><span class="string"># traces: </span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">num_traces</span><span class="punct">.</span><span class="ident">to_s</span>
|
693
|
+
</pre>
|
694
|
+
|
695
|
+
|
696
|
+
<pre class="snippet">
|
697
|
+
<span class="shell_command">$ ./cycle-info2 traces.warts</span>
|
698
|
+
<span class="command_output"></span>
|
699
|
+
<span class="command_output">===> cycle start</span>
|
700
|
+
<span class="command_output"> id: 28</span>
|
701
|
+
<span class="command_output">start_time: 1190158509 (Tue Sep 18 16:35:09 -0700 2007)</span>
|
702
|
+
<span class="command_output"> stop_time: 0 (Wed Dec 31 16:00:00 -0800 1969)</span>
|
703
|
+
<span class="command_output"> hostname: mnl-ph.ark.caida.org</span>
|
704
|
+
<span class="command_output"></span>
|
705
|
+
<span class="command_output">===> cycle stop</span>
|
706
|
+
<span class="command_output"> id: 28</span>
|
707
|
+
<span class="command_output">start_time: 1190158509 (Tue Sep 18 16:35:09 -0700 2007)</span>
|
708
|
+
<span class="command_output"> stop_time: 1190159039 (Tue Sep 18 16:43:59 -0700 2007)</span>
|
709
|
+
<span class="command_output"> hostname: mnl-ph.ark.caida.org</span>
|
710
|
+
<span class="command_output"># traces: 17496</span>
|
711
|
+
</pre>
|
712
|
+
|
713
|
+
<p>
|
714
|
+
<b>NOTE:</b> Warts files produced by
|
715
|
+
the <a href="http://www.caida.org/projects/ark/">Archipelago
|
716
|
+
Measurement Infrastructure</a> (Ark) don't have cycle start or stop
|
717
|
+
records. They only contain cycle def records, and there may be more
|
718
|
+
than one cycle def record per file. This happens because Ark
|
719
|
+
reorganizes raw scamper traces into hourly and daily files, and the
|
720
|
+
current implementation of the reorganization procedure doesn't
|
721
|
+
preserve cycle start/stop records. However, if you
|
722
|
+
use <i>rb-wartslib</i> to process scamper traces you've collected
|
723
|
+
yourself, then you will see cycle start, stop, and def records in the
|
724
|
+
manner described above.
|
725
|
+
</p>
|
726
|
+
|
727
|
+
<h2><a name="writing_files"></a>Writing Files</h2>
|
728
|
+
|
729
|
+
<p>
|
730
|
+
You can write new warts files with this library. This ability is useful
|
731
|
+
for filtering out traces and for re-organizing traces into a different set
|
732
|
+
of files (for example, into daily files). Please note, however, that you
|
733
|
+
can't create completely new traces in memory--that is, you can only write
|
734
|
+
out traces you've read in from another file.
|
735
|
+
</p>
|
736
|
+
|
737
|
+
<p>
|
738
|
+
For example, the following script writes a new file <code>out.warts</code>
|
739
|
+
containing only the traces in the input file that have both a responding
|
740
|
+
destination and a path length greater than 5:
|
741
|
+
</p>
|
742
|
+
|
743
|
+
<!-- 13. write ========================================================== -->
|
744
|
+
<pre class="ruby snippet">
|
745
|
+
<span class="ident">out</span> <span class="punct">=</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span> <span class="punct">"</span><span class="string">out.warts</span><span class="punct">",</span> <span class="punct">"</span><span class="string">w</span><span class="punct">"</span>
|
746
|
+
|
747
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
748
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
749
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">trace</span><span class="punct">|</span>
|
750
|
+
<span class="keyword">if</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">dest_responded?</span> <span class="punct">&&</span> <span class="ident">trace</span><span class="punct">.</span><span class="ident">path_length</span> <span class="punct">></span> <span class="number">5</span>
|
751
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">write</span> <span class="ident">trace</span>
|
752
|
+
<span class="keyword">end</span>
|
753
|
+
<span class="keyword">end</span>
|
754
|
+
<span class="keyword">end</span>
|
755
|
+
|
756
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">close</span>
|
757
|
+
</pre>
|
758
|
+
|
759
|
+
<p>
|
760
|
+
When you write out a trace object, the associated list and cycle objects
|
761
|
+
are written out automatically, which is the reason why the above script is
|
762
|
+
so simple. However, only a cycle-def object is written out automatically,
|
763
|
+
so information about the cycle end time will be missing in the output file
|
764
|
+
(a cycle-def object has the start time so the lack of a cycle-start object
|
765
|
+
isn't a real problem). If all you want to do is analyze trace data, then
|
766
|
+
having only the cycle-def object should be fine. It's easy enough, though,
|
767
|
+
to write out the cycle start and end objects yourself if you need them, as
|
768
|
+
in the following script:
|
769
|
+
</p>
|
770
|
+
|
771
|
+
<!-- 14. write2 ========================================================== -->
|
772
|
+
<pre class="ruby snippet">
|
773
|
+
<span class="ident">out</span> <span class="punct">=</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span> <span class="punct">"</span><span class="string">out.warts</span><span class="punct">",</span> <span class="punct">"</span><span class="string">w</span><span class="punct">"</span>
|
774
|
+
|
775
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
776
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span><span class="punct">,</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_START</span><span class="punct">,</span>
|
777
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_STOP</span>
|
778
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">element</span><span class="punct">|</span>
|
779
|
+
<span class="keyword">if</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">element_type</span> <span class="punct">==</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
780
|
+
<span class="keyword">if</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">dest_responded?</span> <span class="punct">&&</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">path_length</span> <span class="punct">></span> <span class="number">5</span>
|
781
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">write</span> <span class="ident">element</span>
|
782
|
+
<span class="keyword">end</span>
|
783
|
+
<span class="keyword">else</span>
|
784
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">write</span> <span class="ident">element</span>
|
785
|
+
<span class="keyword">end</span>
|
786
|
+
<span class="keyword">end</span>
|
787
|
+
<span class="keyword">end</span>
|
788
|
+
|
789
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">close</span>
|
790
|
+
</pre>
|
791
|
+
|
792
|
+
<p>
|
793
|
+
By default, files are written in the warts format. You can also write out
|
794
|
+
files in the traditional textual traceroute format, as illustrated by the
|
795
|
+
following script:
|
796
|
+
</p>
|
797
|
+
|
798
|
+
<!-- 15. write3 ========================================================== -->
|
799
|
+
<pre class="ruby snippet">
|
800
|
+
<span class="ident">out</span> <span class="punct">=</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span> <span class="punct">"</span><span class="string">out.txt</span><span class="punct">",</span> <span class="punct">"</span><span class="string">w</span><span class="punct">",</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACEROUTE</span>
|
801
|
+
|
802
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
803
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
804
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">trace</span><span class="punct">|</span>
|
805
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">write</span> <span class="ident">trace</span>
|
806
|
+
<span class="keyword">end</span>
|
807
|
+
<span class="keyword">end</span>
|
808
|
+
|
809
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">close</span>
|
810
|
+
</pre>
|
811
|
+
|
812
|
+
|
813
|
+
<pre class="snippet">
|
814
|
+
<span class="shell_command">$ ./trace-txt traces.warts</span>
|
815
|
+
<span class="shell_command">$ cat out.txt</span>
|
816
|
+
<span class="command_output">traceroute from 10.172.226.88 to 10.58.204.93</spa
|
817
|
+
n>
|
818
|
+
<span class="command_output"> 1 10.172.226.1 0.789 ms</span>
|
819
|
+
<span class="command_output"> 2 10.17.46.8 40.779 ms !N</span>
|
820
|
+
<span class="command_output">traceroute from 10.172.226.88 to 10.237.229.96</sp
|
821
|
+
an>
|
822
|
+
<span class="command_output"> 1 10.172.226.1 0.805 ms</span>
|
823
|
+
<span class="command_output"> 2 10.17.46.8 33.306 ms</span>
|
824
|
+
<span class="command_output"> 3 10.164.24.205 5.271 ms</span>
|
825
|
+
<span class="command_output"> 4 10.71.128.5 5.371 ms</span>
|
826
|
+
<span class="command_output"> 5 10.68.102.190 5.841 ms</span>
|
827
|
+
<span class="command_output"> 6 10.69.132.9 16.056 ms</span>
|
828
|
+
<span class="command_output"> 7 10.69.132.9 13.406 ms</span>
|
829
|
+
</pre>
|
830
|
+
|
831
|
+
|
832
|
+
<p>
|
833
|
+
The examples so far have opened files by path. You can also read/write
|
834
|
+
files that are already open by passing either an <code>IO</code> object
|
835
|
+
(and by extension anything that derives from <code>IO</code> like files,
|
836
|
+
pipes, and sockets) or a numeric file descriptor (a la Unix). For example,
|
837
|
+
the following script prints a warts file to stdout in the textual
|
838
|
+
traceroute format:
|
839
|
+
</p>
|
840
|
+
|
841
|
+
<!-- 16. write4 ========================================================== -->
|
842
|
+
<pre class="ruby snippet">
|
843
|
+
<span class="ident">out</span> <span class="punct">=</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span> <span class="global">$stdout</span><span class="punct">,</span> <span class="punct">"</span><span class="string">w</span><span class="punct">",</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACEROUTE</span>
|
844
|
+
|
845
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
846
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_filters</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
847
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">trace</span><span class="punct">|</span>
|
848
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">write</span> <span class="ident">trace</span>
|
849
|
+
<span class="keyword">end</span>
|
850
|
+
<span class="keyword">end</span>
|
851
|
+
</pre>
|
852
|
+
|
853
|
+
|
854
|
+
<h2><a name="modifying_data"></a>Modifying Lists and Cycles</h2>
|
855
|
+
|
856
|
+
<p>
|
857
|
+
Traces read in with this library are immutable, but you can modify the
|
858
|
+
associated list and cycle objects and write out modified versions to files.
|
859
|
+
This ability to modify lists and cycles is supported primarily to enable
|
860
|
+
easy re-organization of traces into a different set of files.
|
861
|
+
</p>
|
862
|
+
|
863
|
+
<p>
|
864
|
+
We say <i>modify</i> as a simplifying fiction, because in truth, list and
|
865
|
+
cycle objects are as equally immutable as traces. To <i>modify</i> lists
|
866
|
+
and cycles, you <b>derive</b> a new object with updated values from an
|
867
|
+
existing object (the old object is unmodified). Then you assign the new
|
868
|
+
object to a trace, thereby replacing the association with the old object.
|
869
|
+
For example, the following script changes the ID and hostname of cycles
|
870
|
+
to <code>5</code> and <code>foo.bar.com</code>, respectivey, and updates
|
871
|
+
traces to use the new cycle objects (note: cycle start and def objects will
|
872
|
+
always be read in before any traces that use those cycle objects):
|
873
|
+
</p>
|
874
|
+
|
875
|
+
<!-- 17. modify ========================================================== -->
|
876
|
+
<pre class="ruby snippet">
|
877
|
+
<span class="ident">out</span> <span class="punct">=</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span> <span class="punct">"</span><span class="string">out.warts</span><span class="punct">",</span> <span class="punct">"</span><span class="string">w</span><span class="punct">"</span>
|
878
|
+
|
879
|
+
<span class="ident">cycle</span> <span class="punct">=</span> <span class="constant">nil</span>
|
880
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
881
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_all_filters</span>
|
882
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">element</span><span class="punct">|</span>
|
883
|
+
<span class="keyword">case</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">element_type</span>
|
884
|
+
<span class="keyword">when</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
885
|
+
<span class="ident">element</span><span class="punct">.</span><span class="ident">cycle</span> <span class="punct">=</span> <span class="ident">cycle</span>
|
886
|
+
|
887
|
+
<span class="keyword">when</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_START</span><span class="punct">,</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_DEF</span><span class="punct">,</span>
|
888
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_STOP</span>
|
889
|
+
<span class="ident">element</span> <span class="punct">=</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">derive</span><span class="punct">(</span><span class="symbol">:id</span> <span class="punct">=></span> <span class="number">5</span><span class="punct">,</span> <span class="symbol">:hostname</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">foo.bar.com</span><span class="punct">")</span>
|
890
|
+
<span class="keyword">unless</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">element_type</span> <span class="punct">==</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_STOP</span>
|
891
|
+
<span class="ident">cycle</span> <span class="punct">=</span> <span class="ident">element</span>
|
892
|
+
<span class="keyword">end</span>
|
893
|
+
<span class="keyword">end</span>
|
894
|
+
|
895
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">write</span> <span class="ident">element</span>
|
896
|
+
<span class="keyword">end</span>
|
897
|
+
<span class="keyword">end</span>
|
898
|
+
|
899
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">close</span>
|
900
|
+
</pre>
|
901
|
+
|
902
|
+
|
903
|
+
<p>
|
904
|
+
You would follow the same basic procedure to modify lists. Note that you
|
905
|
+
can't directly assign a list to a trace object; you must update the list in
|
906
|
+
a cycle and then assign the cycle to a trace. For example, the following
|
907
|
+
script changes the name of lists to <code>dnssurvey</code> (and changes
|
908
|
+
the ID of cycles to 5):
|
909
|
+
</p>
|
910
|
+
|
911
|
+
<!-- 18. modify2 ========================================================= -->
|
912
|
+
<pre class="ruby snippet">
|
913
|
+
<span class="ident">out</span> <span class="punct">=</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="ident">open</span> <span class="punct">"</span><span class="string">out.warts</span><span class="punct">",</span> <span class="punct">"</span><span class="string">w</span><span class="punct">"</span>
|
914
|
+
|
915
|
+
<span class="ident">cycle</span> <span class="punct">=</span> <span class="constant">nil</span>
|
916
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="constant">ARGV</span><span class="punct">[</span><span class="number">0</span><span class="punct">])</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">file</span><span class="punct">|</span>
|
917
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">add_all_filters</span>
|
918
|
+
<span class="ident">file</span><span class="punct">.</span><span class="ident">read</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">element</span><span class="punct">|</span>
|
919
|
+
<span class="keyword">case</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">element_type</span>
|
920
|
+
<span class="keyword">when</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">TRACE</span>
|
921
|
+
<span class="ident">element</span><span class="punct">.</span><span class="ident">cycle</span> <span class="punct">=</span> <span class="ident">cycle</span>
|
922
|
+
|
923
|
+
<span class="keyword">when</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_START</span><span class="punct">,</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_DEF</span><span class="punct">,</span>
|
924
|
+
<span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_STOP</span>
|
925
|
+
<span class="ident">list</span> <span class="punct">=</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">list</span><span class="punct">.</span><span class="ident">derive</span><span class="punct">(</span><span class="symbol">:name</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">dnssurvey</span><span class="punct">")</span>
|
926
|
+
<span class="ident">element</span> <span class="punct">=</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">derive</span><span class="punct">(</span><span class="symbol">:id</span> <span class="punct">=></span> <span class="number">5</span><span class="punct">,</span> <span class="symbol">:list</span> <span class="punct">=></span> <span class="ident">list</span><span class="punct">)</span>
|
927
|
+
<span class="keyword">unless</span> <span class="ident">element</span><span class="punct">.</span><span class="ident">element_type</span> <span class="punct">==</span> <span class="constant">Warts</span><span class="punct">::</span><span class="constant">File</span><span class="punct">::</span><span class="constant">CYCLE_STOP</span>
|
928
|
+
<span class="ident">cycle</span> <span class="punct">=</span> <span class="ident">element</span>
|
929
|
+
<span class="keyword">end</span>
|
930
|
+
<span class="keyword">end</span>
|
931
|
+
|
932
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">write</span> <span class="ident">element</span>
|
933
|
+
<span class="keyword">end</span>
|
934
|
+
<span class="keyword">end</span>
|
935
|
+
|
936
|
+
<span class="ident">out</span><span class="punct">.</span><span class="ident">close</span>
|
937
|
+
</pre>
|
938
|
+
|
939
|
+
|
940
|
+
<h2>Further Reading</h2>
|
941
|
+
|
942
|
+
<p>
|
943
|
+
This concludes the tutorial. There are more features in the library than
|
944
|
+
described so far. Browse the <a href="reference.html">class reference</a>
|
945
|
+
and <a href="samples.html">sample scripts</a> for details.
|
946
|
+
</p>
|
947
|
+
|
948
|
+
<!---->
|
949
|
+
</div></div>
|
950
|
+
</body></html>
|