📄 pcap.c
字号:
#include <stdlib.h>#include <string.h>#include <packet.h>#include <pcap.h>#include <firestorm.h>#include <plugin.h>#include <cleanup.h>#include <args.h>#include <alert.h>#include <signature.h>#include <decode.h>#include <capture.h>#include <args.h>PLUGIN_STD_DEFS();#define READ_TIMEOUT 500#define DEFAULT_MTU 16384struct fpcap_priv { pcap_t *pcap_desc; struct packet pkt; struct proto *proto; unsigned int mtu; char *ifname;};int cb_mtu(struct arg *, void *);int cb_if(struct arg *, void *);struct arg pl_args[]={ {"if",ARGTYPE_STRING,cb_if}, {"mtu",ARGTYPE_UINT,cb_mtu}, {NULL,ARGTYPE_NOP,NULL}};proc_args_parse args_parse;proc_decode_subproto decode_subproto;proc_serial_number serial_number;int cb_mtu(struct arg *a, void *priv){ struct fpcap_priv *p=priv; if ( !p ) return 0; if ( p->mtu ) { mesg(M_WARN,"pcap: you have already specified an mtu of %u", p->mtu); return 1; } p->mtu=a->val.v_uint; return 1;}int cb_if(struct arg *a, void *priv){ struct fpcap_priv *p=priv; if ( !p ) return 0; if ( p->ifname ) { mesg(M_ERR,"pcap: Can't specify two interfaces!"); return 0; } if ( !(p->ifname=strdup(a->val.v_str)) ) { return 0; } return 1;}void *fpcap_init(char *args){ unsigned int lnk; char ebuf[PCAP_ERRBUF_SIZE]; struct fpcap_priv *p=NULL; if ( !args ) return NULL; if ( !(p=calloc(1, sizeof(*p))) ) return NULL; switch( args_parse(pl_args, args, p) ) { case -1: mesg(M_ERR,"pcap: parse error: %s", args); case 0: /* fall through */ goto err; default: break; } /* Should be big enough for most... */ if ( !p->mtu ) p->mtu=DEFAULT_MTU; if ( !(p->pcap_desc=pcap_open_live(p->ifname, p->mtu, 0, /* Not promiscous */ READ_TIMEOUT, ebuf)) ) { mesg(M_ERR,"pcap: %s", ebuf); goto err; } lnk=pcap_datalink(p->pcap_desc); if ( !(p->proto=decode_subproto("__pcap_dlt",lnk)) ) { mesg(M_ERR,"pcap: %s: Can't support protocol 0x%x", p->ifname); pcap_close(p->pcap_desc); goto err; } mesg(M_INFO, "pcap: if=%s mtu=%u", p->ifname, p->mtu); p->pkt.flags=FP_CLONE|FP_LIVE|FP_PROMISC; return p;err: if ( p->ifname ) free(p->ifname); free(p); p=NULL; return NULL;}void fpcap_end(void *priv){ struct fpcap_priv *p=priv; if ( !p ) return; if ( p->pcap_desc ) pcap_close(p->pcap_desc); if ( p->ifname ) free(p->ifname); free(p);}void lpf_callback(u_char *user, struct pcap_pkthdr *header, u_char *data){ struct fpcap_priv *p; if ( !(p=(struct fpcap_priv *)user) ) return; /* Pointers */ p->pkt.base=data; p->pkt.end=data; p->pkt.end+=header->caplen; /* length */ p->pkt.caplen=header->caplen; p->pkt.len=header->len; /* Timestamp */ p->pkt.time.tv_sec=header->ts.tv_sec; p->pkt.time.tv_usec=header->ts.tv_usec; /* first layer */ p->pkt.layer[0].proto=p->proto; p->pkt.layer[0].h.raw=p->pkt.base; p->pkt.layer[0].flags=0; p->pkt.layer[0].session=NULL; p->pkt.llen=0; serial_number(&p->pkt.serial); p->proto->decode(&p->pkt);}void fpcap_go(void *priv, struct capture *c){ struct fpcap_priv *p=priv; p->pkt.capture=c; while(c->state==CAP_STATE_CAPTURE) { if ( pcap_dispatch(p->pcap_desc, 1, (pcap_handler)lpf_callback, priv)<0 ) { c->state=CAP_STATE_STOP; break; } }}struct capdev pcap_cap={ .name="pcap", .init=fpcap_init, .end=fpcap_end, .go=fpcap_go,};int PLUGIN_CAPDEV (struct capture_api *c){ object_check(c); serial_number=c->serial_number; decode_subproto=c->decode_subproto; args_parse=c->args_parse; if ( !c->capdev_add(&pcap_cap) ) return PLUGIN_ERR_FAIL; return PLUGIN_ERR_OK;}int PLUGIN_INIT (struct plugin_in *in, struct plugin_out *out){ /* validate input */ plugin_check(in, out); /* tell firestorm who we are */ PLUGIN_ID("capture.pcap", "Live libpcap capture"); PLUGIN_VERSION(1, 0); PLUGIN_AUTHOR("Gianni Tedesco", "gianni@scaramanga.co.uk"); PLUGIN_LICENSE("GPL"); return PLUGIN_ERR_OK;}int PLUGIN_UNLOAD (int code) { return PLUGIN_ERR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -