public static void NameResolutionOption_ConvertToByte_Test(bool reorder)
            {
                NameResolutionOption preOption = new NameResolutionOption();
                NameResolutionOption postOption;
                preOption.Comment = "Test Comment";
                preOption.DnsName = "Dns Name";
                preOption.DnsIp4Addr = new IPAddress(new byte[] { 127, 0, 0, 1 });
                preOption.DnsIp6Addr = new IPAddress(new byte[] { 0x20, 0x01, 0x0d, 0x0db, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x28, 0x57, 0xab });

                byte[] preOptionByte = preOption.ConvertToByte(reorder, null);

                using (MemoryStream stream = new MemoryStream(preOptionByte))
                {
                    using (BinaryReader binaryReader = new BinaryReader(stream))
                    {
                        postOption = NameResolutionOption.Parse(binaryReader, reorder, null);
                    }
                }

                Assert.IsNotNull(postOption);
                Assert.AreEqual(preOption.Comment, postOption.Comment);
                Assert.AreEqual(preOption.DnsName, postOption.DnsName);
                Assert.AreEqual(preOption.DnsIp4Addr, postOption.DnsIp4Addr);
                Assert.AreEqual(preOption.DnsIp6Addr, postOption.DnsIp6Addr);

            }
            public static void NameResolutionOption_ConvertToByte_Test(bool reorder)
            {
                NameResolutionOption preOption = new NameResolutionOption();
                NameResolutionOption postOption;

                preOption.Comment    = "Test Comment";
                preOption.DnsName    = "Dns Name";
                preOption.DnsIp4Addr = new IPAddress(new byte[] { 127, 0, 0, 1 });
                preOption.DnsIp6Addr = new IPAddress(new byte[] { 0x20, 0x01, 0x0d, 0x0db, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x28, 0x57, 0xab });

                byte[] preOptionByte = preOption.ConvertToByte(reorder, null);

                using (MemoryStream stream = new MemoryStream(preOptionByte))
                {
                    using (BinaryReader binaryReader = new BinaryReader(stream))
                    {
                        postOption = NameResolutionOption.Parse(binaryReader, reorder, null);
                    }
                }

                Assert.IsNotNull(postOption);
                Assert.AreEqual(preOption.Comment, postOption.Comment);
                Assert.AreEqual(preOption.DnsName, postOption.DnsName);
                Assert.AreEqual(preOption.DnsIp4Addr, postOption.DnsIp4Addr);
                Assert.AreEqual(preOption.DnsIp6Addr, postOption.DnsIp6Addr);
            }
        public static NameResolutionOption Parse(BinaryReader binaryReader, bool reverseByteOrder, Action<Exception> ActionOnException)
        {
            Contract.Requires<ArgumentNullException>(binaryReader != null, "binaryReader cannot be null");

            NameResolutionOption option = new NameResolutionOption();
            List<KeyValuePair<ushort, byte[]>> optionsList = EkstractOptions(binaryReader, reverseByteOrder, ActionOnException);
            if (optionsList.Any())
            {
                foreach (var item in optionsList)
                {
                    try
                    {
                        switch (item.Key)
                        {
                            case (ushort)NameResolutionOptionCode.CommentCode:
                                option.Comment = UTF8Encoding.UTF8.GetString(item.Value);
                                break;
                            case (ushort)NameResolutionOptionCode.DnsNameCode:
                                option.DnsName = UTF8Encoding.UTF8.GetString(item.Value);
                                break;
                            case (ushort)NameResolutionOptionCode.DnsIp4AddrCode:
                                if (item.Value.Length == 4)
                                    option.DnsIp4Addr = new IPAddress(item.Value);
                                else
                                    throw new ArgumentException(string.Format("[NameResolutionOption.Parse] DnsIp4AddrCode contains invalid length. Received: {0} bytes, expected: {1}", item.Value.Length, 4));
                                break;
                            case (ushort)NameResolutionOptionCode.DnsIp6AddrCode:                                
                                if (item.Value.Length == 16)
                                    option.DnsIp6Addr = new IPAddress(item.Value);
                                else
                                    throw new ArgumentException(string.Format("[NameResolutionOption.Parse] DnsIp6AddrCode contains invalid length. Received: {0} bytes, expected: {1}", item.Value.Length, 16));
                                break;
                            case (ushort)NameResolutionOptionCode.EndOfOptionsCode:
                            default:
                                break;
                        }
                    }
                    catch (Exception exc)
                    {
                        if (ActionOnException != null)
                            ActionOnException(exc);
                    }
                }
            }
            return option;
        }
        public static NameResolutionOption Parse(BinaryReader binaryReader, bool reverseByteOrder, Action <Exception> ActionOnException)
        {
            //Contract.Requires<ArgumentNullException>(binaryReader != null, "binaryReader cannot be null");

            NameResolutionOption option = new NameResolutionOption();
            List <KeyValuePair <ushort, byte[]> > optionsList = EkstractOptions(binaryReader, reverseByteOrder, ActionOnException);

            if (optionsList.Any())
            {
                foreach (var item in optionsList)
                {
                    try
                    {
                        switch (item.Key)
                        {
                        case (ushort)NameResolutionOptionCode.CommentCode:
                            option.Comment = UTF8Encoding.UTF8.GetString(item.Value);
                            break;

                        case (ushort)NameResolutionOptionCode.DnsNameCode:
                            option.DnsName = UTF8Encoding.UTF8.GetString(item.Value);
                            break;

                        case (ushort)NameResolutionOptionCode.DnsIp4AddrCode:
                            if (item.Value.Length == 4)
                            {
                                option.DnsIp4Addr = new IPAddress(item.Value);
                            }
                            else
                            {
                                throw new ArgumentException(string.Format("[NameResolutionOption.Parse] DnsIp4AddrCode contains invalid length. Received: {0} bytes, expected: {1}", item.Value.Length, 4));
                            }
                            break;

                        case (ushort)NameResolutionOptionCode.DnsIp6AddrCode:
                            if (item.Value.Length == 16)
                            {
                                option.DnsIp6Addr = new IPAddress(item.Value);
                            }
                            else
                            {
                                throw new ArgumentException(string.Format("[NameResolutionOption.Parse] DnsIp6AddrCode contains invalid length. Received: {0} bytes, expected: {1}", item.Value.Length, 16));
                            }
                            break;

                        case (ushort)NameResolutionOptionCode.EndOfOptionsCode:
                        default:
                            break;
                        }
                    }
                    catch (Exception exc)
                    {
                        if (ActionOnException != null)
                        {
                            ActionOnException(exc);
                        }
                    }
                }
            }
            return(option);
        }
 /// <summary>
 /// The Name Resolution Block is used to support the correlation of numeric addresses (present in the captured packets) and their 
 /// corresponding canonical names and it is optional. Having the literal names saved in the file, this prevents the need of a name 
 /// resolution in a delayed time, when the association between names and addresses can be different from the one in use at capture time. 
 /// Moreover, the Name Resolution Block avoids the need of issuing a lot of DNS requests every time the trace capture is opened, 
 /// and allows to have name resolution also when reading the capture with a machine not connected to the network.
 /// A Name Resolution Block is normally placed at the beginning of the file, but no assumptions can be taken about its position. 
 /// Name Resolution Blocks can be added in a second time by tools that process the file, like network analyzers.
 /// </summary>
 public NameResolutionBlock(NameResolutionRecord nameResolutionRecords, NameResolutionOption Options, long PositionInStream = 0)
 {              
     Contract.Requires<ArgumentNullException>(Options != null, "Options cannot be null");
     Contract.Requires<ArgumentNullException>(nameResolutionRecords != null, "NameResolutionRecords cannot be null");
     this.NameResolutionRecords = nameResolutionRecords;            
     this.options = Options;
     this.PositionInStream = PositionInStream;
 }