Tidying of nlsocket
This commit is contained in:
@@ -10,6 +10,13 @@ module Netlink
|
|||||||
ERRNO_MAP[klass::Errno] = klass
|
ERRNO_MAP[klass::Errno] = klass
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Raise an Errno exception if the given rc is not NOERROR
|
||||||
|
def self.check_error(rc)
|
||||||
|
if -rc != Errno::NOERROR::Errno
|
||||||
|
raise ERRNO_MAP[-rc] || "Netlink Error: #{msg.inspect}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# NLSocket provides low-level sending and receiving of messages across
|
# NLSocket provides low-level sending and receiving of messages across
|
||||||
# a netlink socket, adding headers to sent messages and parsing
|
# a netlink socket, adding headers to sent messages and parsing
|
||||||
# received messages.
|
# received messages.
|
||||||
@@ -38,6 +45,7 @@ module Netlink
|
|||||||
attr_accessor :seq # the last sequence number used
|
attr_accessor :seq # the last sequence number used
|
||||||
attr_accessor :pid # default pid to include in message headers
|
attr_accessor :pid # default pid to include in message headers
|
||||||
attr_accessor :timeout # default timeout when receiving message
|
attr_accessor :timeout # default timeout when receiving message
|
||||||
|
attr_accessor :junk_handler # proc to log or handle unexpected messages
|
||||||
|
|
||||||
# Create a new Netlink socket. Pass in chosen protocol:
|
# Create a new Netlink socket. Pass in chosen protocol:
|
||||||
# :protocol => Netlink::NETLINK_ARPD
|
# :protocol => Netlink::NETLINK_ARPD
|
||||||
@@ -137,18 +145,19 @@ module Netlink
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Loop receiving responses until a DONE message is received (or you
|
# Loop receiving responses until a DONE message is received (or you
|
||||||
# break out of the loop, or a timeout exception occurs).
|
# break out of the loop, or a timeout exception occurs). Checks the
|
||||||
|
# message type and pid/seq.
|
||||||
#
|
#
|
||||||
# Yields Netlink::Message objects, or if no block is given, returns an
|
# Yields Netlink::Message objects, or if no block is given, returns an
|
||||||
# array of those objects.
|
# array of those objects.
|
||||||
#
|
#
|
||||||
# (Compare: rtnl_dump_filter_l in lib/libnetlink.c)
|
# (Compare: rtnl_dump_filter_l in lib/libnetlink.c)
|
||||||
def receive_until_done(expected_type=nil, timeout=@timeout, &blk) #:yields: msg
|
def receive_until_done(expected_type, timeout=@timeout, &blk) #:yields: msg
|
||||||
res = []
|
res = []
|
||||||
blk ||= lambda { |obj| res << obj }
|
blk ||= lambda { |obj| res << obj }
|
||||||
receive_responses(true, timeout) do |type,msg|
|
receive_responses(true, timeout) do |type,msg|
|
||||||
return res if type == NLMSG_DONE
|
return res if type == NLMSG_DONE
|
||||||
if expected_type && type != expected_type
|
if type != expected_type
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
blk.call(msg) if msg
|
blk.call(msg) if msg
|
||||||
@@ -156,11 +165,12 @@ module Netlink
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Loop infinitely receiving responses and yielding message objects
|
# This is the entry point for protocols which yield an infinite stream
|
||||||
# of the given type.
|
# of messages (e.g. firewall, ulog). There is no timeout, and
|
||||||
def receive_stream(expected_type=nil)
|
# the pid/seq are not checked.
|
||||||
|
def receive_stream(expected_type) #:yields: msg
|
||||||
receive_responses(false, nil) do |type, msg|
|
receive_responses(false, nil) do |type, msg|
|
||||||
if expected_type && type != expected_type
|
if type != expected_type
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
yield msg
|
yield msg
|
||||||
@@ -168,19 +178,19 @@ module Netlink
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# This is the main loop for receiving responses. It optionally checks
|
# This is the main loop for receiving responses, yielding the type and
|
||||||
# the pid/seq of received messages, and discards those which don't match.
|
# message object for each received message. It optionally checks the pid/seq
|
||||||
# Raises an exception on NLMSG_ERROR.
|
# and discards those which don't match. If the block returns 'false' then
|
||||||
|
# they are also logged as junk.
|
||||||
#
|
#
|
||||||
# Matching messages are yielded to the block. If the block returns
|
# Raises an exception on NLMSG_ERROR (other than Errno::NOERROR), or if
|
||||||
# false then they are treated as junk.
|
# no packet received within the specified timeout. Pass nil for infinite
|
||||||
def receive_responses(check_pid_seq=false, timeout=nil)
|
# timeout.
|
||||||
|
def receive_responses(check_pid_seq, timeout=@timeout)
|
||||||
loop do
|
loop do
|
||||||
receive_response(timeout) do |type, flags, seq, pid, msg|
|
parse_yield(recvmsg(timeout)) do |type, flags, seq, pid, msg|
|
||||||
if !check_pid_seq || (pid == @pid && seq == @seq)
|
if !check_pid_seq || (pid == @pid && seq == @seq)
|
||||||
if type == NLMSG_ERROR && -msg.error != Errno::NOERROR::Errno
|
self.class.check_error(msg.error) if type == NLMSG_ERROR
|
||||||
raise ERRNO_MAP[-msg.error] || "Netlink Error: #{msg.inspect}"
|
|
||||||
end
|
|
||||||
res = yield type, msg
|
res = yield type, msg
|
||||||
next unless res == false
|
next unless res == false
|
||||||
end
|
end
|
||||||
@@ -203,17 +213,6 @@ module Netlink
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Receive one datagram from kernel. Yield header fields plus
|
|
||||||
# Netlink::Message objects (maybe multiple times if the datagram
|
|
||||||
# includes multiple netlink messages). Raise an exception if no
|
|
||||||
# datagram received within the specified or default timeout period;
|
|
||||||
# pass nil for infinite timeout.
|
|
||||||
#
|
|
||||||
# receive_response { |type, flags, seq, pid, msg| p msg }
|
|
||||||
def receive_response(timeout=@timeout, &blk) # :yields: type, flags, seq, pid, Message
|
|
||||||
parse_yield(recvmsg(timeout), &blk)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Parse netlink packet in a string buffer. Yield header fields plus
|
# Parse netlink packet in a string buffer. Yield header fields plus
|
||||||
# a Netlink::Message-derived object for each message. For unknown message
|
# a Netlink::Message-derived object for each message. For unknown message
|
||||||
# types it will yield a raw String, or nil if there is no message body.
|
# types it will yield a raw String, or nil if there is no message body.
|
||||||
|
Reference in New Issue
Block a user