📄 decode.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 decode engine. We keep a big internal graph of all* protocols and all their dependancies on each other. The actual* decoding is done by plugins.*/#include <string.h>#include <firestorm.h>#include <args.h>#include <packet.h>#include <cleanup.h>#include <preproc.h>#include <alert.h>#include <signature.h>#include <decode.h>#include <loader.h>#include <string_hash.h>/* libpcap DLT_* protocol */struct proto pcap_dlt_p=init_proto("__pcap_dlt", NULL, NULL);/* Global protocol list */#define DHASH_SIZE 127struct proto *protos[DHASH_SIZE];/* Protocol request list */static struct preq_list *preqs=NULL;void decode_init(void){ u_int32_t h; memset(protos, 0, sizeof(protos)); h=string_hash((char *)pcap_dlt_p.name)%DHASH_SIZE; protos[h]=&pcap_dlt_p;}/* Find a protocol by name */struct proto *decode_proto(char *proto){ struct proto *p; for(p=protos[string_hash(proto)%DHASH_SIZE]; p; p=p->next) { if ( !strcmp(p->name, proto) ) { return p; } } return NULL;}/* Capture plugins call this */struct proto *decode_subproto(char *proto, unsigned int lt){ struct proto *p; struct proto_child *c; if ( !(p=decode_proto(proto)) ) return NULL; for(c=p->children; c; c=c->next) { if ( c->id == lt ) { return c->proto; } } return NULL;}/* plugins call this to register protocols */int decode_add(struct proto *p, struct proto_req *r){ struct preq_list *req; u_int32_t h; if ( !p || !r || !p->name || (!p->decode&&!p->sdecode) ) return 0; if ( strlen(p->name) > PROTO_LEN ) { mesg(M_WARN, "decode: %s: protocol name is too long", p->name); } /* Check if we have already been added */ if ( p->next || p->children || decode_proto((char *)p->name) ) { mesg(M_DEBUG,"decode: error: '%s' protocol is " "already registered", p->name); return 0; } if ( !(req=calloc(1, sizeof(struct preq_list))) ) { cperror("calloc"); } /* Save the requests for later, when all the protocols * are done registering. We resolve them in * decode.c::decode_resolve_all() */ req->proto=p; req->arr=r; req->next=preqs; preqs=req; h=string_hash((char *)p->name)%DHASH_SIZE; /* Add to the list */ p->next=protos[h]; protos[h]=p; return 1;}/* Resolve a protocol request */int decode_resolve(struct proto_req *req, struct proto *proto){ struct proto_child *pc; struct proto *parent; if ( !(parent=decode_proto(req->name)) ) { return 0; } if ( !(pc=calloc(1, sizeof(struct proto_child))) ) { cperror("calloc"); } /* fill in the proto_child */ pc->id=req->id; pc->proto=proto; /* append it to the rightful owner */ pc->next=parent->children; parent->children=pc;#if 0 mesg(M_DEBUG,"resolve: %s:%u -> %s", parent->name, pc->id, pc->proto->name);#endif return 1;}/* Build the graph of inter-dependencies * for all registered protocols */static int decode_resolve_all(void){ struct preq_list *foo, *bar; int i; for(foo=preqs; foo;) { bar=foo; foo=foo->next; for(i=0; bar->arr[i].name; i++) { decode_resolve(&bar->arr[i], bar->proto); } /* this is only a temporary structure * after all */ free(bar); } preqs=NULL; return 1;}/* Load in all the protocols from all the plugins */void decode_load(void){ struct plugin *p; proc_decode_load fn; static struct decode_api dapi={ .size=sizeof(dapi), .decode_add=decode_add, .dispatch=dispatch, }; /* For each plugin that has the correct symbol we call its * protocol registration function. Protocols should not be * registered unless through this interface. */ for(p=ld_list; p; p=p->next) { if ( !(fn=loader_symbol(p, plugin_decode)) ) continue; loader_perror(p, "decode", fn(&dapi)); } decode_resolve_all();}/* run preprocessors for this layer */void dispatch_preproc(struct packet *pkt, unsigned int l){ struct proto *p=pkt->layer[l].proto; int i; for(i=0; i<p->num_active; i++) { struct pp_active *pp=&p->preproc[i]; pp->process(pkt, l, pp->priv); }}void dispatch(struct packet *p){ unsigned int i; struct layer *l;#if 0 /* Just alert on every single packet */ static struct generator sniffer_gen=init_generator("sniffer", NULL); static struct alert sniffer_a=init_alert("sniffer", 0, 0, 0); alert(&sniffer_gen, p, &sniffer_a); return;#endif /* Run preprocessors */ for(i=0, l=p->layer; i<p->llen; i++,l++) { if ( l->proto && l->proto->num_active ) dispatch_preproc(p, i); } /* Run signatures */ for(i=0, l=p->layer; i<p->llen; i++,l++) { if ( l->proto && l->proto->sig_match ) { l->proto->sig_match(p, i); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -