![]() |
Sylloge
A C# helper library
|
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 }
1.7.4