Sylloge
A C# helper library
code/Net/Net.cs
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 namespace Sylloge
00018 {
00019     public static partial class Net
00020     {
00024         public static class IPv4
00025         {
00029             public struct StructInterface
00030             {
00031                 public bool IsLoopback;
00032                 public string IpAddress;
00033                 public string SubnetMask;
00034                 public string Broadcast;
00035                 public System.Net.NetworkInformation.PhysicalAddress MAC;
00036                 public System.Net.NetworkInformation.NetworkInterface Interface;
00037             }
00038 
00042             public static Sylloge.Net.IPv4.StructInterface[] Interfaces
00043             {
00044                 get
00045                 {
00046                     System.Collections.Generic.List<Sylloge.Net.IPv4.StructInterface> ifaces = new System.Collections.Generic.List<Sylloge.Net.IPv4.StructInterface>();
00047                     foreach (System.Net.NetworkInformation.NetworkInterface iface in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()) {
00048                         bool lback = (iface.NetworkInterfaceType == System.Net.NetworkInformation.NetworkInterfaceType.Loopback);
00049                         foreach (System.Net.NetworkInformation.UnicastIPAddressInformation IP in iface.GetIPProperties().UnicastAddresses) {
00050                             if (IP.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) {
00051                                 if (IP != null && IP.Address != null && IP.IPv4Mask != null) {
00052                                     Sylloge.Net.IPv4.StructInterface Item = new Sylloge.Net.IPv4.StructInterface();
00053                                     Item.Interface = iface;
00054                                     Item.IsLoopback = lback;
00055                                     Item.IpAddress = IP.Address.ToString();
00056                                     Item.SubnetMask = IP.IPv4Mask.ToString();
00057                                     Item.MAC = iface.GetPhysicalAddress();
00058                                     Item.Broadcast = Sylloge.Net.IPv4.GetBroadcastFromIpAndSubnet(Item.IpAddress, Item.SubnetMask);
00059                                     ifaces.Add(Item);
00060                                 }
00061 
00062                             }
00063                         }
00064                     }
00065                     return ifaces.ToArray();
00066                 }
00067             }
00068 
00076             public static string GetBroadcastFromIpAndSubnet(string ipAddress, string subnetMask)
00077             {
00078                 if (!Sylloge.Net.IPv4.IsValidIp(ipAddress)) { throw new System.FormatException("Invalid IP address"); }
00079                 if (!Sylloge.Net.IPv4.IsValidIp(subnetMask)) { throw new System.FormatException("Invalid subnet mask"); }
00080                 string[] curip = ipAddress.Split('.');
00081                 string[] curmsk = subnetMask.Split('.');
00082                 string[] bcast = { "", "", "", "" };
00083                 for (int count = 0; count < 3; count++) {
00084                     int bs = (int)(System.Convert.ToInt32(curip[count]) | (int)(System.Convert.ToInt32(curmsk[count]) ^ 255));
00085                     bcast[count] = bs.ToString();
00086                 }
00087                 return string.Format("{0}.{1}.{2}.{3}", bcast[0], bcast[1], bcast[2], bcast[3]);
00088             }
00089 
00095             public static bool IsValidIp(string ipAddress)
00096             {
00097                 System.Net.IPAddress o = new System.Net.IPAddress(0);
00098                 if (!System.Net.IPAddress.TryParse(ipAddress, out o)) { return false; }
00099                 return o.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork;
00100             }
00101         }
00102 
00106         public class IpHeader
00107         {
00108             public delegate void IpErrorEventHandler(string message);
00112             public event IpErrorEventHandler IpError;
00113 
00114             public enum IpProtocol
00115             {
00116                 TCP = 6,
00117                 UDP = 17,
00118                 UNKNOWN = -1
00119             }
00120 
00121             #region Properties
00122 
00123             //IP Header fields
00124             // Eight bits for version and header length
00125             private byte _VersionAndHeaderLength;
00126             // Eight bits for differentiated services (TOS)
00127             private byte _DifferentiatedServices;
00128             // Sixteen bits for total length of the datagram (header + message)
00129             private ushort _TotalLength;
00130             // Sixteen bits for identification
00131             private ushort _Identification;
00132             // Eight bits for flags and fragmentation offset
00133             private ushort _FlagsAndOffset;
00134             // Eight bits for TTL (Time To Live)
00135             private byte _TTL;
00136             // Eight bits for the underlying protocol
00137             private byte _Protocol;
00138             // Sixteen bits containing the checksum of the header, (checksum can be negative so taken as short)
00139             private short _Checksum;
00140             // Thirty two bit source IP Address
00141             private uint _SourceIpAddress;
00142             // Thirty two bit destination IP Address
00143             private uint _DestinationIpAddress;
00144             //End IP Header fields
00145             // Header length
00146             private byte _HeaderLength;
00147             // Data carried by the datagram
00148             private byte[] _IpData = new byte[4097];
00149 
00150             #endregion
00151 
00157             public IpHeader(byte[] data, int length)
00158             {
00159                 try {
00160                     // Create MemoryStream out of the received bytes
00161                     System.IO.MemoryStream MemoryStream = new System.IO.MemoryStream(data, 0, length);
00162                     // Next we create a BinaryReader out of the MemoryStream
00163                     System.IO.BinaryReader BinaryReader = new System.IO.BinaryReader(MemoryStream);
00164                     // The first eight bits of the IP header contain the version and header length so we read them
00165                     this._VersionAndHeaderLength = BinaryReader.ReadByte();
00166                     // The next eight bits contain the Differentiated services
00167                     this._DifferentiatedServices = BinaryReader.ReadByte();
00168                     // Next eight bits hold the total length of the datagram
00169                     this._TotalLength = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00170                     // Next sixteen have the identification bytes
00171                     this._Identification = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00172                     // Next sixteen bits contain the flags and fragmentation offset
00173                     this._FlagsAndOffset = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00174                     // Next eight bits have the TTL value
00175                     this._TTL = BinaryReader.ReadByte();
00176                     // Next eight represnts the protocol encapsulated in the datagram
00177                     this._Protocol = BinaryReader.ReadByte();
00178                     // Next sixteen bits contain the checksum of the header
00179                     this._Checksum = System.Convert.ToInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00180                     // Next thirty two bits have the source IP address
00181                     this._SourceIpAddress = System.Convert.ToUInt32(BinaryReader.ReadUInt32());
00182                     // Next thirty two hold the destination IP address
00183                     this._DestinationIpAddress = System.Convert.ToUInt32(BinaryReader.ReadUInt32());
00184                     // Now we calculate the header length
00185                     this._HeaderLength = this._VersionAndHeaderLength;
00186                     // The last four bits of the version and header length field contain the
00187                     // header length, we perform some simple binary airthmatic operations to
00188                     // extract them
00189                     this._HeaderLength <<= 4;
00190                     this._HeaderLength >>= 4;
00191                     // Multiply by four to get the exact header length
00192                     this._HeaderLength = System.Convert.ToByte(this._HeaderLength * 4);
00193                     // Copy the data carried by the data gram into another array so that
00194                     // according to the protocol being carried in the IP datagram
00195                     System.Array.Copy(data, this._HeaderLength, this._IpData, 0, this._TotalLength - this._HeaderLength);
00196                 } catch (System.Exception ex) {
00197                     if (IpError != null) {
00198                         IpError(ex.ToString());
00199                     }
00200                 }
00201             }
00202 
00206             public string Version
00207             {
00208                 get
00209                 {
00210                     switch ((this._VersionAndHeaderLength >> 4)) {
00211                         case 4:
00212                             return "IP v4";
00213                         case 6:
00214                             return "IP v6";
00215                         default:
00216                             return "Unknown";
00217                     }
00218                 }
00219             }
00220 
00224             public string HeaderLength
00225             {
00226                 get { return this._HeaderLength.ToString(); }
00227             }
00228 
00232             public ushort MessageLength
00233             {
00234                 // MessageLength = Total length of the datagram - Header length
00235                 get { return System.Convert.ToUInt16(this._TotalLength - this._HeaderLength); }
00236             }
00237 
00241             public string DifferentiatedServices
00242             {
00243                 get { return string.Format("0x{0:x2} ({1})", this._DifferentiatedServices, this._DifferentiatedServices); }
00244             }
00245 
00249             public string Flags
00250             {
00251                 get
00252                 {
00253                     // The first three bits of the flags and fragmentation field 
00254                     //    represent the flags (which indicate whether the data is 
00255                     //    fragmented or not)
00256                     int ReceivedFlags = this._FlagsAndOffset >> 13;
00257                     switch (ReceivedFlags) {
00258                         case 2:
00259                             return "Don't Fragment";
00260                         case 1:
00261                             return "More Fragments To Come";
00262                         default:
00263                             return ReceivedFlags.ToString();
00264                     }
00265                 }
00266             }
00267 
00271             public string FragmentationOffset
00272             {
00273                 get
00274                 {
00275                     // The last thirteen bits of the flags and fragmentation field 
00276                     //    contain the fragmentation offset
00277                     int Offset = this._FlagsAndOffset << 3;
00278                     Offset >>= 3;
00279                     return Offset.ToString();
00280                 }
00281             }
00282 
00286             public string TTL
00287             {
00288                 get { return System.Convert.ToString(this._TTL); }
00289             }
00290 
00294             public IpProtocol ProtocolType
00295             {
00296                 get
00297                 {
00298                     // The protocol field represents the protocol in the data portion
00299                     //    of the datagram
00300                     switch (System.Convert.ToInt32(this._Protocol)) {
00301                         case 6:
00302                             return IpProtocol.TCP;
00303                         case 17:
00304                             return IpProtocol.UDP;
00305                         default:
00306                             return IpProtocol.UNKNOWN;
00307                     }
00308                 }
00309             }
00310 
00314             public string Checksum
00315             {
00316                 get { return string.Format("0x{0:x2}", this._Checksum); }
00317             }
00318 
00322             public System.Net.IPAddress SourceIpAddress
00323             {
00324                 get { return new System.Net.IPAddress(this._SourceIpAddress); }
00325             }
00326 
00330             public System.Net.IPAddress DestinationIpAddress
00331             {
00332                 get { return new System.Net.IPAddress(this._DestinationIpAddress); }
00333             }
00334 
00338             public string TotalLength
00339             {
00340                 get { return this._TotalLength.ToString(); }
00341             }
00342 
00346             public string Identification
00347             {
00348                 get { return this._Identification.ToString(); }
00349             }
00350 
00354             public byte[] Data
00355             {
00356                 get { return this._IpData; }
00357             }
00358         }
00359 
00363         public class UdpHeader
00364         {
00365             #region UDP Header fields
00366 
00367             // Sixteen bits for the source port number        
00368             private ushort _SourcePort;
00369             // Sixteen bits for the destination port number
00370             private ushort _DestinationPort;
00371             // Length of the UDP header
00372             private ushort _Length;
00373             // Sixteen bits for the checksum (checksum can be negative so taken as short)              
00374             private ushort _Checksum;
00375             // End UDP header fields
00376             // Data carried by the UDP packet
00377             private byte[] _UdpData = new byte[4097];
00378 
00379             #endregion
00380 
00386             public UdpHeader(byte[] data, int length)
00387             {
00388                 System.IO.MemoryStream MemoryStream = new System.IO.MemoryStream(data, 0, length);
00389                 System.IO.BinaryReader BinaryReader = new System.IO.BinaryReader(MemoryStream);
00390                 // The first sixteen bits contain the source port
00391                 this._SourcePort = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00392                 // The next sixteen bits contain the destination port
00393                 this._DestinationPort = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00394                 // The next sixteen bits contain the length of the UDP packet
00395                 this._Length = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00396                 // The next sixteen bits contain the checksum
00397                 this._Checksum = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00398                 // Copy the data carried by the UDP packet into the data buffer
00399                 // The UDP header is of 8 bytes so we start copying after it
00400                 System.Array.Copy(data, 8, this._UdpData, 0, length - 8);
00401             }
00402 
00406             public string Checksum
00407             {
00408                 get { return string.Format("0x{0:x2}", this._Checksum); }
00409             }
00410 
00414             public string DestinationPort
00415             {
00416                 get { return this._DestinationPort.ToString(); }
00417             }
00418 
00422             public string Length
00423             {
00424                 get { return this._Length.ToString(); }
00425             }
00426 
00430             public string SourcePort
00431             {
00432                 get { return this._SourcePort.ToString(); }
00433             }
00434 
00438             public byte[] UdpData
00439             {
00440                 get { return this._UdpData; }
00441             }
00442         }
00443 
00447         public class TcpHeader
00448         {
00449             public delegate void TcpErrorEventHandler(string message);
00453             public event TcpErrorEventHandler TcpError;
00454 
00455             #region Properties
00456 
00457             // TCP header fields
00458             // Sixteen bits for the source port number
00459             private ushort _SourcePort;
00460             // Sixteen bits for the destination port number
00461             private ushort _DestinationPort;
00462             // Thirty two bits for the sequence number
00463             private uint _SequenceNumber = 555;
00464             // Thirty two bits for the acknowledgement number
00465             private uint _AcknowledgementNumber = 555;
00466             // Sixteen bits for flags and data offset
00467             private ushort _DataOffsetAndFlags = 555;
00468             // Sixteen bits for the window size
00469             private ushort _Window = 555;
00470             // Sixteen bits for the checksum (checksum can be negative so taken as short)
00471             private short _Checksum = 555;
00472             // Sixteen bits for the urgent pointer
00473             private ushort _UrgentPointer;
00474             // End TCP header fields
00475             // Header length
00476             private byte _HeaderLength;
00477             // Length of the data being carried
00478             private ushort _MessageLength;
00479             // Data carried by the TCP packet
00480             private byte[] _TcpData = new byte[4097];
00481 
00482             #endregion
00483 
00489             public TcpHeader(byte[] data, int length)
00490             {
00491                 try {
00492                     // Create MemoryStream out of the received bytes
00493                     System.IO.MemoryStream MemoryStream = new System.IO.MemoryStream(data, 0, length);
00494                     // Next we create a BinaryReader out of the MemoryStream
00495                     System.IO.BinaryReader BinaryReader = new System.IO.BinaryReader(MemoryStream);
00496                     // The first sixteen bits contain the source port
00497                     this._SourcePort = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00498                     // The next sixteen contain the destiination port
00499                     this._DestinationPort = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00500                     // Next thirty two have the sequence number
00501                     this._SequenceNumber = System.Convert.ToUInt32(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt32()));
00502                     // Next thirty two have the acknowledgement number
00503                     this._AcknowledgementNumber = System.Convert.ToUInt32(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt32()));
00504                     // The next sixteen bits hold the flags and the data offset
00505                     this._DataOffsetAndFlags = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00506                     // The next sixteen contain the window size
00507                     this._Window = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00508                     // In the next sixteen we have the checksum
00509                     this._Checksum = System.Convert.ToInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00510                     // The following sixteen contain the urgent pointer
00511                     this._UrgentPointer = System.Convert.ToUInt16(System.Net.IPAddress.NetworkToHostOrder(BinaryReader.ReadInt16()));
00512                     // The data offset indicates where the data begins, so using it we
00513                     // calculate the header length
00514                     this._HeaderLength = System.Convert.ToByte(this._DataOffsetAndFlags >> 12);
00515                     this._HeaderLength = System.Convert.ToByte(this._HeaderLength * 4);
00516                     // Message length = Total length of the TCP packet - Header length
00517                     this._MessageLength = System.Convert.ToUInt16(length - this._HeaderLength);
00518                     // Copy the TCP data into the data buffer
00519                     System.Array.Copy(data, this._HeaderLength, this._TcpData, 0, length - this._HeaderLength);
00520                 } catch (System.Exception ex) {
00521                     if (TcpError != null) {
00522                         TcpError(ex.Message);
00523                     }
00524                 }
00525             }
00526 
00530             public string SourcePort
00531             {
00532                 get { return this._SourcePort.ToString(); }
00533             }
00534 
00538             public string DestinationPort
00539             {
00540                 get { return this._DestinationPort.ToString(); }
00541             }
00542 
00546             public string SequenceNumber
00547             {
00548                 get { return this._SequenceNumber.ToString(); }
00549             }
00550 
00554             public string AcknowledgementNumber
00555             {
00556                 get
00557                 {
00558                     // If the ACK flag is set then only we have a valid value in
00559                     //    the acknowlegement field, so check for it beore returning anything
00560                     if ((this._DataOffsetAndFlags & 0x10) != 0) {
00561                         return this._AcknowledgementNumber.ToString();
00562                     } else {
00563                         return string.Empty;
00564                     }
00565                 }
00566             }
00567 
00571             public string DataOffsetAndFlags
00572             {
00573                 get { return this._DataOffsetAndFlags.ToString(); }
00574             }
00575 
00579             public string Window
00580             {
00581                 get { return this._Window.ToString(); }
00582             }
00583 
00587             public string Checksum
00588             {
00589                 get { return string.Format("0x{0:x2}", this._Checksum); }
00590             }
00591 
00595             public string UrgentPointer
00596             {
00597                 get
00598                 {
00599                     if ((this._DataOffsetAndFlags & 0x20) != 0) {
00600                         return this._UrgentPointer.ToString();
00601                     } else {
00602                         return string.Empty;
00603                     }
00604                 }
00605             }
00606 
00610             public string Flags
00611             {
00612                 get
00613                 {
00614                     // The last six bits of the data offset and flags contain the control bits
00615                     // First we extract the flags
00616                     int CurrentFlags = (this._DataOffsetAndFlags & 0x3f);
00617                     string Value = string.Format("0x{0:x2} (", CurrentFlags);
00618                     // Now we start looking whether individual bits are set or not
00619                     if ((CurrentFlags & 0x1) != 0) {
00620                         Value += "FIN, ";
00621                     }
00622                     if ((CurrentFlags & 0x2) != 0) {
00623                         Value += "SYN, ";
00624                     }
00625                     if ((CurrentFlags & 0x4) != 0) {
00626                         Value += "RST, ";
00627                     }
00628                     if ((CurrentFlags & 0x8) != 0) {
00629                         Value += "PSH, ";
00630                     }
00631                     if ((CurrentFlags & 0x10) != 0) {
00632                         Value += "ACK, ";
00633                     }
00634                     if ((CurrentFlags & 0x20) != 0) {
00635                         Value += "URG";
00636                     }
00637                     Value += ")";
00638                     if ((Value.Contains("()"))) {
00639                         Value = Value.Remove(Value.Length - 3);
00640                     } else if ((Value.Contains(", )"))) {
00641                         Value = Value.Remove(Value.Length - 3, 2);
00642                     }
00643                     return Value;
00644                 }
00645             }
00646 
00650             public string HeaderLength
00651             {
00652                 get { return this._HeaderLength.ToString(); }
00653             }
00654 
00658             public ushort MessageLength
00659             {
00660                 get { return this._MessageLength; }
00661             }
00662 
00666             public byte[] TcpData
00667             {
00668                 get { return this._TcpData; }
00669             }
00670         }
00671 
00676         public class BroadcastListener
00677         {
00681             public enum ListenerType
00682             {
00686                 BROADCAST_LISTENER,
00690                 PACKET_SNIFFER
00691             }
00692 
00696             public enum ThreadErrorType
00697             {
00701                 GENERAL,
00705                 CANT_BIND,
00709                 NO_PROMISC
00710             }
00711 
00712             #region Events
00713 
00714             public delegate void DelegateThreadError(ThreadErrorType errorType);
00718             public event DelegateThreadError ThreadError;
00719             public delegate void DelegateThreadReset();
00723             public event DelegateThreadReset ThreadReset;
00724 
00725             private void OnThreadError(ThreadErrorType errorType)
00726             {
00727                 if (ThreadError != null) { ThreadError(errorType); }
00728             }
00729 
00730             private void OnThreadReset()
00731             {
00732                 if (ThreadReset != null) { ThreadReset(); }
00733             }
00734 
00735             #endregion
00736 
00737             #region Local Attributes
00738 
00742             public System.Net.Sockets.Socket BroadcastSocket { get; private set; }
00746             public string IpAddressToListenfor { get; set; }
00750             public string IpAddressToListenOn { get; set; }
00754             public bool IsRunning { get; private set; }
00758             public System.Threading.Thread ListenThread { get; private set; }
00762             public byte[] ReceiveBuffer { get; private set; }
00763 
00764             private Sylloge.Net.BroadcastListener.ListenerType m_Type { get; set; }
00765 
00766             #endregion
00767 
00768             #region Class Mehtods and Properties
00769 
00773             public BroadcastListener(Sylloge.Net.BroadcastListener.ListenerType type)
00774             {
00775                 this.m_Type = type;
00776             }
00777 
00781             public void Close()
00782             {
00783                 this.IsRunning = false;
00784                 if (this.BroadcastSocket != null) {
00785                     try {
00786                         this.BroadcastSocket.Close();
00787                     } catch (System.Exception ex) {
00788                         System.Console.WriteLine(ex.Message);
00789                     }
00790                 }
00791                 if (this.ListenThread != null) {
00792                     try {
00793                         this.ListenThread.Abort();
00794                     } catch (System.Exception ex) {
00795                         System.Console.WriteLine(ex.Message);
00796                     }
00797                 }
00798             }
00799 
00803             private void ListenBroadcast()
00804             {
00805                 try {
00806                     System.Net.IPAddress IpAddress = new System.Net.IPAddress(0);
00807                     System.Net.IPAddress.TryParse(this.IpAddressToListenOn, out IpAddress);
00808                     System.Net.IPEndPoint BindEndPoint = new System.Net.IPEndPoint(IpAddress, 0);
00809                     this.BroadcastSocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Raw, System.Net.Sockets.ProtocolType.IP);
00810                     try {
00811                         this.BroadcastSocket.Bind(BindEndPoint);
00812                     } catch (System.Exception ex) {
00813                         System.Console.WriteLine("Broadcast error: " + ex.Message);
00814                         this.OnThreadError(ThreadErrorType.CANT_BIND);
00815                         return;
00816                     }
00817                     this.BroadcastSocket.SetSocketOption(System.Net.Sockets.SocketOptionLevel.IP, System.Net.Sockets.SocketOptionName.HeaderIncluded, true);
00818                     byte[] OptionCaptureAllPackets = { 1, 0, 0, 0 }; // Capture all packets 
00819                     byte[] OptionTrue = { 1, 0, 0, 0 }; // True
00820                     try {
00821                         this.BroadcastSocket.IOControl(System.Net.Sockets.IOControlCode.ReceiveAll, OptionTrue, OptionCaptureAllPackets);
00822                     } catch (System.Exception ex) {
00823                         // Here are a couple reasons for the exception here
00824                         // 1.) The user running is NOT an admin on the machine
00825                         // 2.) The interface can not be put into promiscuous mode
00826                         System.Console.WriteLine(ex.Message);
00827                         this.OnThreadError(ThreadErrorType.NO_PROMISC);
00828                         return;
00829                     }
00830                     this.BroadcastSocket.BeginReceive(this.ReceiveBuffer, 0, this.ReceiveBuffer.Length, System.Net.Sockets.SocketFlags.None, new System.AsyncCallback(this.OnReceiveData), null);
00831                 } catch (System.Exception ex) {
00832                     System.Console.WriteLine("Broadcast error: " + ex.Message);
00833                     this.OnThreadError(ThreadErrorType.GENERAL);
00834                 }
00835             }
00836 
00841             private void OnReceiveData(System.IAsyncResult ia)
00842             {
00843                 int BytesReceived = 0;
00844                 try {
00845                     BytesReceived = this.BroadcastSocket.EndReceive(ia);
00846                 } catch (System.Exception ex) { // Silent catch here
00847                     System.Console.WriteLine(ex.Message);
00848                 }
00849                 this.ParseReceivedData(this.ReceiveBuffer, BytesReceived);
00850                 if (this.IsRunning) {
00851                     this.ReceiveBuffer = new byte[4096];
00852                     this.BroadcastSocket.BeginReceive(
00853                         this.ReceiveBuffer, 
00854                         0, 
00855                         this.ReceiveBuffer.Length, 
00856                         System.Net.Sockets.SocketFlags.None,
00857                         new System.AsyncCallback(this.OnReceiveData), 
00858                         null
00859                     );
00860                 }
00861             }
00862 
00868             private void ParseReceivedData(byte[] data, int length)
00869             {
00870                 // Since all protocol packets are encapsulated in the IP datagram, we start by
00871                 //    parsing the IP header and see what protocol data is being carried by it
00872                 IpHeader IpHeader = new Sylloge.Net.IpHeader(data, length);
00873                 if (IpHeader.DestinationIpAddress.ToString() == this.IpAddressToListenfor) {
00874                     System.Net.Sockets.Socket ResponseSocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Raw, System.Net.Sockets.ProtocolType.Icmp);
00875                     System.Net.IPEndPoint RemoteEndPoint = new System.Net.IPEndPoint(IpHeader.SourceIpAddress, 0);
00876                     System.Net.IPEndPoint LocalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(this.IpAddressToListenOn), 0);
00877                     ResponseSocket.Bind(LocalEndPoint);
00878                     // For a proper reply, the response MUST be the same exact data
00879                     ResponseSocket.SendTo(data, System.Net.Sockets.SocketFlags.None, RemoteEndPoint);
00880                     ResponseSocket.Close();
00881                     ResponseSocket = null;
00882                 }
00883                 if (this.m_Type == ListenerType.PACKET_SNIFFER) {
00884                     // DEV_NOTE: We could use this as a packet sniffer, uncomment the below lines and grab the info from the headers
00885                     // Connection.TcpHeader TcpHeader = null;
00886                     // Connection.UdpHeader UdpHeader = null;
00887                     // switch (IpHeader.ProtocolType) {
00888                     //    case Connection.IpHeader.enumProtocol.TCP:
00889                     //       TcpHeader = new TcpHeader(IpHeader.Data, Convert.ToInt32(IpHeader.MessageLength));
00890                     //       break;
00891                     //    case Connection.IpHeader.enumProtocol.UDP:
00892                     //       UdpHeader = new UdpHeader(IpHeader.Data, Convert.ToInt32(IpHeader.MessageLength));
00893                     //       break;
00894                     //    case Connection.IpHeader.enumProtocol.UNKNOWN:
00895                     //       break;
00896                     // }
00897                 }                
00898             }
00899 
00905             public void Start(string ipToListenOn, string broadcastAddress)
00906             {
00907                 this.IpAddressToListenOn = ipToListenOn;
00908                 this.IpAddressToListenfor = broadcastAddress;
00909                 // Regular and Special both use the same listen thread address
00910                 System.Threading.ThreadStart StartAddress = new System.Threading.ThreadStart(this.ListenBroadcast);
00911                 this.ListenThread = new System.Threading.Thread(StartAddress);
00912                 this.ListenThread.Start();
00913                 this.IsRunning = true;
00914             }
00915 
00916             #endregion
00917         }
00918 
00919         #region Static Members
00920 
00926         public static bool IsHostUp(string ipAddress)
00927         {
00928             System.Net.NetworkInformation.PingReply Reply = Sylloge.Net.Ping(ipAddress);
00929             if (Reply == null || Reply.Status != System.Net.NetworkInformation.IPStatus.Success) { return false; }
00930             return true;
00931         }
00932 
00942         public static System.Net.NetworkInformation.PingReply Ping(string ipAddress, System.Net.NetworkInformation.PingCompletedEventHandler pceh = null)
00943         {
00944             try {
00945                 System.Net.NetworkInformation.Ping Ping = new System.Net.NetworkInformation.Ping();
00946                 if (pceh != null) { Ping.PingCompleted += pceh; }
00947                 System.Net.IPAddress o = new System.Net.IPAddress(0);
00948                 System.Net.IPAddress.TryParse(ipAddress, out o);
00949                 return Ping.Send(o);
00950             } catch (System.Exception ex) {
00951                 System.Console.WriteLine("Error while pinging: " + ex.Message);
00952             }
00953             return null;
00954         }
00955 
00962         public static void SendUdp(string ipAddress, int port, byte[] data)
00963         {
00964             try {
00965                 System.Net.Sockets.UdpClient Client = new System.Net.Sockets.UdpClient(port, System.Net.Sockets.AddressFamily.InterNetwork);
00966                 System.Net.IPAddress IPAddress = new System.Net.IPAddress(0);
00967                 System.Net.IPAddress.TryParse(ipAddress, out IPAddress);
00968                 Client.Connect(IPAddress, port);
00969                 Client.Send(data, data.Length);
00970                 Client.Close();
00971             } catch (System.Exception ex) {
00972                 System.Console.WriteLine("Error sending UDP: " + ex.Message);
00973             }
00974         }
00975 
00982         public static void SendTcp(string ipAddress, int port, byte[] data)
00983         {
00984             try {
00985                 System.Net.IPAddress IPAddress = new System.Net.IPAddress(0);
00986                 System.Net.IPAddress.TryParse(ipAddress, out IPAddress);
00987                 try {
00988                     System.Net.Sockets.TcpClient TcpClient = new System.Net.Sockets.TcpClient();
00989                     TcpClient.Connect(IPAddress, port);
00990                     if (TcpClient != null && TcpClient.Connected) {
00991                         System.Net.Sockets.NetworkStream Stream = TcpClient.GetStream();
00992                         Stream.Write(data, 0, data.Length);
00993                         Stream.Close();
00994                         TcpClient.Close();
00995                     }
00996                 } catch (System.Exception ex) {
00997                     System.Console.WriteLine("Error connecting: " + ex.Message);
00998                     return;
00999                 }
01000             } catch (System.Exception ex) {
01001                 System.Console.WriteLine("Error connecting: " + ex.Message);
01002                 return;
01003             }
01004         }
01005 
01006         #endregion
01007     }
01008 }
 All Classes Namespaces Files Functions Variables Enumerations Properties Events