Format data into IPAddr and Struct LinkStats
This commit is contained in:
@@ -1,6 +1,20 @@
|
|||||||
require 'netlink/constants'
|
require 'netlink/constants'
|
||||||
|
require 'ipaddr'
|
||||||
|
|
||||||
module Netlink
|
module Netlink
|
||||||
|
LinkStats = Struct.new :rx_packets, :tx_packets,
|
||||||
|
:rx_bytes, :tx_bytes,
|
||||||
|
:rx_errors, :tx_errors,
|
||||||
|
:rx_dropped, :tx_dropped,
|
||||||
|
:multicast, :collisions,
|
||||||
|
:rx_length_errors, :rx_over_errors,
|
||||||
|
:rx_crc_errors, :rx_frame_errors,
|
||||||
|
:rx_fifo_errors, :rx_missed_errors,
|
||||||
|
:tx_aborted_errorsr, :tx_carrier_errors,
|
||||||
|
:tx_fifo_errors, :tx_heartbeat_errors,
|
||||||
|
:tx_window_errors,
|
||||||
|
:rx_compressed, :tx_compressed
|
||||||
|
|
||||||
# Base class for Netlink messages
|
# Base class for Netlink messages
|
||||||
class Message
|
class Message
|
||||||
# Map of numeric message type code => message class
|
# Map of numeric message type code => message class
|
||||||
@@ -20,10 +34,20 @@ module Netlink
|
|||||||
:short => { :pattern => "s_" },
|
:short => { :pattern => "s_" },
|
||||||
:int => { :pattern => "i" },
|
:int => { :pattern => "i" },
|
||||||
:long => { :pattern => "l_" },
|
:long => { :pattern => "l_" },
|
||||||
:binary => { :pattern => "a*", :default => "" },
|
:binary => { :pattern => "a*", :default => "".freeze },
|
||||||
:cstring => { :pattern => "Z*", :default => "" },
|
:cstring => { :pattern => "Z*", :default => "".freeze },
|
||||||
:stats32 => { :pattern => "L*", :default => [] },
|
:stats32 => {
|
||||||
:stats64 => { :pattern => "Q*", :default => [] },
|
:pack => lambda { |val| val.to_a.pack("L23") },
|
||||||
|
:unpack => lambda { |str| LinkStats.new(*(str.unpack("L23"))) },
|
||||||
|
},
|
||||||
|
:stats64 => {
|
||||||
|
:pack => lambda { |val| val.to_a.pack("Q23") },
|
||||||
|
:unpack => lambda { |str| LinkStats.new(*(str.unpack("Q23"))) },
|
||||||
|
},
|
||||||
|
:l3addr => {
|
||||||
|
:pack => lambda { |val| val.hton },
|
||||||
|
:unpack => lambda { |val| IPAddr.new_ntoh(val) },
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# You can initialize a message from a Hash or from another
|
# You can initialize a message from a Hash or from another
|
||||||
@@ -138,7 +162,7 @@ module Netlink
|
|||||||
|
|
||||||
def self.rtattr(name, code, type=nil, opt={})
|
def self.rtattr(name, code, type=nil, opt={})
|
||||||
info = TYPE_INFO[type]
|
info = TYPE_INFO[type]
|
||||||
self::RTATTRS[code] = [name, info && info[:pattern]]
|
self::RTATTRS[code] = [name, info]
|
||||||
define_method name do
|
define_method name do
|
||||||
@attrs.fetch name
|
@attrs.fetch name
|
||||||
end
|
end
|
||||||
@@ -153,10 +177,14 @@ module Netlink
|
|||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
data = super
|
data = super
|
||||||
self.class::RTATTRS.each do |code, (name, pattern)|
|
self.class::RTATTRS.each do |code, (name, info)|
|
||||||
if val = @attrs[name]
|
if val = @attrs[name]
|
||||||
Message.pad(data)
|
Message.pad(data)
|
||||||
val = Array(val).pack(pattern) if pattern
|
if pack = info[:pack]
|
||||||
|
val = pack[val]
|
||||||
|
elsif pattern = info[:pattern]
|
||||||
|
val = Array(val).pack(pattern)
|
||||||
|
end
|
||||||
data << [val.bytesize+RTATTR_SIZE, code].pack(RTATTR_PACK) << val
|
data << [val.bytesize+RTATTR_SIZE, code].pack(RTATTR_PACK) << val
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -178,11 +206,14 @@ module Netlink
|
|||||||
end
|
end
|
||||||
|
|
||||||
def _add_attr(code, val) # :nodoc:
|
def _add_attr(code, val) # :nodoc:
|
||||||
name, pattern = self.class::RTATTRS[code]
|
name, info = self.class::RTATTRS[code]
|
||||||
if name
|
if name
|
||||||
if pattern
|
if !info
|
||||||
val = val.unpack(pattern)
|
# skip
|
||||||
val = val.first if val.size == 1
|
elsif unpack = info[:unpack]
|
||||||
|
val = unpack[val]
|
||||||
|
elsif pattern = info[:pattern]
|
||||||
|
val = val.unpack(pattern).first
|
||||||
end
|
end
|
||||||
warn "Duplicate attribute #{name} (#{code}): #{@attrs[name].inspect} -> #{val.inspect}" if @attrs[name]
|
warn "Duplicate attribute #{name} (#{code}): #{@attrs[name].inspect} -> #{val.inspect}" if @attrs[name]
|
||||||
@attrs[name] = val
|
@attrs[name] = val
|
||||||
@@ -234,13 +265,13 @@ module Netlink
|
|||||||
field :flags, :uchar
|
field :flags, :uchar
|
||||||
field :scope, :uchar
|
field :scope, :uchar
|
||||||
field :index, :int
|
field :index, :int
|
||||||
rtattr :address, IFA_ADDRESS
|
rtattr :address, IFA_ADDRESS, :l3addr
|
||||||
rtattr :local, IFA_LOCAL
|
rtattr :local, IFA_LOCAL, :l3addr
|
||||||
rtattr :label, IFA_LABEL, :cstring
|
rtattr :label, IFA_LABEL, :cstring
|
||||||
rtattr :broadcast, IFA_BROADCAST
|
rtattr :broadcast, IFA_BROADCAST, :l3addr
|
||||||
rtattr :anycase, IFA_ANYCAST
|
rtattr :anycast, IFA_ANYCAST, :l3addr
|
||||||
rtattr :cacheinfo, IFA_CACHEINFO
|
rtattr :cacheinfo, IFA_CACHEINFO
|
||||||
rtattr :multicast, IFA_MULTICAST
|
rtattr :multicast, IFA_MULTICAST, :l3addr
|
||||||
end
|
end
|
||||||
|
|
||||||
class Route < RtattrMessage
|
class Route < RtattrMessage
|
||||||
@@ -254,13 +285,13 @@ module Netlink
|
|||||||
field :scope, :uchar
|
field :scope, :uchar
|
||||||
field :type, :uchar
|
field :type, :uchar
|
||||||
field :flags, :uint
|
field :flags, :uint
|
||||||
rtattr :dst, RTA_DST
|
rtattr :dst, RTA_DST, :l3addr
|
||||||
rtattr :src, RTA_SRC
|
rtattr :src, RTA_SRC, :l3addr
|
||||||
rtattr :iif, RTA_IIF, :uint32
|
rtattr :iif, RTA_IIF, :uint32
|
||||||
rtattr :oif, RTA_OIF, :uint32
|
rtattr :oif, RTA_OIF, :uint32
|
||||||
rtattr :gateway, RTA_GATEWAY
|
rtattr :gateway, RTA_GATEWAY, :l3addr
|
||||||
rtattr :priority, RTA_PRIORITY, :uint32
|
rtattr :priority, RTA_PRIORITY, :uint32
|
||||||
rtattr :prefsrc, RTA_PREFSRC
|
rtattr :prefsrc, RTA_PREFSRC, :l3addr
|
||||||
rtattr :metrics, RTA_METRICS
|
rtattr :metrics, RTA_METRICS
|
||||||
rtattr :multipath, RTA_MULTIPATH
|
rtattr :multipath, RTA_MULTIPATH
|
||||||
rtattr :flow, RTA_FLOW
|
rtattr :flow, RTA_FLOW
|
||||||
|
Reference in New Issue
Block a user