1 /*
2  * pcapfile.h
3  *
4  * Ethernet capture (PCAP) file declaration
5  *
6  * Portable Tools Library
7  *
8  * Copyright (C) 2011 Vox Lucida Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Tools Library.
21  *
22  * The Initial Developer of the Original Code is Vox Lucida
23  *
24  * All Rights Reserved.
25  *
26  * Contributor(s): ______________________________________.
27  *
28  * $Revision: 27285 $
29  * $Author: rjongbloed $
30  * $Date: 2012-03-22 20:44:50 -0500 (Thu, 22 Mar 2012) $
31  */
32 
33 #ifndef PTLIB_PCAPFILE_H
34 #define PTLIB_PCAPFILE_H
35 
36 #ifdef P_USE_PRAGMA
37 #pragma interface
38 #endif
39 
40 #include <rtp/rtp.h>
41 #include <opal/mediafmt.h>
42 #include <ptlib/sockets.h>
43 
44 
45 /**Class for a reading RTP from an Ethernet Capture (PCAP) file.
46  */
47 class OpalPCAPFile : public PFile
48 {
49     PCLASSINFO(OpalPCAPFile, PFile);
50   public:
51     OpalPCAPFile();
52 
53     bool Open(const PFilePath & filename);
54     bool Restart();
55 
56     void PrintOn(ostream & strm) const;
57 
58     bool ReadRawPacket(PBYTEArray & payload);
59     int GetDataLink(PBYTEArray & payload);
60     int GetIP(PBYTEArray & payload);
61     int GetUDP(PBYTEArray & payload);
62     int GetRTP(RTP_DataFrame & rtp);
63 
GetPacketTime()64     const PTime & GetPacketTime() const { return m_packetTime; }
GetSrcIP()65     const PIPSocket::Address & GetSrcIP() const { return m_packetSrcIP; }
GetDstIP()66     const PIPSocket::Address & GetDstIP() const { return m_packetDstIP; }
IsFragmentated()67     unsigned IsFragmentated() const { return m_fragmentated; }
GetSrcPort()68     WORD GetSrcPort() const { return m_packetSrcPort; }
GetDstPort()69     WORD GetDstPort() const { return m_packetDstPort; }
70 
SetFilterSrcIP(const PIPSocket::Address & ip)71     void SetFilterSrcIP(
72       const PIPSocket::Address & ip
73     ) { m_filterSrcIP = ip; }
GetFilterSrcIP()74     const PIPSocket::Address & GetFilterSrcIP() const { return m_filterSrcIP; }
75 
SetFilterDstIP(const PIPSocket::Address & ip)76     void SetFilterDstIP(
77       const PIPSocket::Address & ip
78     ) { m_filterDstIP = ip; }
GetFilterDstIP()79     const PIPSocket::Address & GetFilterDstIP() const { return m_filterDstIP; }
80 
SetFilterSrcPort(WORD port)81     void SetFilterSrcPort(
82       WORD port
83     ) { m_filterSrcPort = port; }
GetFilterSrcPort()84     WORD GetFilterSrcPort() const { return m_filterSrcPort; }
85 
SetFilterDstPort(WORD port)86     void SetFilterDstPort(
87       WORD port
88     ) { m_filterDstPort = port; }
GetFilterDstPort()89     WORD GetFilterDstPort() const { return m_filterDstPort; }
90 
91 
92     struct DiscoveredRTPInfo {
93       DiscoveredRTPInfo();
94 
95       PIPSocketAddressAndPort     m_addr[2];
96       RTP_DataFrame::PayloadTypes m_payload[2];
97       bool                        m_found[2];
98 
99       DWORD m_ssrc[2];
100       WORD  m_seq[2];
101       DWORD m_ts[2];
102 
103       unsigned m_ssrc_matches[2];
104       unsigned m_seq_matches[2];
105       unsigned m_ts_matches[2];
106 
107       RTP_DataFrame m_firstFrame[2];
108 
109       PString m_type[2];
110       PString m_format[2];
111 
112       size_t m_index[2];
113     };
114     class DiscoveredRTPMap : public PObject, public std::map<std::string, DiscoveredRTPInfo>
115     {
116         PCLASSINFO(DiscoveredRTPMap, PObject);
117       public:
118         void PrintOn(ostream & strm) const;
119     };
120 
121     bool DiscoverRTP(DiscoveredRTPMap & discoveredRTPMap);
122 
123     void SetFilters(
124       const DiscoveredRTPInfo & rtp,
125       int dir
126     );
127     bool SetFilters(
128       const DiscoveredRTPMap & rtp,
129       size_t index
130     );
131 
132     bool SetPayloadMap(
133       RTP_DataFrame::PayloadTypes pt,
134       const OpalMediaFormat & format
135     );
136 
137     OpalMediaFormat GetMediaFormat(const RTP_DataFrame & rtp) const;
138 
139   protected:
140     PINDEX GetNetworkLayerHeaderSize();
141 
142     struct FileHeader {
143       DWORD magic_number;   /* magic number */
144       WORD  version_major;  /* major version number */
145       WORD  version_minor;  /* minor version number */
146       DWORD thiszone;       /* GMT to local correction */
147       DWORD sigfigs;        /* accuracy of timestamps */
148       DWORD snaplen;        /* max length of captured packets, in octets */
149       DWORD network;        /* data link type */
150     };
151 
152     struct RecordHeader {
153       DWORD ts_sec;         /* timestamp seconds */
154       DWORD ts_usec;        /* timestamp microseconds */
155       DWORD incl_len;       /* number of octets of packet saved in file */
156       DWORD orig_len;       /* actual length of packet */
157     };
158 
159 
160     FileHeader m_fileHeader;
161     bool       m_otherEndian;
162     PBYTEArray m_rawPacket;
163     PTime      m_packetTime;
164 
165     PIPSocket::Address m_filterSrcIP;
166     PIPSocket::Address m_filterDstIP;
167     PIPSocket::Address m_packetSrcIP;
168     PIPSocket::Address m_packetDstIP;
169 
170     PBYTEArray m_fragments;
171     bool       m_fragmentated;
172     unsigned   m_fragmentProto;
173 
174     WORD m_filterSrcPort;
175     WORD m_filterDstPort;
176     WORD m_packetSrcPort;
177     WORD m_packetDstPort;
178 
179     std::map<RTP_DataFrame::PayloadTypes, OpalMediaFormat> m_payloadType2mediaFormat;
180 };
181 
182 
183 #endif // PTLIB_PCAPFILE_H
184 
185 
186 // End Of File ///////////////////////////////////////////////////////////////
187