netmask.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // Generated by CoffeeScript 1.12.7
  2. (function() {
  3. var Netmask, atob, chr, chr0, chrA, chra, ip2long, long2ip;
  4. long2ip = function(long) {
  5. var a, b, c, d;
  6. a = (long & (0xff << 24)) >>> 24;
  7. b = (long & (0xff << 16)) >>> 16;
  8. c = (long & (0xff << 8)) >>> 8;
  9. d = long & 0xff;
  10. return [a, b, c, d].join('.');
  11. };
  12. ip2long = function(ip) {
  13. var b, c, i, j, n, ref;
  14. b = [];
  15. for (i = j = 0; j <= 3; i = ++j) {
  16. if (ip.length === 0) {
  17. break;
  18. }
  19. if (i > 0) {
  20. if (ip[0] !== '.') {
  21. throw new Error('Invalid IP');
  22. }
  23. ip = ip.substring(1);
  24. }
  25. ref = atob(ip), n = ref[0], c = ref[1];
  26. ip = ip.substring(c);
  27. b.push(n);
  28. }
  29. if (ip.length !== 0) {
  30. throw new Error('Invalid IP');
  31. }
  32. switch (b.length) {
  33. case 1:
  34. if (b[0] > 0xFFFFFFFF) {
  35. throw new Error('Invalid IP');
  36. }
  37. return b[0] >>> 0;
  38. case 2:
  39. if (b[0] > 0xFF || b[1] > 0xFFFFFF) {
  40. throw new Error('Invalid IP');
  41. }
  42. return (b[0] << 24 | b[1]) >>> 0;
  43. case 3:
  44. if (b[0] > 0xFF || b[1] > 0xFF || b[2] > 0xFFFF) {
  45. throw new Error('Invalid IP');
  46. }
  47. return (b[0] << 24 | b[1] << 16 | b[2]) >>> 0;
  48. case 4:
  49. if (b[0] > 0xFF || b[1] > 0xFF || b[2] > 0xFF || b[3] > 0xFF) {
  50. throw new Error('Invalid IP');
  51. }
  52. return (b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3]) >>> 0;
  53. default:
  54. throw new Error('Invalid IP');
  55. }
  56. };
  57. chr = function(b) {
  58. return b.charCodeAt(0);
  59. };
  60. chr0 = chr('0');
  61. chra = chr('a');
  62. chrA = chr('A');
  63. atob = function(s) {
  64. var base, dmax, i, n, start;
  65. n = 0;
  66. base = 10;
  67. dmax = '9';
  68. i = 0;
  69. if (s.length > 1 && s[i] === '0') {
  70. if (s[i + 1] === 'x' || s[i + 1] === 'X') {
  71. i += 2;
  72. base = 16;
  73. } else if ('0' <= s[i + 1] && s[i + 1] <= '9') {
  74. i++;
  75. base = 8;
  76. dmax = '7';
  77. }
  78. }
  79. start = i;
  80. while (i < s.length) {
  81. if ('0' <= s[i] && s[i] <= dmax) {
  82. n = (n * base + (chr(s[i]) - chr0)) >>> 0;
  83. } else if (base === 16) {
  84. if ('a' <= s[i] && s[i] <= 'f') {
  85. n = (n * base + (10 + chr(s[i]) - chra)) >>> 0;
  86. } else if ('A' <= s[i] && s[i] <= 'F') {
  87. n = (n * base + (10 + chr(s[i]) - chrA)) >>> 0;
  88. } else {
  89. break;
  90. }
  91. } else {
  92. break;
  93. }
  94. if (n > 0xFFFFFFFF) {
  95. throw new Error('too large');
  96. }
  97. i++;
  98. }
  99. if (i === start) {
  100. throw new Error('empty octet');
  101. }
  102. return [n, i];
  103. };
  104. Netmask = (function() {
  105. function Netmask(net, mask) {
  106. var error, i, j, ref;
  107. if (typeof net !== 'string') {
  108. throw new Error("Missing `net' parameter");
  109. }
  110. if (!mask) {
  111. ref = net.split('/', 2), net = ref[0], mask = ref[1];
  112. }
  113. if (!mask) {
  114. mask = 32;
  115. }
  116. if (typeof mask === 'string' && mask.indexOf('.') > -1) {
  117. try {
  118. this.maskLong = ip2long(mask);
  119. } catch (error1) {
  120. error = error1;
  121. throw new Error("Invalid mask: " + mask);
  122. }
  123. for (i = j = 32; j >= 0; i = --j) {
  124. if (this.maskLong === (0xffffffff << (32 - i)) >>> 0) {
  125. this.bitmask = i;
  126. break;
  127. }
  128. }
  129. } else if (mask || mask === 0) {
  130. this.bitmask = parseInt(mask, 10);
  131. this.maskLong = 0;
  132. if (this.bitmask > 0) {
  133. this.maskLong = (0xffffffff << (32 - this.bitmask)) >>> 0;
  134. }
  135. } else {
  136. throw new Error("Invalid mask: empty");
  137. }
  138. try {
  139. this.netLong = (ip2long(net) & this.maskLong) >>> 0;
  140. } catch (error1) {
  141. error = error1;
  142. throw new Error("Invalid net address: " + net);
  143. }
  144. if (!(this.bitmask <= 32)) {
  145. throw new Error("Invalid mask for ip4: " + mask);
  146. }
  147. this.size = Math.pow(2, 32 - this.bitmask);
  148. this.base = long2ip(this.netLong);
  149. this.mask = long2ip(this.maskLong);
  150. this.hostmask = long2ip(~this.maskLong);
  151. this.first = this.bitmask <= 30 ? long2ip(this.netLong + 1) : this.base;
  152. this.last = this.bitmask <= 30 ? long2ip(this.netLong + this.size - 2) : long2ip(this.netLong + this.size - 1);
  153. this.broadcast = this.bitmask <= 30 ? long2ip(this.netLong + this.size - 1) : void 0;
  154. }
  155. Netmask.prototype.contains = function(ip) {
  156. if (typeof ip === 'string' && (ip.indexOf('/') > 0 || ip.split('.').length !== 4)) {
  157. ip = new Netmask(ip);
  158. }
  159. if (ip instanceof Netmask) {
  160. return this.contains(ip.base) && this.contains(ip.broadcast || ip.last);
  161. } else {
  162. return (ip2long(ip) & this.maskLong) >>> 0 === (this.netLong & this.maskLong) >>> 0;
  163. }
  164. };
  165. Netmask.prototype.next = function(count) {
  166. if (count == null) {
  167. count = 1;
  168. }
  169. return new Netmask(long2ip(this.netLong + (this.size * count)), this.mask);
  170. };
  171. Netmask.prototype.forEach = function(fn) {
  172. var index, lastLong, long;
  173. long = ip2long(this.first);
  174. lastLong = ip2long(this.last);
  175. index = 0;
  176. while (long <= lastLong) {
  177. fn(long2ip(long), long, index);
  178. index++;
  179. long++;
  180. }
  181. };
  182. Netmask.prototype.toString = function() {
  183. return this.base + "/" + this.bitmask;
  184. };
  185. return Netmask;
  186. })();
  187. exports.ip2long = ip2long;
  188. exports.long2ip = long2ip;
  189. exports.Netmask = Netmask;
  190. }).call(this);