From 8b52a31ed2c299b759f330c4f976b9c70f5765f4 Mon Sep 17 00:00:00 2001 From: Hanoh Haim Date: Wed, 24 Jun 2015 14:03:29 +0300 Subject: first version --- src/common/captureFile.cpp | 328 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100755 src/common/captureFile.cpp (limited to 'src/common/captureFile.cpp') diff --git a/src/common/captureFile.cpp b/src/common/captureFile.cpp new file mode 100755 index 00000000..a4fe78be --- /dev/null +++ b/src/common/captureFile.cpp @@ -0,0 +1,328 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "captureFile.h" +#include "pcap.h" +#include "erf.h" +#include "basic_utils.h" +#include +#include +#include +#include + + +void CPktNsecTimeStamp::Dump(FILE *fd){ + fprintf(fd,"%.6f [%x:%x]",getNsec(),m_time_sec,m_time_nsec ); +} + + +void * CAlignMalloc::malloc(uint16_t size,uint8_t align){ + assert(m_p==0); + m_p=(char *)::malloc(size+align); + uintptr_t v =(uintptr_t)m_p; + char *p=(char *)my_utl_align_up( v,align); + return (void *)p; +} + +void CAlignMalloc::free(){ + ::free(m_p); + m_p=0; +} + +#define PKT_ALIGN 128 + + +CCapPktRaw::CCapPktRaw(CCapPktRaw *obj){ + flags =0; + pkt_cnt=obj->pkt_cnt; + pkt_len=obj->pkt_len; + time_sec=obj->time_sec; + time_nsec=obj->time_nsec; + assert ((pkt_len>0) && (pkt_lenraw,pkt_len); +} + + +CCapPktRaw::CCapPktRaw(int size){ + pkt_cnt=0; + flags =0; + pkt_len=size; + time_sec=0; + time_nsec=0; + if (size==0) { + raw =0; + }else{ + raw = (char *)m_handle.malloc(size,PKT_ALIGN); + memset(raw,0xee,size); + } + +} + +CCapPktRaw::CCapPktRaw(){ + flags =0; + pkt_cnt=0; + pkt_len=0; + time_sec=0; + time_nsec=0; + raw = (char *)m_handle.malloc((uint16_t)MAX_PKT_SIZE,PKT_ALIGN); + memset(raw,0xee,MAX_PKT_SIZE); +} + +CCapPktRaw::~CCapPktRaw(){ + if (raw && (getDoNotFree()==false) ) { + m_handle.free(); + } +} + +char * CCapPktRaw::append(uint16_t len){ + CAlignMalloc h; + char * p; + char * new_raw = (char *)h.malloc(pkt_len+len,PKT_ALIGN); + memcpy(new_raw,raw,pkt_len); + m_handle.free(); + raw=new_raw; + p= raw+pkt_len; + pkt_len+=len; + m_handle.m_p =h.m_p; + /* new pointer */ + return(p); +} + + +void CCapPktRaw::CloneShalow(CCapPktRaw *obj){ + pkt_len=obj->pkt_len; + raw = obj->raw; + setDoNotFree(true); +} + +void CCapPktRaw::Dump(FILE *fd,int verbose){ + fprintf(fd," =>pkt (%p) %llu , len %d, time [%x:%x] \n",raw,pkt_cnt,pkt_len,time_sec,time_nsec); + if (verbose) { + utl_DumpBuffer(fd,raw,pkt_len,0); + } +} + + +bool CCapPktRaw::Compare(CCapPktRaw * obj,int dump,double dsec){ + + if (pkt_len != obj->pkt_len) { + if ( dump ){ + printf(" ERROR len is not eq \n"); + } + return (false); + } + + if ( getInterface() != obj->getInterface() ){ + printf(" ERROR original packet from if=%d and cur packet from if=%d \n",getInterface(),obj->getInterface()); + return (false); + } + + CPktNsecTimeStamp t1(time_sec,time_nsec); + CPktNsecTimeStamp t2(obj->time_sec,obj->time_nsec); + if ( t1.diff(t2) > dsec ){ + if ( dump ){ + printf(" ERROR diff of 1 msec in time \n"); + } + return (false); + } + + if ( memcmp(raw,obj->raw,pkt_len) == 0 ){ + return (true); + }else{ + if ( dump ){ + fprintf(stdout," ERROR buffer not the same \n"); + fprintf(stdout," B1 \n"); + fprintf(stdout," ---------------\n"); + utl_DumpBuffer(stdout,raw,pkt_len,0); + fprintf(stdout," B2 \n"); + fprintf(stdout," ---------------\n"); + + utl_DumpBuffer(stdout,obj->raw,obj->pkt_len,0); + } + return (false); + } +} + + +bool CErfCmp::compare(std::string f1, std::string f2 ){ + + if ( dump ){ + printf(" compare %s %s \n",f1.c_str(),f2.c_str()); + } + bool res=true; + CCapReaderBase * lp1=CCapReaderFactory::CreateReader((char *)f1.c_str(),0); + if (lp1 == 0) { + if ( dump ){ + printf(" ERROR file %s does not exits or not supported \n",(char *)f1.c_str()); + } + return (false); + } + + CCapReaderBase * lp2=CCapReaderFactory::CreateReader((char *)f2.c_str(),0); + if (lp2 == 0) { + delete lp1; + if ( dump ){ + printf(" ERROR file %s does not exits or not supported \n",(char *)f2.c_str()); + } + return (false); + } + + CCapPktRaw raw_packet1; + bool has_pkt1; + CCapPktRaw raw_packet2; + bool has_pkt2; + + int pkt_cnt=1; + while ( true ) { + /* read packet */ + has_pkt1 = lp1->ReadPacket(&raw_packet1) ; + has_pkt2 = lp2->ReadPacket(&raw_packet2) ; + + /* one has finished */ + if ( !has_pkt1 || !has_pkt2 ) { + if (has_pkt1 != has_pkt2 ) { + if ( dump ){ + printf(" ERROR not the same number of packets \n"); + } + res=false; + } + break; + } + if (!raw_packet1.Compare(&raw_packet2,true,d_sec) ){ + res=false; + printf(" ERROR in pkt %d \n",pkt_cnt); + break; + } + + + pkt_cnt++; + } + + delete lp1; + delete lp2; + return (res); +} + + + +/** + * try to create type by type + * @param name + * + * @return CCapReaderBase* + */ +CCapReaderBase * CCapReaderFactory::CreateReader(char * name, int loops) +{ + if (name == NULL) { + printf("Got null file name\n"); + return NULL; + } + + /* make sure we have a file */ + FILE * f = CAP_FOPEN_64(name, "rb"); + if (f == NULL) { + if (errno == ENOENT) { + printf("\nERROR: Cap file not found %s\n\n",name); + } else { + printf("\nERROR: Failed to open cap file '%s' with errno %d\n\n", name, errno); + } + return NULL; + } + // close the file + fclose(f); + + for (capture_type_e i = LIBPCAP ; iCreate(name,loops)) { + return next; + } + delete next; + } + + printf("\nERROR: file %s format not supported",name); + printf("\nERROR: formats supported are LIBPCAP and ERF. other formats are deprecated\n\n"); + + return NULL; +} + +CCapReaderBase * CCapReaderFactory::CreateReaderInstace(capture_type_e type) +{ + switch(type) + { + case ERF: + return new CErfFileReader(); + case LIBPCAP: + return new LibPCapReader(); + default: + printf("Got unsupported file type\n"); + return NULL; + } + +} + + + +/** + * The factory function will create the matching reader instance + * according to the type. + * + * @param type - the foramt + * @param name - new file name + * + * @return CCapWriter* - return pointer to the writer instance + * or NULL if failed from some reason. Instance user + * should relase memory when instance not needed + * anymore. + */ +CFileWriterBase * CCapWriterFactory::CreateWriter(capture_type_e type ,char * name) +{ + if (name == NULL) { + return NULL; + } + + CFileWriterBase * toRet = CCapWriterFactory::createWriterInsance(type); + + if (toRet) { + if (!toRet->Create(name)) { + delete toRet; + toRet = NULL; + } + } + + return toRet; +} + +/** + * Create instance for writer if type is supported. + * @param type + * + * @return CFileWriterBase* + */ +CFileWriterBase * CCapWriterFactory::createWriterInsance(capture_type_e type ) +{ + switch(type) { + case LIBPCAP: + return new LibPCapWriter(); + case ERF: + return new CErfFileWriter(); + // other is not supported yet. + default: + return NULL; + } +} + -- cgit 1.2.3-korg