📄 spp_defrag.c
字号:
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 + -