📄 spp_frag3.c
字号:
/** * Handle IP Options in fragmented packets. * * @param ft Current frag tracker for this packet * @param p Current packet to check for options * @param context In case we get an anomaly * * @return status * @retval 0 on an error * @retval 1 on success */static int Frag3HandleIPOptions(FragTracker *ft, Packet *p){ unsigned int i = 0; /* counter */ if(p->frag_offset == 0) { /* * This is the first packet. If it has IP options, * save them off, so we can set them on the reassembled packet. */ if (p->ip_options_len) { ft->ip_options_len = p->ip_options_len; ft->ip_option_count = p->ip_option_count; ft->ip_options_data = SnortAlloc(p->ip_options_len); memcpy(ft->ip_options_data, p->ip_options_data, p->ip_options_len); } } else { /* check that options match those from other non-offset 0 packets */ /* XXX: could check each individual option here, but that * would be performance ugly. So, we'll just check that the * option counts match. Alert if invalid, but still include in * reassembly. */ if (ft->copied_ip_option_count) { if (ft->copied_ip_option_count != p->ip_option_count) { EventAnomIpOpts(ft->context); } } else { ft->copied_ip_option_count = p->ip_option_count; for (i = 0;i< p->ip_option_count && i < IP_OPTMAX; i++) { /* Is the high bit set? If not, weird anomaly. */ if (!(p->ip_options[i].code & 0x80)) EventAnomIpOpts(ft->context); } } } return 1;}/** * Didn't find a FragTracker in the hash table, create a new one and put it * into the f_cache * * @param p Current packet to fill in FragTracker fields * @param fkey FragKey struct to use for table insertion * * @return status * @retval 0 on an error * @retval 1 on success */static int Frag3NewTracker(Packet *p, FRAGKEY *fkey, Frag3Context *f3context){ FragTracker *tmp; Frag3Frag *f = NULL; //int ret = 0; char *fragStart; u_int16_t fragLength; u_int16_t frag_end; SFXHASH_NODE *hnode; fragStart = (u_int8_t *)p->iph + IP_HLEN(p->iph) * 4; /* Use the actual length here, because packet may have been * truncated. Don't want to try to copy more than we actually * captured. */ fragLength = p->actual_ip_len - IP_HLEN(p->iph) * 4;#ifdef DEBUG if (p->actual_ip_len != ntohs(p->iph->ip_len)) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "IP Actual Length (%d) != specified length (%d), " "truncated packet (%d)?\n", p->actual_ip_len, ntohs(p->iph->ip_len), snaplen);); }#endif /* Just to double check */ if (fragLength > snaplen) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Overly large fragment %d 0x%x 0x%x %d\n", fragLength, p->iph->ip_len, p->iph->ip_off, p->frag_offset << 3);); /* Ah, crap. Return that tracker. */ return 0; } /* Get a node from the hash table */ hnode = sfxhash_get_node(f_cache, fkey); if (!hnode) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Frag3NewTracker: sfxhash_get_node() failed\n");); return 0; } else { if (hnode->data) { tmp = hnode->data; memset(tmp, 0, sizeof(FragTracker)); } else { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Frag3NewTracker: sfxhash_get_node() failed\n");); return 0; } } /* * setup the frag tracker */ tmp->sip = fkey->sip; tmp->dip = fkey->dip; tmp->id = fkey->id; tmp->protocol = fkey->proto; tmp->ttl = p->iph->ip_ttl; /* store the first ttl we got */ tmp->calculated_size = 0; tmp->alerted = 0; tmp->frag_flags = 0; tmp->frag_bytes = 0; tmp->frag_pkts = 0; tmp->frag_time.tv_sec = p->pkth->ts.tv_sec; tmp->frag_time.tv_usec = p->pkth->ts.tv_usec; tmp->alert_count = 0; tmp->ip_options_len = 0; tmp->ip_option_count = 0; tmp->ip_options_data = NULL; tmp->copied_ip_options_len = 0; tmp->copied_ip_option_count = 0; tmp->context = f3context; tmp->ordinal = 0; /* * get our first fragment storage struct */ if(!global_config.use_prealloc) { if(mem_in_use > global_config.memcap) { if (Frag3Prune(tmp) == 0) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Frag3NewTracker: Pruning failed\n");); return 0; } } f = (Frag3Frag *) SnortAlloc(sizeof(Frag3Frag)); mem_in_use += sizeof(Frag3Frag); f->fptr = (u_int8_t *) SnortAlloc(fragLength); mem_in_use += fragLength; } else { while((f = Frag3PreallocPop()) == NULL) { if (Frag3Prune(tmp) == 0) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Frag3NewTracker: Pruning failed\n");); return 0; } } } f3stats.fragnodes_created++; sfPerf.sfBase.iFragCreates++; sfPerf.sfBase.iCurrentFrags++; if (sfPerf.sfBase.iCurrentFrags > sfPerf.sfBase.iMaxFrags) sfPerf.sfBase.iMaxFrags = sfPerf.sfBase.iCurrentFrags; /* initialize the fragment list */ tmp->fraglist = NULL; /* * setup the Frag3Frag struct with the current packet's data */ memcpy(f->fptr, fragStart, fragLength); f->size = f->flen = fragLength; f->offset = p->frag_offset << 3; frag_end = f->offset + fragLength; f->ord = tmp->ordinal++; f->data = f->fptr; /* ptr to adjusted start position */ if (!p->mf) { f->last = 1; } else { /* * all non-last frags are supposed to end on 8-byte boundries */ if(frag_end & 7) { /* * bonk/boink/jolt/etc attack... */ DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "[..] Short frag (Bonk, etc) attack!\n");); EventAnomShortFrag(f3context); /* don't return, might still be interesting... */ } /* can't have non-full fragments... */ frag_end &= ~7; /* Adjust len to take into account the jolting/non-full fragment. */ f->size = frag_end - f->offset; } /* insert the fragment into the frag list */ tmp->fraglist = f; tmp->fraglist_tail = f; tmp->fraglist_count = 1; /* XXX: Are these duplciates? */ tmp->frag_pkts = 1; /* * mark the FragTracker if this is the first/last frag */ Frag3CheckFirstLast(p, tmp); tmp->frag_bytes += fragLength; Frag3HandleIPOptions(tmp, p); DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "[#] accumulated bytes on FragTracker: %d\n", tmp->frag_bytes);); DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Initial fragment for tracker, ptr %p, offset %d, " "size %d\n", f, f->offset, f->size););#ifdef DEBUG_FRAG3 PrintFragKey(fkey);#endif DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Calling sfxhash(add), overhead at %lu\n", f_cache->overhead_bytes););#if 0 /* * insert the frag tracker into the fragment hash */ if((ret = sfxhash_add(f_cache, fkey, &tmp)) != SFXHASH_OK) { if(ret == SFXHASH_INTABLE) { LogMessage("Key collision in sfxhash!\n"); } DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Frag3NewTracker: sfxhash_add() failed\n");); return 0; }#endif f3stats.fragtrackers_created++; pc.frag_trackers++; p->fragtracker = (void *)tmp; return 1;}/** * Handle the creation of the new frag node and list insertion. * Separating this from actually calculating the values. * * @param ft FragTracker to hold the packet * @param fragStart Pointer to start of the packet data * @param fragLength Length of packet data * @param len Length of this fragment * @param slide Adjustment to make to left side of data (for left overlaps) * @param trunc Adjustment to maek to right side of data (for right overlaps) * @param frag_offset Offset for this fragment * @prarm left FragNode prior to this one * @param retFrag this one after its inserted (returned) * * @return status * @retval FRAG_INSERT_FAILED Memory problem, insertion failed * @retval FRAG_INSERT_OK All okay */static int AddFragNode(FragTracker *ft, Packet *p, Frag3Context *f3context, u_int8_t *fragStart, int16_t fragLength, char lastfrag, int16_t len, u_int16_t slide, u_int16_t trunc, u_int16_t frag_offset, Frag3Frag *left, Frag3Frag **retFrag){ Frag3Frag *newfrag = NULL; /* new frag container */ int16_t newSize = len - slide - trunc; if (newSize <= 0) { /* * zero size frag */ DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "zero size frag after left & right trimming " "(len: %d slide: %d trunc: %d)\n", len, slide, trunc);); f3stats.discards++;#ifdef DEBUG newfrag = ft->fraglist; while (newfrag) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Size: %d, offset: %d, len %d, " "Prev: 0x%x, Next: 0x%x, This: 0x%x, Ord: %d, %s\n", newfrag->size, newfrag->offset, newfrag->flen, newfrag->prev, newfrag->next, newfrag, newfrag->ord, newfrag->last ? "Last":"");); newfrag = newfrag->next; }#endif return FRAG_INSERT_ANOMALY; } /* * grab/generate a new frag node */ if(!global_config.use_prealloc) { if(mem_in_use > global_config.memcap) { if (Frag3Prune(ft) == 0) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Frag3Insert: Pruning failed\n");); return FRAG_INSERT_FAILED; } } /* * build a frag struct to track this particular fragment */ newfrag = (Frag3Frag *) SnortAlloc(sizeof(Frag3Frag)); mem_in_use += sizeof(Frag3Frag); /* * allocate some space to hold the actual data */ newfrag->fptr = (u_int8_t*)SnortAlloc(fragLength); mem_in_use += fragLength; } else { /* * fragments are preallocated, grab one from the list */ while((newfrag = Frag3PreallocPop()) == NULL) { if (Frag3Prune(ft) == 0) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Frag3Insert: Pruning failed\n");); return FRAG_INSERT_FAILED; } } DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "got newfrag (%p) from prealloc\n", newfrag);); } f3stats.fragnodes_created++; newfrag->flen = fragLength; memcpy(newfrag->fptr, fragStart, fragLength); newfrag->ord = ft->ordinal++; /* * twiddle the frag values for overlaps */ newfrag->da
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -