Class: Net::Proto

Inherits:
Object
  • Object
show all
Extended by:
FFI::Library
Defined in:
lib/linux/net/proto.rb,
lib/sunos/net/proto.rb,
lib/net/proto/common.rb,
lib/generic/net/proto.rb,
lib/windows/net/proto.rb

Overview

The Proto class serves as the base class for the various protocol methods.

Defined Under Namespace

Classes: ProtoStruct

Constant Summary collapse

VERSION =

The version of the net-proto library

'1.4.2'

Class Method Summary collapse

Class Method Details

.get_protocol(arg) ⇒ Object

If given a protocol string, returns the corresponding number. If given a protocol number, returns the corresponding string.

Returns nil if not found in either case.

Examples:

Net::Proto.get_protocol('tcp') # => 6
Net::Proto.get_protocol(1)     # => 'icmp'


30
31
32
33
34
35
36
# File 'lib/linux/net/proto.rb', line 30

def self.get_protocol(argument)
  if argument.is_a?(String)
    getprotobyname(argument)
  else
    getprotobynumber(argument)
  end
end

.getprotobyname(protocol, hwnd = 0, msg = 0) ⇒ Object

Given a protocol string, returns the corresponding number, or nil if not found.

Examples:

Net::Proto.getprotobyname('tcp')   # => 6
Net::Proto.getprotobyname('bogus') # => nil

On MS Windows, you may also pass a window handle and a message (int) that window will receive. If present, this method becomes asynchronous and yields a block instead, with the protocol and handle.

Example:

Net::Proto.getprotobyname('tcp', SOME_WINDOW, SOME_MSG){ |num, handle| ... }

Raises:

  • (TypeError)


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/linux/net/proto.rb', line 46

def self.getprotobyname(protocol)
  raise TypeError unless protocol.is_a?(String)

  pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  buf  = FFI::MemoryPointer.new(:char, 1024)

  begin
    setprotoent(0)
    int = getprotobyname_r(protocol, pptr, buf, buf.size, qptr)
  ensure
    endprotoent()
  end

  int > 0 || qptr.get_pointer(0).null? ? nil : ProtocolStruct.new(pptr)[:p_proto]
end

.getprotobynumber(protocol, hwnd = 0, msg = 0) ⇒ Object

Given a protocol number, returns the corresponding string, or nil if not found.

Examples:

Net::Proto.getprotobynumber(6)   # => 'tcp'
Net::Proto.getprotobynumber(999) # => nil

On MS Windows, you may also pass a window handle and a message (int) that window will receive. If present, this method becomes asynchronous and yields a block instead, with the protocol and handle.

Example:

Net::Proto.getprotobynumber(6, SOME_WINDOW, SOME_MSG){ |name, handle| ... }

Raises:

  • (TypeError)


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/linux/net/proto.rb', line 71

def self.getprotobynumber(protocol)
  raise TypeError unless protocol.is_a?(Integer)

  pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  buf  = FFI::MemoryPointer.new(:char, 1024)

  begin
    setprotoent(0)
    int = getprotobynumber_r(protocol, pptr, buf, buf.size, qptr)
  ensure
    endprotoent()
  end

  int > 0 || qptr.get_pointer(0).null? ? nil : ProtocolStruct.new(pptr)[:p_name]
end

.getprotoentObject

In block form, yields each entry from /etc/protocol as a struct of type Proto::ProtoStruct. In non-block form, returns an array of structs.

The fields are ‘name’ (a string), ‘aliases’ (an array of strings, though often only one element), and ‘proto’ (a number).

Example:

Net::Proto.getprotoent.each{ |prot|
   p prot.name
   p prot.aliases
   p prot.proto
}

Note that on Windows this code reads directly out of a %SystemRoot% subfolder using pure Ruby, so you will need read access or this method will fail.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/linux/net/proto.rb', line 102

def self.getprotoent
  structs = block_given? ? nil : []

  pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  buf  = FFI::MemoryPointer.new(1024)

  begin
    setprotoent(0)

    while int = getprotoent_r(pptr, buf, buf.size, qptr)
      break if int > 0 || qptr.null?
      buf = FFI::MemoryPointer.new(1024)

      ffi_struct = ProtocolStruct.new(pptr)

      ruby_struct = ProtoStruct.new(
        ffi_struct[:p_name],
        ffi_struct[:p_aliases].read_array_of_string,
        ffi_struct[:p_proto]
      ).freeze

      if block_given?
        yield ruby_struct
      else
        structs << ruby_struct
      end
    end
  ensure
    endprotoent
  end

  structs
end