本文共 2702 字,大约阅读时间需要 9 分钟。
前面的很多里面涉及到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;}
往链表尾插入节点
intsflist_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代码会相对轻松一些。
转载地址:http://gvtmd.baihongyu.com/