![]() |
![]()
| ![]() |
![]()
NAME"IO::Socket::Netlink" - Object interface to "PF_NETLINK" domain sockets SYNOPSISuse 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; DESCRIPTIONThis 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 METHODSregister_protocol$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. CONSTRUCTORnew$sock = IO::Socket::Netlink->new( %args ) Creates a new "IO::Socket::Netlink" object. The recognised arguments are:
METHODSsockpid$pid = $sock->sockpid Returns the socket identifier sockgroups$groups = $sock->sockgroups Returns the 32bit bitmask of multicast groups new_message$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. new_request$msg = $sock->new_request( %args ) A convenience wrapper around "new_message" which sets the "NLM_F_REQUEST" flag on the returned message. new_command$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. send_nlmsg$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. recv_nlmsg$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. recv_nlmsgs$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 OBJECTSNetlink 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:
The following options are recognised:
Fields defined simply by name are given the type of "decimal" with a default value of 0, and no other options.
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_typeCalled 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->nlattrsReturns 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_stringRenders 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_stringRenders the flags into a readable string form. Each flag present is named, joined by "|" characters. $str = $message->nlmsg_stringIntended 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 OBJECTSIf 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_errorAccessor 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_msgAccessor for the original netlink message header that invoked the error. This value may be unpacked using "unpack_nlmsghdr". SEE ALSO
AUTHORPaul Evans <leonerd@leonerd.org.uk>
|