前面的很多里面涉及到snort的基础数据结构, snort里面很多数据结构都是自己实现的比如今天要讲解的链表,后面要讲的哈希表的实现。
具体文件 sflsq.h|c
链表的数据结构定义
typedef void * NODE_DATA;
/*
* 节点定义, 队列、栈、链表(双向)
*/
typedef struct sf_lnode
{
struct sf_lnode *next;
struct sf_lnode *prev;
/* 节点实际存储的内容*/
NODE_DATA ndata;
}
SF_QNODE,SF_SNODE,SF_LNODE;
/*
* 链表头, 双向链表, 头尾指针, 链表长度。cur用于实际操作链表
*/
typedef struct sf_list
{
SF_LNODE *head, *tail;
SF_LNODE *cur; /* used for First/Next walking */
unsigned count;
}
SF_QUEUE,SF_STACK,SF_LIST;
接口函数
/* 创建、回收、增删改查*/
SF_LIST * sflist_new ( void );
void sflist_init ( SF_LIST * s);
int sflist_add_tail ( SF_LIST* s, NODE_DATA ndata );
int sflist_add_head ( SF_LIST* s, NODE_DATA ndata );
int sflist_add_before ( SF_LIST* s, SF_LNODE * lnode, NODE_DATA ndata );
int sflist_add_after ( SF_LIST* s, SF_LNODE * lnode, NODE_DATA ndata );
NODE_DATA sflist_remove_head ( SF_LIST * s);
NODE_DATA sflist_remove_tail ( SF_LIST * s);
void sflist_remove_node (SF_LIST * s, SF_LNODE * n, void (*free)(void*) );
int sflist_count ( SF_LIST* s);
NODE_DATA sflist_first( SF_LIST * s);
NODE_DATA sflist_next( SF_LIST * s);
SF_LNODE * sflist_first_node( SF_LIST * s );
SF_LNODE * sflist_next_node( SF_LIST * s );
NODE_DATA sflist_firstpos( SF_LIST * s, SF_LNODE ** v );
NODE_DATA sflist_nextpos ( SF_LIST * s, SF_LNODE ** v );
void sflist_free ( SF_LIST * s);
void sflist_free_all( SF_LIST * s, void (*free)(void*) );
void sflist_static_free_all(SF_LIST *, void(*nfree)(void *));
void sflist_static_free(SF_LIST *);
创建新链表
/* 创建链表头, 并初始化*/
SF_LIST * sflist_new(void)
{
SF_LIST * s;
s = (SF_LIST*)s_alloc( sizeof(SF_LIST) );
if( s )sflist_init( s );
return s;
}
往链表尾插入节点
int
sflist_add_tail ( SF_LIST* s, NODE_DATA ndata )
{
SF_LNODE * q;
/* 链表尾空, 分配节点内存, 将前继、后继指针设成空, 将数据附加到节点上*/
if (!s->head)
{
q = s->tail = s->head = (SF_LNODE *) s_alloc (sizeof (SF_LNODE));
if(!q)return -1;
q->ndata = (NODE_DATA)ndata;
q->next = 0;
q->prev = 0;
}
/* 链表不为空, 通过链表头的尾指针进行设置,简单的双向链表节点插入操作*/
else
{
q = (SF_LNODE *) s_alloc (sizeof (SF_LNODE));
if(!q)return -1;
q->ndata = ndata;
q->next = 0;
q->prev = s->tail;
s->tail->next = q;
s->tail = q;
}
/* 更新链表长度*/
s->count++;
return 0;
}
/*
* 删除链表尾节点, 将删除的节点的数据部分返回, 链表没有节点,返回空
*/
NODE_DATA sflist_remove_tail (SF_LIST * s)
{
NODE_DATA ndata = 0;
SF_QNODE * q;
if (s && s->tail)
{
q = s->tail;
ndata = q->ndata;
s->count--;
s->tail = q->prev;
if (!s->tail)
{
s->tail = 0;
s->head = 0;
s->count = 0;
}
else
{
if( q->prev ) q->prev->next = 0;
}
s_free (q);
}
return (NODE_DATA)ndata;
}
其他的操作都是类似的,了解这些结构之后阅读snort代码会相对轻松一些。