Native Datatypes
Libnids makes use of a great deal of global data and provides several native datatypes that the application programmer needs to know about.
struct nids_prm {
nids_prm is the main control structure for libnids. It dictates most of libnids' behavior throughout the entire library. It is a global structure available to every libnids function.
int n_tcp_streams;
n_tcp_streams sets the size of the hash table used for storing TCP connections (struct tcp_stream). This parameter implicitly sets the limit on the number of concurrent TCP connections that libnids will monitor. If the limit is set to 0, libnids does not assemble any TCP connections (although this action would disable a large portion of libnids' functionality).
int n_hosts;
n_hosts sets the size of the hash table used for storing IP defragmentation information.
char *device;
device is the canonical name of the network interface to monitor. If the device is set to NULL, libnids calls libpcap's pcap_lookupdev () to find a suitable device. Under Linux, if the device is set to "all", libnids monitors every available network interface. In some circumstances, however, this situation can result in duplicate packets delivered to UDP and IP callback functions (which maintain no state). Libnids properly handles duplicate TCP data and delivers it to the TCP callbacks.
int sk_buff_size;
sk_buff_size controls how large struct sk_buff gets, which in turn is useful for queuing packets. Generally speaking, you should set this value to the same size as the hosts you are monitoring.
int dev_addon;
dev_addon is the number of bytes in sk_buff, which are reserved for link-layer information. If this value is set to -1, libnids determines an appropriate offset automatically based on the link-layer type.
void (*syslog) ();
syslog () is a callback function that reports unusual conditions, such as port scan attempts, invalid TCP header flags, and so on. Information handed to syslog () then passes back to the operating system.
int syslog_level;
syslog_level is the syslog reporting level used for reporting events to the operating system. You can find more information in the documentation, specifically syslog(3).
int scan_num_hosts;
scan_num_hosts is the size of the hash table used for storing port-scan information (the maximum number of portscans that will be detected simultaneously). If scan_num_hosts is set to 0, portscan detection will be disabled.
int scan_delay;
scan_delay sets the maximum delay in milliseconds for connections to different TCP ports for libnids to identify them as part of a portscan.
int scan_num_ports;
scan_num_hosts sets the low-water threshold for the number of TCP packets to different ports on a machine before libnids identifies it as a portscan. Note that libnids' portscan detection is not restricted to a monotonically increasing port number; rather, libnids works from an event-based model that will detect port scans to different "random" ports (on different IP addresses) by looking at inter-arrival time periods.
void (*no_mem) (char *);
no_mem () is a callback function used to terminate the calling process gracefully when the underlying memory allocation function fails. The default program simply writes to STDERR and exits.
int (*ip_filter) ();
ip_filter () is a callback function that selectively discards IP packets after reassembly and inspection. If the function returns a non-zero value, the packet is processed; otherwise, the packet is discarded. The libnids default function is set to always return true.
char *pcap_filter;
pcap_filter specifies a BPF filter string to apply to the link-layer device. Note that certain filters will not catch specially fragmented packets. For example, a filter string of "tcp dst port 23" does not catch 8-byte IP fragments that do not contain TCP header information (even if upon reassembly the IP packet contains a TCP segment).
int promisc;
promisc controls whether or not libnids places the interface into promiscuous mode or not. As with any libpcap-based sniffing application, the interface might be put in promiscuous mode by a different application (see Chapter 2 for additional details on libpcap).
int one_loop_less;
one_loop_less, when set, changes the overall behavior of libnids. If a callback function consumes some (but not all) of newly arrived data, libnids immediately calls it again to process the rest of the data. This process continues until libnids processes all of the data. If there is no new data, however, the callback function will not be called again.
};
struct tuple4 {
tuple4 contains the standard TCP/IP "4-tuple" information needed to uniquely identify a TCP connection.
u_short source;
source is the source port of the packet.
u_short dest;
dest is the destination port of the packet.
u_int saddr;
saddr is the IP source address of the packet.
u_int daddr;
daddr is the IP destination address of the packet.
};
struct half_stream {
half_stream tracks the state of one-half of a TCP connection and controls some of libnids' behavior on the referenced half of the connection.
char state;
state refers to the state of the connection (TCP_ESTABLISHED, TCP_SYN_RECV, and so on).
char collect;
collect is a Boolean value specifying whether or not libnids should collect data for this half of the referenced connection into the buffer to which the data points.
char collect_urg;
collect_urg is a Boolean value specifying whether or not libnids should collect urgent data (specified by the TCP URG flag and pointed to by the TCP urgent pointer) for this half of the referenced connection into the buffer to which urgdata points.
char *data;
data points to the buffer for normal data.
int offset;
offset identifies the first byte of new data in data, as referenced from the beginning of the buffer.
int count;
count refers to the number of bytes appended to data since the creation of the connection.
int count_new;
count_new refers to the number of bytes appended to data since the last invocation of the TCP callback function. If count_new is 0, no new data has arrived.
u_char urgdata;
urgdata is a 1-byte buffer for urgent data.
u_char count_new_urg;
count_new refers to the number of bytes appended to urgdata since the last invocation of the TCP callback function. If count_new_urg is 0, no new data has arrived.
...
Other members of this structure are internal to libnids, and the application programmer does not need to know about them.
};
struct tcp_stream {
tcp_stream references a TCP connection between two hosts.
struct tuple4 addr;
tuple4 contains the 4-tuple information for the connection, as we described earlier.
char nids_state;
nids_state controls the behavior of the user-defined TCP callback function as per five control states:
NIDS_JUST_EST describes a connection that has just been established.
NIDS_DATA indicates new data has arrived on the connection.
NIDS_CLOSE, NIDS_RESET, and NIDS_TIMED_OUT indicate that the connection has been closed and that the TCP callback function should free allocated resources referencing this connection.
struct half_stream client;
client refers to the client side of the TCP connection.
struct half_stream server;
server refers to the server side of the TCP connection.
...
Other members of this structure are internal to libnids, and the applications programmer does not need to know about them.