libnids常用数据结构

数据结构的定义,源代码来自libnids-1.24版本,虽然libnids貌似更新的不频繁,但是基本是跟Linux内核的TCP/IP协议栈实现类似的,所以十分有用

1:报警类型

对IP,TCP,UDP数据包异常以及扫描的检测,不同的方式提供不同的报警类型

 23 enum
 24 {
 25   NIDS_WARN_IP = 1,         //表示IP数据包异常
 26   NIDS_WARN_TCP,            //表示TCP数据包异常
 27   NIDS_WARN_UDP,            //表示UDP数据包异常
 28   NIDS_WARN_SCAN            //表示有扫描攻击发生
 29 };

 31 enum
 32 {
 33   NIDS_WARN_UNDEFINED = 0,          //表示未定义
 34   NIDS_WARN_IP_OVERSIZED,           //表示IP数据包超长
 35   NIDS_WARN_IP_INVLIST,             //表示无效的碎片队列
 36   NIDS_WARN_IP_OVERLAP,             //表示发生重叠
 37   NIDS_WARN_IP_HDR,                 //表示无效的IP首部,IP数据包异常
 38   NIDS_WARN_IP_SRR,                 //表示源路由IP数据包
 39   NIDS_WARN_TCP_TOOMUCH,            //表示TCP数据个数太多,因为在Libnids中在同一时刻
 //捕获的TCP个数最大值为TCP连接参数的哈希表长度的3/4
 40   NIDS_WARN_TCP_HDR,                //表示无效的TCP首部,TCP数据包发生异常
 41   NIDS_WARN_TCP_BIGQUEUE,           //表示TCP接收的队列数据过多
 42   NIDS_WARN_TCP_BADFLAGS            //表示错误标记
 43 };

2:TCP连接状态

 45 # define NIDS_JUST_EST 1            //TCP连接建立,在此状态下可以决定是否对此TCP连接
 //进行数据分析,可以决定是否捕获TCP客户端或者服务器接收的数据或者紧急数据
 46 # define NIDS_DATA 2                //TCP连接接收数据的状态;在这个状态可以判断是否有
 //新的数据到达,如果有就可以把数据储存起来,可以在这个状态之中来分析TCP传输的数据,
 //此数据就存储在half_stream数据结构的缓存之中
 47 # define NIDS_CLOSE 3               //TCP连接正常关闭
 48 # define NIDS_RESET 4               //TCP连接被重置关闭
 49 # define NIDS_TIMED_OUT 5           //TCP连接超时关闭
 50 # define NIDS_EXITING 6             //libnids正在退出,这个状态下可以最后一次使用存储
 //在half_stream数据结构中的缓存数据

而其实TCP状态一共有11种

 enum {
        TCP_ESTABLISHED = 1,    //表示ESTABLISHED状态,TCP连接建立,开始传输数据
        TCP_SYN_SENT,           //表示SYN_SENT状态,主动打开
        TCP_SYN_RECV,           //表示SYN_RECV状态,接收SYN
        TCP_FIN_WAIT1,         //表示FIN_WAIT_1状态
        TCP_FIN_WAIT2,          //表示FIN_WAIT_2状态
        TCP_TIME_WAIT,          //表示TIME_WAIT状态
        TCP_CLOSE,              //表示CLOSED状态
        TCP_CLOSE_WAIT,         //表示CLOSE_WAIT状态
        TCP_LAST_ACK,           //表示LAST_ACk状态
        TCP_LISTEN,             //表示LISTEN状态
        TCP_CLOSING             //表示CLOSING状态
 }

3:校验和

libnids里实现了是否计算校验和功能

#define NIDS_DO_CHKSUM 0        //表示需要计算校验和
#define NIDS_DONT_CHKSUM 1      //表示不需要计算校验和

4:四元组

tuple4描述了四元组

 55 struct tuple4
 56 {
 57   u_short source;   //源端口
 58   u_short dest;     //目的端口
 59   u_int saddr;      //源IP地址
 60   u_int daddr;      //目的IP地址
 61 };

这里描述的不仅仅是TCP协议分析,UDP也是一样的

5:half_stream

这个数据结构描述在TCP连接中某一端的所有信息,可以是客户端,也可以是服务端

 63 struct half_stream
 64 {
 65   char state;               //套接字的状态,也就是上面说的TCP连接状态
 66   char collect;             //collect表示有数据到达,大于0此数据存放在data缓冲区中;
                                        //也可以表示不存储此数据到data中,不大于0,忽略
 67   char collect_urg;         //collect_urg表示是否有紧急数据到达,大于0存放在urgdata
                                        //中,也可以不存储到urgdata中,小于0,忽略
 68
 69   char *data;               //用来存储正常接收到的数据
 70   int offset;               //用来存储在data缓冲区中数据的第一个字节的偏移量
 71   int count;                //从TCP连接开始已经存储到data缓冲区中的数据的字节数
 72   int count_new;            //有多少新的数据存储到data中,如为0,表示没新数据到达
 73   int bufsize;              //数据区最大长度
 74   int rmem_alloc;           //该TCP连接所有数据的长度和,包括list队列里的
 75
 76   int urg_count;            //如果不为0,新的紧急数据到达
 77   u_int acked;
 78   u_int seq;
 79   u_int ack_seq;
 80   u_int first_data_seq;
 81   u_char urgdata;           //存储紧急数据
 82   u_char count_new_urg;     //是否有紧急数据到达,如果不为0,有新的紧急数据到达
 83   u_char urg_seen;          //有新的URG数据,不是以前的重复数据
 84   u_int urg_ptr;            //指向URG数据在流中的位置
 85   u_short window;           //窗口大小
 86   u_char ts_on;
 87   u_char wscale_on;
 88   u_int curr_ts;
 89   u_int wscale;
 90   struct skbuff *list;
 //当收到的TCP包中SEQ比期望的SEQ大时,则将数据先保存到此双向链表中,
 //为了访问方便,此链表按包中的SEQ从小到大排序,链尾为含最大SEQ的TCP包
 91   struct skbuff *listtail;  //ptr to tail of list
 92 };

虽然数据结构half_stream的成员十分多,但特别注意的不太多;state非常重要,描述了当前TCP的连接状态,只有知道了TCP连接状态之后,才能进行下一步的动作;data用来存储接收到的正常的网络数据信息;urgdata存储接收到的紧急数据;count_new判断是否有新的正常数据到达;count_new_urg判断是否有新的紧急数据到达;输出新到达的数据内容,正常数据存储在data中,紧急数据存储在urgdata中

6:tcp_stream

描述了一个TCP连接的所有信息,这应该是最重要的一个数据结构

 94 struct tcp_stream
 95 {
 96   struct tuple4 addr;               //TCP连接的四元组信息
 97   char nids_state;                  //TCP连接的逻辑状态(6种)
 98   struct lurker_node *listeners;    //给TCP处理的回调函数使用,其中一成员指向回调函数
 99   struct half_stream client;        //客户端信息
100   struct half_stream server;        //服务器信息
101   struct tcp_stream *next_node;
102   struct tcp_stream *prev_node;
103   int hash_index;
104   struct tcp_stream *next_time;
105   struct tcp_stream *prev_time;
106   int read;                         //本次读取数据缓冲区的数据的长度
107   struct tcp_stream *next_free;     //指向下一个空闲TCP结构
108   void *user;
109 };

7:nids_prm

描述了全局变量参数信息

111 struct nids_prm
112 {
113   int n_tcp_streams;                //用来存放tcp_stream数据结构的哈希表的大小,默认1040;
//在同一时刻libnids捕获的TCP数据包的最大个数必须是此参数值的3/4
114   int n_hosts;                      //存放IP碎片信息哈希表的大小,默认256
115   char *device;                     //网络接口,在此接口上捕获数据,默认NULL;libnids用
//pcap_lookupdev查找可用的网络接口,如果是all表示捕获所有网络接口的数据
116   char *filename;                   //存储网络数据包文件,必须是libpcap格式
117   int sk_buff_size;                 //数据结构sk_buff的大小;sk_buff是linux内核中用来
//进行数据包排队操作的,默认值为168
118   int dev_addon;                    //在数据结构sk_buff中用于网络接口上信息的字节数;如果
//是-1(默认),那么libnids会根据不同的网络接口进行修正
119   void (*syslog) ();                //函数指针,默认为nids_syslog()函数;在syslog函数中可以
//检测入侵攻击,比如网络扫描,以及一些异常比如无效TCP标记等情况
120   int syslog_level;                 //日志等级,默认为LOG_ALERT
121   int scan_num_hosts;               //存储端口扫描信息哈希表的大小;表示libnids要检测的同时
//扫描的端口数据;如果为0,libnids就不提供端口扫描功能;默认为256
122   int scan_delay;                   //在扫描检测中,两端口扫描的间隔时间,单位毫秒,默认3000
123   int scan_num_ports;               //想通源地址必须扫描的TCP端口数目,默认为10
124   void (*no_mem) (char *);          //函数指针,当libnids发生内存溢出时被调用
125   int (*ip_filter) ();              //函数指针,函数用来分析IP数据包;当有IP数据包到达时,
//函数被调用;如果此函数返回非零值,此数据包就被处理;如果返回0,此IP数据包就被丢弃;
//默认值为nids_ip_filter函数,总是返回1
126   char *pcap_filter;                //过滤规则;默认NULL,表示捕获所有的数据包,这里可以
//自行设置过滤规则,只捕获感兴趣的开发包
127   int promisc;                      //网卡模式;非零表示混杂模式,为零非混杂模式,默认为1
128   int one_loop_less;                //初始值为0
129   int pcap_timeout;                 //捕获数据返回的时间,单位毫秒;表示的就是libpcap函数
//中的pcap_open_live函数的timeout参数,默认值为1024
130   int multiproc;
131   int queue_limit;
132   int tcp_workarounds;
133   pcap_t *pcap_desc;
134 };

在libnids.c里有定义和初始化

 90 struct nids_prm nids_params = {
 91     1040,                       /* n_tcp_streams */
 92     256,                        /* n_hosts */
 93     NULL,                       /* device */
 94     NULL,                       /* filename */
 95     168,                        /* sk_buff_size */
 96     -1,                         /* dev_addon */
 97     nids_syslog,                /* syslog() */
 98     LOG_ALERT,                  /* syslog_level */
 99     256,                        /* scan_num_hosts */
100     3000,                       /* scan_delay */
101     10,                         /* scan_num_ports */
102     nids_no_mem,                /* no_mem() */
103     nids_ip_filter,             /* ip_filter() */
104     NULL,                       /* pcap_filter */
105     1,                          /* promisc */
106     0,                          /* one_loop_less */
107     1024,                       /* pcap_timeout */
108     0,                          /* multiproc */
109     20000,                      /* queue_limit */
110     0,                          /* tcp_workarounds */
111     NULL                        /* pcap_desc */
112 };

发表回复