📄 spp_defrag.c
字号:
printf("reassembly writecount: %d\n", writecount);
#endif
}
else
{
#ifdef DEBUG
printf("Overflow attack in rebuild!\n");
#endif
/*(*AlertFunc)(p, "Fragmentation Overflow Attack");*/
CallAlertFuncs(p, "Fragmentation Overflow Attack", NULL);
}
/* clear the fragment store of the frag that was just put into the
* reassembly
*/
if(froot)
{
/*fragmemuse -= froot->key->pkth->caplen + sizeof(Packet);*/
np = (char *)froot->key->pkth; /* address for free later */
fragrank = fragget_rank(froot);
if(np)
{
#ifdef DEBUG
fprintf(stderr, "------------------------\n");
fprintf(stderr, "%p - packet Free\n", np);
fprintf(stderr, "------------------------\n");
fflush(stderr);
mem_freed += ((struct pcap_pkthdr *)np)->caplen + overhead + 20;
#endif
/* this fragment was an element of a rebuilt packet */
pc.rebuild_element++;
fragmemuse -= (((struct pcap_pkthdr *)np)->caplen + overhead + 20);
free(np);
}
froot = fragdelete(froot->key, froot);
}
}
memcpy(&slowarisfix, p->iph, sizeof(IPHdr));
p->iph = &slowarisfix;
/* and now some jolt2proofing */
if(psize > 8192) /* only kick in for monstergrams */
{
if((unsigned int)writecount > (psize>>1)) /*packets have to be half full for us to look at them */
{
if(p)
{
#ifdef DEBUG
printf("Fragmented packet rebuilt, processing...\n");
printf("BPF header (%d bytes):\n", overhead);
PrintNetData(stdout,(char *) p->pkth, overhead);
ClearDumpBuf();
printf("Packet dump (%d bytes):\n", p->pkth->caplen);
PrintNetData(stdout, (char *)p->pkt, p->pkth->caplen);
ClearDumpBuf();
#endif
/* keep stats for the packet counter struct -MFR */
pc.rebuilt_frags++; /* Marty... Huh?? --dr */
ProcessPacket(NULL,p->pkth, p->pkt);
}
}
else
{
/*(*AlertFunc)(p, "Mostly Empty Fragmented Packet Discarded!");*/
CallAlertFuncs(p, "Incomplete Packet Fragments Discarded", NULL);
}
}
else
{
if(p)
{
#ifdef DEBUG
printf("Fragmented packet rebuilt, processing...\n");
printf("BPF header (%d bytes):\n", overhead);
ClearDumpBuf();
PrintNetData(stdout,(char *) p->pkth, overhead);
ClearDumpBuf();
printf("Packet dump (%d bytes):\n", p->pkth->caplen);
PrintNetData(stdout,(char *) p->pkt, p->pkth->caplen);
ClearDumpBuf();
#endif
/* keep stats for the packet counter struct -MFR */
pc.rebuilt_frags++; /* Marty... Huh?? --dr */
ProcessPacket(NULL, p->pkth, p->pkt);
}
}
#ifdef DEBUG
fprintf(stderr, "------------------------\n");
fprintf(stderr, "%p - frankenpacket Free\n",(p->pkth));
fprintf(stderr, "%p - p-struct Free\n", p);
fprintf(stderr, "------------------------\n");
fflush(stderr);
treedump(froot);
mem_freed += psize+overhead+moreoverhead+sizeof(IPHdr)+32;
mem_freed += sizeof(Packet);
#endif
fragmemuse -= (psize+overhead+moreoverhead+sizeof(IPHdr)+32+sizeof(Packet));
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 *packet_copy;
time_struct timecheck;
Tree *found;
struct pcap_pkthdr *freetemp;
int overhead;
int cap;
u_char *tmp;
#ifdef DEBUG
printf("fragments =>\n");
printf(" mem used: %u\n", mem_locked);
printf(" mem freed: %u\n", mem_freed);
printf(" fragmemuse: %u\n", fragmemuse);
#endif
if(!p || !p->pkth || !p->pkt)
{
if(pv.verbose_flag)
{
ErrorMessage("%s\n","Garbage Packet with Null Pointer discarded!");
}
return;
}
/* check to make sure the IP header exists and that
* there isn't a bad IP checksum
*/
if(!p->iph || (p->csum_flags & CSE_IP))
{
return;
}
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;
packet_copy = malloc(sizeof(Packet));
fragmemuse += sizeof(Packet);
#ifdef DEBUG
fprintf(stderr, "++++++++++++++++++++++++\n");
fprintf(stderr, "%p + p-struct Alloc (%d bytes) ", packet_copy, sizeof(Packet));
fflush(stderr);
mem_locked += sizeof(Packet);
#endif
if(!packet_copy)
{
ErrorMessage("[!] ERROR: Cannot allocate fragment buffer(usage 0x%X)\n",fragmemuse);
return;
}
/* cleared by MFR, accounted for below */
/*fragmemuse += sizeof(Packet);*/
memcpy(packet_copy, p, sizeof(Packet));
cap = p->pkth->caplen + overhead;
tmp = calloc(cap + 20, sizeof(char));
fragmemuse += (cap + 20);
packet_copy->pkth = (struct pcap_pkthdr *) tmp;
#ifdef DEBUG
fprintf(stderr, " && %p + packet Alloc\n", packet_copy->pkth);
fprintf(stderr, "++++++++++++++++++++++++\n");
fflush(stderr);
mem_locked += cap+20;
#endif
if(!packet_copy->pkth)
{
ErrorMessage("[!] ERROR: Cannot allocate fragment buffer(usage %X)\n",fragmemuse);
return;
}
packet_copy->pkt = (u_char*)packet_copy->pkth + overhead;
packet_copy->iph = (IPHdr*)((u_char*)packet_copy->pkt + ((u_char*)p->iph - (u_char*)p->pkt));
/* cleared by MFR, accounted for below */
/*fragmemuse += p->pkth->caplen + overhead;*/
last_frag_time.tv_sec = p->pkth->ts.tv_sec;
last_frag_time.tv_usec = p->pkth->ts.tv_usec;
/* we do this with two memcopies to cope with Linux non-contiguous bpf headers */
memcpy(packet_copy->pkth, p->pkth, overhead);
memcpy(packet_copy->pkt, p->pkt, p->pkth->caplen);
froot = fraginsert(packet_copy, 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.))
{
#ifdef DEBUGg
fprintf(stderr, "Generic timeout cleanup in progress...\n");
#endif
/* cleared by MFR */
/*fragmemuse -= froot->key->pkth->caplen + sizeof(Packet);*/
freetemp = froot->key->pkth;
#ifdef DEBUG
fprintf(stderr, "------------------------\n");
fprintf(stderr, "%p - packet Free\n", freetemp);
fprintf(stderr, "------------------------\n");
fflush(stderr);
mem_freed += freetemp->caplen + overhead + 20;
#endif
fragmemuse -= freetemp->caplen + overhead + 20;
free(freetemp);
froot = fragdelete(froot->key, froot);
fragsweep--;
pc.frag_timeout++;
}
}
/* 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. ))
{
#ifdef DEBUG
fprintf(stderr, "Frag memory overcommitted, cleanup in progress...\n");
#endif
/*fragmemuse -= froot->key->pkth->caplen + sizeof(Packet);*/
freetemp = froot->key->pkth;
#ifdef DEBUG
fprintf(stderr, "------------------------\n");
fprintf(stderr, "%p - packet Free\n", freetemp);
fprintf(stderr, "------------------------\n");
fflush(stderr);
mem_freed += freetemp->caplen + overhead + 20;
#endif
fragmemuse -= freetemp->caplen + overhead + 20;
free(freetemp);
froot = fragdelete(froot->key, froot);
fragsweep--;
pc.frag_incomp++;
}
}
}
}
}
/* check to see if we've gotten any frags in the last n seconds
* and if we haven't, start clearing out old data
*
* this works best with a realistic timeout value...
*/
if(froot)
{
/* add the timeout value to the last fragment time */
addtime(&last_frag_time, &fragtimeout, &timecheck);
/* check the global timeout vs. the latest packet's timestamp */
if(TIME_LT(timecheck. , p->pkth->ts. ))
{
#ifdef DEBUG
fprintf(stderr, "Packets have timedout, cleaning [%d, %d]...\n", fragsweep, node_size(froot));
#endif
if(++fragsweep > node_size(froot))
{
fragsweep = 1;
}
found = fragfind_rank(fragsweep,froot);
if(found)
{
/* is it really necessary to calculate this for every packet?
* can't we just calculate it at init time?
*/
overhead = (char*)p->pkt - (char*)p->pkth;
/* Linux fix code */
if(overhead < 1 || overhead > sizeof(struct pcap_pkthdr) + 2)
{
overhead = sizeof(struct pcap_pkthdr) + 2;
}
froot = fragsplay(found->key, froot);
/* cleared by MFR */
/*fragmemuse -= froot->key->pkth->caplen + sizeof(Packet);*/
freetemp = froot->key->pkth;
#ifdef DEBUG
fprintf(stderr, "------------------------\n");
fprintf(stderr, "%p - packet Free\n", freetemp);
fprintf(stderr, "------------------------\n");
fflush(stderr);
mem_freed += freetemp->caplen + overhead + 20;
treedump(froot);
#endif
fragmemuse -= freetemp->caplen + overhead + 20;
free(freetemp);
froot = fragdelete(froot->key, froot);
fragsweep--;
pc.frag_timeout++;
}
#ifdef DEBUG
else
{
fprintf(stderr, "Nothing found to clean...\n");
}
#endif
}
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -