| 
									
										
										
										
											2014-04-21 02:43:45 +02:00
										 |  |  | // Copyright 2014 Dolphin Emulator Project
 | 
					
						
							| 
									
										
										
										
											2015-05-18 01:08:10 +02:00
										 |  |  | // Licensed under GPLv2+
 | 
					
						
							| 
									
										
										
										
											2014-04-21 02:43:45 +02:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <chrono>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							|  |  |  | #include "Common/FileUtil.h"
 | 
					
						
							|  |  |  | #include "Common/PcapFile.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | namespace | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-04-21 02:43:45 +02:00
										 |  |  | const u32 PCAP_MAGIC = 0xa1b2c3d4; | 
					
						
							|  |  |  | const u16 PCAP_VERSION_MAJOR = 2; | 
					
						
							|  |  |  | const u16 PCAP_VERSION_MINOR = 4; | 
					
						
							|  |  |  | const u32 PCAP_CAPTURE_LENGTH = 65535; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TODO(delroth): Make this configurable at PCAP creation time?
 | 
					
						
							|  |  |  | const u32 PCAP_DATA_LINK_TYPE = 147;  // Reserved for internal use.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Designed to be directly written into the PCAP file. The PCAP format is
 | 
					
						
							|  |  |  | // endian independent, so this works just fine.
 | 
					
						
							|  |  |  | #pragma pack(push, 1)
 | 
					
						
							|  |  |  | struct PCAPHeader | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 magic_number; | 
					
						
							|  |  |  |   u16 version_major; | 
					
						
							|  |  |  |   u16 version_minor; | 
					
						
							|  |  |  |   s32 tz_offset;       // Offset in seconds from the GMT timezone.
 | 
					
						
							|  |  |  |   u32 ts_accuracy;     // In practice, 0.
 | 
					
						
							|  |  |  |   u32 capture_length;  // Size at which we truncate packets.
 | 
					
						
							|  |  |  |   u32 data_link_type; | 
					
						
							| 
									
										
										
										
											2014-04-21 02:43:45 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct PCAPRecordHeader | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 ts_sec; | 
					
						
							|  |  |  |   u32 ts_usec; | 
					
						
							|  |  |  |   u32 size_in_file;  // Size after eventual truncation.
 | 
					
						
							|  |  |  |   u32 real_size;     // Size before eventual truncation.
 | 
					
						
							| 
									
										
										
										
											2014-04-21 02:43:45 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | #pragma pack(pop)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PCAP::AddHeader() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   PCAPHeader hdr = {PCAP_MAGIC, PCAP_VERSION_MAJOR,  PCAP_VERSION_MINOR, 0, | 
					
						
							|  |  |  |                     0,          PCAP_CAPTURE_LENGTH, PCAP_DATA_LINK_TYPE}; | 
					
						
							|  |  |  |   m_fp->WriteBytes(&hdr, sizeof(hdr)); | 
					
						
							| 
									
										
										
										
											2014-04-21 02:43:45 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PCAP::AddPacket(const u8* bytes, size_t size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   std::chrono::system_clock::time_point now(std::chrono::system_clock::now()); | 
					
						
							|  |  |  |   auto ts = now.time_since_epoch(); | 
					
						
							|  |  |  |   PCAPRecordHeader rec_hdr = { | 
					
						
							|  |  |  |       (u32)std::chrono::duration_cast<std::chrono::seconds>(ts).count(), | 
					
						
							|  |  |  |       (u32)(std::chrono::duration_cast<std::chrono::microseconds>(ts).count() % 1000000), (u32)size, | 
					
						
							|  |  |  |       (u32)size}; | 
					
						
							|  |  |  |   m_fp->WriteBytes(&rec_hdr, sizeof(rec_hdr)); | 
					
						
							|  |  |  |   m_fp->WriteBytes(bytes, size); | 
					
						
							| 
									
										
										
										
											2014-04-21 02:43:45 +02:00
										 |  |  | } |