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; } } }
浙公网安备 33010602011771号