/********************************************************************************\ * Uruky Project * * * * Copyright (C) 2006 Ahmed Zamil - ahmed@dijlh.com * * http://www.dijlh.com * * * * 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. * * * * File: Packet.cs * * Description: Ethernet/ARP/IPv4/TCP/UDP Packet Decoding & Encoding Class * * Compatibility: .Net Framework 2.0 / Mono 1.1.8 * * * \********************************************************************************/ using System; using System.Text; using Esiur.Misc; using Esiur.Net.DataLink; using System.Net.NetworkInformation; using Esiur.Data; namespace Esiur.Net.Packets { internal static class Functions { public static void AddData(ref byte[] dest, byte[] src) { int I = 0; if (src == null) { return; } if (dest != null) { I = dest.Length; Array.Resize(ref dest, dest.Length + src.Length); //dest = (byte[])Resize(dest, dest.Length + src.Length); } else { dest = new byte[src.Length]; } Array.Copy(src, 0, dest, I, src.Length); } /* public static Array Resize(Array array, int newSize) { Type myType = Type.GetType(array.GetType().FullName.TrimEnd('[', ']')); Array nA = Array.CreateInstance(myType, newSize); Array.Copy(array, nA, (newSize > array.Length ? array.Length : newSize)); return nA; } */ //Computes the checksum used in IP, ARP..., ie the // "The 16 bit one's complement of the one 's complement sum //of all 16 bit words" as seen in RFCs // Returns a 4 characters hex string // data's lenght must be multiple of 4, else zero padding public static ushort IP_CRC16(byte[] data) { ulong Sum = 0; bool Padding = false; /// * Padding if needed if (data.Length % 2 != 0) { Array.Resize(ref data, data.Length + 1); //data = (byte[])Resize(data, data.Length + 1); Padding = true; } int count = data.Length; ///* add 16-bit words */ while (count > 0) //1) { ///* this is the inner loop */ Sum += GetInteger(data[count - 2], data[count - 1]); ///* Fold 32-bit sum to 16-bit */ while (Sum >> 16 != 0) { Sum = (Sum & 0XFFFF) + (Sum >> 16); } count -= 2; } /// * reverse padding if (Padding) { Array.Resize(ref data, data.Length - 1); //data = (byte[])Resize(data, data.Length - 1); } ///* Return one's compliment of final sum. //return (ushort)(ushort.MaxValue - (ushort)Sum); return (ushort)(~Sum); } public static ushort GetInteger(byte B1, byte B2) { return BitConverter.ToUInt16(new byte[] { B2, B1 }, 0); //return System.Convert.ToUInt16("&h" + GetHex(B1) + GetHex(B2)); } public static uint GetLong(byte B1, byte B2, byte B3, byte B4) { return BitConverter.ToUInt32(new byte[] { B4, B3, B2, B1 }, 0); //return System.Convert.ToUInt32("&h" + GetHex(B1) + GetHex(B2) + GetHex(B3) + GetHex(B4)); } public static string GetHex(byte B) { return (((B < 15) ? 0 + System.Convert.ToString(B, 16).ToUpper() : System.Convert.ToString(B, 16).ToUpper())); } public static bool GetBit(uint B, byte Pos) { //return BitConverter.ToBoolean(BitConverter.GetBytes(B), Pos + 1); return (B & (uint)(Math.Pow(2, (Pos - 1)))) == (Math.Pow(2, (Pos - 1))); } public static ushort RemoveBit(ushort I, byte Pos) { return (ushort)RemoveBit((uint)I, Pos); } public static uint RemoveBit(uint I, byte Pos) { if (GetBit(I, Pos)) { return I - (uint)(Math.Pow(2, (Pos - 1))); } else { return I; } } public static void SplitInteger(ushort I, ref byte BLeft, ref byte BRight) { byte[] b = BitConverter.GetBytes(I); BLeft = b[1]; BRight = b[0]; //BLeft = I >> 8; //BRight = (I << 8) >> 8; } public static void SplitLong(uint I, ref byte BLeft, ref byte BLeftMiddle, ref byte BRightMiddle, ref byte BRight) { byte[] b = BitConverter.GetBytes(I); BLeft = b[3]; BLeftMiddle = b[2]; BRightMiddle = b[1]; BRight = b[0]; //BLeft = I >> 24; //BLeftMiddle = (I << 8) >> 24; //BRightMiddle = (I << 16) >> 24; //BRight = (I << 24) >> 24; } } public class PosixTime { ulong seconds; ulong microseconds; PosixTime(ulong Seconds, ulong Microseconds) { seconds = Seconds; microseconds = Microseconds; } public override string ToString() { return seconds + "." + microseconds; } } public class Packet { //public EtherServer2.EthernetSource Source; public PacketSource Source; public DateTime Timestamp; public enum PPPType : ushort { IP = 0x0021, // Internet Protocol version 4 [RFC1332] SDTP = 0x0049, // Serial Data Transport Protocol (PPP-SDTP) [RFC1963] IPv6HeaderCompression = 0x004f, // IPv6 Header Compression IPv6 = 0x0057, // Internet Protocol version 6 [RFC5072] W8021dHelloPacket = 0x0201, // 802.1d Hello Packets [RFC3518] IPv6ControlProtocol = 0x8057, // IPv6 Control Protocol [RFC5072] } public enum ProtocolType : ushort { IP = 0x800, // IPv4 ARP = 0x806, // Address Resolution Protocol IPv6 = 0x86DD, // IPv6 FrameRelayARP = 0x0808, // Frame Relay ARP [RFC1701] VINESLoopback = 0x0BAE, // VINES Loopback [RFC1701] VINESEcho = 0x0BAF, // VINES ECHO [RFC1701] TransEtherBridging = 0x6558, // TransEther Bridging [RFC1701] RawFrameRelay = 0x6559, // Raw Frame Relay [RFC1701] IEE8021QVLAN = 0x8100, // IEEE 802.1Q VLAN-tagged frames (initially Wellfleet) SNMP = 0x814C, // SNMP [JKR1] TCPIP_Compression = 0x876B, // TCP/IP Compression [RFC1144] IPAutonomousSystems = 0x876C, // IP Autonomous Systems [RFC1701] SecureData = 0x876D, // Secure Data [RFC1701] PPP = 0x880B, // PPP [IANA] MPLS = 0x8847, // MPLS [RFC5332] MPLS_UpstreamAssignedLabel = 0x8848, // MPLS with upstream-assigned label [RFC5332] PPPoEDiscoveryStage = 0x8863, // PPPoE Discovery Stage [RFC2516] PPPoESessionStage = 0x8864, // PPPoE Session Stage [RFC2516] } /* public static void GetPacketMACAddresses(Packet packet, out byte[] srcMAC, out byte[] dstMAC) { // get the node address Packet root = packet.RootPacket; if (root is TZSPPacket) { TZSPPacket tp = (TZSPPacket)root; if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.Ethernet) { EthernetPacket ep = (EthernetPacket)tp.SubPacket; srcMAC = ep.SourceMAC; dstMAC = ep.DestinationMAC; } else if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.IEEE802_11) { W802_11Packet wp = (W802_11Packet)tp.SubPacket; srcMAC = wp.SA; dstMAC = wp.DA; } else { srcMAC = null; dstMAC = null; } } else if (root is EthernetPacket) { EthernetPacket ep = (EthernetPacket)root; srcMAC = ep.SourceMAC; dstMAC = ep.DestinationMAC; } else if (root is W802_11Packet) { W802_11Packet wp = (W802_11Packet)root; srcMAC = wp.SA; dstMAC = wp.DA; } else { srcMAC = null; dstMAC = null; } } public static void GetPacketAddresses(Packet packet, ref string srcMAC, ref string dstMAC, ref string srcIP, ref string dstIP) { if (packet is TCPv4Packet) { if (packet.ParentPacket is IPv4Packet) { IPv4Packet ip = (IPv4Packet)packet.ParentPacket; srcIP = ip.SourceIP.ToString(); dstIP = ip.DestinationIP.ToString(); } } // get the node address Packet root = packet.RootPacket; if (root is TZSPPacket) { TZSPPacket tp = (TZSPPacket)root; if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.Ethernet) { EthernetPacket ep = (EthernetPacket)tp.SubPacket; srcMAC = DC.GetPhysicalAddress(ep.SourceMAC, 0).ToString(); dstMAC = DC.GetPhysicalAddress(ep.DestinationMAC, 0).ToString(); } else if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.IEEE802_11) { W802_11Packet wp = (W802_11Packet)tp.SubPacket; srcMAC = DC.GetPhysicalAddress(wp.SA, 0).ToString(); dstMAC = DC.GetPhysicalAddress(wp.DA, 0).ToString(); } } else if (root is EthernetPacket) { EthernetPacket ep = (EthernetPacket)root; srcMAC = DC.GetPhysicalAddress(ep.SourceMAC, 0).ToString(); dstMAC = DC.GetPhysicalAddress(ep.DestinationMAC, 0).ToString(); } else if (root is W802_11Packet) { W802_11Packet wp = (W802_11Packet)root; srcMAC = DC.GetPhysicalAddress(wp.SA, 0).ToString(); dstMAC = DC.GetPhysicalAddress(wp.DA, 0).ToString(); } } */ PosixTime Timeval; public byte[] Header; public byte[] Preamble; //public byte[] Payload; public byte[] Data; public Packet SubPacket; public Packet ParentPacket; public virtual long Parse(byte[] data, uint offset, uint ends) { return 0; } public virtual bool Compose() { return false; } public Packet RootPacket { get { Packet root = this; while (root.ParentPacket != null) root = root.ParentPacket; return root; } } public Packet LeafPacket { get { Packet leaf = this; while (leaf.SubPacket != null) leaf = leaf.SubPacket; return leaf; } } } } /************************************ EOF *************************************/