1#ifndef __CAPTURE_FILE_H__
2#define __CAPTURE_FILE_H__
3/*
4Copyright (c) 2015-2015 Cisco Systems, Inc.
5
6Licensed under the Apache License, Version 2.0 (the "License");
7you may not use this file except in compliance with the License.
8You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing, software
13distributed under the License is distributed on an "AS IS" BASIS,
14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15See the License for the specific language governing permissions and
16limitations under the License.
17*/
18
19
20
21#include "c_common.h"
22#include <stdio.h>
23#include "bitMan.h"
24#include <math.h>
25#include <stdlib.h>
26#include <string>
27#include <iostream>
28#include <cmath>
29
30#ifdef WIN32
31#pragma warning(disable:4786)
32#endif
33
34
35typedef enum capture_type {
36	LIBPCAP,
37	ERF,
38	LAST_TYPE
39} capture_type_e;
40
41#define MAX_PKT_SIZE (9*1024+22) /* 9k IP +14+4 FCS +some spare */
42
43#define READER_MAX_PACKET_SIZE MAX_PKT_SIZE
44
45class CAlignMalloc {
46public:
47    CAlignMalloc(){
48        m_p=0;
49    }
50    void * malloc(uint16_t size,uint8_t align);
51    void free();
52public:
53    char * m_p;
54};
55
56static inline uintptr_t my_utl_align_up(uintptr_t num,uint16_t round){
57    if ((num & ((round-1)) )==0) {
58        //the number align
59        return(num);
60    }
61    return( (num+round) & (~(round-1)) );
62}
63
64
65
66
67class CPktNsecTimeStamp {
68public:
69
70    #define _NSEC_TO_SEC 1000000000.0
71    CPktNsecTimeStamp(){
72        m_time_sec  =0;
73        m_time_nsec =0;
74    }
75
76    CPktNsecTimeStamp(uint32_t sec,uint32_t nsec){
77        m_time_sec =sec;
78        m_time_nsec =nsec;
79    }
80    CPktNsecTimeStamp(double nsec){
81        m_time_sec = (uint32_t)floor (nsec);
82        nsec -= m_time_sec;
83        m_time_nsec = (uint32_t)floor(nsec*_NSEC_TO_SEC);
84    }
85
86    double getNsec() const {
87         return ((double)m_time_sec +(double)m_time_nsec/(_NSEC_TO_SEC));
88    }
89
90    double diff(const CPktNsecTimeStamp & obj){
91        return (std::abs(getNsec() - obj.getNsec() ) );
92    }
93
94    void Dump(FILE *fd);
95public:
96    uint32_t     m_time_sec;
97    uint32_t     m_time_nsec;
98};
99
100
101
102class CCapPktRaw {
103
104public:
105	CCapPktRaw();
106    CCapPktRaw(int size);
107    CCapPktRaw(CCapPktRaw  *obj);
108	virtual ~CCapPktRaw();
109
110    uint32_t     time_sec;
111    uint32_t     time_nsec;
112    char       * raw;
113    uint64_t	 pkt_cnt;
114
115    uint16_t     pkt_len;
116private:
117    uint16_t     flags;
118    CAlignMalloc  m_handle;
119public:
120    double get_time(void) {
121        CPktNsecTimeStamp t1(time_sec,time_nsec);
122        return ( t1.getNsec());
123    }
124    void set_new_time(double new_time){
125        CPktNsecTimeStamp t1(new_time);
126        time_sec =t1.m_time_sec;
127        time_nsec=t1.m_time_nsec;
128    }
129
130    /* enlarge the packet */
131    char * append(uint16_t len);
132
133    void CloneShalow(CCapPktRaw  *obj);
134
135    void setInterface(uint8_t _if){
136        btSetMaskBit16(flags,10,8,_if);
137    }
138
139    uint8_t getInterface(){
140        return ((uint8_t)btGetMaskBit16(flags,10,8));
141    }
142
143    void setDoNotFree(bool do_not_free){
144        btSetMaskBit16(flags,0,0,do_not_free?1:0);
145    }
146
147    bool getDoNotFree(){
148        return ( ( btGetMaskBit16(flags,0,0) ? true:false) );
149    }
150
151    bool Compare(CCapPktRaw * obj,int dump,double dsec);
152
153
154public:
155	inline uint16_t getTotalLen(void) {
156		return (pkt_len);
157	}
158	void Dump(FILE *fd,int verbose);
159};
160
161/**
162 * Interface for capture file reader.
163 *
164 */
165class CCapReaderBase
166{
167public:
168
169    virtual ~CCapReaderBase(){}
170
171    virtual bool ReadPacket(CCapPktRaw * lpPacket)=0;
172
173
174    /* by default all reader reads one packet
175       and gives the feature one packet
176    */
177    virtual uint32_t  get_last_pkt_count() {return 1;}
178
179    /* method for rewind the reader
180      abstract and optional
181    */
182    virtual void Rewind() {};
183	/**
184     * open file for reading.
185     */
186	virtual bool Create(char * name, int loops = 0) = 0;
187
188    virtual capture_type_e get_type() = 0;
189
190protected:
191    int 		m_loops;
192    uint64_t 	m_file_size;
193};
194
195/**
196 * Factory for creating reader inteface of some of the supported
197 * formats.
198 *
199 */
200class CCapReaderFactory {
201public:
202	/**
203     * The function will try to create the matching reader for the
204     * file format (libpcap,ngsniffer...etc). Since there is no real
205     * connection (stile repository) between file suffix and its
206     * type we just try one bye one,
207     * @param name - cature file name
208     * @param loops - number of loops for the same capture. use 0
209     *                for one time transmition
210     * @param err - IO stream to print error
211     *
212     * @return CCapReaderBase* - pointer to new instance (allocated
213     *         by the function). the user should release the
214     *         instance once it has no use any more.
215	 */
216	static CCapReaderBase * CreateReader(char * name, int loops = 0, std::ostream &err = std::cout);
217
218
219private:
220	static CCapReaderBase * CreateReaderInstace(capture_type_e type);
221};
222
223/**
224 * Interface for capture file writer.
225 *
226 */
227class CFileWriterBase {
228
229public:
230
231    virtual ~CFileWriterBase(){};
232    virtual bool Create(char * name) = 0;
233    virtual bool write_packet(CCapPktRaw * lpPacket)=0;
234    virtual void flush_to_disk() = 0;
235
236};
237
238
239/**
240 * Factory for creating capture file interface of some of the
241 * supported formats.
242 *
243 */
244class CCapWriterFactory {
245public:
246
247	/**
248     * The factory function will create the matching reader instance
249     * according to the type.
250     *
251     * @param type - the foramt
252     * @param name - new file name
253	 *
254     * @return CCapWriter* - return pointer to the writer instance
255     *         or NULL if failed from some reason (or unsupported
256     *         format).Instance user
257     *         should relase memory when instance not needed
258     *         anymore.
259	 */
260	static CFileWriterBase * CreateWriter(capture_type_e type ,char * name);
261
262private:
263
264    static CFileWriterBase * createWriterInsance(capture_type_e type );
265};
266
267
268#if WIN32
269
270#define CAP_FOPEN_64 fopen
271#define CAP_FSEEK_64 fseek
272#define CAP_FTELL_64 ftell
273
274#else
275
276#define CAP_FOPEN_64 fopen64
277#define CAP_FSEEK_64 fseeko64
278#define CAP_FTELL_64 ftello64
279
280#endif
281
282
283class CErfCmp
284 {
285public:
286    CErfCmp(){
287        dump=false;
288        d_sec=0.001;
289    }
290    bool compare(std::string f1, std::string f2 );
291
292    bool cpy(std::string src,std::string dst);
293public:
294    bool dump;
295    double d_sec;
296};
297
298
299
300#endif
301