Search code examples
c#wiresharkpcapsharppcap

sharppcap: '.' characters instead of spaces with printHex() method


I am successfully parcing '.pcap' files using SharpPcap libary.

The goal is to retrieve XML data from the TCP/HTTP packets. In order to do this, I am using the code below (removed null checks to make it more readable):

Packet packet = Packet.ParsePacket(eventArguments.Packet.LinkLayerType, eventArguments.Packet.Data);
EthernetPacket ethernetPacket = ((EthernetPacket)packet);

IpPacket ipPacket = (IpPacket)packet.Extract(typeof(IpPacket));

TcpPacket tcpPacket = (TcpPacket)packet.Extract(typeof(TcpPacket));

string rawData = tcpPacket.PrintHex();

Moving, aside the hex values and the initial lines, I am able to extract the XML data from the rawData variable, along with an unexpected side-effect.

Instead of spaces, the .PrintHex() returns '.' characters:

Instead of:

<xml>Only text here</xml>

I am getting this:

<xml>Only.text.here</xml>

I am not doing any weird replacements or byte conversions. The above behavior is exactly what .PrintHex() returns.

  • Is this by any chance the expected outcome?
  • And more importantly... How can this be fixed or prevented? (having in mind that valid '.' from converted '.' cannot be distinguished)

Library versions:

  • .NET Framework: > 4.5.2

  • Pcapsharp: 4.2.0


Solution

  • Try to use override of ToString() method which seems to do exactly what you expect.

    Optionally if that does not work, implement public string PrintHex() from Packet on your own. If you take a look at decompiled code here is your problem :

        if ((int) bytes[index - 1] < 33 || (int) bytes[index - 1] > 126)
          str2 += ".";
        else
          str2 += Encoding.ASCII.GetString(new byte[1]
          {
            bytes[index - 1]
          });
    

    Only characters with dec code ranging from 33 to 126 will be left unchanged, rest will be replaced with . (including space which is 32 http://www.asciitable.com/). And since BytesHighPerformance.Bytes is public you can write your own extension method rather easily along those lines.

    TcpPacket tcpPacket = (TcpPacket)packet.Extract(typeof(TcpPacket));
    string rawData = tcpPacket.CustomPrintHex();
    
    public static class Extensions
    {
        public static string CustomPrintHex(this TcpPacket self)
        {
            byte[] bytes = self.BytesHighPerformance.Bytes;
    
            // copy / paste of `PrintHex()` with your custom conversion
        }
    }