📄 spp_defrag.c
字号:
new_tree_node->left = t->left;
new_tree_node->right = t;
t->left = NULL;
t->size = 1+node_size(t->right);
}
else
{
new_tree_node->right = t->right;
new_tree_node->left = t;
t->right = NULL;
t->size = 1+node_size(t->left);
}
new_tree_node->key = i;
new_tree_node->size = 1 + node_size(new_tree_node->left) + node_size(new_tree_node->right);
return new_tree_node;
}
/* Function: Tree * fragdelete(frag i, Tree *t) */
/* Deletes i from the tree if it's there. */
/* Return a pointer to the resulting tree. */
Tree *fragdelete(frag i, Tree *t)
{
Tree * x;
int tsize;
if(!t) return NULL;
tsize = t->size;
t = fragsplay(i,t);
if(fragcompare(i, t->key) == 0)
{ /* found it */
if(!t->left)
{
x = t->right;
}
else
{
x = fragsplay(i, t->left);
x->right = t->right;
}
if(t->key != NULL)
{
#ifdef DEBUG
fprintf(stderr, "------------------------\n");
fprintf(stderr,"%p - p-struct Free\n", t->key);
fprintf(stderr, "------------------------\n");
fflush(stderr);
mem_freed += sizeof(Packet);
#endif
fragmemuse -= sizeof(Packet);
free(t->key);
}
#ifdef DEBUG
fprintf(stderr, "------------------------\n");
fprintf(stderr,"%p - Tree Free\n", t);
fprintf(stderr, "------------------------\n");
fflush(stderr);
mem_freed += sizeof(Tree);
#endif
fragmemuse -= sizeof(Tree);
free(t);
if(x)
{
x->size = tsize-1;
}
return x;
}
else
{
return t; /* It wasn't there */
}
}
/* Function: Tree *fragfind_rank(int r, Tree *t) */
/* Returns a pointer to the node in the tree with the given rank. */
/* Returns NULL if there is no such node. */
/* Does not change the tree. To guarantee logarithmic behavior, */
/* the node found here should be splayed to the root. */
Tree *fragfind_rank(int r, Tree *t)
{
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);
}
/* Function: treedump(t) */
/* dumps the tree in table form */
void treedump(Tree *t)
{
int loc;
Tree *temp;
fprintf(stdout,"Rank Ptr ID Lptr Rptr \n");
fprintf(stdout,"========================================== \n");
for(loc = 0; loc < node_size(t); loc++)
{
temp = fragfind_rank(loc, t);
fprintf(stdout,"%3d %p %d %p %p\n", loc, temp, ID(temp->key), temp->left, temp->right);
}
fflush(stdout);
}
/******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 */
{
#ifdef DEBUG
printf(" => sip1 = 0x%X, sip2 = 0x%X\n", SADDR(i), SADDR(j));
printf(" => dip1 = 0x%X, dip2 = 0x%X\n", DADDR(i), DADDR(j));
printf(" => id1 = %d, id2 = %d\n", ID(i), ID(j));
printf(" => proto1 = %d, proto2 = %d\n", PROTO(i), PROTO(j));
#endif
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 */
#ifdef DEBUG
printf("psize calculated to be %d bytes (last payload: %d)(last offset: %d)\n", psize, (froot->key)->dsize, FOFF(froot->key));
#endif
/* we've got to have a packet at least as large as an ICMP header */
if(psize < 4)
{
ErrorMessage("[!] ERROR: Defrag plugin is fucked up, calculated packet size too small\n");
}
/* 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;
/* Linux fix code */
if(overhead < sizeof(struct pcap_pkthdr) || overhead > sizeof( struct pcap_pkthdr) + 2)
{
overhead = sizeof(struct pcap_pkthdr) + 2;
}
#ifdef DEBUG
printf("Overhead = %d, struct size = %d\n", overhead, sizeof(struct pcap_pkthdr));
#endif
p = (Packet *)malloc(sizeof(Packet));
fragmemuse += sizeof(Packet);
#ifdef DEBUG
fprintf(stderr, "+++++++++++++++++++++++++\n");
fprintf(stderr, "%p + p-struct Alloc\n", p);
fprintf(stderr, "+++++++++++++++++++++++++\n");
fflush(stderr);
mem_locked += sizeof(Packet);
#endif
if(!p)
{
ErrorMessage("[!] ERROR: Unable to allocate memory for fragment rebuild!\n");
return NULL;
}
/* MFR: Why are we copying this header if we're in the reassembly phase?
* Why not use the original and modify its data in place?
*/
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 that 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);
fragmemuse += (psize + overhead + moreoverhead + sizeof(IPHdr) + 32);
#ifdef DEBUG
fprintf(stderr, "+++++++++++++++++++++++++\n");
fprintf(stderr, "%p + frankenpacket Alloc\n", p->pkth);
fprintf(stderr, "+++++++++++++++++++++++++\n");
fflush(stderr);
mem_locked += sizeof(psize+overhead+moreoverhead+sizeof(IPHdr)+32);
#endif
if(!p->pkth)
{
ErrorMessage("[!] ERROR: Unable to allocate memory for fragment rebuild!\n");
#ifdef DEBUG
fprintf(stderr, "------------------------\n");
fprintf(stderr, "%p - p-struct Free\n", p);
fprintf(stderr, "------------------------\n");
fflush(stderr);
mem_freed += sizeof(Packet);
#endif
fragmemuse -= sizeof(Packet);
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((unsigned short)psize);
p->iph->ip_off = 0;
p->frag_flag = 0;
fragrank = fragget_rank(froot);
#ifdef DEBUG
printf("fragrank = %d, froot = %p, fragaddrmatch = %d\n", fragrank, froot,
fragaddrmatch(p, froot->key));
#endif
while(fragrank > 0 && froot && fragaddrmatch(p,froot->key))
{
if(FOFF(froot->key) + froot->key->dsize <= psize)
{
#ifdef DEBUG
printf("Writing %d bytes from %p at %p\n", froot->key->dsize,
DATA(froot->key), (u_int8_t *) DATA(p)+FOFF(froot->key));
#endif
memcpy((u_int8_t *)DATA(p)+FOFF(froot->key), DATA(froot->key),
froot->key->dsize);
writecount += froot->key->dsize;
#ifdef DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -