/// <summary>
        ///     Write interface description block to output file based on specified interface instance
        /// </summary>
        private UInt32 WriteInterfaceDescriptionBlock(BinaryWriter binWriter, PcapNgInterface iface)
        {
            var blockTotalLength = this.CountInterfaceDescriptionBlockSize();

            binWriter.Write((UInt32)0x00000001); // Block type
            binWriter.Write(blockTotalLength);   // Block total length
            binWriter.Write(iface.LinkType);     // LinkType
            binWriter.Write((UInt16)0x0000);     // reserved
            binWriter.Write(iface.SnapLen);

            // Option tsresol :
            binWriter.Write((UInt16)PcapNgInterface.InterfaceOptions.IfTsresol);
            binWriter.Write((UInt16)0x0001);

            binWriter.Write((Byte)0x09);  // in nanoseconds
            binWriter.Write((Byte)0x00);  // padding
            binWriter.Write((Byte)0x00);  // padding
            binWriter.Write((Byte)0x00);  // padding

            // Option opt_endofopt :
            binWriter.Write((UInt32)0x0000);

            binWriter.Write(blockTotalLength); // Block total length

            return(blockTotalLength);
        }
Exemplo n.º 2
0
        private PcapNgInterface _iface;    // holds link to interface to which frame belongs

        /// <summary>
        ///     Constructor used when indexing
        /// </summary>
        public PmFramePcapNg(
            PmCaptureBase pmCapture,
            Int64 fraIndex,
            Int64 fraOffset,
            PmLinkType pmLinkType,
            DateTime timeStamp,
            Int64 oriLength,
            Int64 incLength,
            FrameBLockType type,
            PcapNgInterface iface) : base(pmCapture, pmLinkType, timeStamp, incLength, PmFrameType.PcapNg, fraIndex, oriLength)
        {
            this.FrameOffset = fraOffset;
            this._blockType  = type;
            this._iface      = iface;

            UInt32 startOffset = 0;

            switch (this._blockType)
            {
            case FrameBLockType.EnhancedPacket:
                startOffset = 28;
                break;

            case FrameBLockType.SimplePacket:
                startOffset = 12;
                break;

            case FrameBLockType.PacketBlock:
                startOffset = 28;
                break;
            }
            this.L2Offset = this.FrameOffset + startOffset;
        }
        /// <summary>
        ///     Create PCAP-ng file that includes all frames stored in current instace.
        ///     For each link type will be created "virtual interface" and all frames
        ///     with this link type will in output file belong to it.
        /// </summary>
        private Boolean CreatePcapNgOutput(String outputFile)
        {
            try
            {
                // holds list of all link types inclede in frame vector
                var framesLinkTypes = new List <PmLinkType>();

                // TODO - optimize LINQ ?
                foreach (var fr in this.PmCapture.Frames)
                {
                    if (!framesLinkTypes.Contains(fr.PmLinkType))
                    {
                        framesLinkTypes.Add(fr.PmLinkType);
                    }
                }

                // holds list of new created virtual interfaces :
                var virtualInterfaces = new List <PcapNgInterface>();
                // directory for faster lookup :
                var virtualInterfacesDictionary = new Dictionary <PmLinkType, PcapNgInterface>();

                UInt16 ifaceId = 0;
                foreach (var type in framesLinkTypes)
                {
                    // create new itnerface for each link type :
                    var newIface = new PcapNgInterface((UInt16)ConvertCommonLayer2ToPcapNgLayer2(type), ifaceId);
                    virtualInterfaces.Add(newIface);
                    virtualInterfacesDictionary.Add(type, newIface);
                    ifaceId++;
                }

                // open output file stream :
                var binWriter = new BinaryWriter(File.Open(Path.GetFullPath(outputFile), FileMode.Create, FileAccess.Write, FileShare.ReadWrite));

                // skipt section header for now - will be add at end
                binWriter.BaseStream.Seek(this.CountSectionHeaderBlockSize(), SeekOrigin.Begin);
                var sectionSize = virtualInterfaces.Aggregate <PcapNgInterface, UInt64>(0, (current, iface) => current + this.WriteInterfaceDescriptionBlock(binWriter, iface));

                sectionSize = this.PmCapture.Frames.Aggregate(sectionSize, (current, fr) => current + this.WriteEnhancedPacketBlock(binWriter, fr, virtualInterfacesDictionary));

                // add section header size (section size is now known) :
                binWriter.BaseStream.Seek(0, SeekOrigin.Begin);
                this.WriteSectionHeaderBlock(binWriter, sectionSize);

                // close output file
                binWriter.Close();
            }
            /* If anything went bad generate exception and return false */
            catch (Exception ex) //todo to general
            {
                //todo fix
                //Log.Error("PmCaptureProcessorPcapNg General error", ex);
                PmConsolePrinter.PrintError(ex.Message);
                return(false);
            }
            /* otherwise return true if everything went good */
            return(true);
        }
        private DateTime ConvertUint64ToTimeStamp(UInt64 data, PcapNgInterface iface)
        {
            UInt64 mult;

            if (iface.HasTsresol)
            {
                var tsresol = iface.Tsresol;
                var pow     = (tsresol & 0x7F);
                if ((tsresol & 0x80) == 0) // negPower of 10
                {
                    mult = (UInt64)Math.Pow(10, pow);
                }
                else // negPower of 2
                {
                    mult = (UInt64)Math.Pow(2, pow);
                }
            }
            else
            {
                mult = 1000000;
            }

            var sec  = data / mult;
            var frac = data % mult;

            sec += iface.Tzone;

            const UInt32 ticksPerSecond = 10000000;

            var fracMult = ticksPerSecond / mult;

            //  Console.WriteLine("Ticks per second : " + DateTime.TicksPerSecond);


            var pTime = new DateTime(1970, 01, 01, 0, 0, 0);

            pTime = pTime.AddSeconds(sec);
            pTime = pTime.AddTicks((Int64)(frac * fracMult));
            return(pTime);
        }
        private void ParseInterfaceDescriptionBlock(Int64 offset, Boolean swapValue, UInt16 ifaceId, List <PcapNgInterface> sectionIfaceList)
        {
            var linkType = this.GetInterfaceLinkType(offset, swapValue);
            var snapLen  = this.GetInterfaceSnapLen(offset, swapValue);

            var newIface = new PcapNgInterface(snapLen, linkType, ifaceId);

            sectionIfaceList.Add(newIface);

            var blockLen = this.GetGeneralBlockTotalLength(offset, swapValue);

            var currentOffset  = offset + 16;
            var eofBlockOffset = offset + blockLen - 4;

            // PmConsolePrinter.PrintDebug("Interface description block " + currentOffset + " " + eofBlockOffset);

            var eofFound = false;

            while (!eofFound && currentOffset < eofBlockOffset)
            {
                var optionCode   = this.GetOptionCode(currentOffset, swapValue);
                var optionLength = this.GetOptionLength(currentOffset, swapValue);

                var dataOffset = currentOffset + 4;

                //Console.WriteLine("Option :" + (PcapNgInterface.InterfaceOptions)optionCode + " " + optionLength + " Lenght : "+ optionLength);

                switch ((PcapNgInterface.InterfaceOptions)optionCode)
                {
                case PcapNgInterface.InterfaceOptions.OptEndofopt:
                    eofFound = true;
                    break;

                case PcapNgInterface.InterfaceOptions.IfName:
                    newIface.IfName = this.GetOptionString(dataOffset, optionLength);
                    break;

                case PcapNgInterface.InterfaceOptions.IfDescription:
                    newIface.IfDescription = this.GetOptionString(dataOffset, optionLength);
                    break;

                case PcapNgInterface.InterfaceOptions.IfIPv4Addr:
                    newIface.Addresses.Add(new IPAddress(GetOptionBytes(dataOffset, optionLength), 4));
                    break;

                case PcapNgInterface.InterfaceOptions.IfIPv6Addr:
                    newIface.Addresses.Add(new IPAddress(this.GetOptionBytes(dataOffset, optionLength), 4));
                    break;

                case PcapNgInterface.InterfaceOptions.IfMaCaddr:
                    newIface.MacAddress = this.GetOptionBytes(dataOffset, optionLength);
                    break;

                case PcapNgInterface.InterfaceOptions.IfEuIaddr:
                    newIface.EuiAddr = this.GetOptionBytes(dataOffset, optionLength);
                    break;

                case PcapNgInterface.InterfaceOptions.IfSpeed:
                    newIface.Speed = this.GetOptionUint64(dataOffset, swapValue);
                    break;

                case PcapNgInterface.InterfaceOptions.IfTsresol:
                    newIface.Tsresol    = this.GetOptionByte(dataOffset);
                    newIface.HasTsresol = true;
                    break;

                case PcapNgInterface.InterfaceOptions.IfTzone:
                    newIface.Tzone = this.GetOptionUint64(dataOffset, swapValue);
                    break;

                case PcapNgInterface.InterfaceOptions.IfFilter:
                    newIface.Filter = this.GetOptionBytes(dataOffset, optionLength);
                    break;

                case PcapNgInterface.InterfaceOptions.IfOs:
                    newIface.Os = this.GetOptionString(dataOffset, optionLength);
                    break;

                case PcapNgInterface.InterfaceOptions.IfFcslen:
                    newIface.Fcslen = this.GetOptionByte(dataOffset);
                    break;

                case PcapNgInterface.InterfaceOptions.IfTsoffset:
                    newIface.Tsoffset = this.GetOptionUint64(dataOffset, swapValue);
                    break;
                }

                currentOffset += this.AdjustLength(optionLength) + 4;
            }
        }