iana 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README +46 -0
- data/examples/ports.rb +31 -0
- data/examples/protocols.rb +28 -0
- data/examples/tlds.rb +47 -0
- data/lib/iana.rb +28 -0
- data/lib/iana/port.rb +79 -0
- data/lib/iana/protocol.rb +79 -0
- data/lib/iana/tld.rb +53 -0
- metadata +60 -0
data/README
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
== What
|
2
|
+
IANA Ruby module version 0.0.4
|
3
|
+
|
4
|
+
I like to look stuff up, like TCP/IP port numbers, protocols, top-level
|
5
|
+
domains, et al. I get my data from the Internet Assigned Numbers Authority
|
6
|
+
(IANA) and like to make it available to my programs. Since I am open sourcing
|
7
|
+
this code you can add this functionality to your own programs as well.
|
8
|
+
|
9
|
+
== How
|
10
|
+
require 'rubygems'
|
11
|
+
require 'iana'
|
12
|
+
|
13
|
+
The IANA Ruby module loads the data into conveniently searchable data
|
14
|
+
structures. The flat files the IANA Ruby module consume as data are hosted at
|
15
|
+
iana.org. You will need to fetch them so you can process the content locally.
|
16
|
+
I grab these files with with curl (but you can use wget or whatever if you
|
17
|
+
don't use curl):
|
18
|
+
|
19
|
+
curl -O http://www.iana.org/assignments/port-numbers
|
20
|
+
curl -O http://www.iana.org/assignments/protocol-numbers
|
21
|
+
curl -O http://data.iana.org/TLD/tlds-alpha-by-domain.txt
|
22
|
+
|
23
|
+
== Examples
|
24
|
+
When you run the example programs, do it like so:
|
25
|
+
|
26
|
+
ruby examples/ports.rb port-numbers
|
27
|
+
|
28
|
+
Use these example programs to see how you might use and otherwise integrate
|
29
|
+
IANA data functionality into your own programs.
|
30
|
+
|
31
|
+
== Install
|
32
|
+
I added a Rakefile and a gem spec. To build the gem, just type:
|
33
|
+
|
34
|
+
rake gem
|
35
|
+
|
36
|
+
To install the gem, just type:
|
37
|
+
|
38
|
+
sudo gem install pkg/iana-0.0.4.gem
|
39
|
+
|
40
|
+
== Notes
|
41
|
+
I haven't tested this code with YARV, so YMMV.
|
42
|
+
|
43
|
+
== Contribute
|
44
|
+
The source is availble at github: git://github.com/yesmar/iana.git. Feel free
|
45
|
+
to clone it and implement your own awesome ideas. You can also send your
|
46
|
+
patches by email to yesmar[at]speakeasy[dot]net.
|
data/examples/ports.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
dir = Pathname.new(File.expand_path(__FILE__)).realpath
|
5
|
+
require File.join(File.dirname(dir.to_s), '../lib/iana')
|
6
|
+
|
7
|
+
SCRIPT = File.basename(__FILE__)
|
8
|
+
|
9
|
+
if ARGV.length == 1
|
10
|
+
begin
|
11
|
+
IANA_PORT, IANA_PORT_UPDATED = IANA::Port::load(ARGV[0])
|
12
|
+
rescue
|
13
|
+
puts "#{SCRIPT}: #{$!}"
|
14
|
+
exit 1
|
15
|
+
end
|
16
|
+
else
|
17
|
+
puts "Usage: #{SCRIPT} <port-numbers>"
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
21
|
+
puts "#{IANA_PORT_UPDATED} => #{IANA_PORT.size} entries"
|
22
|
+
|
23
|
+
# lookup port 22
|
24
|
+
port = 22
|
25
|
+
result = IANA_PORT[port]
|
26
|
+
puts "#{result.size} matches for port #{port}:"
|
27
|
+
result.each do |p|
|
28
|
+
puts "=> #{p.keyword} #{port}/#{p.protocol} \"#{p.description}\""
|
29
|
+
end
|
30
|
+
|
31
|
+
exit 0
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
dir = Pathname.new(File.expand_path(__FILE__)).realpath
|
5
|
+
require File.join(File.dirname(dir.to_s), '../lib/iana')
|
6
|
+
|
7
|
+
SCRIPT = File.basename(__FILE__)
|
8
|
+
|
9
|
+
if ARGV.length == 1
|
10
|
+
begin
|
11
|
+
IANA_PROTO, IANA_PROTO_UPDATED = IANA::Protocol::load(ARGV[0])
|
12
|
+
rescue
|
13
|
+
puts "#{SCRIPT}: #{$!}"
|
14
|
+
exit 1
|
15
|
+
end
|
16
|
+
else
|
17
|
+
puts "Usage: #{SCRIPT} <protocol-numbers>"
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
21
|
+
puts "#{IANA_PROTO_UPDATED} => #{IANA_PROTO.size} entries"
|
22
|
+
|
23
|
+
# lookup protocol 50
|
24
|
+
result = IANA_PROTO[50]
|
25
|
+
puts "protocol 50 => #{result.keyword} \"#{result.description}\" " \
|
26
|
+
"#{result.references}"
|
27
|
+
|
28
|
+
exit 0
|
data/examples/tlds.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# tlds.rb
|
4
|
+
# yesmar@speakeasy.net
|
5
|
+
|
6
|
+
require 'pathname'
|
7
|
+
dir = Pathname.new(File.expand_path(__FILE__)).realpath
|
8
|
+
require File.join(File.dirname(dir.to_s), '../lib/iana')
|
9
|
+
|
10
|
+
SCRIPT = File.basename(__FILE__)
|
11
|
+
|
12
|
+
def tld?(dn)
|
13
|
+
raise ArgumentError, 'nil dn' if dn.nil?
|
14
|
+
raise ArgumentError, 'invalid dn class' if dn.class != String
|
15
|
+
raise ArgumentError, 'empty dn' if dn.empty?
|
16
|
+
|
17
|
+
return IANA_TLD.include?(dn) ? true : false
|
18
|
+
end
|
19
|
+
|
20
|
+
if ARGV.length == 1
|
21
|
+
begin
|
22
|
+
IANA_TLD, IANA_TLD_UPDATED, IANA_TLD_VERSION = IANA::TLD::load(ARGV[0])
|
23
|
+
rescue
|
24
|
+
puts "#{SCRIPT}: #{$!}"
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
else
|
28
|
+
puts "Usage: #{SCRIPT} <tlds>"
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
|
32
|
+
puts "#{IANA_TLD_VERSION} updated #{IANA_TLD_UPDATED} => " \
|
33
|
+
"#{IANA_TLD.size} entries"
|
34
|
+
|
35
|
+
# is com a TLD?
|
36
|
+
puts "com is a TLD? => #{tld?('com')}"
|
37
|
+
|
38
|
+
# how about to?
|
39
|
+
puts "to is a TLD? => #{tld?('to')}"
|
40
|
+
|
41
|
+
# grizzlebat is probably not a TLD
|
42
|
+
puts "grizzlebat is a TLD? => #{tld?('grizzlebat')}"
|
43
|
+
|
44
|
+
# how about yn?
|
45
|
+
puts "yn is a TLD? => #{tld?('yn')}"
|
46
|
+
|
47
|
+
exit 0
|
data/lib/iana.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# iana.rb
|
4
|
+
# yesmar@speakeasy.net
|
5
|
+
|
6
|
+
$KCODE = 'UTF8'
|
7
|
+
require 'jcode'
|
8
|
+
|
9
|
+
module IANA
|
10
|
+
IANA::NAME = 'iana'
|
11
|
+
IANA::VERSION = '0.0.4'
|
12
|
+
IANA::COPYRIGHT = 'Copyright (c) 2008 Ramsey Dow'
|
13
|
+
def self.copyright() IANA::COPYRIGHT end
|
14
|
+
def self.version() IANA::VERSION end
|
15
|
+
def self.libdir() File.expand_path(__FILE__).gsub(%r/\.rb$/, '') end
|
16
|
+
end
|
17
|
+
|
18
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__)+'/iana')
|
19
|
+
|
20
|
+
require 'port'
|
21
|
+
require 'protocol'
|
22
|
+
require 'tld'
|
23
|
+
|
24
|
+
# TODO: bad developer, no unit tests
|
25
|
+
# TODO: lookup needs to be more flexible
|
26
|
+
# TODO: add IANA ethernet-numbers support
|
27
|
+
|
28
|
+
raise RuntimeError, 'This library is for require only' if $0 == __FILE__
|
data/lib/iana/port.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# port.rb
|
4
|
+
# yesmsar@speakeasy.net
|
5
|
+
|
6
|
+
module IANA
|
7
|
+
module Port
|
8
|
+
Port = Struct.new('PORT', :keyword, :protocol, :description)
|
9
|
+
|
10
|
+
# load IANA ports list from flat file:
|
11
|
+
# http://www.iana.org/assignments/port-numbers
|
12
|
+
def self.load(pathname)
|
13
|
+
raise ArgumentError, 'nil pathname' if pathname.nil?
|
14
|
+
raise ArgumentError, 'invalid pathname class' if pathname.class != String
|
15
|
+
raise ArgumentError, 'empty pathname' if pathname.empty?
|
16
|
+
|
17
|
+
# TODO: better error checking for files with incorrect content
|
18
|
+
|
19
|
+
ports = {}
|
20
|
+
updated = nil
|
21
|
+
|
22
|
+
begin
|
23
|
+
f = File.new(pathname, 'r')
|
24
|
+
while (line = f.gets)
|
25
|
+
line.chomp!
|
26
|
+
|
27
|
+
# extract update stamp
|
28
|
+
if line =~ /^\(last updated (\d{4}-\d{2}-\d{2})\)\s*$/
|
29
|
+
updated = $1
|
30
|
+
next
|
31
|
+
end
|
32
|
+
|
33
|
+
# skip commented lines
|
34
|
+
next if line =~ /^#/
|
35
|
+
|
36
|
+
# skip lines which do not contain the /{proto} pattern
|
37
|
+
if line !~ /\/tcp/ && line !~ /\/udp/ && line !~ /\/sctp/ && \
|
38
|
+
line !~ /\/dccp/
|
39
|
+
next
|
40
|
+
end
|
41
|
+
|
42
|
+
line.strip!
|
43
|
+
tokens = line.split(/[\s\t]+/)
|
44
|
+
|
45
|
+
# if first token is a port/proto pair then the port is unnamed
|
46
|
+
if tokens[0] =~ /\//
|
47
|
+
name = nil
|
48
|
+
num,proto = tokens[0].split(/\//)
|
49
|
+
tokens.delete_at(0)
|
50
|
+
else
|
51
|
+
name = tokens[0]
|
52
|
+
num,proto = tokens[1].split(/\//)
|
53
|
+
2.times { tokens.delete_at(0) }
|
54
|
+
end
|
55
|
+
|
56
|
+
# remainder of tokens serves as the description
|
57
|
+
desc = tokens.join(' ')
|
58
|
+
|
59
|
+
p = Port.new(name, proto, desc)
|
60
|
+
|
61
|
+
if ports[num.to_i].nil?
|
62
|
+
ports[num.to_i] = p
|
63
|
+
else
|
64
|
+
c = []
|
65
|
+
c << ports[num.to_i]
|
66
|
+
c << p
|
67
|
+
ports[num.to_i] = c.flatten
|
68
|
+
end
|
69
|
+
end
|
70
|
+
ensure
|
71
|
+
f.close if !f.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
return ports, updated
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
raise RuntimeError, 'This library is for require only' if $0 == __FILE__
|
@@ -0,0 +1,79 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# protocol.rb
|
4
|
+
# yesmar@speakeasy.net
|
5
|
+
|
6
|
+
module IANA
|
7
|
+
module Protocol
|
8
|
+
Protocol = Struct.new('PROTOCOL', :keyword, :description, :references)
|
9
|
+
|
10
|
+
# load IANA protocols list from flat file:
|
11
|
+
# http://www.iana.org/assignments/protocol-numbers
|
12
|
+
def self.load(pathname)
|
13
|
+
raise ArgumentError, 'nil pathname' if pathname.nil?
|
14
|
+
raise ArgumentError, 'invalid pathname class' if pathname.class != String
|
15
|
+
raise ArgumentError, 'empty pathname' if pathname.empty?
|
16
|
+
|
17
|
+
# TODO: better error checking for files with incorrect content
|
18
|
+
|
19
|
+
protocols = {}
|
20
|
+
updated = nil
|
21
|
+
|
22
|
+
begin
|
23
|
+
f = File.new(pathname, 'r')
|
24
|
+
while (line = f.gets)
|
25
|
+
line.chomp!
|
26
|
+
|
27
|
+
# extract update stamp
|
28
|
+
if line =~ /^\(last updated (\d{4}-\d{2}-\d{2})\)\s*$/
|
29
|
+
updated = $1
|
30
|
+
next
|
31
|
+
end
|
32
|
+
|
33
|
+
# match spaces d[dd][-ddd] spaces
|
34
|
+
if line =~ /^\s+\d{1,3}([\-]{1}\d{3})?\s+/
|
35
|
+
line.strip!
|
36
|
+
line.gsub!(/\t/, ' ')
|
37
|
+
line.gsub!(/\s{2,}/, '|')
|
38
|
+
data = line.split('|')
|
39
|
+
raw_decimal = data[0]
|
40
|
+
|
41
|
+
if raw_decimal =~ /\-/
|
42
|
+
first,second = raw_decimal.split(' ')
|
43
|
+
raw_low,raw_high = first.split('-')
|
44
|
+
low = raw_low.to_i
|
45
|
+
high = raw_high.to_i
|
46
|
+
low.upto(high) do |i|
|
47
|
+
p = Protocol.new
|
48
|
+
p.keyword = '<unassigned>'
|
49
|
+
p.description = '<unassigned>'
|
50
|
+
p.references = '[IANA]'
|
51
|
+
protocols[i] = p
|
52
|
+
end
|
53
|
+
else
|
54
|
+
p = Protocol.new
|
55
|
+
decimal = raw_decimal.to_i
|
56
|
+
case data.size
|
57
|
+
when 3
|
58
|
+
p.keyword = nil
|
59
|
+
p.description = data[1]
|
60
|
+
p.references = data[2]
|
61
|
+
else
|
62
|
+
p.keyword = data[1]
|
63
|
+
p.description = data[2]
|
64
|
+
p.references = data[3]
|
65
|
+
end
|
66
|
+
protocols[decimal] = p
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
ensure
|
71
|
+
f.close if !f.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
return protocols, updated
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
raise RuntimeError, 'This library is for require only' if $0 == __FILE__
|
data/lib/iana/tld.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# tld.rb
|
4
|
+
# yesmar@speakeasy.net
|
5
|
+
|
6
|
+
module IANA
|
7
|
+
module TLD
|
8
|
+
# load IANA TLD list from flat file:
|
9
|
+
# http://data.iana.org/TLD/tlds-alpha-by-domain.txt
|
10
|
+
def self.load(pathname)
|
11
|
+
raise ArgumentError, 'nil pathname' if pathname.nil?
|
12
|
+
raise ArgumentError, 'invalid pathname class' if pathname.class != String
|
13
|
+
raise ArgumentError, 'empty pathname' if pathname.empty?
|
14
|
+
|
15
|
+
# TODO: better error checking for files with incorrect content
|
16
|
+
|
17
|
+
tlds = []
|
18
|
+
updated = nil
|
19
|
+
|
20
|
+
begin
|
21
|
+
f = File.new(pathname, 'r')
|
22
|
+
while (line = f.gets)
|
23
|
+
line.chomp!
|
24
|
+
|
25
|
+
if line =~ /^# Version \d{10}, Last Updated ([\w\W\d\s]*)$/
|
26
|
+
# extract update stamp
|
27
|
+
updated = $1
|
28
|
+
version,gunk= line.split(',')
|
29
|
+
version.sub!(/^# /, '')
|
30
|
+
updated.strip!
|
31
|
+
else
|
32
|
+
tlds << line.downcase!
|
33
|
+
end
|
34
|
+
end
|
35
|
+
ensure
|
36
|
+
f.close if !f.nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
return tlds, updated, version
|
40
|
+
end
|
41
|
+
|
42
|
+
# is specified domain name a TLD?
|
43
|
+
def self.tld?(dn)
|
44
|
+
raise ArgumentError, 'nil dn' if dn.nil?
|
45
|
+
raise ArgumentError, 'invalid dn class' if dn.class != String
|
46
|
+
raise ArgumentError, 'empty dn' if dn.empty?
|
47
|
+
|
48
|
+
return IANA_TLD.include?(dn) ? true : false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
raise RuntimeError, 'This library is for require only' if $0 == __FILE__
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: iana
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ramsey Dow
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-02-25 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: yesmar @nospam@ speakeasy.net
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
files:
|
25
|
+
- lib/iana.rb
|
26
|
+
- lib/iana/port.rb
|
27
|
+
- lib/iana/protocol.rb
|
28
|
+
- lib/iana/tld.rb
|
29
|
+
- examples/ports.rb
|
30
|
+
- examples/protocols.rb
|
31
|
+
- examples/tlds.rb
|
32
|
+
- README
|
33
|
+
has_rdoc: true
|
34
|
+
homepage: http://iana.rubyforge.org/
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
requirements: []
|
53
|
+
|
54
|
+
rubyforge_project: http://rubyforge.org/projects/iana/
|
55
|
+
rubygems_version: 1.0.1
|
56
|
+
signing_key:
|
57
|
+
specification_version: 2
|
58
|
+
summary: Ruby module which process flat files from IANA
|
59
|
+
test_files: []
|
60
|
+
|