⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.c

📁 Firestorm NIDS是一个性能非常高的网络入侵检测系统 (NIDS)。目前
💻 C
字号:
#include "tcpip.h"/* Generator */struct generator tcp_gen=init_generator("sig.tcp", NULL);static int  tcp_serialize(struct packet *, unsigned int, char *, int);static void *tcp_deserialize(struct packet*, unsigned int, char *, int);struct proto tcp_p={	.name="tcp",	.decode=tcp_decode,	.print=tcp_dprint,	.sig_add=tcp_commit,	.sig_match=tcp_match,	.serialize=tcp_serialize,	.deserialize=tcp_deserialize,	.free=free,};struct proto_req tcp_r[]={	proto_request("ip", 6),	null_request()};/* for serialize/deserialize *//* XXX: are htonl() and ntohl() interchangable on all CPUs? */static void tcp_swapbytes(struct tcp_stream *s, struct tcp_stream *f){	f->state=s->state;	f->flags=s->flags;	f->scale=s->scale;	f->reserved=s->reserved;	f->ts_recent=htonl(s->ts_recent);	f->ts_recent_stamp=htonl(s->ts_recent_stamp);	f->snd_una=htonl(s->snd_una);	f->snd_nxt=htonl(s->snd_una);	f->rcv_nxt=htonl(s->snd_una);	f->rcv_wnd=htonl(s->snd_una);	f->rcv_wup=htonl(s->snd_una);	f->isn=htonl(s->isn);}static int tcp_serialize(struct packet *p, unsigned int i, char *buf, int len){	struct tcp_session *s=(struct tcp_session *)p->layer[i].session;	struct tcp_serial  *f=(struct tcp_serial  *)buf;	if ( len < sizeof(struct tcp_serial) )		return -1;	/* Already network byte order */	f->c_addr=s->c_addr;	f->s_addr=s->s_addr;	f->c_port=s->c_port;	f->s_port=s->s_port;	tcp_swapbytes(&s->client, &f->client);	tcp_swapbytes(&s->server, &f->server);	return sizeof(*f);}/* Remember: this data is un-trusted so validate it! */static void *tcp_deserialize(struct packet *p, unsigned int i, char *buf, int len){	struct tcp_session *s;	struct tcp_serial *f=(struct tcp_serial *)buf;	if ( len < sizeof(*f) ) return NULL;	/* validate input */	if ( f->server.state >= TCP_MAX_STATES ) return NULL;	if ( f->client.state >= TCP_MAX_STATES ) return NULL;		if ( !(s=calloc(1, sizeof(*s))) ) return NULL;	/* already network byte order */	s->c_addr=f->c_addr;	s->s_addr=f->s_addr;	s->c_port=f->c_port;	s->s_port=f->s_port;	tcp_swapbytes(&f->client, &s->client);	tcp_swapbytes(&f->server, &s->server);	return s;}int tcp_dprint(struct layer *l, char *buf, int buflen){	char tcpflags[]="FSRPAU12";	char disp[9];	int n, x;	for(n=0,x=1; n<8; n++, x*=2) {		if ( l->h.tcp->flags.flags & x ){			disp[n]=tcpflags[n];		}else{			disp[n]='*';		}	}disp[8]='\0';	return snprintf(buf, buflen,		"%u > %u [%s] seq=0x%x ack=0x%x win=%u",		ntohs(l->h.tcp->sport),		ntohs(l->h.tcp->dport),		disp,		ntohl(l->h.tcp->seq),		ntohl(l->h.tcp->ack),		ntohs(l->h.tcp->win));}static inline u_int32_t tcp_csum(struct packet *pkt, unsigned int l){	struct pkt_iphdr *iph=pkt->layer[l].h.ip;	struct pkt_tcphdr *tcph=pkt->layer[l+1].h.tcp;	struct tcp_phdr ph;	u_int16_t *tmp;	u_int32_t sum=0;	u_int16_t len, csum;	int i;	if ( pkt->layer[l].flags&FLAG_IP_DTRUNC )		return 0;	len=ntohs(iph->tot_len) - (iph->ihl<<2);	/* Make pseudo-header */	ph.sip=iph->saddr;	ph.dip=iph->daddr;	ph.zero=0;	ph.proto=iph->protocol;	ph.tcp_len=htons(len);	/* Checksum the pseudo-header */	tmp=(u_int16_t *)&ph;	for(i=0; i<6; i++) {		sum+=tmp[i];		if(sum & 0x80000000) {			sum = (sum & 0xffff) + (sum >> 16);		}	}	/* Checksum the header+data */	tmp=(u_int16_t *)tcph;	for(i=0; i<len>>1; i++) {		sum+=tmp[i];		if(sum & 0x80000000) {			sum = (sum & 0xffff) + (sum >> 16);		}	}	/* Deal with last byte (if odd number of bytes) */	if ( len&1 ) {		union {			u_int8_t b[2];			u_int16_t s;		}f;		f.b[0]=((u_int8_t *)tcph)[len-1];		f.b[1]=0;		sum+=f.s;	}	while(sum >> 16)		sum = (sum & 0xffff) + (sum >> 16);	csum=(~sum) & 0xffff;	return csum ? 0 : FLAG_TCP_CSUM;}void tcp_decode(struct packet *p){	struct layer *l=&p->layer[p->llen];	/* Check it is at least minimum size */	if ( l->h.raw+sizeof(struct pkt_tcphdr) > p->end ) {		return;	}	/* Use the doff field to decode the packet */	if ( (p->layer[p->llen+1].h.raw=		l->h.raw+(l->h.tcp->doff<<2))		> p->end ) {		return;	}	p->llen++;	if ( p->llen >= PKT_LAYERS ) return;	/* State tracking */	if ( tcp_stateful ) {		l->flags|=tcp_csum(p, p->llen-2);		tcpstream_process(p, p->llen-2);		return;	}	if ( p->layer[p->llen].h.raw<p->end )		p->layer[p->llen++].proto=NULL;	dispatch(p);}/* =================================================== * PACKET MATCHING STUFF BEYOND THIS POINT * =================================================== */struct sig_node tcp_root;void tcp_match(struct packet *p, unsigned int l){	l--;	detect_set(&cur_alert, &alert_depth);	detect(tcp_root.child, p, l);	if ( cur_alert ) alert(&tcp_gen, p, cur_alert);}int tcp_commit(struct rule *r){	struct criteria *c;	struct sig_node *x;	struct matcher *m;	struct alert *a;	unsigned int i;	int forceflow=(tcp_stateful) ? 1 : 0;	/* Can't handle this case */	if ( r->num_criteria==0 ) return 0;	if ( !(x=calloc(r->num_criteria+1, sizeof(*x))) ) return 0;	/* Copy the alert data */	if ( !(a=calloc(1, sizeof(*a))) ) {		free(x);		return 0;	}	memcpy(a, &r->alert, sizeof(*a));	/* Build an array of all the nodes we want to add */	for(c=r->criteria,i=0; c; c=c->next,i++) {		char *key;		if ( !strcmp(c->crit, "src") ) {			key="ip_src";		}else if ( !strcmp(c->crit, "dst") ) {			key="ip_dst";		}else if ( !strcmp(c->crit, "sport") ) {			key="tcp_sport";		}else if ( !strcmp(c->crit, "dport") ) {			key="tcp_dport";		}else if ( !strcmp(c->crit, "flow") || 			!strcmp(c->crit, "stateless") ) {			if ( !tcp_stateful ) {				/* dont allow flow or stateless if tcpstream				 * is disabled */				forceflow=-1;				i--;				continue;			}			forceflow=0;			key=c->crit;		}else key=c->crit;		if ( !(m=matcher_find(key)) ) {			mesg(M_ERR,"tcp_commit: cannot find '%s' matcher", key);			detect_free_sig(x, i);			return 0;		}		x[i].match=m;		x[i].n=c->negate;		x[i].cost=m->cost;		if ( !(x[i].m=m->validate(c->args,			&x[i].p, c->modifier, &x[i].cost)) ) {			detect_free_sig(x, i);			return 0;		}	}	/* Enforce a default policy on flow */	if ( forceflow==1 ) {		if ( !(m=matcher_find("flow")) ) {			mesg(M_ERR,"tcp_commit: cannot find '%s' matcher", "flow");			detect_free_sig(x, i);			return 0;		}		x[i].match=m;		x[i].n=0;		x[i].cost=m->cost;		if ( !(x[i].m=m->validate(NULL,&x[i].p, NULL, &x[i].cost)) ) {			detect_free_sig(x, i);			return 0;		}	}	return detect_add_sig(x, r->num_criteria+forceflow, &tcp_root, a);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -