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

📄 spp_defrag.c

📁 该软件是一个有名的基于网络的入侵检测系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    int lsize;
    if ((r < 0) || (r >= node_size(t))) return NULL;
    for (; t != 0 ;) {
	lsize = node_size(t->left);
	if (r < lsize) {
	    t = t->left;
	} else if (r > lsize) {
	    r = r - lsize -1;
	    t = t->right;
	} else {
	    return t;
	}
    }
    return NULL;
}

/* Function: fragget_rank(t)					   */
/* returns the rank of a tree element				   */

int fragget_rank(Tree *t) {
	if(!t)
		return(0);
	return(node_size(t->left)+1);
}




/******Snort Stuff******/

/*
 * Function: SetupDefrag()
 * Purpose:
 * Registers the preprocessor keyword and initialization function
 * into the preprocessor list.  This is the function that gets called from
 * InitPreprocessors() in plugbase.c.
 * Arguments: None.
 * Returns: void function
 */
void SetupDefrag()
{
	RegisterPreprocessor("defrag", DefragInit);
}

/*
 * Function: DefragInit(u_char *)
 * Purpose:
 * Calls the argument parsing function, performs final setup on data
 * structs, links the preproc function into the function list.
 * Arguments: args => ptr to argument string
 * Returns: void function
 */
void DefragInit(u_char *args)
{
	AddFuncToPreprocList(PreprocDefrag);

	froot = NULL;  /* initialize empty fragment tree */
	fragmemuse = 0;	/* No memory yet */
	fragtimeout.tv_sec = FRAGTIMEOUTSEC;
	fragtimeout.tv_usec = FRAGTIMEOUTUSEC;
	fragsweep = 0;
}



/******Fragmentation Stuff******/

/* Function: fragaddrmatch(i,j) 				*/
/* returns true if the fragments belong to the same reassembly	*/

int fragaddrmatch(i,j)
frag i,j;
/* This is the comparison.                                   */
/* Returns 1 if i j have matching addresses else 0           */
{

	if(( SADDR(i) == SADDR(j) )
                && ( DADDR(i) == DADDR(j) )
                && ( ID(i) == ID(j) )
                && ( PROTO(i) == PROTO(j) ))

                return (1);
        return (0);
}
 
/*
 * Function: Packet *ReassembleIP(frag *froot)
 * Purpose: Generate a Packet * and pass it to ProcessPacket, then deallocate packet
 * Arguments: froot - root of the tree containing the last packet of the frame
 * Returns: tree with reassembled fragments deleted
 */
Tree *ReassembleIP(Tree *froot)
{
	Packet *p;
	int writecount = 0;
	char *np;
        u_char *tmp;
	u_int psize;
	int fragrank;
	unsigned int overhead, moreoverhead;
	IPHdr slowarisfix;

	psize = (froot->key)->dsize + FOFF(froot->key); /* last frag is at top of tree */
	/* hopefully moreoverhead here finds out about all the wierd MAC sizes like FDDI and ATM */
	moreoverhead = (char*)froot->key->iph - (char*)froot->key->pkt;
	overhead = (char*)froot->key->pkt - (char*)froot->key->pkth; /* +4 mystery points */
	/* Linux fix code */
	if(overhead < 1 || overhead > sizeof( struct pcap_pkthdr) + 2)
		overhead = sizeof(struct pcap_pkthdr) + 2;
 
	p = (Packet *)malloc(sizeof(Packet));
	if (!p)
		return NULL;
        memcpy(p, froot->key, sizeof(Packet));

	/* SEMI BOGUS - setting up ethernet time header - required by one of the
	 * decode routines - we set the timestamp equal to froot (last fragment)
	 * note also thet our bogus reassembledgrams may not have the bpf header
	 * contiguous and datagram access through this pointer is suspect. Been warned.
	 */

	p->pkth = (struct pcap_pkthdr *)malloc(psize + overhead + moreoverhead + sizeof(IPHdr) + 32);
	if(!p->pkth)
	{
		free(p);
		return NULL;
	}

	p->iph = (IPHdr *)((u_char*)p->pkth + overhead + moreoverhead);
	p->pkt = (u_char*)p->iph - moreoverhead;

	/*
	 * Now copy the header and fragments into the newly-allocated buffer,
	 * reconstructing the packet chunk by chunk. Current algorithm is first 
	 * write to an area wins, play with splay order to change.
	 * we start from the last fragment and work back....
	 */

	/* fill in packet header bpf header first*/
	memcpy(p->pkth, froot->key->pkth, overhead); 

	/* then the mac junk, split into two copies for Linux non-contiguous headers */
	memcpy((char*)p->pkth + overhead, froot->key->pkt, moreoverhead); 

	/*
	 * then the IP header just to be paranoid for debugging because in the
         * real world we would do these in one copy
 	 */
        tmp = (u_char *) froot->key->iph;
	memcpy(p->iph, tmp, sizeof(IPHdr)); 
  
	p->pkth->caplen = psize + overhead + moreoverhead + sizeof(IPHdr);
	p->pkth->len = p->pkth->caplen;

	/*
	 * Clear the more fragments bit, and set the length in the ip header
	 * (in network byte order).
	 */
	p->iph->ip_len = htons(psize);
	p->iph->ip_off = 0;
        p->frag_flag = 0;

	fragrank = fragget_rank(froot);
	while(fragrank > 0 && froot && fragaddrmatch(p,froot->key))
	{
		if(FOFF(froot->key) + froot->key->dsize <= psize)
		{

			memcpy((char*)DATA(p)+FOFF(froot->key), DATA(froot->key), froot->key->dsize);
			writecount += froot->key->dsize;

		} else
			(*AlertFunc)(p, "Fragmentation Overflow Attack");

		if(froot)
		{
			fragmemuse -= froot->key->pkth->caplen + sizeof(Packet);
			np = (char *)froot->key->pkth;  /* address for free later */
			fragrank = fragget_rank(froot);
			froot = fragdelete(froot->key, froot);
			if(np)
				free(np);
		}
	}

	memcpy(&slowarisfix, p->iph, sizeof(IPHdr));
	p->iph = &slowarisfix; 

	/* and now some jolt2proofing */
	if(psize > 8192)  /* only kick in for monstergrams */
	{
		if(writecount > psize/2)	/*packets have to be half full for us to look at them */
		{	
			if(p)
				ProcessPacket(NULL, p->pkth, p->pkt);
		} else {
			(*AlertFunc)(p, "Mostly Empty Fragmented Packet Discarded!");
		}
	} else {
		if(p)
			ProcessPacket(NULL, p->pkth, p->pkt);
	}
	
	free(p->pkth);	/* set the frankensteingram free.... */
	free(p);
	return(froot);
}

/*
 * Function: PreprocDefrag(Packet *)
 * Purpose:
 * Driver function for the IP defragmentation preprocessor.
 * Arguments: p => pointer to the current packet data struct
 * Returns: void function
 */
void PreprocDefrag(Packet *p)
{
        Packet *new;
	time_struct timecheck;
	Tree *found;
	frag freetemp;
	int overhead;
        int cap;
        u_char *tmp;

	if(!p || !p->pkth || !p->pkt)
	{
		ErrorMessage("%s\n","Garbage Packet with Null Pointer discarded!");
		return;
	}
	if(!p->iph)
		return;	/* return quietly for arps and such with no ip headers */
	if(p->frag_flag)
	{  /* heads up, live fragments inbound  */
		overhead = (char*)p->pkt - (char*)p->pkth; /* +4 mystery points */
		/* Linux fix code */
		if( overhead < 1 || overhead > sizeof(struct pcap_pkthdr) + 2)
			overhead = sizeof(struct pcap_pkthdr) + 2;

		new = malloc(sizeof(Packet));
		if(!new)
		{
			ErrorMessage("Cannot allocate fragment buffer(usage 0x%X)\n",fragmemuse);
			return;
		}
		fragmemuse += sizeof(Packet);

		memcpy(new, p, sizeof(Packet));
		cap = p->pkth->caplen + overhead;
		tmp = calloc(cap + 20, sizeof(char));
                new->pkth = (struct pcap_pkthdr *) tmp;
		if(!new->pkth)
		{
			ErrorMessage("Cannot allocate fragment buffer(usage %X)\n",fragmemuse);
			return;
		}

		new->pkt = (u_char*)new->pkth + overhead;
		new->iph = (IPHdr*)((u_char*)new->pkt + ((u_char*)p->iph - (u_char*)p->pkt));
  
		fragmemuse += p->pkth->caplen + overhead;
		/* we do this with two memcopies to cope with Linux non-contiguous bpf headers */
		memcpy(new->pkth, p->pkth, overhead);
		memcpy(new->pkt, p->pkt, p->pkth->caplen);
		froot = fraginsert(new, froot); 

		/* now check if we have to reassemble anything... */
		if(!MF(p))
			froot = ReassembleIP(froot);

		/* OK now check for a fragment timeout - sweeping the clutter away :-) */
		if(froot)
		{
			if(++fragsweep > node_size(froot)+1)
				fragsweep = 1;
			found = fragfind_rank(fragsweep,froot);
			if(found)
			{
				froot = fragsplay(found->key, froot);
	                        addtime((time_struct *)&(froot->key->pkth->ts), &fragtimeout, &timecheck);
                                if(TIME_LT(timecheck. , p->pkth->ts.))
                                {
					fragmemuse -= froot->key->pkth->caplen + sizeof(Packet);
					freetemp = froot->key;
					froot = fragdelete(froot->key, froot);
					free(freetemp->pkth);  /* free packet copy */
					free(freetemp);
					fragsweep--;
				}
			}

			/* and now do the whole thing again if we are being a memory hog */
			if(froot && fragmemuse > FASTSWEEPLIM)
			{
				if(++fragsweep > node_size(froot))
					fragsweep = 1;
				found = fragfind_rank(fragsweep,froot);
				if(found)
				{
					froot = fragsplay(found->key, froot);
					addtime((time_struct *)&(froot->key->pkth->ts), &fragtimeout, &timecheck);
					if(TIME_LT(timecheck. , p->pkth->ts. ))
					{
						fragmemuse -= froot->key->pkth->caplen + sizeof(Packet);
						freetemp = froot->key;
						froot = fragdelete(froot->key, froot);
						free(freetemp->pkth);  /* free packet copy */
						free(freetemp);
						fragsweep--;
					}
				}
			}
		}
	}
	return;
}


⌨️ 快捷键说明

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