📄 detect.c
字号:
/** This file is part of Firestorm NIDS* Copyright (c) 2002 Gianni Tedesco* This program is released under the terms of the GNU GPL version 2** This is the detection engine, it is generic to all protocols* although each protocol is expected to maintain its own root* node. It is a very fast binary tree like structure. If you* want more details mail me ;) -- GT*/#include <config.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <firestorm.h>#include <packet.h>#include <cleanup.h>#include <alert.h>#include <signature.h>#include <matcher.h>#include <detect.h>struct alert **cur_alert=NULL;unsigned int *alert_depth=NULL;unsigned int cur_depth=0;/* Sort rules by cost */int m_sorter(const void *p1, const void *p2){ const struct sig_node *r1=p1; const struct sig_node *r2=p2; if ( r1->cost < r2->cost) return -1; if ( r1->cost > r2->cost) return 1; if ( !r1->n && r2->n ) return -1; if ( r1->n && !r2->n ) return 1; /* Tertiary sorting, based on function, * pointer, just to be consistent */ if ( r1->m < r2->m ) return -1; if ( r1->m > r2->m ) return 1; return 0;}/* Prepare to run a packet against a tree */void detect_set(struct alert **a, unsigned int *d){ if ( !a || !d ) { cleanup(EXIT_ERR, "detect_set(): report this bug\n"); return; } alert_depth=d; *alert_depth=0; cur_depth=0; cur_alert=a; *cur_alert=NULL;}/* Run a packet against a tree */void detect(struct sig_node *n, struct packet *p, unsigned int l){ cur_depth++; for(; n; n=n->next) { if ( n->m(p, n->p, l, n->n) ) { if ( n->a && cur_depth>*alert_depth ) { *cur_alert=n->a; *alert_depth=cur_depth; } detect(n->child, p, l); } } cur_depth--;}/* Add a signature to a tree */int detect_add_sig(struct sig_node *x, unsigned int num, struct sig_node *cur, struct alert *a){ struct sig_node *n, *use=NULL; unsigned int i; int m,t; /* Sort the list by cost */ qsort(x, num, sizeof(*x), m_sorter); /* The last item is the alert */ x[num-1].a=a; /* Add the nodes to the tree */ for(i=0; i<num; i++) { /* We may need to go above everyone else if some * higher cost nodes were added first */ if (cur->child && m_sorter(cur->child, &x[i])>0) { x[i].next=cur->child; cur->child=&x[i]; cur=&x[i]; continue; } /* Skip past lower cost nodes than us that are * not relevent to this rule */ if ( cur->child && m_sorter(cur->child, &x[i])<0 ) { struct sig_node *tmp; for(tmp=cur->child; tmp; tmp=tmp->next) { if ( m_sorter(tmp, &x[i])>=0 ) break; use=tmp; } t=1; }else{ use=cur->child; t=2; } /* Check if an identical node already exists in the * tree, if so then we can use that instead */ for(m=0,n=use; n; n=n->next) { if ( t==1 && m_sorter(n, &x[i])>0 ) break; if ( n->n==x[i].n && n->m==x[i].m && !n->match->compare(n->p, x[i].p) ) { /* Make sure we don't lose the alert by * forgetting about this node just * because a similar one exists */ if ( x[i].a ) n->a=x[i].a; cur=n; m=1; break; } } if ( m ) { if ( x[i].match->cleanup ) x[i].match->cleanup(x[i].p); continue; } /* Add ourselves to the bottom of the tree */ if ( t==2 ) { x[i].next=cur->child; cur->child=&x[i]; cur=&x[i]; }else{ x[i].next=use->next; use->next=&x[i]; cur=&x[i]; } } return 1;}/* Delete a signature, if bits of it are in the tree, * this will fuckup the tree. Eventually this code will * allow 'hot-plugging' and 'unplugging' of signatures. */void detect_free_sig(struct sig_node *r, unsigned int n){ unsigned int i; if (!r) return; for(i=0; i<n; i++) { r[i].match->cleanup(r[i].p); } free(r);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -