net-proto 1.0.6 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ require 'rbconfig'
2
+
3
+ case RbConfig::CONFIG['host_os']
4
+ when /linux/i
5
+ require 'linux/net/proto'
6
+ when /sunos|solaris/i
7
+ require 'sunos/net/proto'
8
+ else
9
+ require 'generic/net/proto'
10
+ end
@@ -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
@@ -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.6'
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.add_development_dependency('test-unit', '>= 2.1.1')
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
@@ -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 returns expected value" do
32
- assert_equal('1.0.6', Net::Proto::VERSION)
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 the protocol cannot be found" do
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 requires a numeric argument" do
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 cannot be found" do
68
- assert_equal(nil, Net::Proto.getprotobyname('foo'))
69
- assert_equal(nil, Net::Proto.getprotobyname('tcpx'))
70
- assert_equal(nil, Net::Proto.getprotobyname(''))
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 requires a string argument" do
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, 'Skipped on MS 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 accepts a block" do
90
- omit_if(@@windows, 'Skipped on MS 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 "structs returned by getprotoent contain specific members" do
101
- omit_if(@@windows, 'Skipped on MS 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 returns an array of strings" do
115
- omit_if(@@windows, 'Skipped on MS 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 "the structs returned by getprotoent are frozen" do
121
- omit_if(@@windows, 'Skipped on MS 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 for the Proto class" do
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: 27
5
- prerelease: false
4
+ hash: 19
5
+ prerelease:
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- - 6
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: 2010-10-22 00:00:00 -06:00
19
- default_executable:
18
+ date: 2012-01-18 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
- name: test-unit
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: 9
28
+ hash: 23
30
29
  segments:
31
- - 2
32
30
  - 1
33
- - 1
34
- version: 2.1.1
35
- type: :development
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
- - ext/extconf.rb
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
- - test/test_net_proto.rb
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
- - ext/extconf.rb
58
- - ext/version.h
59
- - ext/generic/generic.c
60
- - ext/linux/linux.c
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.3.7
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