Format data into IPAddr and Struct LinkStats

This commit is contained in:
Brian Candler
2011-04-29 14:42:59 +01:00
parent 8c690450a7
commit f16c819743

View File

@@ -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