Paul Evans > Socket-Netlink > IO::Socket::Netlink

Download:
Socket-Netlink-0.04.tar.gz

Dependencies

Annotate this POD

CPAN RT

New  1
Open  1
View/Report Bugs
Module Version: 0.04   Source  

NAME ^

IO::Socket::Netlink - Object interface to PF_NETLINK domain sockets

SYNOPSIS ^

 use Socket::Netlink;
 use IO::Socket::Netlink;
 
 my $sock = IO::Socket::Netlink->new( Protocol => 0 ) or die "socket: $!";
 
 $sock->send_nlmsg( $sock->new_request(
    nlmsg_type  => 18,
    nlmsg_flags => NLM_F_DUMP,
    nlmsg       => "\0\0\0\0\0\0\0\0", 
 ) ) or die "send: $!";
 
 $sock->recv_nlmsg( my $message, 65536 ) or die "recv: $!";
 
 printf "Received type=%d flags=%x:\n%v02x\n",
    $message->nlmsg_type, $message->nlmsg_flags, $message->nlmsg;

DESCRIPTION ^

This module provides an object interface to PF_NETLINK sockets on Linux, by building on top of the IO::Socket class. While useful on its own, it is intended itself to serve as a base class, for particular netlink protocols to extend.

CLASS METHODS ^

$class->register_protocol( $proto )

May be called by a subclass implementing a Netlink protocol. If so, then any object constructed using a known protocol on this base class will be automatically reblessed into the appropriate package.

CONSTRUCTOR ^

$sock = IO::Socket::Netlink->new( %args )

Creates a new IO::Socket::Netlink object.

The recognised arguments are:

Protocol => INT

The netlink protocol. This is a required argument.

Pid => INT

Socket identifier (usually the process identifier)

Groups => INT

32bit bitmask of multicast groups to join

METHODS ^

$pid = $sock->sockpid

Returns the socket identifier

$groups = $sock->sockgroups

Returns the 32bit bitmask of multicast groups

$msg = $sock->new_message( %args )

Returns a new message object containing the given arguments. The named arguments are in fact read as an list of key/value pairs, not a hash, so order is significant. The basic nlmsg_* keys should come first, followed by any required by the inner level header.

For more detail, see the "MESSAGE OBJECTS" section below.

$msg = $sock->new_request( %args )

A convenience wrapper around new_message which sets the NLM_F_REQUEST flag on the returned message.

$sock->new_command( %args )

As new_request, but may use a different class for messages. This is for such netlink protocols as TASKSTATS, which uses a different set of message attributes for userland-to-kernel commands, as for kernel-to-userland event messages.

$sock->send_nlmsg( $message )

Sends the given message object to the kernel. $message should be a message object, constructed using the socket's new_message factory method.

$sock->recv_nlmsg( $message, $maxlen )

Receives a single message from the kernel. The $message parameter should be a variable, which will contain the new message object when this method returns successfully.

Sometimes the kernel will respond multiple messages in reply to just one. If this may be the case, see instead recv_nlmsgs.

This method returns success or failure depending only on the result of the underlying socket recv call. If a message was successfully received it returns true, even if that message contains an error. To detect the error, see the nlerr_error accessor.

$sock->recv_nlmsgs( \@messages, $maxlen )

Receives message from the kernel. If the first message received has the NLM_F_MULTI flag, then messages will be collected up until the final NLMSG_DONE which indicates the end of the list. Each message is pushed into the @messages array (which is not cleared initially), excluding the final NLMSG_DONE.

This method returns success or failure depending only on the result of the underlying socket recv call or calls. If any calls fails then the method will return false. If messages were successfully received it returns true, even if a message contains an error. To detect the error, see the nlerr_error accessor.

MESSAGE OBJECTS ^

Netlink messages are passed in to send_nlmsg and returned by recv_nlmsg and recv_nlmsgs in the form of objects, which wrap the protocol headers. These objects are not directly constructed; instead you should use the new_message method on the socket to build a new message to send.

These objects exist also to wrap higher-level protocol fields, for messages in some particular netlink protocol. A subclass of IO::Socket::Netlink would likely use its own subclass of message object; extra fields may exist on these objects.

The following accessors may be used to set or obtain the fields in the toplevel nlmsghdr structure:

Many Netlink-based protocols use standard message headers with attribute bodies. Messages may start with structure layouts containing standard fields, optionally followed by a sequence of one or more attributes in a standard format. Each attribute is an ID number and a value.

Because this class is intended to be subclassed by specific Netlink protocol implementations, a number of class methods exist to declare metadata about the protocol to assist generating the code required to support it. A message class can declare its header format, which defines what extra accessor fields will be created, and functions to pack and unpack the fields to or from the message body. It can also declare its mapping of attribute names, ID numbers, and data types. The message class will then support automatic encoding and decoding of named attributes to or from the buffer.

$messageclass->is_header( %args )

Called by a subclass of the message class, this class method declares that messages of this particular type contain a message header. The four required fields of %args define how this behaves:

When the header is declared, the base class's method named by data will be overridden by generated code. This overridden method unpacks the values of the fields into accessors when it is set, or packs the accessors into a value when queried.

This arrangement can be continued by further subclasses which implement further levels of wrapping, if the pack and unpack functions implement a data tail area; that is, the pack function takes an extra string buffer and the unpack function returns one, for extra bytes after the header itself. The last named field will then contain this buffer.

$messageclass->is_subclassed_by_type

Called by a subclass of the message class, this class method declares that messages are further subclassed according to the value of their nlmsg_type. This will override the nlmsg_type accessor to re-bless the object into its declared subclass according to the types declared to the generated register_nlmsg_type method.

For example

 package IO::Socket::Netlink::SomeProto::_Message;
 use base qw( IO::Socket::Netlink::_Message );

 __PACKAGE__->is_subclassed_by_type;

 package IO::Socket::Netlink::SomeProto::_InfoMessage;

 __PACKAGE__->register_nlmsg_type( 123 );

 ...

At this point, if a message is constructed with this type number, either by code calling new_message, or received from the socket, it will be automatically reblessed to the appropriate class.

This feature is intended for use by netlink protocols where different message types have different stucture types.

$messageclass->has_nlattrs( $fieldname, %attrs )

Called by a subclass of the message class, this class method is intended to be used by subclass authors to declare the attributes the message protocol understands. The data declared here is used by the nlattrs method.

$fieldname should be the name of an existing method on the object class; this method will be used to obtain or set the data field containing the attributes (typically this will be the trailing message body). %attrs should be a hash, mapping symbolic names of fields into their typeid and data format. Each entry should be of the form

 $name => [ $typeid, $datatype ]

When the attrs method is packing attributes into the message body, it will read attributes by $name and encode them using the given $datatype to store in the body by $typeid. When it is unpacking attributes from the body, it will use the $typeid to decode the data, and return it in a hash key of the given $name.

The following standard definitions exist for $datatype:

A subclass can define new data types by providing methods called pack_nlattr_$datatype and unpack_nlattr_$datatype which will be used to encode or decode the attribute value into a string buffer.

$message->nlattrs( \%newattrs )

Sets the message body field by encoding the attributes given by %newattrs, keyed by name, into Netlink attribute values, by using the definitions declared by the subclass's has_nlattrs method.

\%attrs = $message->nlattrs

Returns the decoded attributes from the message body field.

$value = $message->get_nlattr( $name )

Returns the decoded value of a single attribute from the message body field. Similar to

 $value = $message->nlattrs->{$name}

except it does not incur the extra cost of decoding the other attribute values that remain unused.

$message->change_nlattrs( %newvalues )

Changes the stored values of the given attributes in the message body field. Similar to

 $message->nlattrs( { %{ $message->nlattrs }, %newvalues } );

except it does not incur the extra cost of decoding and reencoding the unmodified attribute values.

A value of undef may be assigned to delete an attribute.

The following accessors are provided for debugging purposes

$str = $message->nlmsg_type_string

Renders the message type into a readable string form. Subclasses may wish to override this method to return other strings they recognise, or call to SUPER if they don't.

$str = $message->nlmsg_flags_string

Renders the flags into a readable string form. Each flag present is named, joined by | characters.

$str = $message->nlmsg_string

Intended for subclasses to override, to include more of their own information about nested headers.

$str = $message->STRING

$str = "$message"

Returns a human-readable string form of the message, giving details of the values of the fields. Provided primarily for debugging purposes.

ERROR MESSAGE OBJECTS ^

If a message object has its nlmsg_type field set to NLMSG_ERROR then the object will be reblessed into a subclass that encapsulates the error message.

$message->nlerr_error

Accessor for the error value from the kernel. This will be a system error value such used by $!. This accessor also exists on non-error messages, but returns false. This makes it easy to test for an error after recv_nlmsg:

 $sock->recv_nlmsg( my $message, 2**15 ) or die "Cannot recv - $!";
 ( $! = $message->nlerr_error ) and die "Received NLMSG_ERROR - $!";

$message->nlerr_msg

Accessor for the original netlink message header that invoked the error. This value may be unpacked using unpack_nlmsghdr.

SEE ALSO ^

AUTHOR ^

Paul Evans <leonerd@leonerd.org.uk>

syntax highlighting: