Wireshark Pipe Wireshark 使用管道 Wireshark管道作为捕获源 C# Code

先说两句

主要的问题是虽然可以,但是写入管道的包必须得是从链路层开始的,从ip层开始的办法我没有找到,不代表不行,因为我的需求是从ip层,所以我自己加了一个链路层的头

加链路层的头也比较简单从Wireshark抓的包中复制一些就可以了

并且往管道里写单纯的包也不行,必须还要加一些Wireshark支持的协议头,所以也就变成

Wireshark协议头 -> 链路层 -> 等等

还好从官网抄了一些C#代码,不用自己构造Wireshark协议头,但代码被我改了,全部代码我贴在文章后面

具体的文档参考这里,也有别的语言的实现  https://wiki.wireshark.org/CaptureSetup/Pipes

协议具体格式 https://www.wireshark.org/docs/dfref/f/file-pcap.html

可以这样用

//自动加上Wireshark协议头,你只要保证是从链路层开始就够了

//对面链接了才会返回,否则阻塞
var wir = WiresharkSender.Create("你起的管道的名字");

//写入包,必须要从链路层开始
wir.SendToWireshark(buffer, offset,count);


WiresharkSender构造函数还有一个参数被我隐藏了,主要是一个数据类型?我也不太清楚,我输入1 Wireshark能正常解析包,
假日你的链路层不是以太网则可以参考这里修改
https://www.tcpdump.org/linktypes.html


最重要的Wireshark中如何设置
官方是以命令行参数给的示例,改快捷方式应该也行
比如
Wireshark -ni \\.\pipe\你起的管道名字
从UI里也可以改


只不过参数直接填
\\.\pipe\你起的管道名字
然后回车几下,否则可能什么都没有改变
然后接口主界面里就有相应的项了,只不过退出就没了,不会保存设置








代码

/**************************************************************************
*                           MIT License
* 
* Copyright (C) 2015 Frederic Chaxel <fchaxel@free.fr>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;
using System.IO.Pipes;
using System.Threading;
//
// object creation could be done with 
//      var ws=new Wireshark.WiresharkSender("bacnet",165);  // pipe name is \\.\pipe\bacnet
//
// data to wireshark could be sent with something like that
//      if (ws.isConnected)
//          ws.SendToWireshark(new byte[]{0x55,0xFF,0,5,6,0,0,4}, 0, 8);
//
// Wireshark can be launch with : Wireshark -ni \\.\pipe\bacnet
//
// ... enjoy
//
namespace Wireshark
{
    // Pcap Global Header
    [StructLayout(LayoutKind.Sequential, Pack=1)]
    struct pcap_hdr_g
    {
        UInt32 magic_number;   /* magic number */
        UInt16 version_major;  /* major version number */
        UInt16 version_minor;  /* minor version number */
        Int32  thiszone;       /* GMT to local correction */
        UInt32 sigfigs;        /* accuracy of timestamps */
        UInt32 snaplen;        /* max length of captured packets, in octets */
        UInt32 network;        /* data link type */

        public pcap_hdr_g(UInt32 snaplen, UInt32 network)
        {
            magic_number = 0xa1b2c3d4;
            version_major = 2;
            version_minor = 4;
            thiszone = 0;
            sigfigs = 0;
            this.snaplen = snaplen;
            this.network = network;
        }
     
        // struct Marshaling
        // Maybe a 'manual' byte by byte serialization could be required on some systems
        // work well on Win32, Win64 .NET 3.0 to 4.5
        public byte[] ToByteArray()
        {
            int rawsize = Marshal.SizeOf(this);
            byte[] rawdatas = new byte[rawsize];
            GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
            IntPtr buffer = handle.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, buffer, false);
            handle.Free();
            return rawdatas;
        } 
    }

    // Pcap Packet Header
    [StructLayout(LayoutKind.Sequential, Pack=1)]
    struct pcap_hdr_p
    {
        UInt32 ts_sec;         /* timestamp seconds */
        UInt32 ts_usec;        /* timestamp microseconds */
        UInt32 incl_len;       /* number of octets of packet saved in file */
        UInt32 orig_len;       /* actual length of packet */

        public pcap_hdr_p(UInt32 lenght, UInt32 datetime, UInt32 microsecond)
        {
            incl_len=orig_len = lenght;
            ts_sec = datetime;
            ts_usec = microsecond;
        }

        // struct Marshaling
        // Maybe a 'manual' byte by byte serialise could be required on some system
        public byte[] ToByteArray()
        {
            int rawsize = Marshal.SizeOf(this);
            byte[] rawdatas = new byte[rawsize];
            GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
            IntPtr buffer = handle.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, buffer, false);
            handle.Free();
            return rawdatas;
        }             
    }

    public class WiresharkSender
    {
        private readonly object m_lock = new object();

        NamedPipeServerStream WiresharkPipe;

        bool IsConnected = false;

        string pipe_name;
        UInt32 pcap_netid;

        object verrou = new object();

        private WiresharkSender(string pipe_name, UInt32 pcap_netid)
        {
            this.pipe_name = pipe_name;
            this.pcap_netid = pcap_netid;  
        }

        public static WiresharkSender Create(string pipe_name)
        {
            WiresharkSender sender = new WiresharkSender(pipe_name, 1);

            sender.PipeCreate();

            return sender;
        }

        private void PipeCreate()
        {
            
            try
            {
                WiresharkPipe = new NamedPipeServerStream(pipe_name, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
                // Wait
                WiresharkPipe.WaitForConnection();

                // Wireshark Global Header
                pcap_hdr_g p = new pcap_hdr_g(65535, pcap_netid);
                byte[] bh = p.ToByteArray();
                WiresharkPipe.Write(bh, 0, bh.Length);

                IsConnected = true;

            }
            catch { }

        }

        private bool isConnected
        {
            get { return IsConnected; }
        }

        private UInt32 DateTimeToUnixTimestamp(DateTime dateTime)
        {
            return (UInt32)(dateTime - new DateTime(1970, 1, 1).ToLocalTime()).TotalSeconds;
        }

        public bool SendToWireshark(byte[] buffer, int offset, int lenght)
        {
            lock (m_lock)
            {
                return SendToWireshark(buffer, offset, lenght, DateTime.Now);
            }

           
        }

        private bool SendToWireshark(byte[] buffer, int offset, int lenght, DateTime date)
        {
            UInt32 date_sec, date_usec;

            // Suppress all values for ms, us and ns
            DateTime d2 = new DateTime((date.Ticks / (long)10000000) * (long)10000000);

            date_sec = DateTimeToUnixTimestamp(date);
            date_usec =( UInt32)((date.Ticks - d2.Ticks) / 10);         

            return SendToWireshark(buffer, offset, lenght, date_sec, date_usec);
        }

        private bool SendToWireshark(byte[] buffer, int offset, int lenght, UInt32 date_sec, UInt32 date_usec)
        {
            if (IsConnected == false)
                return false;

            if (buffer == null) return false;
            if (buffer.Length < (offset + lenght)) return false;
            
            pcap_hdr_p pHdr = new pcap_hdr_p((UInt32)lenght, date_sec, date_usec);
            byte[] b = pHdr.ToByteArray();

            try
            {
                // Wireshark Header
                WiresharkPipe.Write(b, 0, b.Length);
                // Bacnet packet
                WiresharkPipe.Write(buffer, offset, lenght);
            }
            catch (System.IO.IOException)
            {
                // broken pipe, try to restart
                IsConnected = false;
                WiresharkPipe.Close();
                WiresharkPipe.Dispose();
                Thread th = new Thread(PipeCreate);
                th.IsBackground = true;
                th.Start();
                return false;
            }
            catch (Exception)
            {
                // Unknow error, not due to the pipe
                // No need to restart it
                return false;
            }

            return true;
        }

    }
}

 




posted @ 2021-03-23 15:39  FfD4edyo  阅读(1121)  评论(0)    收藏  举报