snort 源码分析之基础数据结构 链表

前面的很多里面涉及到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代码会相对轻松一些。

猜你喜欢

转载自blog.csdn.net/guoguangwu/article/details/88529229