net-proto 1.0.6 → 1.1.0
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 +9 -0
- data/MANIFEST +6 -6
- data/README +22 -15
- data/Rakefile +7 -58
- data/doc/netproto.txt +14 -17
- data/examples/example_net_proto.rb +11 -11
- data/lib/generic/net/proto.rb +145 -0
- data/lib/linux/net/proto.rb +140 -0
- data/lib/net/proto.rb +10 -0
- data/lib/net/proto/common.rb +37 -0
- data/lib/sunos/net/proto.rb +134 -0
- data/net-proto.gemspec +3 -6
- data/test/test_net_proto.rb +52 -45
- metadata +40 -27
- data/ext/extconf.rb +0 -19
- data/ext/generic/generic.c +0 -168
- data/ext/linux/linux.c +0 -175
- data/ext/sunos/sunos.c +0 -160
- data/ext/version.h +0 -2
- data/ext/windows/windows.c +0 -86
data/lib/net/proto.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module Net
|
4
|
+
class Proto
|
5
|
+
extend FFI::Library
|
6
|
+
|
7
|
+
# The version of the net-proto library
|
8
|
+
VERSION = '1.1.0'
|
9
|
+
|
10
|
+
private_class_method :new
|
11
|
+
|
12
|
+
class ProtocolStruct < FFI::Struct
|
13
|
+
layout(
|
14
|
+
:p_name, :string,
|
15
|
+
:p_aliases, :pointer,
|
16
|
+
:p_proto, :int
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
class FFI::Pointer
|
21
|
+
def read_array_of_string
|
22
|
+
elements = []
|
23
|
+
|
24
|
+
loc = self
|
25
|
+
|
26
|
+
until ((element = loc.read_pointer).null?)
|
27
|
+
elements << element.read_string
|
28
|
+
loc += FFI::Type::POINTER.size
|
29
|
+
end
|
30
|
+
|
31
|
+
elements
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
ProtoStruct = Struct.new('ProtoStruct', :name, :aliases, :proto)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'net/proto/common'
|
2
|
+
|
3
|
+
# The Net module serves as a namespace only.
|
4
|
+
module Net
|
5
|
+
|
6
|
+
# The Proto class serves as the base class for the various protocol methods.
|
7
|
+
class Proto
|
8
|
+
ffi_lib 'socket'
|
9
|
+
|
10
|
+
attach_function :setprotoent, [:int], :void
|
11
|
+
attach_function :endprotoent, [], :void
|
12
|
+
attach_function :getprotobyname_r, [:string, :pointer, :pointer, :int], :pointer
|
13
|
+
attach_function :getprotobynumber_r, [:int, :pointer, :pointer, :int], :pointer
|
14
|
+
attach_function :getprotoent_r, [:pointer, :pointer, :int], :pointer
|
15
|
+
|
16
|
+
private_class_method :setprotoent, :endprotoent, :getprotobyname_r
|
17
|
+
private_class_method :getprotobynumber_r, :getprotoent_r
|
18
|
+
|
19
|
+
public
|
20
|
+
|
21
|
+
# If given a protocol string, returns the corresponding number. If
|
22
|
+
# given a protocol number, returns the corresponding string.
|
23
|
+
#
|
24
|
+
# Returns nil if not found in either case.
|
25
|
+
#
|
26
|
+
# Examples:
|
27
|
+
#
|
28
|
+
# Net::Proto.get_protocol('tcp') # => 6
|
29
|
+
# Net::Proto.get_protocol(1) # => 'icmp'
|
30
|
+
#
|
31
|
+
def self.get_protocol(argument)
|
32
|
+
if argument.is_a?(String)
|
33
|
+
getprotobyname(argument)
|
34
|
+
else
|
35
|
+
getprotobynumber(argument)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Given a protocol string, returns the corresponding number, or nil if
|
40
|
+
# not found.
|
41
|
+
#
|
42
|
+
# Examples:
|
43
|
+
#
|
44
|
+
# Net::Proto.getprotobyname('tcp') # => 6
|
45
|
+
# Net::Proto.getprotobyname('bogus') # => nil
|
46
|
+
#
|
47
|
+
def self.getprotobyname(protocol)
|
48
|
+
raise TypeError unless protocol.is_a?(String)
|
49
|
+
|
50
|
+
pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
51
|
+
buff = FFI::MemoryPointer.new(:char, 1024)
|
52
|
+
|
53
|
+
begin
|
54
|
+
setprotoent(0)
|
55
|
+
ptr = getprotobyname_r(protocol, pptr, buff, buff.size)
|
56
|
+
ensure
|
57
|
+
endprotoent()
|
58
|
+
end
|
59
|
+
|
60
|
+
ptr.null? ? nil : ProtocolStruct.new(pptr)[:p_proto]
|
61
|
+
end
|
62
|
+
|
63
|
+
# Given a protocol number, returns the corresponding string, or nil if
|
64
|
+
# not found.
|
65
|
+
#
|
66
|
+
# Examples:
|
67
|
+
#
|
68
|
+
# Net::Proto.getprotobynumber(6) # => 'tcp'
|
69
|
+
# Net::Proto.getprotobynumber(999) # => nil
|
70
|
+
#
|
71
|
+
def self.getprotobynumber(protocol)
|
72
|
+
raise TypeError unless protocol.is_a?(Integer)
|
73
|
+
|
74
|
+
pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
75
|
+
buff = FFI::MemoryPointer.new(:char, 1024)
|
76
|
+
|
77
|
+
begin
|
78
|
+
setprotoent(0)
|
79
|
+
ptr = getprotobynumber_r(protocol, pptr, buff, buff.size)
|
80
|
+
ensure
|
81
|
+
endprotoent()
|
82
|
+
end
|
83
|
+
|
84
|
+
ptr.null? ? nil : ProtocolStruct.new(pptr)[:p_name]
|
85
|
+
end
|
86
|
+
|
87
|
+
# In block form, yields each entry from /etc/protocols as a struct of type
|
88
|
+
# Proto::ProtoStruct. In non-block form, returns an array of structs.
|
89
|
+
#
|
90
|
+
# The fields are 'name' (a string), 'aliases' (an array of strings,
|
91
|
+
# though often only one element), and 'proto' (a number).
|
92
|
+
#
|
93
|
+
# Example:
|
94
|
+
#
|
95
|
+
# Net::Proto.getprotoent.each{ |prot|
|
96
|
+
# p prot.name
|
97
|
+
# p prot.aliases
|
98
|
+
# p prot.proto
|
99
|
+
# }
|
100
|
+
#
|
101
|
+
def self.getprotoent
|
102
|
+
structs = block_given? ? nil : []
|
103
|
+
|
104
|
+
pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
105
|
+
buff = FFI::MemoryPointer.new(1024)
|
106
|
+
|
107
|
+
begin
|
108
|
+
setprotoent(0)
|
109
|
+
|
110
|
+
while ptr = getprotoent_r(pptr, buff, buff.size)
|
111
|
+
break if ptr.null?
|
112
|
+
|
113
|
+
ffi_struct = ProtocolStruct.new(pptr)
|
114
|
+
|
115
|
+
ruby_struct = ProtoStruct.new(
|
116
|
+
ffi_struct[:p_name],
|
117
|
+
ffi_struct[:p_aliases].read_array_of_string,
|
118
|
+
ffi_struct[:p_proto]
|
119
|
+
).freeze
|
120
|
+
|
121
|
+
if block_given?
|
122
|
+
yield ruby_struct
|
123
|
+
else
|
124
|
+
structs << ruby_struct
|
125
|
+
end
|
126
|
+
end
|
127
|
+
ensure
|
128
|
+
endprotoent
|
129
|
+
end
|
130
|
+
|
131
|
+
structs
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/net-proto.gemspec
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
|
3
|
-
# To build a regular gem => rake build_gem
|
4
|
-
# To build a binary gem => rake build_binary_gem
|
5
|
-
|
6
3
|
Gem::Specification.new do |gem|
|
7
4
|
gem.name = 'net-proto'
|
8
|
-
gem.version = '1.0
|
5
|
+
gem.version = '1.1.0'
|
9
6
|
gem.author = 'Daniel J. Berger'
|
10
7
|
gem.license = 'Artistic 2.0'
|
11
8
|
gem.email = 'djberg96@gmail.com'
|
@@ -13,13 +10,13 @@ Gem::Specification.new do |gem|
|
|
13
10
|
gem.platform = Gem::Platform::RUBY
|
14
11
|
gem.summary = 'A Ruby interface for determining protocol information'
|
15
12
|
gem.test_file = 'test/test_net_proto.rb'
|
16
|
-
gem.extensions = ['ext/extconf.rb']
|
17
13
|
gem.files = Dir['**/*'].reject{ |f| f.include?('git') }
|
18
14
|
|
19
15
|
gem.rubyforge_project = 'sysutils'
|
20
16
|
gem.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST', 'doc/netproto.txt']
|
21
17
|
|
22
|
-
gem.
|
18
|
+
gem.add_dependency('ffi', '>= 1.0.0')
|
19
|
+
gem.add_development_dependency('test-unit', '>= 2.2.0')
|
23
20
|
|
24
21
|
gem.description = <<-EOF
|
25
22
|
The net-proto library provides an interface for get protocol information
|
data/test/test_net_proto.rb
CHANGED
@@ -6,7 +6,6 @@
|
|
6
6
|
###########################################################################
|
7
7
|
require 'rubygems'
|
8
8
|
gem 'test-unit'
|
9
|
-
|
10
9
|
require 'net/proto'
|
11
10
|
require 'test/unit'
|
12
11
|
|
@@ -14,22 +13,39 @@ class TC_Net_Proto < Test::Unit::TestCase
|
|
14
13
|
|
15
14
|
# These were the protocols listed in my own /etc/protocols file on Solaris 9
|
16
15
|
def self.startup
|
17
|
-
@@windows = Config::CONFIG['host_os'] =~ /win32|msdos|mswin|cygwin|mingw/i
|
18
|
-
|
19
16
|
@@protocols = %w/
|
20
17
|
ip icmp igmp ggp ipip tcp cbt egp igp pup udp mux hmp
|
21
18
|
xns-idp rdp idpr idpr-cmtp sdrp idrp rsvp gre
|
22
19
|
mobile ospf pim ipcomp vrrp sctp hopopt ipv6
|
23
20
|
ipv6-route ipv6-frag esp ah ipv6-icmp ipv6-nonxt ipv6-opts
|
24
21
|
/
|
22
|
+
|
23
|
+
@@windows = File::ALT_SEPARATOR
|
25
24
|
end
|
26
25
|
|
27
26
|
def setup
|
28
27
|
@protoent = nil
|
29
28
|
end
|
30
29
|
|
31
|
-
test "version number
|
32
|
-
assert_equal('1.0
|
30
|
+
test "version number is set to expected value" do
|
31
|
+
assert_equal('1.1.0', Net::Proto::VERSION)
|
32
|
+
end
|
33
|
+
|
34
|
+
test "get_protocol method basic functionality" do
|
35
|
+
assert_respond_to(Net::Proto, :get_protocol)
|
36
|
+
end
|
37
|
+
|
38
|
+
test "get_protocol method accepts a string or a number" do
|
39
|
+
assert_nothing_raised{ Net::Proto.get_protocol(1) }
|
40
|
+
assert_nothing_raised{ Net::Proto.get_protocol('tcp') }
|
41
|
+
end
|
42
|
+
|
43
|
+
test "get_protocol returns nil if protocol not found" do
|
44
|
+
assert_nil(Net::Proto.get_protocol(9999999))
|
45
|
+
end
|
46
|
+
|
47
|
+
test "get_protocol fails if an invalid type is passed" do
|
48
|
+
assert_raise(TypeError){ Net::Proto.get_protocol([]) }
|
33
49
|
end
|
34
50
|
|
35
51
|
test "getprotobynumber basic functionality" do
|
@@ -43,94 +59,85 @@ class TC_Net_Proto < Test::Unit::TestCase
|
|
43
59
|
assert_equal('tcp', Net::Proto.getprotobynumber(6))
|
44
60
|
end
|
45
61
|
|
46
|
-
test "getprotobynumber returns nil if
|
62
|
+
test "getprotobynumber returns nil if not found" do
|
47
63
|
assert_equal(nil, Net::Proto.getprotobynumber(9999999))
|
48
64
|
assert_equal(nil, Net::Proto.getprotobynumber(-1))
|
49
65
|
end
|
50
66
|
|
51
|
-
test "getprotobynumber
|
67
|
+
test "getprotobynumber raises a TypeError if a non-numeric arg is used" do
|
52
68
|
assert_raise(TypeError){ Net::Proto.getprotobynumber('foo') }
|
53
69
|
assert_raise(TypeError){ Net::Proto.getprotobynumber(nil) }
|
54
70
|
end
|
55
71
|
|
56
|
-
test "getprotobyname basic functionality" do
|
72
|
+
test "getprotobyname method basic functionality" do
|
57
73
|
assert_respond_to(Net::Proto, :getprotobyname)
|
58
74
|
@@protocols.each{ |n| assert_nothing_raised{ Net::Proto.getprotobyname(n) } }
|
59
|
-
assert_kind_of(Fixnum, Net::Proto.getprotobyname('tcp'))
|
60
75
|
end
|
61
76
|
|
62
|
-
test "getprotobyname returns expected result" do
|
77
|
+
test "getprotobyname returns the expected result" do
|
63
78
|
assert_equal(1, Net::Proto.getprotobyname('icmp'))
|
64
79
|
assert_equal(6, Net::Proto.getprotobyname('tcp'))
|
65
80
|
end
|
66
81
|
|
67
|
-
test "getprotobyname returns nil if the protocol
|
68
|
-
|
69
|
-
|
70
|
-
|
82
|
+
test "getprotobyname returns nil if the protocol is not found" do
|
83
|
+
assert_nil(Net::Proto.getprotobyname('foo'))
|
84
|
+
assert_nil(Net::Proto.getprotobyname('tcpx'))
|
85
|
+
assert_nil(Net::Proto.getprotobyname(''))
|
71
86
|
end
|
72
87
|
|
73
|
-
test "getprotobyname
|
88
|
+
test "getprotobyname raises a TypeError if an invalid arg is passed" do
|
74
89
|
assert_raises(TypeError){ Net::Proto.getprotobyname(1) }
|
75
|
-
assert_raises(TypeError){ Net::Proto.getprotobyname(nil) }
|
90
|
+
assert_raises(TypeError){ Net::Proto.getprotobyname(nil) }
|
76
91
|
end
|
77
92
|
|
78
93
|
test "getprotoent basic functionality" do
|
79
|
-
omit_if(@@windows, '
|
80
|
-
assert_respond_to(Net::Proto, :getprotoent)
|
94
|
+
omit_if(@@windows, 'getprotoent tests skipped on MS Windows')
|
95
|
+
assert_respond_to(Net::Proto, :getprotoent)
|
81
96
|
assert_nothing_raised{ Net::Proto.getprotoent }
|
82
|
-
end
|
83
|
-
|
84
|
-
test "getprotoent returns an array if no block is provided" do
|
85
|
-
omit_if(@@windows, 'Skipped on MS Windows')
|
86
97
|
assert_kind_of(Array, Net::Proto.getprotoent)
|
87
98
|
end
|
88
99
|
|
89
|
-
test "getprotoent
|
90
|
-
omit_if(@@windows, '
|
91
|
-
assert_nothing_raised{ Net::Proto.getprotoent{} }
|
92
|
-
assert_nil(Net::Proto.getprotoent{})
|
93
|
-
end
|
94
|
-
|
95
|
-
test "getprotoent returns an array of structs" do
|
96
|
-
omit_if(@@windows, 'Skipped on MS Windows')
|
100
|
+
test "getprotoent method returns the expected results" do
|
101
|
+
omit_if(@@windows, 'getprotoent tests skipped on MS Windows')
|
97
102
|
assert_kind_of(Struct::ProtoStruct, Net::Proto.getprotoent.first)
|
103
|
+
assert_nil(Net::Proto.getprotoent{})
|
98
104
|
end
|
99
105
|
|
100
|
-
test "
|
101
|
-
omit_if(@@windows, '
|
106
|
+
test "struct returned by getprotoent method contains the expected data" do
|
107
|
+
omit_if(@@windows, 'getprotoent tests skipped on MS Windows')
|
102
108
|
@protoent = Net::Proto.getprotoent.first
|
103
109
|
assert_equal(['name', 'aliases', 'proto'], @protoent.members)
|
104
|
-
end
|
105
|
-
|
106
|
-
test "struct members are of a specific type" do
|
107
|
-
omit_if(@@windows, 'Skipped on MS Windows')
|
108
|
-
@protoent = Net::Proto.getprotoent.first
|
109
110
|
assert_kind_of(String, @protoent.name)
|
110
111
|
assert_kind_of(Array, @protoent.aliases)
|
111
112
|
assert_kind_of(Integer, @protoent.proto)
|
112
113
|
end
|
113
114
|
|
114
|
-
test "aliases struct member
|
115
|
-
omit_if(@@windows, '
|
115
|
+
test "all members of the aliases struct member are strings" do
|
116
|
+
omit_if(@@windows, 'getprotoent tests on MS Windows')
|
116
117
|
@protoent = Net::Proto.getprotoent.first
|
117
118
|
assert_true(@protoent.aliases.all?{ |e| e.is_a?(String) })
|
118
119
|
end
|
119
120
|
|
120
|
-
test "
|
121
|
-
omit_if(@@windows, '
|
121
|
+
test "struct returned by getprotoent method is frozen" do
|
122
|
+
omit_if(@@windows, 'getprotoent tests skipped on MS Windows')
|
122
123
|
@protoent = Net::Proto.getprotoent.first
|
123
124
|
assert_true(@protoent.frozen?)
|
124
125
|
end
|
125
|
-
|
126
|
-
test "there is no constructor
|
127
|
-
assert_raise(NoMethodError){ Net::Proto.new }
|
126
|
+
|
127
|
+
test "there is no constructor" do
|
128
|
+
assert_raise(NoMethodError){ Net::Proto.new }
|
129
|
+
end
|
130
|
+
|
131
|
+
test "ffi functions are private" do
|
132
|
+
methods = Net::Proto.methods(false).map{ |m| m.to_sym }
|
133
|
+
assert_false(methods.include?(:setprotoent))
|
134
|
+
assert_false(methods.include?(:endprotoent))
|
128
135
|
end
|
129
136
|
|
130
137
|
def teardown
|
131
138
|
@protoent = nil
|
132
139
|
end
|
133
|
-
|
140
|
+
|
134
141
|
def self.shutdown
|
135
142
|
@@protocols = nil
|
136
143
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-proto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.6
|
10
|
+
version: 1.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Daniel J. Berger
|
@@ -15,52 +15,65 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
19
|
-
default_executable:
|
18
|
+
date: 2012-01-18 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
21
|
+
name: ffi
|
23
22
|
prerelease: false
|
24
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
24
|
none: false
|
26
25
|
requirements:
|
27
26
|
- - ">="
|
28
27
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
28
|
+
hash: 23
|
30
29
|
segments:
|
31
|
-
- 2
|
32
30
|
- 1
|
33
|
-
-
|
34
|
-
|
35
|
-
|
31
|
+
- 0
|
32
|
+
- 0
|
33
|
+
version: 1.0.0
|
34
|
+
type: :runtime
|
36
35
|
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: test-unit
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 7
|
45
|
+
segments:
|
46
|
+
- 2
|
47
|
+
- 2
|
48
|
+
- 0
|
49
|
+
version: 2.2.0
|
50
|
+
type: :development
|
51
|
+
version_requirements: *id002
|
37
52
|
description: " The net-proto library provides an interface for get protocol information\n by name or by number. It can also iterate over the list of protocol\n entries defined on your system.\n"
|
38
53
|
email: djberg96@gmail.com
|
39
54
|
executables: []
|
40
55
|
|
41
|
-
extensions:
|
42
|
-
|
56
|
+
extensions: []
|
57
|
+
|
43
58
|
extra_rdoc_files:
|
44
59
|
- CHANGES
|
45
60
|
- README
|
46
61
|
- MANIFEST
|
47
62
|
- doc/netproto.txt
|
48
63
|
files:
|
49
|
-
- Rakefile
|
50
|
-
- README
|
51
|
-
- doc/netproto.txt
|
52
|
-
- net-proto.gemspec
|
53
64
|
- CHANGES
|
65
|
+
- doc/netproto.txt
|
54
66
|
- examples/example_net_proto.rb
|
55
|
-
-
|
67
|
+
- lib/generic/net/proto.rb
|
68
|
+
- lib/linux/net/proto.rb
|
69
|
+
- lib/net/proto/common.rb
|
70
|
+
- lib/net/proto.rb
|
71
|
+
- lib/sunos/net/proto.rb
|
56
72
|
- MANIFEST
|
57
|
-
-
|
58
|
-
-
|
59
|
-
-
|
60
|
-
-
|
61
|
-
- ext/sunos/sunos.c
|
62
|
-
- ext/windows/windows.c
|
63
|
-
has_rdoc: true
|
73
|
+
- net-proto.gemspec
|
74
|
+
- Rakefile
|
75
|
+
- README
|
76
|
+
- test/test_net_proto.rb
|
64
77
|
homepage: http://www.rubyforge.org/projects/sysutils
|
65
78
|
licenses:
|
66
79
|
- Artistic 2.0
|
@@ -90,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
103
|
requirements: []
|
91
104
|
|
92
105
|
rubyforge_project: sysutils
|
93
|
-
rubygems_version: 1.
|
106
|
+
rubygems_version: 1.8.10
|
94
107
|
signing_key:
|
95
108
|
specification_version: 3
|
96
109
|
summary: A Ruby interface for determining protocol information
|