source: trip-planner-front/node_modules/ip/lib/ip.js@ e29cc2e

Last change on this file since e29cc2e was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 10.0 KB
RevLine 
[6a3a178]1'use strict';
2
3var ip = exports;
4var Buffer = require('buffer').Buffer;
5var os = require('os');
6
7ip.toBuffer = function(ip, buff, offset) {
8 offset = ~~offset;
9
10 var result;
11
12 if (this.isV4Format(ip)) {
13 result = buff || new Buffer(offset + 4);
14 ip.split(/\./g).map(function(byte) {
15 result[offset++] = parseInt(byte, 10) & 0xff;
16 });
17 } else if (this.isV6Format(ip)) {
18 var sections = ip.split(':', 8);
19
20 var i;
21 for (i = 0; i < sections.length; i++) {
22 var isv4 = this.isV4Format(sections[i]);
23 var v4Buffer;
24
25 if (isv4) {
26 v4Buffer = this.toBuffer(sections[i]);
27 sections[i] = v4Buffer.slice(0, 2).toString('hex');
28 }
29
30 if (v4Buffer && ++i < 8) {
31 sections.splice(i, 0, v4Buffer.slice(2, 4).toString('hex'));
32 }
33 }
34
35 if (sections[0] === '') {
36 while (sections.length < 8) sections.unshift('0');
37 } else if (sections[sections.length - 1] === '') {
38 while (sections.length < 8) sections.push('0');
39 } else if (sections.length < 8) {
40 for (i = 0; i < sections.length && sections[i] !== ''; i++);
41 var argv = [ i, 1 ];
42 for (i = 9 - sections.length; i > 0; i--) {
43 argv.push('0');
44 }
45 sections.splice.apply(sections, argv);
46 }
47
48 result = buff || new Buffer(offset + 16);
49 for (i = 0; i < sections.length; i++) {
50 var word = parseInt(sections[i], 16);
51 result[offset++] = (word >> 8) & 0xff;
52 result[offset++] = word & 0xff;
53 }
54 }
55
56 if (!result) {
57 throw Error('Invalid ip address: ' + ip);
58 }
59
60 return result;
61};
62
63ip.toString = function(buff, offset, length) {
64 offset = ~~offset;
65 length = length || (buff.length - offset);
66
67 var result = [];
68 if (length === 4) {
69 // IPv4
70 for (var i = 0; i < length; i++) {
71 result.push(buff[offset + i]);
72 }
73 result = result.join('.');
74 } else if (length === 16) {
75 // IPv6
76 for (var i = 0; i < length; i += 2) {
77 result.push(buff.readUInt16BE(offset + i).toString(16));
78 }
79 result = result.join(':');
80 result = result.replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3');
81 result = result.replace(/:{3,4}/, '::');
82 }
83
84 return result;
85};
86
87var ipv4Regex = /^(\d{1,3}\.){3,3}\d{1,3}$/;
88var ipv6Regex =
89 /^(::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?$/i;
90
91ip.isV4Format = function(ip) {
92 return ipv4Regex.test(ip);
93};
94
95ip.isV6Format = function(ip) {
96 return ipv6Regex.test(ip);
97};
98function _normalizeFamily(family) {
99 return family ? family.toLowerCase() : 'ipv4';
100}
101
102ip.fromPrefixLen = function(prefixlen, family) {
103 if (prefixlen > 32) {
104 family = 'ipv6';
105 } else {
106 family = _normalizeFamily(family);
107 }
108
109 var len = 4;
110 if (family === 'ipv6') {
111 len = 16;
112 }
113 var buff = new Buffer(len);
114
115 for (var i = 0, n = buff.length; i < n; ++i) {
116 var bits = 8;
117 if (prefixlen < 8) {
118 bits = prefixlen;
119 }
120 prefixlen -= bits;
121
122 buff[i] = ~(0xff >> bits) & 0xff;
123 }
124
125 return ip.toString(buff);
126};
127
128ip.mask = function(addr, mask) {
129 addr = ip.toBuffer(addr);
130 mask = ip.toBuffer(mask);
131
132 var result = new Buffer(Math.max(addr.length, mask.length));
133
134 var i = 0;
135 // Same protocol - do bitwise and
136 if (addr.length === mask.length) {
137 for (i = 0; i < addr.length; i++) {
138 result[i] = addr[i] & mask[i];
139 }
140 } else if (mask.length === 4) {
141 // IPv6 address and IPv4 mask
142 // (Mask low bits)
143 for (i = 0; i < mask.length; i++) {
144 result[i] = addr[addr.length - 4 + i] & mask[i];
145 }
146 } else {
147 // IPv6 mask and IPv4 addr
148 for (var i = 0; i < result.length - 6; i++) {
149 result[i] = 0;
150 }
151
152 // ::ffff:ipv4
153 result[10] = 0xff;
154 result[11] = 0xff;
155 for (i = 0; i < addr.length; i++) {
156 result[i + 12] = addr[i] & mask[i + 12];
157 }
158 i = i + 12;
159 }
160 for (; i < result.length; i++)
161 result[i] = 0;
162
163 return ip.toString(result);
164};
165
166ip.cidr = function(cidrString) {
167 var cidrParts = cidrString.split('/');
168
169 var addr = cidrParts[0];
170 if (cidrParts.length !== 2)
171 throw new Error('invalid CIDR subnet: ' + addr);
172
173 var mask = ip.fromPrefixLen(parseInt(cidrParts[1], 10));
174
175 return ip.mask(addr, mask);
176};
177
178ip.subnet = function(addr, mask) {
179 var networkAddress = ip.toLong(ip.mask(addr, mask));
180
181 // Calculate the mask's length.
182 var maskBuffer = ip.toBuffer(mask);
183 var maskLength = 0;
184
185 for (var i = 0; i < maskBuffer.length; i++) {
186 if (maskBuffer[i] === 0xff) {
187 maskLength += 8;
188 } else {
189 var octet = maskBuffer[i] & 0xff;
190 while (octet) {
191 octet = (octet << 1) & 0xff;
192 maskLength++;
193 }
194 }
195 }
196
197 var numberOfAddresses = Math.pow(2, 32 - maskLength);
198
199 return {
200 networkAddress: ip.fromLong(networkAddress),
201 firstAddress: numberOfAddresses <= 2 ?
202 ip.fromLong(networkAddress) :
203 ip.fromLong(networkAddress + 1),
204 lastAddress: numberOfAddresses <= 2 ?
205 ip.fromLong(networkAddress + numberOfAddresses - 1) :
206 ip.fromLong(networkAddress + numberOfAddresses - 2),
207 broadcastAddress: ip.fromLong(networkAddress + numberOfAddresses - 1),
208 subnetMask: mask,
209 subnetMaskLength: maskLength,
210 numHosts: numberOfAddresses <= 2 ?
211 numberOfAddresses : numberOfAddresses - 2,
212 length: numberOfAddresses,
213 contains: function(other) {
214 return networkAddress === ip.toLong(ip.mask(other, mask));
215 }
216 };
217};
218
219ip.cidrSubnet = function(cidrString) {
220 var cidrParts = cidrString.split('/');
221
222 var addr = cidrParts[0];
223 if (cidrParts.length !== 2)
224 throw new Error('invalid CIDR subnet: ' + addr);
225
226 var mask = ip.fromPrefixLen(parseInt(cidrParts[1], 10));
227
228 return ip.subnet(addr, mask);
229};
230
231ip.not = function(addr) {
232 var buff = ip.toBuffer(addr);
233 for (var i = 0; i < buff.length; i++) {
234 buff[i] = 0xff ^ buff[i];
235 }
236 return ip.toString(buff);
237};
238
239ip.or = function(a, b) {
240 a = ip.toBuffer(a);
241 b = ip.toBuffer(b);
242
243 // same protocol
244 if (a.length === b.length) {
245 for (var i = 0; i < a.length; ++i) {
246 a[i] |= b[i];
247 }
248 return ip.toString(a);
249
250 // mixed protocols
251 } else {
252 var buff = a;
253 var other = b;
254 if (b.length > a.length) {
255 buff = b;
256 other = a;
257 }
258
259 var offset = buff.length - other.length;
260 for (var i = offset; i < buff.length; ++i) {
261 buff[i] |= other[i - offset];
262 }
263
264 return ip.toString(buff);
265 }
266};
267
268ip.isEqual = function(a, b) {
269 a = ip.toBuffer(a);
270 b = ip.toBuffer(b);
271
272 // Same protocol
273 if (a.length === b.length) {
274 for (var i = 0; i < a.length; i++) {
275 if (a[i] !== b[i]) return false;
276 }
277 return true;
278 }
279
280 // Swap
281 if (b.length === 4) {
282 var t = b;
283 b = a;
284 a = t;
285 }
286
287 // a - IPv4, b - IPv6
288 for (var i = 0; i < 10; i++) {
289 if (b[i] !== 0) return false;
290 }
291
292 var word = b.readUInt16BE(10);
293 if (word !== 0 && word !== 0xffff) return false;
294
295 for (var i = 0; i < 4; i++) {
296 if (a[i] !== b[i + 12]) return false;
297 }
298
299 return true;
300};
301
302ip.isPrivate = function(addr) {
303 return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i
304 .test(addr) ||
305 /^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
306 /^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$/i
307 .test(addr) ||
308 /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
309 /^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
310 /^f[cd][0-9a-f]{2}:/i.test(addr) ||
311 /^fe80:/i.test(addr) ||
312 /^::1$/.test(addr) ||
313 /^::$/.test(addr);
314};
315
316ip.isPublic = function(addr) {
317 return !ip.isPrivate(addr);
318};
319
320ip.isLoopback = function(addr) {
321 return /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/
322 .test(addr) ||
323 /^fe80::1$/.test(addr) ||
324 /^::1$/.test(addr) ||
325 /^::$/.test(addr);
326};
327
328ip.loopback = function(family) {
329 //
330 // Default to `ipv4`
331 //
332 family = _normalizeFamily(family);
333
334 if (family !== 'ipv4' && family !== 'ipv6') {
335 throw new Error('family must be ipv4 or ipv6');
336 }
337
338 return family === 'ipv4' ? '127.0.0.1' : 'fe80::1';
339};
340
341//
342// ### function address (name, family)
343// #### @name {string|'public'|'private'} **Optional** Name or security
344// of the network interface.
345// #### @family {ipv4|ipv6} **Optional** IP family of the address (defaults
346// to ipv4).
347//
348// Returns the address for the network interface on the current system with
349// the specified `name`:
350// * String: First `family` address of the interface.
351// If not found see `undefined`.
352// * 'public': the first public ip address of family.
353// * 'private': the first private ip address of family.
354// * undefined: First address with `ipv4` or loopback address `127.0.0.1`.
355//
356ip.address = function(name, family) {
357 var interfaces = os.networkInterfaces();
358 var all;
359
360 //
361 // Default to `ipv4`
362 //
363 family = _normalizeFamily(family);
364
365 //
366 // If a specific network interface has been named,
367 // return the address.
368 //
369 if (name && name !== 'private' && name !== 'public') {
370 var res = interfaces[name].filter(function(details) {
371 var itemFamily = details.family.toLowerCase();
372 return itemFamily === family;
373 });
374 if (res.length === 0)
375 return undefined;
376 return res[0].address;
377 }
378
379 var all = Object.keys(interfaces).map(function (nic) {
380 //
381 // Note: name will only be `public` or `private`
382 // when this is called.
383 //
384 var addresses = interfaces[nic].filter(function (details) {
385 details.family = details.family.toLowerCase();
386 if (details.family !== family || ip.isLoopback(details.address)) {
387 return false;
388 } else if (!name) {
389 return true;
390 }
391
392 return name === 'public' ? ip.isPrivate(details.address) :
393 ip.isPublic(details.address);
394 });
395
396 return addresses.length ? addresses[0].address : undefined;
397 }).filter(Boolean);
398
399 return !all.length ? ip.loopback(family) : all[0];
400};
401
402ip.toLong = function(ip) {
403 var ipl = 0;
404 ip.split('.').forEach(function(octet) {
405 ipl <<= 8;
406 ipl += parseInt(octet);
407 });
408 return(ipl >>> 0);
409};
410
411ip.fromLong = function(ipl) {
412 return ((ipl >>> 24) + '.' +
413 (ipl >> 16 & 255) + '.' +
414 (ipl >> 8 & 255) + '.' +
415 (ipl & 255) );
416};
Note: See TracBrowser for help on using the repository browser.