开发者

Decoding IPFIX packets using BitArray C#

Following on from my previous thread, I seem to be closer to decoding IPFIX data from a Sonicwall firewall using a UDP listener and a BitArray in C#.

I now get data in my BitArray but it doesnt make sense - I thought I would see binary in my array but I am getting values very different e.g. 8 - 10 characters some positive and some negative and the Count of the array always varies.

Here is the main part of the code I am using to get the bits:

byte[] bytes = listener.Receive(ref _myEndPoint);

BitArray bitarray = new BitArray(bytes);

Does any one know of any way I can decode my IPFIX data or have any pointers that will help me?

Thanks in advance,

James


Output from code supplied by Chris:

byte[] bytes = {0x00, 0x0A, 0x04, 0xB4, 0x4D, 0xAE, 0x8F, 0xF4, 0x00, 0x6D, 0x8F, 0xC7, 0x16, 0x2B, 0xFC, 0x00, 0x01, 0x01, 0x04, 0xA4, 0x4D, 0xAE, 0x8F, 0xD2, 0x8D, 0xCC, 0xC8, 0x20, 0x00, 0x26, 0x99, 0xD4, 0x5F, 0xD7, 0x30, 0x37, 0xA6, 0xD6, 0xBE, 0xB9, 0x51, 0x90, 0xF3, 0x45, 0x4A, 0x7D, 0xE6, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x69, 0x00, 0x50, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0xB3, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x42, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0xC7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x72, 0x4D, 0xAE, 0x8F, 0xD2, 0x4D, 0xAE, 0x8F, 0xF4, 0x00, 0x31, 0x06, 0x00, 0x00, 0x00, 0x10, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, 0x4D, 0xAE, 0x8F, 0xEE, 0x8E, 0x42, 0xF9, 0xA0, 0x30, 0x37, 0xA6, 0xD6, 0xBE, 0xB9, 0x00, 0x50, 0x56, 0x96, 0x00, 0x00, 0x51, 0x8D, 0x42, 0xFE, 0x51, 0x90, 0xF3, 0x46, 0x51, 0x90, 0xF3, 0x41, 0x51, 0x90, 0xF3, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5, 0x85, 0x00, 0x50, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x09, 0x6E, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0xDF, 0xE1, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x04, 0x86, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x6E, 0x65, 0x4D, 0xAE, 0x8F, 0xEE, 0x4D, 0xAE, 0x8F, 0xF4, 0x00, 0x31, 0x06, 0x00, 0x00, 0x00, 0x10, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, 0x4D, 0xAE, 0x8F, 0xF3, 0x8E, 0x5B, 0x17, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x01, 0x55, 0xC0, 0xA8, 0x6F, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xF8, 0x23, 0x8C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xAE, 0x8F, 0xF3, 0x4D, 0xAE, 0x8F, 0xF4, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0xC0, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x4D, 0xAE, 0x8F, 0xBE, 0x8E, 0xA0, 0x53, 0xA0, 0x1C, 0xC1, 0xDE, 0xA7, 0x2D, 0x01, 0x30, 0x37, 0xA6, 0xD6, 0xBE, 0xB9, 0x0A, 0x00, 0x01, 0x5A, 0x4A, 0xC9, 0x75, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x8F, 0x00, 0x50, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0xA4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xAE, 0x8F, 0xBE, 0x4D, 0xAE, 0x8F, 0xF4, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00, 0xC0, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, 0x4D, 0xAE, 0x8F, 0xB6, 0x8D, 0xCE, 0x0A, 0x20, 0x1C, 0xC1, 0xDE, 0xA7, 0x2D, 0x01, 0x30, 0x37, 0xA6, 0xD6, 0xBE, 0xB9, 0x0A, 0x00, 0x01, 0x5A, 0x5D, 0xB8, 0xDD, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x77, 0x00, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xAE, 0x8F, 0xB开发者_运维问答6, 0x4D, 0xAE, 0x8F, 0xF4, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00, 0xC0, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x4D, 0xAE, 0x8F, 0xB6, 0x8E, 0x58, 0xD0, 0xE0, 0x1C, 0xC1, 0xDE, 0xA7, 0x2D, 0x01, 0x30, 0x37, 0xA6, 0xD6, 0xBE, 0xB9, 0x0A, 0x00, 0x01, 0x5A, 0x58, 0xDD, 0x5E, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x72, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x04, 0x86, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xAE, 0x8F, 0xB6, 0x4D, 0xAE, 0x8F, 0xF4, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00, 0xC0, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x01, 0x4D, 0xAE, 0x8F, 0xB5, 0x8E, 0x95, 0xA4, 0x60, 0x1C, 0xC1, 0xDE, 0xA7, 0x2D, 0x01, 0x30, 0x37, 0xA6, 0xD6, 0xBE, 0xB9, 0x0A, 0x00, 0x01, 0x5A, 0x40, 0x98, 0xD0, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x6E, 0x00, 0x50, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x05, 0x7E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xAE, 0x8F, 0xB5, 0x4D, 0xAE, 0x8F, 0xF4, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00, 0xC0, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x01, 0x4D, 0xAE, 0x8F, 0xB4, 0x8E, 0xDA, 0xAB, 0xE0, 0x1C, 0xC1, 0xDE, 0xA7, 0x2D, 0x01, 0x30, 0x37, 0xA6, 0xD6, 0xBE, 0xB9, 0x0A, 0x00, 0x01, 0x5A, 0xD1, 0x55, 0x8F, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x5F, 0x00, 0x50, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xAE, 0x8F, 0xB4, 0x4D, 0xAE, 0x8F, 0xF4, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00, 0xC0, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01};


Can you give us a dump of one of the byte packets that you're receiving? Pass the array to the code below and it will dump it to the output window. This will help us see a raw packet.

    private static string PrintByteArray(byte[] bytes){
        return "byte[] bytes = {0x" + BitConverter.ToString(bytes).Replace("-", ", 0x") + "};";
    }

Do you understand what @Paul Sasik was talking about in his answer for parsing the data? The structure is in the RFC spec that he linked to. The first two bytes (16 bits) of the packet will be the version number. I haven't read through the spec but bytes can be written in two different ways, little and big endian. So according to the spec the first two bytes should be something like 0x00 0x0a or 0x0a 0x00.

EDIT

Don't think in terms of bits versus bytes, just that the latter is a collection of 8 of the former.

The spec says that the first 16 bits (2 bytes) are the version number 0x000a which matches what you have. It then says the next 2 bytes are the length of the entire message in bytes (it actually says octets, same thing). Your data has 0x04b4 which is 1204 in decimal which is exactly how long the byte array is. The next field is a 4 byte field for export time in seconds since Jan 1st, 1970 (aka Unix/Posix time). You have 0x4dae8ff4 which is 1,303,285,748 in decimal which according to this site is Wed, 20 Apr 2011 07:49:08 GMT. You can use the code below to parse the message header. Hopefully this will get you going on parsing the raw data.

    private static IPFIX ParseMessageHeader(byte[] bytes)
    {
        IPFIX ret = new IPFIX();
        ret.Version = ToUInt16BigEndian(bytes, 0);
        ret.Length = ToUInt16BigEndian(bytes, 2);
        ret.ExportTime = (new DateTime(1970, 1, 1, 0, 0, 0)).AddSeconds(ToUInt32BigEndian(bytes, 4));
        ret.SequenceNumber = ToUInt32BigEndian(bytes, 8);
        ret.ObservationDomainID = ToUInt32BigEndian(bytes, 12);
        ret.Sets = new List<Set>();
        Int32 CurOctet = 16;
        Set S;
        while (true)
        {
            S = new Set();
            S.SetId = ToUInt16BigEndian(bytes, CurOctet);
            S.Length = ToUInt16BigEndian(bytes, CurOctet + 2);
            S.data = bytes.Skip(CurOctet).Take(S.Length).ToArray();
            ret.Sets.Add(S);
            CurOctet += S.Length;
            if (CurOctet >= ret.Length)
            {
                break;
            }
        }
        
        return ret;
    }

    //These two functions are from here http://snipplr.com/view/15179/adapt-systembitconverter-to-handle-big-endian-network-byte-ordering-in-order-to-create-number-types-from-bytes-and-viceversa/
    //BitConverter.ToUInt16 would parse the results in "little endian" order so 0x000a would actually be parsed as 0x0a00 and give you 2,560 instead of 10.
    //The spec says that everything should be in "big endian" (also known as "network order"
    public static UInt16 ToUInt16BigEndian(byte[] value, int startIndex)
    {
        return System.BitConverter.ToUInt16(value.Reverse().ToArray(), value.Length - sizeof(UInt16) - startIndex);
    }
    public static UInt32 ToUInt32BigEndian(byte[] value, int startIndex)
    {
        return System.BitConverter.ToUInt32(value.Reverse().ToArray(), value.Length - sizeof(UInt32) - startIndex);
    }
    struct IPFIX
    {
        public UInt16 Version;
        public UInt16 Length;
        public DateTime ExportTime;
        public UInt32 SequenceNumber;
        public UInt32 ObservationDomainID;
        public List<Set> Sets;
    }
    struct Set
    {
        public UInt16 SetId;
        public UInt16 Length;
        public byte[] data;
        public SetType SetType
        {
            get
            {
                if (SetId == 2) return SetType.TemplateSet;
                if (SetId == 3) return SetType.OptionTemplate;
                if (SetId > 255) return SetType.DataSet;
                throw new ArgumentOutOfRangeException("SetId", "SetId not in expected range of 2, 3 or >255");
            }
        }

    }
    enum SetType { TemplateSet, OptionTemplate, DataSet };

One thing to be careful of is "endian-ness". Windows parses values as little endian by default but all values here need to be parsed as big endian per spec. The normal BitConvertor class won't work here so there are two helper functions above that tweak it to work as needed. Also, you'll see that instead of regular ints I'm using UInt16 and UInt32. That's also per spec. An Int16 holds both negative and positive numbers while an UInt16 doesn't have the concept of either (although we generally think of it as positive).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜