I am stuck.
I have used PCAP.NET to read .PCAP files and write the packets into a database. Now I can query the database and get packets back that match the constraints. I need a way to write the results to a new .PCAP file.
The problem is that, as far as I can tell, the only way to generate a new PCAP file is via the DumpFile which can only be initialized via a PacketCommunicator that is itself tied to a PacketDevice.
an example can be seen here: http://pcapdotnet.codeplex.com/wikipage?title=Pcap.Net%20Tutorial%20-%20Handling%20offline%20dump%20files&referringTitle=Pcap.Net%20User%20Guide
Well and good, but in this scenario I don't have a device.
Should I roll my own PCAP writer just for this purpose?
Have I missed something obvious?
How can I get these packets into a new PCAP file?
I am convinced that I have overlooked something simple... PCAP is new territory for me and I'm feeling very out of sorts. The Unix folks at work indicate that libpcap which winpcap and therefore pcap.net are based upon provides the ability to write directly to a pcap file. Is the functionality not exposed in the library?
Recommendations are very much appreciated.
Thanks,
Chris
P.S. This is a revision to my original question asked here: .NET writing PCAP files
Is the functionality not exposed in the library?
Which library?
It's exposed in libpcap/WinPcap, but opening the file for output is a bit awkward - you need a pcap_t for a capture device, a pcap_t for a capture file, or a dummy pcap_t for the link-layer header type and snapshot length of the file you're writing if the packets you're writing aren't coming from a live capture or an existing capture file.
I couldn't find any reference documentation for Pcap.NET, just tutorial documentation, but there didn't seem to be anything that let you open a dummy handle - you can open a capture device or a offline capture file, but I didn't see anything about creating a dummy handle from which you can't read packets but that you can use when opening a capture file for writing - so all the functionality available in libpcap/WinPcap is NOT exposed in Pcap.NET, as far as I can tell.
You can create a pcap header and a format, the specification is easy and you don't need a external library apart of the pcap.h.
struct pcap_file_header {
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone; /* gmt to local correction */
bpf_u_int32 sigfigs; /* accuracy of timestamps */
bpf_u_int32 snaplen; /* max length saved portion of each pkt */
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
};
So your file first create a header for the pcap file, for example:
struct pcap_file_header pheader;
pheader.magic = 0xA1B2C3D4; // MAGIC NUMBER FOR TCPDUMP
pheader.version_major = PCAP_VERSION_MAJOR;
pheader.version_minor = PCAP_VERSION_MINOR;
pheader.thiszone = 0;
pheader.sigfigs = 0;
pheader.snaplen = 1500;
pheader.linktype = 1;
And for write each packet you need a struct like:
typedef struct {
int32_t t0;
int32_t t1;
int32_t len;
int32_t caplen;
} pcap_header_writeable;
So you will write on the file like:
pcap_header_writeable header;
header.t0 = 0;
header.t1 = 0;
header.len = length;
header.caplen = length;
// write the header on the file
// write the packet on the file after the header
In the Pcap.Net User Guide, the "Handling offline dump files" page has an example using the PacketDumpFile class to write out a dump file. I'm not seeing any Pcap.Net reference manual; to answer this question, the user read the Pcap.Net source code.
Related
I have a pcap-ng file, and I'd like to extract the source/destination IPs.
According to the winpcap dump file format, the data I'm looking for is in the Packet Data section of the enhanced packet block.
I've been using this library in C# to parse through the pcap-ng file. And while I've been able to successfully get out the Enhanced Packet Block, I'm really not sure how to get into it.
The current Enhanced Packet Block Packet Data comes out as a byte array, using the following method.
private static void extractEnhancedPacketBlock()
{
var myFile = "\\path\\to\\my.pcapng"
using (StreamWriter file = new StreamWriter(myFile))
{
foreach (var enhancedPacketBlock in reader.EnhancedPacketBlocks)
{
byte[] packetData = enhancedPacketBlock.Data;
Console.WriteLine(BitConverter.ToString(packetData));
}
}
}
Which outputs what you would expect, similar to the following:
79-2C-C8-80-A8-65-00-00-BC-C4-2F-65-09-00-42-00-01-5E...etc
A good answer to this could be a few different things like, guidance on where to look to learn more about what I need to do next. A library that already does that that I could use (I've tried a lot of libraries, and none of them seem to go this deep). Or if you already have some code that does this, that would be awesome. I'm also open to moving to Python if necessary.
Additional info.
I know that I can parse the source IP and destination IP out of the Enhanced Packet Blocks, and I know that it will require a hexadecimal to IP conversion, but I do not know where the IP Hex exists in the Enhanced Packet Blocks. I know it's not in the same place every time, but I need to know how to calculate this.
Use https://github.com/chmorgan/packetnet for parsing the packet data
Example:
var packet = Packet.ParsePacket(LinkLayers.Ethernet, enhancedPacketBlock.Data);
var ip = packet.Extract<IPPacket>();
I'm using this sample exactly (except I changed tchar to char everywhere):
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365601%28v=vs.85%29.aspx
I'm using the following c# code to send a medium sized (=400kb) file to the c++ server:
var client = new NamedPipeClientStream(#"SamplePipe");
client.Connect();
StreamWriter writer = new StreamWriter(client);
string bla = File.ReadAllText(#"D:\Request.txt");
writer.Write(bla);
This is the file I'm sending:
http://www.gutenberg.org/cache/epub/45745/pg45745.txt
It never sends data beyond this passage: "of us stand as high as a tall man, and a measure four feet from bill to tail. Thur" (around 170kb of 400kb)
(I dont understand where the 'ur' comes from, the next word would be 'There')
The last thing that happens is a WAIT_IO_COMPLETION as far as I can tell and then it just stays forever on the writer.Write(bla) line. But this may be circumstancial.
What's going on? I have also tried some of the other samples and they all seem to have problems with larger files.
Ok I think I figured it out:
Your C++ sample has the PipeTransmissionMode set to 'Message' (PIPE_TYPE_MESSAGE and PIPE_READMODE_MESSAGE) while your C# NamedPipeClientStream is using the PipeTransmissionMode 'Byte' by default.
So change PIPE_TYPE_MESSAGE to PIPE_TYPE_BYTE and PIPE_READMODE_MESSAGE to PIPE_READMODE_BYTE.
Check this CreateNamedPipe function page on MSDN for more information to make sure your PipeServer is properly setup.
Hey everyone just trying to make a program that browses video files and reads the title and description from the files metadata. I found some docs from microsoft here giving whats needed but how do I access these functions? what using namespaces are needed in c#? I would love any help that can be provided.
In that link you posted, scroll to the bottom and click "Shell Metadata Providers". There's more more information and some sample C++ code.
Here are some other relevant links:
Reading/Writing metadata of audio/video files
http://www.codeproject.com/Articles/14535/Accessing-WMF-metadata-with-C
https://social.msdn.microsoft.com/Forums/pt-BR/0f36a3b2-4d3d-4842-88a4-bea493bbbace/read-video-filemov-avi-mpg-etc-meta-data?forum=csharpgeneral
https://web.archive.org/web/20170225230114/https://stackoverflow.com/questions/7396265/c-sharp-to-read-properties-of-video-files
Sorry I can't give you anything more concrete, however it looks like some tag libraries (i.e. for reading MP3 metadata) may work as well, as the metadata for videos seems to be stored in a similar, if not identical, format. That being said, you can give TagLib# a shot.
https://www.nuget.org/packages/taglib/
I've made a simple C# code (portable to Unity, too) csatomreader. It's optimized for speed and can read the atoms over HTTP, too.
E.g. Get title:
using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
var mp4Reader = new AtomReader(stream);
string value = mp4Reader.GetMetaAtomValue(AtomReader.TitleTypeName);
Console.WriteLine($"{atomTypeName}: {value}");
}
If you need to get more metadata values at once, then iterate over ParseAtoms(), e.g. see the GetMetaAtomValue() source.
I am developing an application which requires to read a text file which is continuously updating. I need to read the file till the end of file(at that very moment) and need to remember this location for my next file read. I am planning to develop this application in C#.net . How can I perform these partial reads and remember the locations as C# does not provide pointers in file handling ?
Edit : File is updated every 30 seconds and new data is appended to the old file.
I tried with maintaining the length of previous read and then reading the data from that location but the file can not be accessed by two applications at the same time.
You can maintain the last offset of the read pointer in the file. You can do sth like this
long lastOffset = 0;
using (var fs = new FileStream("myFile.bin", FileMode.Open))
{
fs.Seek(lastOffset, SeekOrigin.Begin);
// Read the file here
// Once file is read, update the lastOffset
lastOffset=fs.Seek(0, SeekOrigin.End);
}
Open the file, read everything, save the count of bytes you read in a variable (let's assume it's read_until_here).
next time you read the file, just take the new information (whichever comes after the location of your read_until_here variable ...
I am planning to develop this application in C#.net . How can I perform these partial reads and remember the locations as C# does not provide pointers in file handling ?
Not entirely sure why you'd be concerned about the supposed lack of pointers... I'd look into int FileStream.Read(byte[] array, int offset, int count) myself.
It allows you to read from an offset into a buffer, as many bytes as you want, and tells you how many bytes were actually read... which looks to be all the functionality you'd need.
I will like to compress a file before sending it through the network. I think the best approach is 7zip because it is free and open source.
How I use 7zip with .net?
I know that 7zip is free and that they have the source code in c# but for some reason it is very slow on c# so I rather call the dll 7z.dll that comes when installing 7zip for performance reasons. So the way I am able to eassily marshal and call the methods in 7z.dll is with the help of the library called sevenzipsharp . For example adding that dll to my project will enable me to do:
// if you installed 7zip 64bit version then make sure you change plataform target
// like on the picture I showed above!
SevenZip.SevenZipCompressor.SetLibraryPath(#"C:\Program Files\7-Zip\7z.dll");
var stream = System.IO.File.OpenRead(#"SomeFileToCompress.txt");
var outputStream = System.IO.File.Create("Output.7z");
SevenZip.SevenZipCompressor compressor = new SevenZip.SevenZipCompressor();
compressor.CompressionMethod = SevenZip.CompressionMethod.Lzma2;
compressor.CompressionLevel = SevenZip.CompressionLevel.Ultra;
compressor.CompressStream(stream, outputStream);
that's how I use 7zip within c#.
Now my question is:
I will like to send a compressed file over the network. I know I could compress it first then send it. The file is 4GB so I will have to wait a long time for it to compress. I will be wasting a lot of space on hard drive. then I will finally be able to send it. I think that is to complicated. I was wondering how it will be possible to send the file meanwhile it is being compressed.
It seems to be a problem with SevenZipSharp:
Have you considered an alternate library - one that doesn't even require 7-Zip to be installed / available?
From the description posted at http://dotnetzip.codeplex.com/ :
creating zip files from stream content, saving to a stream, extracting
to a stream, reading from a stream
Unlike 7-Zip, DotNetZip is designed to work with C# / .Net.
Plenty of examples - including streaming, are available at http://dotnetzip.codeplex.com/wikipage?title=CS-Examples&referringTitle=Examples .
Another option is to use the 7-Zip Command Line Version (7z.exe), and write to/read from standard in/out. This would allow you to use the 7-Zip file format, while also keeping all of the core work in native code (though there likely won't be much of a significant difference).
Looking back at SevenZipSharp:
Since the 0.29 release, streaming is supported.
Looking at http://sevenzipsharp.codeplex.com/SourceControl/changeset/view/59007#364711 :
it seems you'd want this method:
public void CompressStream(Stream inStream, Stream outStream)
Thank you for considering performance here! I think way too many people would do exactly what you're trying to avoid: compress to a temp file, then do something with the temp file.
CompressStream threw an exception. My code is as follows:
public void TestCompress()
{
string fileToCompress = #"C:\Users\gary\Downloads\BD01.DAT";
byte[] inputBytes = File.ReadAllBytes(fileToCompress);
var inputStream = new MemoryStream(inputBytes);
byte[] zipBytes = new byte[38000000]; // this memory size is large enough.
MemoryStream outStream = new MemoryStream(zipBytes);
string compressorEnginePath = #"C:\Engine\7z.dll";
SevenZipCompressor.SetLibraryPath(compressorEnginePath);
compressor = new SevenZip.SevenZipCompressor();
compressor.CompressionLevel = CompressionLevel.Fast;
compressor.CompressionMethod = CompressionMethod.Lzma2;
compressor.CompressStream(inputStream, outputStream);
inputStream.Close();
outputStream.Close();
The exception messages:
Message: Test method Test7zip.UnitTest1.TestCompress threw exception:
SevenZip.SevenZipException: The execution has failed due to the bug in the SevenZipSharp.
Please report about it to http://sevenzipsharp.codeplex.com/WorkItem/List.aspx, post the release number and attach the archive