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

📄 ip.c

📁 Firestorm NIDS是一个性能非常高的网络入侵检测系统 (NIDS)。目前
💻 C
字号:
#include "tcpip.h"/* Decode Stuff */struct proto ipv4_p=init_proto2("ip", ipv4_decode, ipv4_dprint, ip_match, ip_commit);struct proto_req ipv4_r[]={	proto_request("ethernet", __constant_htons(0x0800)),	proto_request("sll", __constant_htons(0x0800)),	proto_request("linux", __constant_htons(0x0800)),	proto_request("__pcap_dlt", 12), /* DLT_RAW */	null_request()};/* Token bucket for ip/ipfrag alerts */struct tokenbucket ip_tb={	.cost=(RATE_SEC/1), /* 1 alert per second */	.burst=(RATE_SEC/1)*10, /* a burst of 10 alerts per second */};/* Generator */struct generator ip_gen=init_generator("sig.ip", NULL);struct generator dip_gen=init_generator("decode.ip", &ip_tb);/* Print out an IPv4 header */int ipv4_dprint(struct layer *l, char *buf, int buflen){	struct in_addr s, d;	char sip[32], dip[32];	char end[32];	struct pkt_iphdr *iph=l->h.ip;	s.s_addr=iph->saddr;	d.s_addr=iph->daddr;	strncpy(sip, inet_ntoa(s), 32);	strncpy(dip, inet_ntoa(d), 32);	if ( iph->frag_off & htons(IP_MF|IP_OFFMASK) ) {		snprintf(end, sizeof(end), "(frag %u:%u@%u%s)",		ntohs(iph->id),		ntohs(iph->tot_len)-(iph->ihl<<2),		(ntohs(iph->frag_off)&IP_OFFMASK)<<3,		(ntohs(iph->frag_off)&IP_MF) ? "+" : "");	}else if ( l->flags & FLAG_IP_REASM ) {		snprintf(end, sizeof(end),			"(reasm %u:%u@0)",			ntohs(iph->id),			ntohs(iph->tot_len)-(iph->ihl<<2));	}else{		snprintf(end, sizeof(end),			"len=%u", ntohs(iph->tot_len));	}	return snprintf(buf, buflen,		"%s > %s ttl=%u proto=%u %s%s",		sip,dip,iph->ttl,iph->protocol,end,		(l->flags&FLAG_IP_CSUM) ? "" : " !!bad_csum!!");}static inline u_int32_t ip_csum(struct pkt_iphdr *iph){	u_int16_t *tmp=(u_int16_t *)iph;	u_int16_t csum;	u_int32_t sum=0;	int i;	for(i=0; i<iph->ihl<<1; i++) {		sum+=tmp[i];		if(sum & 0x80000000) {			sum = (sum & 0xffff) + (sum >> 16);		}	}	while(sum >> 16)		sum = (sum & 0xffff) + (sum >> 16);	csum=(~sum) & 0xffff;	return csum ? 0 : FLAG_IP_CSUM;}/* Decode an IPv4 packet */void ipv4_decode(struct packet *p){	struct proto_child *pc;	int my_layer=p->llen;	struct layer *l=&p->layer[my_layer];	int ks=0;	/* Check it meets minimum size of packet */	if ( l->h.raw+sizeof(struct pkt_iphdr) > p->end ) {		return;	}	/* Check to see if the whole datagram is here */	if ( l->h.raw+ntohs(l->h.ip->tot_len) > p->end ) {		l->flags|=FLAG_IP_DTRUNC;	}	/* Check the header length isn't bogus, encapsulated	 * protocols can't overlap the header! */	if ( l->h.ip->ihl<5 ) {		static struct alert a=init_alert(			"Invalid IP header length", 1, 0, 5);		alert(&dip_gen, p, &a);		return;	}	/* We only accept IPv4 */	if ( l->h.ip->version!=4 ) {		static struct alert a=init_alert(			"IP version != 4", 2, 0, 5);		alert(&dip_gen, p, &a);		return;	}	/* The total length can't be less than the header length. */	if ( ntohs(l->h.ip->tot_len) < (l->h.ip->ihl<<2) ) {		static struct alert a=init_alert(			"IP datagram reported smaller than header", 3, 0, 5);		alert(&dip_gen, p, &a);		return;	}	/* We don't really need to check the checksum because you	 * can't use bad IP header checksums to exploit anything, no	 * routers will actually pass them on. Though you could	 * generate attacks locally or it could be a genuine error.	 * either way, its only 20 bytes! :) */	l->flags|=ip_csum(l->h.ip);	/* Use the ihl header field to decode the packet */	if ( (p->layer[p->llen+1].h.raw=		l->h.raw+(l->h.ip->ihl<<2))		> p->end ) return;	/* We now know we have valid data */	p->llen++;	/* Perform IP de-fragmentation */	if ( use_ipfrag && (l->h.ip->frag_off & ipfmask) ) {		ks=ipfrag_process(p, my_layer);	}	/* Only decode fragments with offset 0, ie:	 * those containing the next header */	if ( l->h.ip->frag_off & __constant_htons(IP_OFFMASK) )		goto nodecode;	/* Don't decode too far */	if ( p->llen >= PKT_LAYERS )		goto finish;	/* Find a relevent protocol handler to	 * decode our encapsulated content */	for(pc=l->proto->children; pc; pc=pc->next)	{		if ( l->h.ip->protocol == pc->id ) {			p->layer[p->llen].flags=0;			p->layer[p->llen].session=NULL;			p->layer[p->llen].proto=pc->proto;			pc->proto->decode(p);			goto finish;		}	}nodecode:	if ( p->layer[p->llen].h.raw<p->end )		p->layer[p->llen++].proto=NULL;	dispatch(p);finish:	if ( ks ) ipq_kill(l->session);}/* =================================================== * PACKET MATCHING STUFF BEYOND THIS POINT * =================================================== */struct sig_node ip_root;void ip_match(struct packet *p, unsigned int l){	detect_set(&cur_alert, &alert_depth);	detect(ip_root.child, p, l);	if ( cur_alert ) {		alert(&ip_gen, p, cur_alert);		return;	}}int ip_commit(struct rule *r){	struct criteria *c;	struct sig_node *x;	struct matcher *m;	struct alert *a;	unsigned int i;	/* Can't handle this case */	if ( r->num_criteria==0 )		return 0;	if ( !(x=calloc(r->num_criteria, 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="ip_sport";		}else if ( !strcmp(c->crit, "dport") ) {			key="ip_dport";		}else key=c->crit;		if ( !(m=matcher_find(key)) ) {			mesg(M_ERR,"ip_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;		}	}	return detect_add_sig(x, r->num_criteria, &ip_root, a);}

⌨️ 快捷键说明

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