Author image David Cannings
and 1 contributors


Net::LibNIDS - Perl extension for reassembly of TCP/IP streams using the libnids package


  use Net::LibNIDS;
  Net::LibNIDS::param::set_device('en1');  #set which device to use, see pcap documentation
  Net::LibNIDS::init();                    # processes all parameters
  Net::LibNIDS::tcp_callback(\&collector ); # a callback to be called for each packet
  Net::LibNIDS::run();                      # start the collection
  sub collector {
    my $connection = shift;
    if($connection->state == Net::LibNIDS::NIDS_JUST_EST()) {
       $connection->server->collect_on;  #start tracing data from server     
       $connection->client->collect_on;  #start tracing data from server     
    if($connect->state == Net::LibNIDS::NIDS_DATA()) {
       if($connection->client->count_new) {
         print ">" . $connection->client->data;
       } else {
         print "<" . $connection->server->data;


  This module embeds the libnids C library written by Rafal Wojtczuk E<lt><gt>.
  libnids is designed to do all lowlevel network code required by a network intrusion detection 
  system (whichis what NIDS stands for). This module uses libnids to allow you to read 
  the reassembled tcp stream without any duplicates or incorrect order. That is, like a normal 
  host would have seen the stream.


The workflow of using libnids is to set all parameters, then call init, set up a callback then run.

Net::LibNIDS::init( )

Must be called once before run() is called, will return 1 if successful, will croak with a message if it fails.

Net::LibNIDS::tcp_callback( collector_callback )

This registers the tcp_callback function that will be invoked with each packet. The callback function is called with an object of Net::LibNIDS::tcp_stream

Net::LibNIDS::run( )

This starts the NIDS collector, it will not finish until you call exit() or the packet file you are processing is finished

Net::LibNIDS::checksum_off( )

Disables libnids internal checksumming for all packets by setting NIDS_DONT_CHKSUM.

Net::LibNIDS::nids_discard($tcp_stream, $num_bytes)

Exports the nids_discard function, which may be called from within your TCP callback. See the libnids documentation for further information on how to use this function.


This object is called as the first argument to tcp_callback function. It has the following methods

$tcp_stream->state( )

Returns the state of this connection. It can be one of the following:


Set when a connection is just established, if you don't register your interest in it, you will not see this connection again.


Set when there is more data on the connection


Set when the connection has been closed normally


Set when the connection has been closed by a reset


Set when the connection has been closed by a timeout


Set when NIDS is exiting, this is the last time you will get this callback, so if you want to save any data you have to do it now.


Returns the state as a string instead of an integer, easier for debugging.

$tcp_stream->server_ip $tcp_stream->client_ip

Returns the IP address of the server and client. Client is the initiator of the connection. Returned as a string.

$tcp_stream->server_port $tcp_stream->client_port

Returns the port of the server and client. Client is the initiator of the connection.


Returns the seconds from epoch that this packet was recorded. Only available with libnids version >= 1.19.


Returns the microsecond fraction that this packet was recorded. Used together with $tcp_stream->lastpacket to get the most correct timestamp possible. Only available with libnids version >= 1.19.

$tcp_stream->server $tcp_stream->client

Returns a Net::LibNIDS::tcp_stream::half object, corresponding to the client half and the server half.


$tcp_stream->server->collect( ) $tcp_stream->client->collect( )

Returns a boolean, 1 if it is collecting, 0 if it is not

$tcp_stream->server->collect_on( ) $tcp_stream->client->collect_on( )

Turns on collection for selected half_stream.

$tcp_stream->server->collect_off( ) $tcp_stream->client->collect_off( )

Turns off collection for selected half_stream.

$tcp_stream->server->collect_urg( ) $tcp_stream->client->collect_urg( )

Returns a boolean, 1 if it is collecting urgent data, 0 if it is not

$tcp_stream->server->collect_urg_on( ) $tcp_stream->client->collect_urg_on( )

Turns on collection for urgent data on selected half_stream.

$tcp_stream->server->collect_urg_off( ) $tcp_stream->client->collect_urg_off( )

Turns off collection for urgent data on selected half_stream.

$tcp_stream->server->count( ) $tcp_stream->client->count( )

Length of all data recieved on the respective half_stream since start of connection.

$tcp_stream->server->count_new( ) $tcp_stream->client->count_new( )

Amount of data that has been added since the last time the callback has been invoked. As far as I can tell from libnids documentation, count_new can only be set in client or server half_stream for a given callback. This is the best way to check which side is active.

$tcp_stream->server->count_urg_new( ) $tcp_stream->client->count_urg_new( )

Same as above, but for URGent data.

$tcp_stream->server->offset( ) $tcp_stream->client->offset( )

See libnids documentation, this maps directly down to its' underlying data structures.

$tcp_stream->server->data( ) $tcp_stream->client->data( )

The new data that has arrived since the last the callback was called. Should match the count_new field in length.


This maps down the libnids nids.params configuration structure, there is a get and a set function for each parameter. Some of them are not certain they work yet.

device (Net::LibNIDS::param::set_device(dev) Net::LibNIDS::param::get_device)

Sets the device libnids uses

filename (Net::LibNIDS::param::set_filename(filename) Net::LibNIDS::param::get_filename)

Sets the filename to read packets from (tcpdump file), if this is set, then libnids will process that filename.

pcap_filter (Net::LibNIDS::param::set_pcap_filter(pcap_filter) Net::LibNIDS::param::get_pcap_filter)

The pcap filter to apply on the packets. Note however that if you have fragmented packets you cannot use the pcap filter on for example ports, since fragmented IP packets might not contain enough tcp information to determine port.

See the note in the libnids manpage for a workaround, or check the code in

n_tcp_streams (Net::LibNIDS::param::set_n_tcp_streams(numbers) Net::LibNIDS::param::get_n_tcp_streams)

From libnids documentation: "size of the hash table used for storing structures tcp_stream; libnis will follow no more than 3/4 * n_tcp_streams connections simultaneously default value: 1040. If set to 0, libnids will not assemble TCP streams."

n_hosts (Net::LibNIDS::param::set_n_hosts(numbers) Net::LibNIDS::param::get_n_hosts)

From libnids documentation: "size of the hash table used for storing info on IP defragmentation; default value: 256"

sk_buff_size (Net::LibNIDS::param::set_sk_buff_size(numbers) Net::LibNIDS::param::get_sk_buff_size)

From libnids documentation: " size of struct sk_buff, a structure defined by Linux kernel, used by kernel for packets queuing. If this parameter has different value from sizeof(struct sk_buff), libnids can be bypassed by attacking resource managing of libnis (see TEST file). If you are paranoid, check sizeof(sk_buff) on the hosts on your network, and correct this parameter. Default value: 168"

dev_addon (Net::LibNIDS::param::set_dev_addon(numbers) Net::LibNIDS::param::get_dev_addon)

From libnids documentation: "how many bytes in structure sk_buff is reserved for information on net interface; if dev_addon==-1, it will be corrected during nids_init() according to type of the interface libnids will listen on. Default value: -1."


Not supported by this extension

syslog_level (Net::LibNIDS::param::set_syslog_level(numbers) Net::LibNIDS::param::get_syslog_level)

From libnids documentation: "if nids_params.syslog==nids_syslog, then this field determines loglevel used by reporting events by system daemon syslogd; default value: LOG_ALERT"

scan_num_hosts (Net::LibNIDS::param::set_scan_num_hosts(numbers) Net::LibNIDS::param::get_scan_num_hosts)

From libnids documentation: " size of hash table used for storing info on port scanning; the number of simultaneuos port scan attempts libnids will detect. if set to 0, port scanning detection will be turned off. Default value: 256."

scan_num_ports (Net::LibNIDS::param::set_scan_num_ports(numbers) Net::LibNIDS::param::get_scan_num_ports)

From libnids documentation: " how many TCP ports has to be scanned from the same source. Default value: 10."

scan_delay (Net::LibNIDS::param::set_scan_delay(numbers) Net::LibNIDS::param::get_scan_delay) From libnids documentation: " with no more than scan_delay milisecond pause between two ports, in order to make libnids report portscan attempt. Default value: 3000"

promisc (Net::LibNIDS::param::set_promisc(numbers) Net::LibNIDS::param::get_promisc)

From libnids documentation: "if non-zero, the device(s) libnids reads packets from will be put in promiscuous mode. Default: 1"

one_loop_less (Net::LibNIDS::param::set_one_loop_less(numbers) Net::LibNIDS::param::get_one_loop_less)

Set libnids API.txt documentation on how to use.


Not currently supported by this extension


Not currently supported by this extension


Previous versions of Net::LibNIDS included a patch against libnids in order to obtain packet timings. This is no longer necessary as long as libnids-1.19 or greater is used.


libnids man page libpcap man page API.txt documentation from libnids distributions and


Arthur Bergman, <> Modified for libnids >= 1.19 by David Cannings, <>


Copyright 2004 by Arthur Bergman

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.