/Nighthawk/Network.cs

https://github.com/klemenb/nighthawk · C# · 181 lines · 128 code · 38 blank · 15 comment · 10 complexity · a93de2e79898168dce48edfd95d98944 MD5 · raw file

  1. using System;
  2. using System.Linq;
  3. using System.Net;
  4. using System.Net.NetworkInformation;
  5. using System.Text.RegularExpressions;
  6. namespace Nighthawk
  7. {
  8. /* Some helper functions - mainly from "http://stackoverflow.com/" */
  9. class Network
  10. {
  11. // convert subnet mask to CIDR notation
  12. public static int MaskToCIDR(string subnetMask)
  13. {
  14. IPAddress subnetAddress = IPAddress.Parse(subnetMask);
  15. byte[] ipParts = subnetAddress.GetAddressBytes();
  16. uint subnet = 16777216 * Convert.ToUInt32(ipParts[0]) + 65536 * Convert.ToUInt32(ipParts[1]) + 256 * Convert.ToUInt32(ipParts[2]) + Convert.ToUInt32(ipParts[3]);
  17. uint mask = 0x80000000;
  18. uint subnetConsecutiveOnes = 0;
  19. for (int i = 0; i < 32; i++)
  20. {
  21. if (!(mask & subnet).Equals(mask)) break;
  22. subnetConsecutiveOnes++;
  23. mask = mask >> 1;
  24. }
  25. return (int)subnetConsecutiveOnes;
  26. }
  27. // get starting IP from subnet mask
  28. public static long[] MaskToStartEnd(string ip, string subnetMask)
  29. {
  30. return MaskToStartEnd(ip, MaskToCIDR(subnetMask));
  31. }
  32. // get ending IP from subnet mask
  33. public static long[] MaskToStartEnd(string ip, int bits)
  34. {
  35. IPAddress ipAddr = IPAddress.Parse(ip);
  36. uint mask = ~(uint.MaxValue >> bits);
  37. byte[] ipBytes = ipAddr.GetAddressBytes();
  38. byte[] maskBytes = BitConverter.GetBytes(mask).Reverse().ToArray();
  39. byte[] startIPBytes = new byte[ipBytes.Length];
  40. byte[] endIPBytes = new byte[ipBytes.Length];
  41. for (int i = 0; i < ipBytes.Length; i++)
  42. {
  43. startIPBytes[i] = (byte)(ipBytes[i] & maskBytes[i]);
  44. endIPBytes[i] = (byte)(ipBytes[i] | ~maskBytes[i]);
  45. }
  46. IPAddress startIP = new IPAddress(startIPBytes);
  47. IPAddress endIP = new IPAddress(endIPBytes);
  48. return new long[] { (IPToLong(startIP.ToString()) + 1), (IPToLong(endIP.ToString()) - 1) }; // +1 and -1 to filter out network and broadcast
  49. }
  50. // IP to long
  51. public static long IPToLong(string addr)
  52. {
  53. string[] ipBytes;
  54. double num = 0;
  55. if (!string.IsNullOrEmpty(addr))
  56. {
  57. ipBytes = addr.Split('.');
  58. for (int i = ipBytes.Length - 1; i >= 0; i--)
  59. {
  60. num += ((int.Parse(ipBytes[i]) % 256) * Math.Pow(256, (3 - i)));
  61. }
  62. }
  63. return (long)num;
  64. }
  65. // long to IP
  66. public static IPAddress LongToIP(long address)
  67. {
  68. return IPAddress.Parse(address.ToString());
  69. }
  70. // convert MAC to friendly MAC (with :)
  71. public static string FriendlyPhysicalAddress(PhysicalAddress mac)
  72. {
  73. var macString = mac.ToString();
  74. var output = string.Empty;
  75. for (int i = 0; i < macString.Length; i++)
  76. {
  77. if (i % 2 == 0 && i > 0)
  78. {
  79. output += ":" + macString[i];
  80. }
  81. else
  82. {
  83. output += macString[i];
  84. }
  85. }
  86. return output;
  87. }
  88. // convert hexadecimal to bytes
  89. public static byte[] HexToByte(string hex)
  90. {
  91. hex = hex.Replace(" ", "");
  92. int numberChars = hex.Length;
  93. byte[] bytes = new byte[numberChars / 2];
  94. for (int i = 0; i < numberChars; i += 2)
  95. {
  96. bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
  97. }
  98. return bytes;
  99. }
  100. // convert ipv6 to it's full hexadecimal form
  101. public static string IPv6ToFullHex(string ipv6)
  102. {
  103. return BitConverter.ToString(IPAddress.Parse(ipv6).GetAddressBytes()).Replace("-", "").ToLower();
  104. }
  105. // check for valid IPv6 /64 prefix
  106. public static bool PrefixValid(string prefix)
  107. {
  108. var regex = new Regex("^([0-9A-Fa-f]{1,4}):([0-9A-Fa-f]{1,4}):([0-9A-Fa-f]{1,4}):([0-9A-Fa-f]{1,4}::)$");
  109. return regex.IsMatch(prefix);
  110. }
  111. // get /64 prefix from IPv6 address
  112. public static string GetPrefixFromIP(string ip)
  113. {
  114. var parts = ip.Split(':');
  115. return parts[0] + ":" + parts[1] + ":" + parts[2] + ":" + parts[3] + "::";
  116. }
  117. // get IPv6 pseudo-header (adapted from: http://www.winsocketdotnetworkprogramming.com/clientserversocketnetworkcommunication8f_3.html)
  118. public static byte[] GetPseudoHeader(IPAddress sourceIP, IPAddress destinationIP, int icmpv6Length, int nextHeader)
  119. {
  120. byte[] pseudoHeader, byteValue;
  121. int offset = 0, payLoadLength;
  122. // now build the pseudo header
  123. pseudoHeader = new byte[40];
  124. byteValue = sourceIP.GetAddressBytes();
  125. Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
  126. offset += byteValue.Length;
  127. byteValue = destinationIP.GetAddressBytes();
  128. Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
  129. offset += byteValue.Length;
  130. // Packet total length
  131. payLoadLength = IPAddress.HostToNetworkOrder(4 + icmpv6Length);
  132. byteValue = BitConverter.GetBytes(payLoadLength);
  133. Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
  134. offset += byteValue.Length;
  135. // 3 bytes of zero padding
  136. pseudoHeader[offset++] = (byte)0;
  137. pseudoHeader[offset++] = (byte)0;
  138. pseudoHeader[offset++] = (byte)0;
  139. pseudoHeader[offset++] = (byte)nextHeader;
  140. return pseudoHeader;
  141. }
  142. }
  143. }