Attachment 'WiresharkSender.cs'

Download

   1 /**************************************************************************
   2 *                           MIT License
   3 * 
   4 * Copyright (C) 2015 Frederic Chaxel <fchaxel@free.fr>
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining
   7 * a copy of this software and associated documentation files (the
   8 * "Software"), to deal in the Software without restriction, including
   9 * without limitation the rights to use, copy, modify, merge, publish,
  10 * distribute, sublicense, and/or sell copies of the Software, and to
  11 * permit persons to whom the Software is furnished to do so, subject to
  12 * the following conditions:
  13 *
  14 * The above copyright notice and this permission notice shall be included
  15 * in all copies or substantial portions of the Software.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  21 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24 *
  25 *********************************************************************/
  26 using System;
  27 using System.Runtime.InteropServices;
  28 using System.IO;
  29 using System.Diagnostics;
  30 using System.IO.Pipes;
  31 using System.Threading;
  32 //
  33 // object creation could be done with 
  34 //      var ws=new Wireshark.WiresharkSender("bacnet",165);  // pipe name is \\.\pipe\bacnet
  35 //
  36 // data to wireshark could be sent with something like that
  37 //      if (ws.isConnected)
  38 //          ws.SendToWireshark(new byte[]{0x55,0xFF,0,5,6,0,0,4}, 0, 8);
  39 //
  40 // Wireshark can be launch with : Wireshark -ni \\.\pipe\bacnet
  41 //
  42 // ... enjoy
  43 //
  44 namespace Wireshark
  45 {
  46     // Pcap Global Header
  47     [StructLayout(LayoutKind.Sequential, Pack=1)]
  48     struct pcap_hdr_g
  49     {
  50         UInt32 magic_number;   /* magic number */
  51         UInt16 version_major;  /* major version number */
  52         UInt16 version_minor;  /* minor version number */
  53         Int32  thiszone;       /* GMT to local correction */
  54         UInt32 sigfigs;        /* accuracy of timestamps */
  55         UInt32 snaplen;        /* max length of captured packets, in octets */
  56         UInt32 network;        /* data link type */
  57 
  58         public pcap_hdr_g(UInt32 snaplen, UInt32 network)
  59         {
  60             magic_number = 0xa1b2c3d4;
  61             version_major = 2;
  62             version_minor = 4;
  63             thiszone = 0;
  64             sigfigs = 0;
  65             this.snaplen = snaplen;
  66             this.network = network;
  67         }
  68      
  69         // struct Marshaling
  70         // Maybe a 'manual' byte by byte serialization could be required on some systems
  71         // work well on Win32, Win64 .NET 3.0 to 4.5
  72         public byte[] ToByteArray()
  73         {
  74             int rawsize = Marshal.SizeOf(this);
  75             byte[] rawdatas = new byte[rawsize];
  76             GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
  77             IntPtr buffer = handle.AddrOfPinnedObject();
  78             Marshal.StructureToPtr(this, buffer, false);
  79             handle.Free();
  80             return rawdatas;
  81         } 
  82     }
  83 
  84     // Pcap Packet Header
  85     [StructLayout(LayoutKind.Sequential, Pack=1)]
  86     struct pcap_hdr_p
  87     {
  88         UInt32 ts_sec;         /* timestamp seconds */
  89         UInt32 ts_usec;        /* timestamp microseconds */
  90         UInt32 incl_len;       /* number of octets of packet saved in file */
  91         UInt32 orig_len;       /* actual length of packet */
  92 
  93         public pcap_hdr_p(UInt32 lenght, UInt32 datetime, UInt32 microsecond)
  94         {
  95             incl_len=orig_len = lenght;
  96             ts_sec = datetime;
  97             ts_usec = microsecond;
  98         }
  99 
 100         // struct Marshaling
 101         // Maybe a 'manual' byte by byte serialise could be required on some system
 102         public byte[] ToByteArray()
 103         {
 104             int rawsize = Marshal.SizeOf(this);
 105             byte[] rawdatas = new byte[rawsize];
 106             GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
 107             IntPtr buffer = handle.AddrOfPinnedObject();
 108             Marshal.StructureToPtr(this, buffer, false);
 109             handle.Free();
 110             return rawdatas;
 111         }             
 112     }
 113 
 114     public class WiresharkSender
 115     {
 116         NamedPipeServerStream WiresharkPipe;
 117 
 118         bool IsConnected = false;
 119 
 120         string pipe_name;
 121         UInt32 pcap_netid;
 122 
 123         object verrou = new object();
 124 
 125         public WiresharkSender(string pipe_name, UInt32 pcap_netid)
 126         {
 127             this.pipe_name = pipe_name;
 128             this.pcap_netid = pcap_netid;
 129 
 130             // Open the pipe and wait to Wireshark on a background thread
 131             Thread th = new Thread(PipeCreate);
 132             th.IsBackground = true;
 133             th.Start();
 134         }
 135 
 136         private void PipeCreate()
 137         {
 138             
 139             try
 140             {
 141                 WiresharkPipe = new NamedPipeServerStream(pipe_name, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
 142                 // Wait
 143                 WiresharkPipe.WaitForConnection();
 144 
 145                 // Wireshark Global Header
 146                 pcap_hdr_g p = new pcap_hdr_g(65535, pcap_netid);
 147                 byte[] bh = p.ToByteArray();
 148                 WiresharkPipe.Write(bh, 0, bh.Length);
 149 
 150                 IsConnected = true;
 151 
 152             }
 153             catch { }
 154 
 155         }
 156 
 157         public bool isConnected
 158         {
 159             get { return IsConnected; }
 160         }
 161 
 162         private UInt32 DateTimeToUnixTimestamp(DateTime dateTime)
 163         {
 164             return (UInt32)(dateTime - new DateTime(1970, 1, 1).ToLocalTime()).TotalSeconds;
 165         }
 166 
 167         public bool SendToWireshark(byte[] buffer, int offset, int lenght)
 168         {
 169             return SendToWireshark(buffer, offset, lenght, DateTime.Now);
 170         }
 171 
 172         public bool SendToWireshark(byte[] buffer, int offset, int lenght, DateTime date)
 173         {
 174             UInt32 date_sec, date_usec;
 175 
 176             // Suppress all values for ms, us and ns
 177             DateTime d2 = new DateTime((date.Ticks / (long)10000000) * (long)10000000);
 178 
 179             date_sec = DateTimeToUnixTimestamp(date);
 180             date_usec =( UInt32)((date.Ticks - d2.Ticks) / 10);         
 181 
 182             return SendToWireshark(buffer, offset, lenght, date_sec, date_usec);
 183         }
 184 
 185         public bool SendToWireshark(byte[] buffer, int offset, int lenght, UInt32 date_sec, UInt32 date_usec)
 186         {
 187             if (IsConnected == false)
 188                 return false;
 189 
 190             if (buffer == null) return false;
 191             if (buffer.Length < (offset + lenght)) return false;
 192             
 193             pcap_hdr_p pHdr = new pcap_hdr_p((UInt32)lenght, date_sec, date_usec);
 194             byte[] b = pHdr.ToByteArray();
 195 
 196             try
 197             {
 198                 // Wireshark Header
 199                 WiresharkPipe.Write(b, 0, b.Length);
 200                 // Bacnet packet
 201                 WiresharkPipe.Write(buffer, offset, lenght);
 202             }
 203             catch (System.IO.IOException)
 204             {
 205                 // broken pipe, try to restart
 206                 IsConnected = false;
 207                 WiresharkPipe.Close();
 208                 WiresharkPipe.Dispose();
 209                 Thread th = new Thread(PipeCreate);
 210                 th.IsBackground = true;
 211                 th.Start();
 212                 return false;
 213             }
 214             catch (Exception)
 215             {
 216                 // Unknow error, not due to the pipe
 217                 // No need to restart it
 218                 return false;
 219             }
 220 
 221             return true;
 222         }
 223 
 224     }
 225 }

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2015-03-04 04:17:02, 7.8 KB) [[attachment:WiresharkSender.cs]]
 All files | Selected Files: delete move to page

You are not allowed to attach a file to this page.