inline #endif int pcapProcess(pcap_pkthdr** header, u_char** packet, bool *destroy, bool enableDefrag, bool enableCalcMD5, bool enableDedup, bool enableDump, pcapProcessData *ppd, int pcapLinklayerHeaderType, pcap_dumper_t *pcapDumpHandle, const char *interfaceName) { if(destroy) { *destroy = false; } if(!parseEtherHeader(pcapLinklayerHeaderType, *packet, ppd->header_sll, ppd->header_eth, ppd->header_ip_offset, ppd->protocol)) { syslog(LOG_ERR, "BAD DATALINK %s: datalink number [%d] is not supported", interfaceName ? interfaceName : "---", pcapLinklayerHeaderType); return(0); } if(ppd->protocol != ETHERTYPE_IP) { #if TCPREPLAY_WORKARROUND if(ppd->protocol == 0) { ppd->header_ip_offset += 2; ppd->protocol = ETHERTYPE_IP; } else #endif { if(interfaceName && !strcmp(interfaceName, "lo")) { syslog(LOG_ERR, "BAD PROTOCOL (not ipv4) IN %s (dlt %d) - TRY TCPREPLAY_WORKARROUND", interfaceName, pcapLinklayerHeaderType); } return(0); } } ppd->header_ip = (iphdr2*)(*packet + ppd->header_ip_offset); extern BogusDumper *bogusDumper; static u_long lastTimeLogErrBadIpHeader = 0; if(ppd->header_ip->version != 4) { if(interfaceName) { if(bogusDumper) { bogusDumper->dump(*header, *packet, pcapLinklayerHeaderType, interfaceName); } u_long actTime = getTimeMS(*header); if(actTime - 1000 > lastTimeLogErrBadIpHeader) { syslog(LOG_ERR, "BAD HEADER_IP: %s: bogus ip header version %i", interfaceName, ppd->header_ip->version); lastTimeLogErrBadIpHeader = actTime; } } return(0); } if(htons(ppd->header_ip->tot_len) + ppd->header_ip_offset > (*header)->len) { if(interfaceName) { if(bogusDumper) { bogusDumper->dump(*header, *packet, pcapLinklayerHeaderType, interfaceName); } u_long actTime = getTimeMS(*header); if(actTime - 1000 > lastTimeLogErrBadIpHeader) { syslog(LOG_ERR, "BAD HEADER_IP: %s: bogus ip header length %i, len %i", interfaceName, htons(ppd->header_ip->tot_len), (*header)->len); lastTimeLogErrBadIpHeader = actTime; } } return(0); } if(enableDefrag) { //if UDP defrag is enabled process only UDP packets and only SIP packets if(opt_udpfrag && (ppd->header_ip->protocol == IPPROTO_UDP || ppd->header_ip->protocol == 4)) { int foffset = ntohs(ppd->header_ip->frag_off); if ((foffset & IP_MF) || ((foffset & IP_OFFSET) > 0)) { if(htons(ppd->header_ip->tot_len) + ppd->header_ip_offset > (*header)->caplen) { if(interfaceName) { if(bogusDumper) { bogusDumper->dump(*header, *packet, pcapLinklayerHeaderType, interfaceName); } u_long actTime = getTimeMS(*header); if(actTime - 1000 > lastTimeLogErrBadIpHeader) { syslog(LOG_ERR, "BAD FRAGMENTED HEADER_IP: %s: bogus ip header length %i, caplen %i", interfaceName, htons(ppd->header_ip->tot_len), (*header)->caplen); lastTimeLogErrBadIpHeader = actTime; } } //cout << "pcapProcess exit 001" << endl; return(0); } // packet is fragmented if(handle_defrag(ppd->header_ip, header, packet, 0, &ppd->ipfrag_data)) { // packets are reassembled //cout << "*** packets are reassembled in pcapProcess" << endl; ppd->header_ip = (iphdr2*)(*packet + ppd->header_ip_offset); *destroy = true; } else { //cout << "pcapProcess exit 002" << endl; return(0); } } } } bool nextPass; do { nextPass = false; if(ppd->header_ip->protocol == IPPROTO_IPIP) { // ip in ip protocol ppd->header_ip = (iphdr2*)((char*)ppd->header_ip + sizeof(iphdr2)); if(enableDefrag) { //if UDP defrag is enabled process only UDP packets and only SIP packets if(opt_udpfrag && ppd->header_ip->protocol == IPPROTO_UDP) { int foffset = ntohs(ppd->header_ip->frag_off); if ((foffset & IP_MF) || ((foffset & IP_OFFSET) > 0)) { // packet is fragmented pcap_pkthdr* header_old = *header; u_char* packet_old = *packet; if(handle_defrag(ppd->header_ip, header, packet, 0, &ppd->ipfrag_data)) { // packet was returned iphdr2 *header_ip_1 = (iphdr2*)(*packet + ppd->header_ip_offset); // turn off frag flag in the first IP header header_ip_1->frag_off = 0; // turn off frag flag in the second IP header ppd->header_ip = (iphdr2*)((char*)header_ip_1 + sizeof(iphdr2)); ppd->header_ip->frag_off = 0; // update lenght of the first ip header to the len of the second IP header since it can be changed due to reassemble header_ip_1->tot_len = htons((ntohs(ppd->header_ip->tot_len)) + sizeof(iphdr2)); if(*destroy) { delete header_old; delete [] packet_old; } *destroy = true; } else { //cout << "pcapProcess exit 003" << endl; return(0); } } } } } else if(ppd->header_ip->protocol == IPPROTO_GRE) { // gre protocol iphdr2 *header_ip = convertHeaderIP_GRE(ppd->header_ip); if(header_ip) { ppd->header_ip = header_ip; ppd->header_ip_offset = (u_char*)header_ip - *packet; nextPass = true; } else { if(opt_ipaccount == 0) { //cout << "pcapProcess exit 004" << endl; return(0); } } } } while(nextPass); if(enableDefrag) { // if IP defrag is enabled, run each 10 seconds cleaning if(opt_udpfrag && (ppd->ipfrag_lastprune + 10) < (*header)->ts.tv_sec) { ipfrag_prune((*header)->ts.tv_sec, 0, &ppd->ipfrag_data); ppd->ipfrag_lastprune = (*header)->ts.tv_sec; //TODO it would be good to still pass fragmented packets even it does not contain the last semant, the ipgrad_prune just wipes all unfinished frags } } bool enableReturnZeroInCheckData = !opt_udpfrag || enableDefrag || enableCalcMD5 || enableDedup || enableDump; ppd->header_udp = &ppd->header_udp_tmp; if (ppd->header_ip->protocol == IPPROTO_UDP) { // prepare packet pointers ppd->header_udp = (udphdr2*) ((char*) ppd->header_ip + sizeof(*ppd->header_ip)); ppd->data = (char*) ppd->header_udp + sizeof(*ppd->header_udp); ppd->datalen = (int)((*header)->caplen - ((unsigned long) ppd->data - (unsigned long) *packet)); ppd->traillen = (int)((*header)->caplen - ((unsigned long) ppd->header_ip - (unsigned long) *packet)) - ntohs(ppd->header_ip->tot_len); ppd->istcp = 0; } else if (ppd->header_ip->protocol == IPPROTO_TCP) { ppd->istcp = 1; // prepare packet pointers ppd->header_tcp = (tcphdr2*) ((char*) ppd->header_ip + sizeof(*ppd->header_ip)); ppd->data = (char*) ppd->header_tcp + (ppd->header_tcp->doff * 4); ppd->datalen = (int)((*header)->caplen - ((unsigned long) ppd->data - (unsigned long) *packet)); if (!(sipportmatrix[htons(ppd->header_tcp->source)] || sipportmatrix[htons(ppd->header_tcp->dest)]) && !(opt_enable_http && (httpportmatrix[htons(ppd->header_tcp->source)] || httpportmatrix[htons(ppd->header_tcp->dest)]) && (tcpReassemblyHttp->check_ip(htonl(ppd->header_ip->saddr)) || tcpReassemblyHttp->check_ip(htonl(ppd->header_ip->daddr)))) && !(opt_enable_webrtc && (webrtcportmatrix[htons(ppd->header_tcp->source)] || webrtcportmatrix[htons(ppd->header_tcp->dest)]) && (tcpReassemblyWebrtc->check_ip(htonl(ppd->header_ip->saddr)) || tcpReassemblyWebrtc->check_ip(htonl(ppd->header_ip->daddr)))) && !(opt_enable_ssl && (isSslIpPort(htonl(ppd->header_ip->saddr), htons(ppd->header_tcp->source)) || isSslIpPort(htonl(ppd->header_ip->daddr), htons(ppd->header_tcp->dest)))) && !(opt_skinny && (htons(ppd->header_tcp->source) == 2000 || htons(ppd->header_tcp->dest) == 2000))) { // not interested in TCP packet other than SIP port if(opt_ipaccount == 0 && !DEBUG_ALL_PACKETS && enableReturnZeroInCheckData) { //cout << "pcapProcess exit 005" << endl; return(0); } } ppd->header_udp->source = ppd->header_tcp->source; ppd->header_udp->dest = ppd->header_tcp->dest; } else { //packet is not UDP and is not TCP, we are not interested, go to the next packet (but if ipaccount is enabled, do not skip IP ppd->datalen = 0; if(opt_ipaccount == 0 && !DEBUG_ALL_PACKETS && enableReturnZeroInCheckData) { //cout << "pcapProcess exit 006 / protocol: " << (int)ppd->header_ip->protocol << endl; return(0); } } if(ppd->datalen < 0 && enableReturnZeroInCheckData) { //cout << "pcapProcess exit 007" << endl; return(0); } if(enableCalcMD5 || enableDedup) { /* check for duplicate packets (md5 is expensive operation - enable only if you really need it */ if(ppd->datalen > 0 && opt_dup_check && ppd->prevmd5s != NULL && (ppd->traillen < ppd->datalen) && !(ppd->istcp && opt_enable_http && (httpportmatrix[htons(ppd->header_tcp->source)] || httpportmatrix[htons(ppd->header_tcp->dest)])) && !(ppd->istcp && opt_enable_webrtc && (webrtcportmatrix[htons(ppd->header_tcp->source)] || webrtcportmatrix[htons(ppd->header_tcp->dest)])) && !(ppd->istcp && opt_enable_ssl && (isSslIpPort(htonl(ppd->header_ip->saddr), htons(ppd->header_tcp->source)) || isSslIpPort(htonl(ppd->header_ip->daddr), htons(ppd->header_tcp->dest))))) { if(enableCalcMD5) { MD5_Init(&ppd->ctx); if(opt_dup_check_ipheader) { // check duplicates based on full ip header and data MD5_Update(&ppd->ctx, ppd->header_ip, MIN(ppd->datalen - ((char*)ppd->header_ip - ppd->data), ntohs(ppd->header_ip->tot_len))); } else { // check duplicates based only on data (without ip header and without UDP/TCP header). Duplicate packets // will be matched regardless on IP MD5_Update(&ppd->ctx, ppd->data, MAX(0, (unsigned long)ppd->datalen - ppd->traillen)); } MD5_Final((unsigned char*)ppd->md5, &ppd->ctx); } if(enableDedup && ppd->md5[0]) { if(memcmp(ppd->md5, ppd->prevmd5s + (*ppd->md5 * MD5_DIGEST_LENGTH), MD5_DIGEST_LENGTH) == 0) { //printf("dropping duplicate md5[%s]\n", md5); duplicate_counter++; return(0); } memcpy(ppd->prevmd5s+(*ppd->md5 * MD5_DIGEST_LENGTH), ppd->md5, MD5_DIGEST_LENGTH); } } } if(enableDump) { if(pcapDumpHandle) { pcap_dump((u_char*)pcapDumpHandle, *header, *packet); } } return(1); }
inline #endif int pcapProcess(sHeaderPacket **header_packet, int pushToStack_queue_index, pcap_block_store *block_store, int block_store_index, int ppf, pcapProcessData *ppd, int pcapLinklayerHeaderType, pcap_dumper_t *pcapDumpHandle, const char *interfaceName) { pcap_pkthdr_plus2 *pcap_header_plus2 = NULL; u_char *packet = NULL; if(header_packet) { if((*header_packet)->detect_headers & 0x01) { ppd->header_ip_offset = (*header_packet)->header_ip_first_offset; ppd->protocol = (*header_packet)->eth_protocol; ppd->header_ip = (iphdr2*)(HPP(*header_packet) + ppd->header_ip_offset); } else if(parseEtherHeader(pcapLinklayerHeaderType, HPP(*header_packet), ppd->header_sll, ppd->header_eth, ppd->header_ip_offset, ppd->protocol)) { (*header_packet)->detect_headers |= 0x01; (*header_packet)->header_ip_first_offset = ppd->header_ip_offset; (*header_packet)->eth_protocol = ppd->protocol; if(ppd->protocol != ETHERTYPE_IP) { if(sverb.tcpreplay) { if(ppd->protocol == 0) { ppd->header_ip_offset += 2; ppd->protocol = ETHERTYPE_IP; } else { return(0); } } else { pcapProcessEvalError(bad_eth_protocol, *HPH(*header_packet), HPP(*header_packet), ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName); return(0); } } ppd->header_ip = (iphdr2*)(HPP(*header_packet) + ppd->header_ip_offset); if(ppd->header_ip->version != 4) { pcapProcessEvalError(bad_ip_version, *HPH(*header_packet), HPP(*header_packet), ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName); return(0); } if(htons(ppd->header_ip->tot_len) + ppd->header_ip_offset > HPH(*header_packet)->len) { pcapProcessEvalError(bad_ip_length, *HPH(*header_packet), HPP(*header_packet), ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName); return(0); } } else { pcapProcessEvalError(bad_datalink, *HPH(*header_packet), HPP(*header_packet), ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName); return(0); } } else { pcap_header_plus2 = (pcap_pkthdr_plus2*)block_store->get_header(block_store_index); packet = block_store->get_packet(block_store_index); if(pcap_header_plus2->detect_headers & 0x01) { ppd->header_ip_offset = pcap_header_plus2->header_ip_first_offset; ppd->protocol = pcap_header_plus2->eth_protocol; ppd->header_ip = (iphdr2*)(packet + ppd->header_ip_offset); } else if(parseEtherHeader(pcapLinklayerHeaderType, packet, ppd->header_sll, ppd->header_eth, ppd->header_ip_offset, ppd->protocol)) { pcap_header_plus2->detect_headers |= 0x01; pcap_header_plus2->header_ip_first_offset = ppd->header_ip_offset; pcap_header_plus2->eth_protocol = ppd->protocol; if(ppd->protocol != ETHERTYPE_IP) { if(sverb.tcpreplay) { if(ppd->protocol == 0) { ppd->header_ip_offset += 2; ppd->protocol = ETHERTYPE_IP; } else { pcap_header_plus2->ignore = true; return(0); } } else { pcapProcessEvalError(bad_eth_protocol, pcap_header_plus2, packet, ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName); pcap_header_plus2->ignore = true; return(0); } } ppd->header_ip = (iphdr2*)(packet + ppd->header_ip_offset); if(ppd->header_ip->version != 4) { pcapProcessEvalError(bad_ip_version, pcap_header_plus2, packet, ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName); pcap_header_plus2->ignore = true; return(0); } if(htons(ppd->header_ip->tot_len) + ppd->header_ip_offset > pcap_header_plus2->get_len()) { pcapProcessEvalError(bad_ip_length, pcap_header_plus2, packet, ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName); pcap_header_plus2->ignore = true; return(0); } } else { pcapProcessEvalError(bad_datalink, pcap_header_plus2, packet, ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName); pcap_header_plus2->ignore = true; return(0); } } if(ppf & ppf_defrag) { //if UDP defrag is enabled process only UDP packets and only SIP packets if(opt_udpfrag) { int foffset = ntohs(ppd->header_ip->frag_off); if ((foffset & IP_MF) || ((foffset & IP_OFFSET) > 0)) { if(htons(ppd->header_ip->tot_len) + ppd->header_ip_offset > HPH(*header_packet)->caplen) { if(interfaceName) { extern BogusDumper *bogusDumper; static u_long lastTimeLogErrBadIpHeader = 0; if(bogusDumper) { bogusDumper->dump(HPH(*header_packet), HPP(*header_packet), pcapLinklayerHeaderType, interfaceName); } u_long actTime = getTimeMS(HPH(*header_packet)); if(actTime - 1000 > lastTimeLogErrBadIpHeader) { syslog(LOG_ERR, "BAD FRAGMENTED HEADER_IP: %s: bogus ip header length %i, caplen %i", interfaceName, htons(ppd->header_ip->tot_len), HPH(*header_packet)->caplen); lastTimeLogErrBadIpHeader = actTime; } } //cout << "pcapProcess exit 001" << endl; return(0); } // packet is fragmented if(handle_defrag(ppd->header_ip, header_packet, &ppd->ipfrag_data, pushToStack_queue_index) > 0) { // packets are reassembled ppd->header_ip = (iphdr2*)(HPP(*header_packet) + ppd->header_ip_offset); if(sverb.defrag) { defrag_counter++; cout << "*** DEFRAG 1 " << defrag_counter << endl; } } else { //cout << "pcapProcess exit 002" << endl; return(0); } } } } bool nextPass; do { nextPass = false; u_int first_header_ip_offset = ppd->header_ip_offset; if(ppd->header_ip->protocol == IPPROTO_IPIP) { // ip in ip protocol ppd->header_ip = (iphdr2*)((char*)ppd->header_ip + sizeof(iphdr2)); ppd->header_ip_offset += sizeof(iphdr2); } else if(ppd->header_ip->protocol == IPPROTO_GRE) { // gre protocol iphdr2 *header_ip = convertHeaderIP_GRE(ppd->header_ip); if(header_ip) { ppd->header_ip = header_ip; ppd->header_ip_offset = (u_char*)header_ip - (header_packet ? HPP(*header_packet) : packet); nextPass = true; } else { if(ppf & ppf_returnZeroInCheckData) { //cout << "pcapProcess exit 004" << endl; if(pcap_header_plus2) { pcap_header_plus2->ignore = true; } return(0); } } } else { break; } if(ppf & ppf_defrag) { //if UDP defrag is enabled process only UDP packets and only SIP packets if(opt_udpfrag && ppd->header_ip->protocol == IPPROTO_UDP) { int foffset = ntohs(ppd->header_ip->frag_off); if ((foffset & IP_MF) || ((foffset & IP_OFFSET) > 0)) { // packet is fragmented if(handle_defrag(ppd->header_ip, header_packet, &ppd->ipfrag_data, pushToStack_queue_index) > 0) { // packets are reassembled iphdr2 *first_header_ip = (iphdr2*)(HPP(*header_packet) + first_header_ip_offset); // turn off frag flag in the first IP header first_header_ip->frag_off = 0; // turn off frag flag in the second IP header ppd->header_ip = (iphdr2*)(HPP(*header_packet) + ppd->header_ip_offset); ppd->header_ip->frag_off = 0; // update lenght of the first ip header to the len of the second IP header since it can be changed due to reassemble first_header_ip->tot_len = htons(ntohs(ppd->header_ip->tot_len) + (ppd->header_ip_offset - first_header_ip_offset)); if(sverb.defrag) { defrag_counter++; cout << "*** DEFRAG 2 " << defrag_counter << endl; } } else { //cout << "pcapProcess exit 003" << endl; return(0); } } } } } while(nextPass); if(header_packet) { (*header_packet)->header_ip_offset = ppd->header_ip_offset; } else { pcap_header_plus2->header_ip_offset = ppd->header_ip_offset; } if(ppf & ppf_defrag) { // if IP defrag is enabled, run each 10 seconds cleaning if(opt_udpfrag && (ppd->ipfrag_lastprune + 10) < HPH(*header_packet)->ts.tv_sec) { ipfrag_prune(HPH(*header_packet)->ts.tv_sec, false, &ppd->ipfrag_data, pushToStack_queue_index, -1); ppd->ipfrag_lastprune = HPH(*header_packet)->ts.tv_sec; //TODO it would be good to still pass fragmented packets even it does not contain the last semant, the ipgrad_prune just wipes all unfinished frags } } if(!(ppf & ppf_defragInPQout)) { u_int32_t caplen; if(header_packet) { caplen = HPH(*header_packet)->caplen; packet = HPP(*header_packet); } else { caplen = pcap_header_plus2->get_caplen(); } ppd->header_udp = &ppd->header_udp_tmp; if (ppd->header_ip->protocol == IPPROTO_UDP) { // prepare packet pointers ppd->header_udp = (udphdr2*) ((char*) ppd->header_ip + sizeof(*ppd->header_ip)); ppd->data = (char*) ppd->header_udp + sizeof(*ppd->header_udp); ppd->datalen = (int)(caplen - ((u_char*)ppd->data - packet)); ppd->traillen = (int)(caplen - ((u_char*)ppd->header_ip - packet)) - ntohs(ppd->header_ip->tot_len); ppd->istcp = 0; } else if (ppd->header_ip->protocol == IPPROTO_TCP) { ppd->istcp = 1; // prepare packet pointers ppd->header_tcp = (tcphdr2*) ((char*) ppd->header_ip + sizeof(*ppd->header_ip)); ppd->data = (char*) ppd->header_tcp + (ppd->header_tcp->doff * 4); ppd->datalen = (int)(caplen - ((u_char*)ppd->data - packet)); if (!(sipportmatrix[htons(ppd->header_tcp->source)] || sipportmatrix[htons(ppd->header_tcp->dest)]) && !(opt_enable_http && (httpportmatrix[htons(ppd->header_tcp->source)] || httpportmatrix[htons(ppd->header_tcp->dest)]) && (tcpReassemblyHttp->check_ip(htonl(ppd->header_ip->saddr)) || tcpReassemblyHttp->check_ip(htonl(ppd->header_ip->daddr)))) && !(opt_enable_webrtc && (webrtcportmatrix[htons(ppd->header_tcp->source)] || webrtcportmatrix[htons(ppd->header_tcp->dest)]) && (tcpReassemblyWebrtc->check_ip(htonl(ppd->header_ip->saddr)) || tcpReassemblyWebrtc->check_ip(htonl(ppd->header_ip->daddr)))) && !(opt_enable_ssl && (isSslIpPort(htonl(ppd->header_ip->saddr), htons(ppd->header_tcp->source)) || isSslIpPort(htonl(ppd->header_ip->daddr), htons(ppd->header_tcp->dest)))) && !(opt_skinny && (htons(ppd->header_tcp->source) == 2000 || htons(ppd->header_tcp->dest) == 2000))) { // not interested in TCP packet other than SIP port if(!opt_ipaccount && !DEBUG_ALL_PACKETS && (ppf & ppf_returnZeroInCheckData)) { //cout << "pcapProcess exit 005" << endl; if(pcap_header_plus2) { pcap_header_plus2->ignore = true; } return(0); } } ppd->header_udp->source = ppd->header_tcp->source; ppd->header_udp->dest = ppd->header_tcp->dest; } else { //packet is not UDP and is not TCP, we are not interested, go to the next packet (but if ipaccount is enabled, do not skip IP ppd->datalen = 0; if(!opt_ipaccount && !DEBUG_ALL_PACKETS && (ppf & ppf_returnZeroInCheckData)) { //cout << "pcapProcess exit 006 / protocol: " << (int)ppd->header_ip->protocol << endl; if(pcap_header_plus2) { pcap_header_plus2->ignore = true; } return(0); } } if(ppd->datalen < 0 && (ppf & ppf_returnZeroInCheckData)) { //cout << "pcapProcess exit 007" << endl; if(pcap_header_plus2) { pcap_header_plus2->ignore = true; } return(0); } } else { ppd->data = NULL; ppd->datalen = 0; } if((ppf & ppf_calcMD5) || (ppf & ppf_dedup)) { // check for duplicate packets (md5 is expensive operation - enable only if you really need it if(opt_dup_check && ppd->prevmd5s != NULL && ((ppf & ppf_defragInPQout) || (ppd->datalen > 0 && (opt_dup_check_ipheader || ppd->traillen < ppd->datalen))) && !(ppd->istcp && opt_enable_http && (httpportmatrix[htons(ppd->header_tcp->source)] || httpportmatrix[htons(ppd->header_tcp->dest)])) && !(ppd->istcp && opt_enable_webrtc && (webrtcportmatrix[htons(ppd->header_tcp->source)] || webrtcportmatrix[htons(ppd->header_tcp->dest)])) && !(ppd->istcp && opt_enable_ssl && (isSslIpPort(htonl(ppd->header_ip->saddr), htons(ppd->header_tcp->source)) || isSslIpPort(htonl(ppd->header_ip->daddr), htons(ppd->header_tcp->dest))))) { uint16_t *_md5 = header_packet ? (*header_packet)->md5 : pcap_header_plus2->md5; if(ppf & ppf_calcMD5) { MD5_Init(&ppd->ctx); if(ppf & ppf_defragInPQout) { u_int32_t caplen = header_packet ? HPH(*header_packet)->caplen : pcap_header_plus2->get_caplen(); MD5_Update(&ppd->ctx, ppd->header_ip, MIN(caplen - ppd->header_ip_offset, ntohs(ppd->header_ip->tot_len))); } else if(opt_dup_check_ipheader) { MD5_Update(&ppd->ctx, ppd->header_ip, MIN(ppd->datalen + (ppd->data - (char*)ppd->header_ip), ntohs(ppd->header_ip->tot_len))); } else { // check duplicates based only on data (without ip header and without UDP/TCP header). Duplicate packets // will be matched regardless on IP MD5_Update(&ppd->ctx, ppd->data, MAX(0, (unsigned long)ppd->datalen - ppd->traillen)); } MD5_Final((unsigned char*)_md5, &ppd->ctx); } if((ppf & ppf_dedup) && _md5[0]) { if(memcmp(_md5, ppd->prevmd5s + (_md5[0] * MD5_DIGEST_LENGTH), MD5_DIGEST_LENGTH) == 0) { //printf("dropping duplicate md5[%s]\n", md5); duplicate_counter++; if(sverb.dedup) { cout << "*** DEDUP " << duplicate_counter << endl; } if(pcap_header_plus2) { pcap_header_plus2->ignore = true; } return(0); } memcpy(ppd->prevmd5s + (_md5[0] * MD5_DIGEST_LENGTH), _md5, MD5_DIGEST_LENGTH); } } } if(ppf & ppf_dump) { if(pcapDumpHandle) { if(header_packet) { pcap_dump((u_char*)pcapDumpHandle, HPH(*header_packet), HPP(*header_packet)); } else { pcap_pkthdr header = pcap_header_plus2->getStdHeader(); pcap_dump((u_char*)pcapDumpHandle, &header, packet); } } } return(1); }