• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lduchosal / ipnetwork / 707

22 Jan 2025 08:20PM UTC coverage: 94.558% (+0.04%) from 94.52%
707

Pull #340

appveyor

web-flow
Merge aca43bd2e into a24b046db
Pull Request #340: TryParse Method Signature for ICidrGuess

1616 of 1709 relevant lines covered (94.56%)

1175439.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.85
/src/System.Net.IPNetwork/IPNetwork2.cs
1
// <copyright file="IPNetwork2.cs" company="IPNetwork">
2
// Copyright (c) IPNetwork. All rights reserved.
3
// </copyright>
4

5
namespace System.Net
6
{
7
    using System.Collections.Generic;
8
    using System.ComponentModel;
9
    using System.IO;
10
    using System.Net.Sockets;
11
    using System.Numerics;
12
    using System.Runtime.Serialization;
13
    using System.Text.RegularExpressions;
14

15
    /// <summary>
16
    /// IP Network utility class.
17
    /// Use IPNetwork.Parse to create instances.
18
    /// </summary>
19
    [Serializable]
20
    public sealed class IPNetwork2 : IComparable<IPNetwork2>, ISerializable
21
    {
22
        #region properties
23

24
        private readonly object _sync = new object();
12,135,901✔
25
        private readonly int _hashCode;
26
        private BigInteger _ipaddress;
27
        private byte _cidr;
28
        private BigInteger? _cachedBroadcast;
29

30
        private AddressFamily _family;
31

32
        /// <summary>
33
        /// Gets or sets the value of the IPNetwork property.
34
        /// </summary>
35
        [DataMember(Name = "IPNetwork", IsRequired = true)]
36
        public string Value
37
        {
38
            get
39
            {
2,000,002✔
40
                return this.ToString();
2,000,002✔
41
            }
2,000,002✔
42

43
            set
44
            {
2,000,004✔
45
                var ipnetwork = IPNetwork2.Parse(value);
2,000,004✔
46
                this._ipaddress = ipnetwork._ipaddress;
2,000,004✔
47
                this._family = ipnetwork._family;
2,000,004✔
48
                this._cidr = ipnetwork._cidr;
2,000,004✔
49
                lock (_sync)
2,000,004✔
50
                {
2,000,004✔
51
                    this._cachedBroadcast = null;
2,000,004✔
52
                }
2,000,004✔
53
            }
2,000,004✔
54
        }
55

56
        #endregion
57

58
        #region accessors
59

60
        internal BigInteger _network
61
        {
62
            get
63
            {
17,168,564✔
64
                BigInteger uintNetwork = this._ipaddress & this._netmask;
17,168,564✔
65
                return uintNetwork;
17,168,564✔
66
            }
17,168,564✔
67
        }
68

69
        /// <summary>
70
        /// Gets network address.
71
        /// </summary>
72
        public IPAddress Network
73
        {
74
            get
75
            {
6,136,455✔
76
                return IPNetwork2.ToIPAddress(this._network, this._family);
6,136,455✔
77
            }
6,136,455✔
78
        }
79

80
        /// <summary>
81
        /// Gets address Family.
82
        /// </summary>
83
        public AddressFamily AddressFamily
84
        {
85
            get
86
            {
134,039✔
87
                return this._family;
134,039✔
88
            }
134,039✔
89
        }
90

91
        internal BigInteger _netmask
92
        {
93
            get
94
            {
17,303,044✔
95
                return IPNetwork2.ToUint(this._cidr, this._family);
17,303,044✔
96
            }
17,303,044✔
97
        }
98

99
        /// <summary>
100
        /// Gets netmask.
101
        /// </summary>
102
        public IPAddress Netmask
103
        {
104
            get
105
            {
367✔
106
                return IPNetwork2.ToIPAddress(this._netmask, this._family);
367✔
107
            }
367✔
108
        }
109

110
        internal BigInteger _broadcast
111
        {
112
            get
113
            {
663,363✔
114
                var cached = this._cachedBroadcast;
663,363✔
115
                if (cached != null)
663,363✔
116
                {
529,452✔
117
                    return cached.Value;
529,452✔
118
                }
119

120
                lock (_sync)
133,911✔
121
                {
133,911✔
122
                    var cached2 = this._cachedBroadcast;
133,911✔
123
                    if (cached2 != null)
133,911✔
124
                    {
×
125
                        return cached2.Value;
×
126
                    }
127

128
                    var network = this._network;
133,911✔
129
                    var computed = CreateBroadcast(ref network, this._netmask, this._family);
133,911✔
130
                    this._cachedBroadcast = computed;
133,911✔
131
                    return computed;
133,911✔
132
                }
133
            }
663,363✔
134
        }
135

136
        /// <summary>
137
        /// Gets broadcast address.
138
        /// </summary>
139
        public IPAddress Broadcast
140
        {
141
            get
142
            {
66,830✔
143
                if (this._family == Sockets.AddressFamily.InterNetworkV6)
66,830✔
144
                {
31✔
145
                    return null;
31✔
146
                }
147

148
                return IPNetwork2.ToIPAddress(this._broadcast, this._family);
66,799✔
149
            }
66,830✔
150
        }
151

152
        /// <summary>
153
        /// Gets first usable IP adress in Network.
154
        /// </summary>
155
        public IPAddress FirstUsable
156
        {
157
            get
158
            {
2,356✔
159
                BigInteger first = this._family == Sockets.AddressFamily.InterNetworkV6
2,356✔
160
                    ? this._network
2,356✔
161
                    : (this.Usable <= 0) ? this._network : this._network + 1;
2,356✔
162
                return IPNetwork2.ToIPAddress(first, this._family);
2,356✔
163
            }
2,356✔
164
        }
165

166
        /// <summary>
167
        /// Gets last usable IP adress in Network.
168
        /// </summary>
169
        public IPAddress LastUsable
170
        {
171
            get
172
            {
2,595✔
173
                BigInteger last = this._family == Sockets.AddressFamily.InterNetworkV6
2,595✔
174
                    ? this._broadcast
2,595✔
175
                    : (this.Usable <= 0) ? this._network : this._broadcast - 1;
2,595✔
176
                return IPNetwork2.ToIPAddress(last, this._family);
2,595✔
177
            }
2,595✔
178
        }
179

180
        /// <summary>
181
        /// Gets number of usable IP adress in Network.
182
        /// </summary>
183
        public BigInteger Usable
184
        {
185
            get
186
            {
2,974✔
187
                if (this._family == Sockets.AddressFamily.InterNetworkV6)
2,974✔
188
                {
32✔
189
                    return this.Total;
32✔
190
                }
191

192
                byte[] mask = new byte[] { 0xff, 0xff, 0xff, 0xff, 0x00 };
2,942✔
193
                var bmask = new BigInteger(mask);
2,942✔
194
                BigInteger usableIps = (this._cidr > 30) ? 0 : ((bmask >> this._cidr) - 1);
2,942✔
195
                return usableIps;
2,942✔
196
            }
2,974✔
197
        }
198

199
        /// <summary>
200
        /// Gets number of IP adress in Network.
201
        /// </summary>
202
        public BigInteger Total
203
        {
204
            get
205
            {
2,601✔
206
                int max = this._family == Sockets.AddressFamily.InterNetwork ? 32 : 128;
2,601✔
207
                var count = BigInteger.Pow(2, max - this._cidr);
2,601✔
208
                return count;
2,601✔
209
            }
2,601✔
210
        }
211

212
        /// <summary>
213
        /// Gets the CIDR netmask notation.
214
        /// </summary>
215
        public byte Cidr
216
        {
217
            get
218
            {
6,205,355✔
219
                return this._cidr;
6,205,355✔
220
            }
6,205,355✔
221
        }
222

223
        #endregion
224

225
        #region constructor
226

227
#if TRAVISCI
228
        public
229
#else
230
        /// <summary>
231
        /// Initializes a new instance of the <see cref="IPNetwork2"/> class with the specified IP address, address family, and CIDR.
232
        /// </summary>
233
        /// <param name="ipaddress">The IP address of the network.</param>
234
        /// <param name="family">The address family of the network.</param>
235
        /// <param name="cidr">The CIDR (Classless Inter-Domain Routing) notation of the network.</param>
236
        internal
8,133,863✔
237
#endif
8,133,863✔
238
            IPNetwork2(BigInteger ipaddress, AddressFamily family, byte cidr)
8,133,863✔
239
        {
8,133,863✔
240
            this.Init(ipaddress, family, cidr);
8,133,863✔
241
            this._hashCode = this.ComputeHashCode();
8,133,862✔
242
        }
8,133,862✔
243

244
        /// <summary>
245
        /// Initializes a new instance of the <see cref="IPNetwork2"/> class.
246
        /// Creates a new IPNetwork.
247
        /// </summary>
248
        /// <param name="ipaddress">An ipaddress.</param>
249
        /// <param name="cidr">A byte representing the netmask in cidr format (/24).</param>
250
        /// <exception cref="ArgumentNullException">ipaddress is null.</exception>
251
        public IPNetwork2(IPAddress ipaddress, byte cidr)
2,033✔
252
        {
2,033✔
253
            if (ipaddress == null)
2,033✔
254
            {
1✔
255
                throw new ArgumentNullException("ipaddress");
1✔
256
            }
257

258
            BigInteger uintIpAddress = ToBigInteger(ipaddress);
2,032✔
259

260
            this.Init(uintIpAddress, ipaddress.AddressFamily, cidr);
2,032✔
261
            this._hashCode = this.ComputeHashCode();
2,030✔
262
        }
2,030✔
263

264
        private void Init(BigInteger ipaddress, AddressFamily family, byte cidr)
265
        {
8,135,895✔
266
            int maxCidr = family == AddressFamily.InterNetwork ? 32 : 128;
8,135,895✔
267
            if (cidr > maxCidr)
8,135,895✔
268
            {
3✔
269
                throw new ArgumentOutOfRangeException("cidr");
3✔
270
            }
271

272
            this._ipaddress = ipaddress;
8,135,892✔
273
            this._family = family;
8,135,892✔
274
            this._cidr = cidr;
8,135,892✔
275
        }
8,135,892✔
276

277
        #endregion
278

279
        #region parsers
280

281
        /// <summary>
282
        /// 192.168.168.100 - 255.255.255.0
283
        ///
284
        /// ```
285
        /// Network   : 192.168.168.0
286
        /// Netmask   : 255.255.255.0
287
        /// Cidr      : 24
288
        /// Start     : 192.168.168.1
289
        /// End       : 192.168.168.254
290
        /// Broadcast : 192.168.168.255
291
        /// ```.
292
        ///
293
        /// </summary>
294
        /// <param name="ipaddress">A string containing an ip address to convert.</param>
295
        /// <param name="netmask">A string representing a netmask in std format (255.255.255.0).</param>
296
        /// <returns>An IPNetwork equivalent to the network contained in ipaddress/netmask.</returns>
297
        public static IPNetwork2 Parse(string ipaddress, string netmask)
298
        {
14✔
299
            IPNetwork2.InternalParse(false, ipaddress, netmask, out IPNetwork2 ipnetwork);
14✔
300
            return ipnetwork;
3✔
301
        }
3✔
302

303
        /// <summary>
304
        /// 192.168.168.100/24
305
        ///
306
        /// Network   : 192.168.168.0
307
        /// Netmask   : 255.255.255.0
308
        /// Cidr      : 24
309
        /// Start     : 192.168.168.1
310
        /// End       : 192.168.168.254
311
        /// Broadcast : 192.168.168.255.
312
        /// </summary>
313
        /// <param name="ipaddress">A string containing an ip address to convert.</param>
314
        /// <param name="cidr">A byte representing the netmask in cidr format (/24).</param>
315
        /// <returns>An IPNetwork equivalent to the network contained in ipaddress/cidr.</returns>
316
        public static IPNetwork2 Parse(string ipaddress, byte cidr)
317
        {
119✔
318
            IPNetwork2.InternalParse(false, ipaddress, cidr, out IPNetwork2 ipnetwork);
119✔
319
            return ipnetwork;
113✔
320
        }
113✔
321

322
        /// <summary>
323
        /// 192.168.168.100 255.255.255.0
324
        ///
325
        /// Network   : 192.168.168.0
326
        /// Netmask   : 255.255.255.0
327
        /// Cidr      : 24
328
        /// Start     : 192.168.168.1
329
        /// End       : 192.168.168.254
330
        /// Broadcast : 192.168.168.255.
331
        /// </summary>
332
        /// <param name="ipaddress">A string containing an ip address to convert.</param>
333
        /// <param name="netmask">A netmask to be used to create the IPNetwork.</param>
334
        /// <returns>An IPNetwork equivalent to the network contained in ipaddress/netmask.</returns>
335
        public static IPNetwork2 Parse(IPAddress ipaddress, IPAddress netmask)
336
        {
6✔
337
            IPNetwork2.InternalParse(false, ipaddress, netmask, out IPNetwork2 ipnetwork);
6✔
338
            return ipnetwork;
2✔
339
        }
2✔
340

341
        /// <summary>
342
        /// 192.168.0.1/24
343
        /// 192.168.0.1 255.255.255.0
344
        ///
345
        /// Network   : 192.168.0.0
346
        /// Netmask   : 255.255.255.0
347
        /// Cidr      : 24
348
        /// Start     : 192.168.0.1
349
        /// End       : 192.168.0.254
350
        /// Broadcast : 192.168.0.255.
351
        /// </summary>
352
        /// <param name="network">A string containing an ip network to convert.</param>
353
        /// <returns>An IPNetwork equivalent to the network contained in string network.</returns>
354
        public static IPNetwork2 Parse(string network)
355
        {
6,000,657✔
356
            IPNetwork2.InternalParse(false, network, CidrGuess.ClassFull, true, out IPNetwork2 ipnetwork);
6,000,657✔
357
            return ipnetwork;
6,000,651✔
358
        }
6,000,651✔
359

360
        /// <summary>
361
        /// 192.168.0.1/24
362
        /// 192.168.0.1 255.255.255.0
363
        ///
364
        /// Network   : 192.168.0.0
365
        /// Netmask   : 255.255.255.0
366
        /// Cidr      : 24
367
        /// Start     : 192.168.0.1
368
        /// End       : 192.168.0.254
369
        /// Broadcast : 192.168.0.255.
370
        /// </summary>
371
        /// <param name="network">A string containing an ip network to convert.</param>
372
        /// <param name="sanitanize">Whether to sanitize network or not.</param>
373
        /// <returns>An IPNetwork equivalent to the network contained in string network.</returns>
374
        public static IPNetwork2 Parse(string network, bool sanitanize)
375
        {
×
376
            IPNetwork2.InternalParse(false, network, CidrGuess.ClassFull, sanitanize, out IPNetwork2 ipnetwork);
×
377
            return ipnetwork;
×
378
        }
×
379

380
        /// <summary>
381
        /// 192.168.0.1/24
382
        /// 192.168.0.1 255.255.255.0
383
        ///
384
        /// Network   : 192.168.0.0
385
        /// Netmask   : 255.255.255.0
386
        /// Cidr      : 24
387
        /// Start     : 192.168.0.1
388
        /// End       : 192.168.0.254
389
        /// Broadcast : 192.168.0.255.
390
        /// </summary>
391
        /// <param name="network">A string containing an ip network to convert.</param>
392
        /// <param name="cidrGuess">A ICidrGuess implementation that will be used to guess CIDR during converion.</param>
393
        /// <returns>An IPNetwork equivalent to the network contained in string network.</returns>
394
        public static IPNetwork2 Parse(string network, ICidrGuess cidrGuess)
395
        {
16✔
396
            IPNetwork2.InternalParse(false, network, cidrGuess, true, out IPNetwork2 ipnetwork);
16✔
397
            return ipnetwork;
16✔
398
        }
16✔
399

400
        /// <summary>
401
        /// 192.168.0.1/24
402
        /// 192.168.0.1 255.255.255.0
403
        ///
404
        /// Network   : 192.168.0.0
405
        /// Netmask   : 255.255.255.0
406
        /// Cidr      : 24
407
        /// Start     : 192.168.0.1
408
        /// End       : 192.168.0.254
409
        /// Broadcast : 192.168.0.255.
410
        /// </summary>
411
        /// <param name="network">A string containing an ip network to convert.</param>
412
        /// <param name="cidrGuess">A ICidrGuess implementation that will be used to guess CIDR during converion.</param>
413
        /// <param name="sanitanize">Whether to sanitize network or not.</param>
414
        /// <returns>An IPNetwork equivalent to the network contained in string network.</returns>
415
        public static IPNetwork2 Parse(string network, ICidrGuess cidrGuess, bool sanitanize)
416
        {
×
417
            IPNetwork2.InternalParse(false, network, cidrGuess, sanitanize, out IPNetwork2 ipnetwork);
×
418
            return ipnetwork;
×
419
        }
×
420

421
        #endregion
422

423
        #region TryParse
424

425
        /// <summary>
426
        /// 192.168.168.100 - 255.255.255.0
427
        ///
428
        /// Network   : 192.168.168.0
429
        /// Netmask   : 255.255.255.0
430
        /// Cidr      : 24
431
        /// Start     : 192.168.168.1
432
        /// End       : 192.168.168.254
433
        /// Broadcast : 192.168.168.255.
434
        /// </summary>
435
        /// <param name="ipaddress">A string containing an ip address to convert.</param>
436
        /// <param name="netmask">A string containing a netmaks to convert (255.255.255.0).</param>
437
        /// <param name="ipnetwork">When this method returns, contains the IPNetwork value equivalent of the ip adress contained in ipaddress with the netmask corresponding to cidr, if the conversion succeeded, or null if the conversion failed. The conversion fails if the s parameter is null or Empty, is not of the correct format, or represents an invalid ip address. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param>
438
        /// <returns>true if ipaddress/netmask was converted successfully; otherwise, false..</returns>
439
        public static bool TryParse(string ipaddress, string netmask, out IPNetwork2 ipnetwork)
440
        {
20✔
441
            IPNetwork2.InternalParse(true, ipaddress, netmask, out IPNetwork2 ipnetwork2);
20✔
442
            bool parsed = ipnetwork2 != null;
20✔
443
            ipnetwork = ipnetwork2;
20✔
444

445
            return parsed;
20✔
446
        }
20✔
447

448
        /// <summary>
449
        /// 192.168.168.100/24
450
        ///
451
        /// Network   : 192.168.168.0
452
        /// Netmask   : 255.255.255.0
453
        /// Cidr      : 24
454
        /// Start     : 192.168.168.1
455
        /// End       : 192.168.168.254
456
        /// Broadcast : 192.168.168.255.
457
        /// </summary>
458
        /// <param name="ipaddress">A string containing an ip address to convert.</param>
459
        /// <param name="cidr">A byte representing the netmask in cidr format (/24).</param>
460
        /// <param name="ipnetwork">When this method returns, contains the IPNetwork value equivalent of the ip adress contained in ipaddress with the netmask corresponding to cidr, if the conversion succeeded, or null if the conversion failed. The conversion fails if the s parameter is null or Empty, is not of the correct format, or represents an invalid ip address. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param>
461
        /// <returns>true if ipaddress/cidr was converted successfully; otherwise, false..</returns>
462
        public static bool TryParse(string ipaddress, byte cidr, out IPNetwork2 ipnetwork)
463
        {
68✔
464
            IPNetwork2.InternalParse(true, ipaddress, cidr, out IPNetwork2 ipnetwork2);
68✔
465
            bool parsed = ipnetwork2 != null;
68✔
466
            ipnetwork = ipnetwork2;
68✔
467

468
            return parsed;
68✔
469
        }
68✔
470

471
        /// <summary>
472
        /// 192.168.0.1/24
473
        /// 192.168.0.1 255.255.255.0
474
        ///
475
        /// Network   : 192.168.0.0
476
        /// Netmask   : 255.255.255.0
477
        /// Cidr      : 24
478
        /// Start     : 192.168.0.1
479
        /// End       : 192.168.0.254
480
        /// Broadcast : 192.168.0.255.
481
        /// </summary>
482
        /// <param name="network">A string containing an ip network to convert.</param>
483
        /// <param name="ipnetwork">When this method returns, contains the IPNetwork value equivalent of the ip adress contained in ipaddress with the netmask corresponding to cidr, if the conversion succeeded, or null if the conversion failed. The conversion fails if the s parameter is null or Empty, is not of the correct format, or represents an invalid ip address. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param>
484
        /// <returns>true if network was converted successfully; otherwise, false..</returns>
485
        public static bool TryParse(string network, out IPNetwork2 ipnetwork)
486
        {
44✔
487
            bool sanitanize = true;
44✔
488
            IPNetwork2.InternalParse(true, network, CidrGuess.ClassFull, sanitanize, out IPNetwork2 ipnetwork2);
44✔
489
            bool parsed = ipnetwork2 != null;
44✔
490
            ipnetwork = ipnetwork2;
44✔
491

492
            return parsed;
44✔
493
        }
44✔
494

495
        /// <summary>
496
        /// 192.168.0.1/24
497
        /// 192.168.0.1 255.255.255.0
498
        ///
499
        /// Network   : 192.168.0.0
500
        /// Netmask   : 255.255.255.0
501
        /// Cidr      : 24
502
        /// Start     : 192.168.0.1
503
        /// End       : 192.168.0.254
504
        /// Broadcast : 192.168.0.255.
505
        /// </summary>
506
        /// <param name="network">A string containing an ip network to convert.</param>
507
        /// <param name="sanitanize">Whether to sanitize network or not.</param>
508
        /// <param name="ipnetwork">When this method returns, contains the IPNetwork value equivalent of the ip adress contained in ipaddress with the netmask corresponding to cidr, if the conversion succeeded, or null if the conversion failed. The conversion fails if the s parameter is null or Empty, is not of the correct format, or represents an invalid ip address. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param>
509
        /// <returns>true if network was converted successfully; otherwise, false..</returns>
510
        public static bool TryParse(string network, bool sanitanize, out IPNetwork2 ipnetwork)
511
        {
24✔
512
            IPNetwork2.InternalParse(true, network, CidrGuess.ClassFull, sanitanize, out IPNetwork2 ipnetwork2);
24✔
513
            bool parsed = ipnetwork2 != null;
24✔
514
            ipnetwork = ipnetwork2;
24✔
515

516
            return parsed;
24✔
517
        }
24✔
518

519
        /// <summary>
520
        /// 192.168.0.1/24
521
        /// 192.168.0.1 255.255.255.0
522
        ///
523
        /// Network   : 192.168.0.0
524
        /// Netmask   : 255.255.255.0
525
        /// Cidr      : 24
526
        /// Start     : 192.168.0.1
527
        /// End       : 192.168.0.254
528
        /// Broadcast : 192.168.0.255.
529
        /// </summary>
530
        /// <param name="ipaddress">An IPAdresse to convert.</param>
531
        /// <param name="netmask">A IPAdresse to be used as netmaks to convert.</param>
532
        /// <param name="ipnetwork">When this method returns, contains the IPNetwork value equivalent of the ip adress contained in ipaddress with the netmask corresponding to cidr, if the conversion succeeded, or null if the conversion failed. The conversion fails if the s parameter is null or Empty, is not of the correct format, or represents an invalid ip address. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param>
533
        /// <returns>true if network was converted successfully; otherwise, false..</returns>
534
        public static bool TryParse(IPAddress ipaddress, IPAddress netmask, out IPNetwork2 ipnetwork)
535
        {
4✔
536
            IPNetwork2.InternalParse(true, ipaddress, netmask, out IPNetwork2 ipnetwork2);
4✔
537
            bool parsed = ipnetwork2 != null;
4✔
538
            ipnetwork = ipnetwork2;
4✔
539

540
            return parsed;
4✔
541
        }
4✔
542

543
        /// <summary>
544
        /// 192.168.0.1/24
545
        /// 192.168.0.1 255.255.255.0
546
        ///
547
        /// Network   : 192.168.0.0
548
        /// Netmask   : 255.255.255.0
549
        /// Cidr      : 24
550
        /// Start     : 192.168.0.1
551
        /// End       : 192.168.0.254
552
        /// Broadcast : 192.168.0.255.
553
        /// </summary>
554
        /// <param name="network">A string containing an ip network to convert.</param>
555
        /// <param name="cidrGuess">A ICidrGuess implementation that will be used to guess CIDR during converion.</param>
556
        /// <param name="ipnetwork">When this method returns, contains the IPNetwork value equivalent of the ip adress contained in ipaddress with the netmask corresponding to cidr, if the conversion succeeded, or null if the conversion failed. The conversion fails if the s parameter is null or Empty, is not of the correct format, or represents an invalid ip address. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param>
557
        /// <returns>true if network was converted successfully; otherwise, false..</returns>
558
        public static bool TryParse(string network, ICidrGuess cidrGuess, out IPNetwork2 ipnetwork)
559
        {
3✔
560
            IPNetwork2.InternalParse(true, network, cidrGuess, true, out IPNetwork2 ipnetwork2);
3✔
561
            bool parsed = ipnetwork2 != null;
3✔
562
            ipnetwork = ipnetwork2;
3✔
563

564
            return parsed;
3✔
565
        }
3✔
566

567
        /// <summary>
568
        /// 192.168.0.1/24
569
        /// 192.168.0.1 255.255.255.0
570
        ///
571
        /// Network   : 192.168.0.0
572
        /// Netmask   : 255.255.255.0
573
        /// Cidr      : 24
574
        /// Start     : 192.168.0.1
575
        /// End       : 192.168.0.254
576
        /// Broadcast : 192.168.0.255.
577
        /// </summary>
578
        /// <param name="network">A string containing an ip network to convert.</param>
579
        /// <param name="cidrGuess">A ICidrGuess implementation that will be used to guess CIDR during converion.</param>
580
        /// <param name="sanitanize">Whether to sanitize network or not.</param>
581
        /// <param name="ipnetwork">When this method returns, contains the IPNetwork value equivalent of the ip adress contained in ipaddress with the netmask corresponding to cidr, if the conversion succeeded, or null if the conversion failed. The conversion fails if the s parameter is null or Empty, is not of the correct format, or represents an invalid ip address. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.</param>
582
        /// <returns>true if network was converted successfully; otherwise, false..</returns>
583
        public static bool TryParse(string network, ICidrGuess cidrGuess, bool sanitanize, out IPNetwork2 ipnetwork)
584
        {
12✔
585
            IPNetwork2.InternalParse(true, network, cidrGuess, sanitanize, out IPNetwork2 ipnetwork2);
12✔
586
            bool parsed = ipnetwork2 != null;
12✔
587
            ipnetwork = ipnetwork2;
12✔
588

589
            return parsed;
12✔
590
        }
12✔
591

592
        #endregion
593

594
        #region InternalParse
595

596
        /// <summary>
597
        /// 192.168.168.100 - 255.255.255.0
598
        ///
599
        /// Network   : 192.168.168.0
600
        /// Netmask   : 255.255.255.0
601
        /// Cidr      : 24
602
        /// Start     : 192.168.168.1
603
        /// End       : 192.168.168.254
604
        /// Broadcast : 192.168.168.255.
605
        /// </summary>
606
        /// <param name="tryParse">Whether to throw exception or not during conversion.</param>
607
        /// <param name="ipaddress">A string containing an ip address to convert.</param>
608
        /// <param name="netmask">A string containing a netmask to convert (255.255.255.0).</param>
609
        /// <param name="ipnetwork">The resulting IPNetwork.</param>
610
        private static void InternalParse(bool tryParse, string ipaddress, string netmask, out IPNetwork2 ipnetwork)
611
        {
85✔
612
            if (string.IsNullOrEmpty(ipaddress))
85✔
613
            {
8✔
614
                if (tryParse == false)
8✔
615
                {
3✔
616
                    throw new ArgumentNullException("ipaddress");
3✔
617
                }
618

619
                ipnetwork = null;
5✔
620
                return;
5✔
621
            }
622

623
            if (string.IsNullOrEmpty(netmask))
77✔
624
            {
9✔
625
                if (tryParse == false)
9✔
626
                {
4✔
627
                    throw new ArgumentNullException("netmask");
4✔
628
                }
629

630
                ipnetwork = null;
5✔
631
                return;
5✔
632
            }
633

634
            bool ipaddressParsed = IPAddress.TryParse(ipaddress, out IPAddress ip);
68✔
635
            if (ipaddressParsed == false)
68✔
636
            {
5✔
637
                if (tryParse == false)
5✔
638
                {
3✔
639
                    throw new ArgumentException("ipaddress");
3✔
640
                }
641

642
                ipnetwork = null;
2✔
643
                return;
2✔
644
            }
645

646
            bool netmaskParsed = IPAddress.TryParse(netmask, out IPAddress mask);
63✔
647
            if (netmaskParsed == false)
63✔
648
            {
4✔
649
                if (tryParse == false)
4✔
650
                {
2✔
651
                    throw new ArgumentException("netmask");
2✔
652
                }
653

654
                ipnetwork = null;
2✔
655
                return;
2✔
656
            }
657

658
            IPNetwork2.InternalParse(tryParse, ip, mask, out ipnetwork);
59✔
659
        }
72✔
660

661
        private static void InternalParse(bool tryParse, string network, ICidrGuess cidrGuess, bool sanitanize, out IPNetwork2 ipnetwork)
662
        {
6,000,756✔
663
            if (string.IsNullOrEmpty(network))
6,000,756✔
664
            {
4✔
665
                if (tryParse == false)
4✔
666
                {
2✔
667
                    throw new ArgumentNullException("network");
2✔
668
                }
669

670
                ipnetwork = null;
2✔
671
                return;
2✔
672
            }
673

674
            if (sanitanize)
6,000,752✔
675
            {
6,000,734✔
676
                network = Regex.Replace(network, @"[^0-9a-fA-F\.\/\s\:]+", string.Empty, RegexOptions.None, TimeSpan.FromMilliseconds(100));
6,000,734✔
677
                network = Regex.Replace(network, @"\s{2,}", " ", RegexOptions.None, TimeSpan.FromMilliseconds(100));
6,000,734✔
678
                network = network.Trim();
6,000,734✔
679
            }
6,000,734✔
680

681
            StringSplitOptions splitOptions = sanitanize ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None;
6,000,752✔
682
            string[] args = network.Split(new char[] { ' ', '/' }, splitOptions);
6,000,752✔
683
            byte cidr = 0;
6,000,752✔
684

685
            if (args.Length == 0)
6,000,752✔
686
            {
1✔
687
                if (tryParse == false)
1✔
688
                {
×
689
                    throw new ArgumentNullException("network");
×
690
                }
691
                
692
                ipnetwork = null;
1✔
693
                return;
1✔
694
            }
695
            
696
            if (args.Length == 1)
6,000,751✔
697
            {
49✔
698
                string cidrlessNetwork = args[0];
49✔
699
                if (cidrGuess.TryGuessCidr(cidrlessNetwork, out cidr))
49✔
700
                {
44✔
701
                    IPNetwork2.InternalParse(tryParse, cidrlessNetwork, cidr, out ipnetwork);
44✔
702
                    return;
44✔
703
                }
704

705
                if (tryParse == false)
5✔
706
                {
2✔
707
                    throw new ArgumentException("network");
2✔
708
                }
709

710
                ipnetwork = null;
3✔
711
                return;
3✔
712
            }
713

714
            if (byte.TryParse(args[1], out cidr))
6,000,702✔
715
            {
6,000,651✔
716
                IPNetwork2.InternalParse(tryParse, args[0], cidr, out ipnetwork);
6,000,651✔
717
                return;
6,000,651✔
718
            }
719

720
            IPNetwork2.InternalParse(tryParse, args[0], args[1], out ipnetwork);
51✔
721
            return;
49✔
722
        }
6,000,750✔
723

724
        /// <summary>
725
        /// 192.168.168.100 255.255.255.0
726
        ///
727
        /// Network   : 192.168.168.0
728
        /// Netmask   : 255.255.255.0
729
        /// Cidr      : 24
730
        /// Start     : 192.168.168.1
731
        /// End       : 192.168.168.254
732
        /// Broadcast : 192.168.168.255.
733
        /// </summary>
734
        /// <param name="tryParse">Whether to throw exception or not during conversion.</param>
735
        /// <param name="ipaddress">An ip address to convert.</param>
736
        /// <param name="netmask">A netmask to convert (255.255.255.0).</param>
737
        /// <param name="ipnetwork">The resulting IPNetwork.</param>
738
        private static void InternalParse(bool tryParse, IPAddress ipaddress, IPAddress netmask, out IPNetwork2 ipnetwork)
739
        {
6,000,901✔
740
            if (ipaddress == null)
6,000,901✔
741
            {
4✔
742
                if (tryParse == false)
4✔
743
                {
2✔
744
                    throw new ArgumentNullException("ipaddress");
2✔
745
                }
746

747
                ipnetwork = null;
2✔
748
                return;
2✔
749
            }
750

751
            if (netmask == null)
6,000,897✔
752
            {
4✔
753
                if (tryParse == false)
4✔
754
                {
2✔
755
                    throw new ArgumentNullException("netmask");
2✔
756
                }
757

758
                ipnetwork = null;
2✔
759
                return;
2✔
760
            }
761

762
            var uintIpAddress = IPNetwork2.ToBigInteger(ipaddress);
6,000,893✔
763
            bool parsed = IPNetwork2.TryToCidr(netmask, out byte? cidr2);
6,000,893✔
764
            if (parsed == false)
6,000,893✔
765
            {
3✔
766
                if (tryParse == false)
3✔
767
                {
1✔
768
                    throw new ArgumentException("netmask");
1✔
769
                }
770

771
                ipnetwork = null;
2✔
772
                return;
2✔
773
            }
774

775
            byte cidr = (byte)cidr2;
6,000,890✔
776

777
            var ipnet = new IPNetwork2(uintIpAddress, ipaddress.AddressFamily, cidr);
6,000,890✔
778
            ipnetwork = ipnet;
6,000,890✔
779

780
            return;
6,000,890✔
781
        }
6,000,896✔
782

783
        /// <summary>
784
        /// 192.168.168.100/24
785
        ///
786
        /// Network   : 192.168.168.0
787
        /// Netmask   : 255.255.255.0
788
        /// Cidr      : 24
789
        /// Start     : 192.168.168.1
790
        /// End       : 192.168.168.254
791
        /// Broadcast : 192.168.168.255.
792
        /// </summary>
793
        /// <param name="tryParse">Whether to throw exception or not during conversion.</param>
794
        /// <param name="ipaddress">A string containing an ip address to convert.</param>
795
        /// <param name="cidr">A byte representing the CIDR to be used in conversion (/24).</param>
796
        /// <param name="ipnetwork">The resulting IPNetwork.</param>
797
        private static void InternalParse(bool tryParse, string ipaddress, byte cidr, out IPNetwork2 ipnetwork)
798
        {
6,000,882✔
799
            if (string.IsNullOrEmpty(ipaddress))
6,000,882✔
800
            {
6✔
801
                if (tryParse == false)
6✔
802
                {
2✔
803
                    throw new ArgumentNullException("ipaddress");
2✔
804
                }
805

806
                ipnetwork = null;
4✔
807
                return;
4✔
808
            }
809

810
            bool ipaddressParsed = IPAddress.TryParse(ipaddress, out IPAddress ip);
6,000,876✔
811
            if (ipaddressParsed == false)
6,000,876✔
812
            {
40✔
813
                if (tryParse == false)
40✔
814
                {
2✔
815
                    throw new ArgumentException("ipaddress");
2✔
816
                }
817

818
                ipnetwork = null;
38✔
819
                return;
38✔
820
            }
821

822
            bool parsedNetmask = IPNetwork2.TryToNetmask(cidr, ip.AddressFamily, out IPAddress mask);
6,000,836✔
823
            if (parsedNetmask == false)
6,000,836✔
824
            {
4✔
825
                if (tryParse == false)
4✔
826
                {
2✔
827
                    throw new ArgumentException("cidr");
2✔
828
                }
829

830
                ipnetwork = null;
2✔
831
                return;
2✔
832
            }
833

834
            IPNetwork2.InternalParse(tryParse, ip, mask, out ipnetwork);
6,000,832✔
835
        }
6,000,876✔
836
        #endregion
837

838
        #region converters
839

840
        #region ToUint
841

842
        /// <summary>
843
        /// Convert an ipadress to decimal
844
        /// 0.0.0.0 -> 0
845
        /// 0.0.1.0 -> 256.
846
        /// </summary>
847
        /// <param name="ipaddress">A string containing an ip address to convert.</param>
848
        /// <returns>A number representing the ipaddress.</returns>
849
        public static BigInteger ToBigInteger(IPAddress ipaddress)
850
        {
6,203,725✔
851
            IPNetwork2.InternalToBigInteger(false, ipaddress, out BigInteger? uintIpAddress);
6,203,725✔
852

853
            return (BigInteger)uintIpAddress;
6,203,723✔
854
        }
6,203,723✔
855

856
        /// <summary>
857
        /// Convert an ipadress to decimal
858
        /// 0.0.0.0 -> 0
859
        /// 0.0.1.0 -> 256.
860
        /// </summary>
861
        /// <param name="ipaddress">A string containing an ip address to convert.</param>
862
        /// <param name="uintIpAddress">A number representing the IPAdress.</param>
863
        /// <returns>true if ipaddress was converted successfully; otherwise, false.</returns>
864
        public static bool TryToBigInteger(IPAddress ipaddress, out BigInteger? uintIpAddress)
865
        {
6,000,968✔
866
            IPNetwork2.InternalToBigInteger(true, ipaddress, out BigInteger? uintIpAddress2);
6,000,968✔
867
            bool parsed = uintIpAddress2 != null;
6,000,968✔
868
            uintIpAddress = uintIpAddress2;
6,000,968✔
869

870
            return parsed;
6,000,968✔
871
        }
6,000,968✔
872

873
#if TRAVISCI
874
        public
875
#else
876
        internal
877
#endif
878
            static void InternalToBigInteger(bool tryParse, IPAddress ipaddress, out BigInteger? uintIpAddress)
879
        {
12,204,693✔
880
            if (ipaddress == null)
12,204,693✔
881
            {
4✔
882
                if (tryParse == false)
4✔
883
                {
2✔
884
                    throw new ArgumentNullException("ipaddress");
2✔
885
                }
886

887
                uintIpAddress = null;
2✔
888
                return;
2✔
889
            }
890

891
#if NET5_0 || NETSTANDARD2_1
892
            byte[] bytes = ipaddress.AddressFamily == AddressFamily.InterNetwork ? new byte[4] : new byte[16];
893
            Span<byte> span = bytes.AsSpan();
894
            if (!ipaddress.TryWriteBytes(span, out _))
895
            {
896
                if (tryParse == false)
897
                {
898
                    throw new ArgumentException("ipaddress");
899
                }
900

901
                uintIpAddress = null;
902
                return;
903
            }
904

905
            uintIpAddress = new BigInteger(span, isUnsigned: true, isBigEndian: true);
906
#elif NET45 || NET46 || NET47 || NETSTANDARD20
907
            byte[] bytes = ipaddress.GetAddressBytes();
908
            bytes.AsSpan().Reverse();
909

910
            // add trailing 0 to make unsigned
911
            byte[] unsigned = new byte[bytes.Length + 1];
912
            Buffer.BlockCopy(bytes, 0, unsigned, 0, bytes.Length);
913
            uintIpAddress = new BigInteger(unsigned);
914
#else
915
            byte[] bytes = ipaddress.GetAddressBytes();
12,204,689✔
916
            Array.Reverse(bytes);
12,204,689✔
917

918
            // add trailing 0 to make unsigned
919
            byte[] unsigned = new byte[bytes.Length + 1];
12,204,689✔
920
            Buffer.BlockCopy(bytes, 0, unsigned, 0, bytes.Length);
12,204,689✔
921
            uintIpAddress = new BigInteger(unsigned);
12,204,689✔
922
#endif
923
        }
12,204,691✔
924

925
        /// <summary>
926
        /// Convert a cidr to BigInteger netmask.
927
        /// </summary>
928
        /// <param name="cidr">A byte representing the netmask in cidr format (/24).</param>
929
        /// <param name="family">Either IPv4 or IPv6.</param>
930
        /// <returns>A number representing the netmask exprimed in CIDR.</returns>
931
        public static BigInteger ToUint(byte cidr, AddressFamily family)
932
        {
23,304,102✔
933
            IPNetwork2.InternalToBigInteger(false, cidr, family, out BigInteger? uintNetmask);
23,304,102✔
934

935
            return (BigInteger)uintNetmask;
23,304,101✔
936
        }
23,304,101✔
937

938
        /// <summary>
939
        /// Convert a cidr to uint netmask.
940
        /// </summary>
941
        /// <param name="cidr">A byte representing the netmask in cidr format (/24).</param>
942
        /// <param name="family">Either IPv4 or IPv6.</param>
943
        /// <param name="uintNetmask">A number representing the netmask.</param>
944
        /// <returns>true if cidr was converted successfully; otherwise, false.</returns>
945
        public static bool TryToUint(byte cidr, AddressFamily family, out BigInteger? uintNetmask)
946
        {
1✔
947
            IPNetwork2.InternalToBigInteger(true, cidr, family, out BigInteger? uintNetmask2);
1✔
948
            bool parsed = uintNetmask2 != null;
1✔
949
            uintNetmask = uintNetmask2;
1✔
950

951
            return parsed;
1✔
952
        }
1✔
953

954
        /// <summary>
955
        /// Convert a cidr to uint netmask.
956
        /// </summary>
957
        /// <param name="tryParse">Whether to throw exception or not during conversion.</param>
958
        /// <param name="cidr">A byte representing the netmask in cidr format (/24).</param>
959
        /// <param name="family">Either IPv4 or IPv6.</param>
960
        /// <param name="uintNetmask">A number representing the netmask.</param>
961
#if TRAVISCI
962
        public
963
#else
964
        internal
965
#endif
966
            static void InternalToBigInteger(bool tryParse, byte cidr, AddressFamily family, out BigInteger? uintNetmask)
967
        {
23,304,108✔
968
            if (family == AddressFamily.InterNetwork && cidr > 32)
23,304,108✔
969
            {
2✔
970
                if (tryParse == false)
2✔
971
                {
1✔
972
                    throw new ArgumentOutOfRangeException("cidr");
1✔
973
                }
974

975
                uintNetmask = null;
1✔
976
                return;
1✔
977
            }
978

979
            if (family == AddressFamily.InterNetworkV6 && cidr > 128)
23,304,106✔
980
            {
2✔
981
                if (tryParse == false)
2✔
982
                {
1✔
983
                    throw new ArgumentOutOfRangeException("cidr");
1✔
984
                }
985

986
                uintNetmask = null;
1✔
987
                return;
1✔
988
            }
989

990
            if (family != AddressFamily.InterNetwork
23,304,104✔
991
                && family != AddressFamily.InterNetworkV6)
23,304,104✔
992
            {
2✔
993
                if (tryParse == false)
2✔
994
                {
1✔
995
                    throw new NotSupportedException(family.ToString());
1✔
996
                }
997

998
                uintNetmask = null;
1✔
999
                return;
1✔
1000
            }
1001

1002
            if (family == AddressFamily.InterNetwork)
23,304,102✔
1003
            {
23,296,857✔
1004
                uintNetmask = cidr == 0 ? 0 : 0xffffffff << (32 - cidr);
23,296,857✔
1005
                return;
23,296,857✔
1006
            }
1007

1008
            var mask = new BigInteger(new byte[]
7,245✔
1009
            {
7,245✔
1010
                0xff, 0xff, 0xff, 0xff,
7,245✔
1011
                0xff, 0xff, 0xff, 0xff,
7,245✔
1012
                0xff, 0xff, 0xff, 0xff,
7,245✔
1013
                0xff, 0xff, 0xff, 0xff,
7,245✔
1014
                0x00,
7,245✔
1015
            });
7,245✔
1016

1017
            BigInteger masked = cidr == 0 ? 0 : mask << (128 - cidr);
7,245✔
1018
            byte[] m = masked.ToByteArray();
7,245✔
1019
            byte[] bmask = new byte[17];
7,245✔
1020
            int copy = m.Length > 16 ? 16 : m.Length;
7,245✔
1021
            Array.Copy(m, 0, bmask, 0, copy);
7,245✔
1022
            uintNetmask = new BigInteger(bmask);
7,245✔
1023
        }
23,304,105✔
1024

1025
        #endregion
1026

1027
        #region ToCidr
1028

1029
        /// <summary>
1030
        /// Convert netmask to CIDR
1031
        ///  255.255.255.0 -> 24
1032
        ///  255.255.0.0   -> 16
1033
        ///  255.0.0.0     -> 8.
1034
        /// </summary>
1035
        /// <param name="tryParse">Whether to throw exception or not during conversion.</param>
1036
        /// <param name="netmask">A number representing the netmask to convert.</param>
1037
        /// <param name="family">Either IPv4 or IPv6.</param>
1038
        /// <param name="cidr">A byte representing the netmask in cidr format (/24).</param>
1039
        private static void InternalToCidr(bool tryParse, BigInteger netmask, AddressFamily family, out byte? cidr)
1040
        {
6,000,955✔
1041
            if (!IPNetwork2.InternalValidNetmask(netmask, family))
6,000,955✔
1042
            {
6✔
1043
                if (tryParse == false)
6✔
1044
                {
2✔
1045
                    throw new ArgumentException("netmask");
2✔
1046
                }
1047

1048
                cidr = null;
4✔
1049
                return;
4✔
1050
            }
1051

1052
            byte cidr2 = IPNetwork2.BitsSet(netmask, family);
6,000,949✔
1053
            cidr = cidr2;
6,000,949✔
1054

1055
            return;
6,000,949✔
1056
        }
6,000,953✔
1057

1058
        /// <summary>
1059
        /// Convert netmask to CIDR
1060
        ///  255.255.255.0 -> 24
1061
        ///  255.255.0.0   -> 16
1062
        ///  255.0.0.0     -> 8.
1063
        /// </summary>
1064
        /// <param name="netmask">An IPAdress representing the CIDR to convert.</param>
1065
        /// <returns>A byte representing the CIDR converted from the netmask.</returns>
1066
        public static byte ToCidr(IPAddress netmask)
1067
        {
33✔
1068
            IPNetwork2.InternalToCidr(false, netmask, out byte? cidr);
33✔
1069
            return (byte)cidr;
30✔
1070
        }
30✔
1071

1072
        /// <summary>
1073
        /// Convert netmask to CIDR
1074
        ///  255.255.255.0 -> 24
1075
        ///  255.255.0.0   -> 16
1076
        ///  255.0.0.0     -> 8.
1077
        /// </summary>
1078
        /// <param name="netmask">An IPAdress representing the CIDR to convert.</param>
1079
        /// <param name="cidr">A byte representing the netmask in cidr format (/24).</param>
1080
        /// <returns>true if netmask was converted successfully; otherwise, false.</returns>
1081
        public static bool TryToCidr(IPAddress netmask, out byte? cidr)
1082
        {
6,000,924✔
1083
            IPNetwork2.InternalToCidr(true, netmask, out byte? cidr2);
6,000,924✔
1084
            bool parsed = cidr2 != null;
6,000,924✔
1085
            cidr = cidr2;
6,000,924✔
1086
            return parsed;
6,000,924✔
1087
        }
6,000,924✔
1088

1089
        private static void InternalToCidr(bool tryParse, IPAddress netmask, out byte? cidr)
1090
        {
6,000,957✔
1091
            if (netmask == null)
6,000,957✔
1092
            {
2✔
1093
                if (tryParse == false)
2✔
1094
                {
1✔
1095
                    throw new ArgumentNullException("netmask");
1✔
1096
                }
1097

1098
                cidr = null;
1✔
1099
                return;
1✔
1100
            }
1101

1102
            bool parsed = IPNetwork2.TryToBigInteger(netmask, out BigInteger? uintNetmask2);
6,000,955✔
1103

1104
            // 20180217 lduchosal
1105
            // impossible to reach code.
1106
            // if (parsed == false) {
1107
            //     if (tryParse == false) {
1108
            //         throw new ArgumentException("netmask");
1109
            //     }
1110
            //     cidr = null;
1111
            //     return;
1112
            // }
1113
            var uintNetmask = (BigInteger)uintNetmask2;
6,000,955✔
1114

1115
            IPNetwork2.InternalToCidr(tryParse, uintNetmask, netmask.AddressFamily, out byte? cidr2);
6,000,955✔
1116
            cidr = cidr2;
6,000,953✔
1117

1118
            return;
6,000,953✔
1119
        }
6,000,954✔
1120

1121
        #endregion
1122

1123
        #region ToNetmask
1124

1125
        /// <summary>
1126
        /// Convert CIDR to netmask
1127
        ///  24 -> 255.255.255.0
1128
        ///  16 -> 255.255.0.0
1129
        ///  8 -> 255.0.0.0.
1130
        /// </summary>
1131
        /// <see href="http://snipplr.com/view/15557/cidr-class-for-ipv4/"/>
1132
        /// <param name="cidr">A byte representing the netmask in cidr format (/24).</param>
1133
        /// <param name="family">Either IPv4 or IPv6.</param>
1134
        /// <returns>An IPAdress representing cidr.</returns>
1135
        public static IPAddress ToNetmask(byte cidr, AddressFamily family)
1136
        {
15✔
1137
            IPNetwork2.InternalToNetmask(false, cidr, family, out IPAddress netmask);
15✔
1138

1139
            return netmask;
11✔
1140
        }
11✔
1141

1142
        /// <summary>
1143
        /// Convert CIDR to netmask
1144
        ///  24 -> 255.255.255.0
1145
        ///  16 -> 255.255.0.0
1146
        ///  8 -> 255.0.0.0.
1147
        /// </summary>
1148
        /// <see href="http://snipplr.com/view/15557/cidr-class-for-ipv4/"/>
1149
        /// <param name="cidr">A byte representing the netmask in cidr format (/24).</param>
1150
        /// <param name="family">Either IPv4 or IPv6.</param>
1151
        /// <param name="netmask">The resulting netmask.</param>
1152
        /// <returns>true if cidr was converted successfully; otherwise, false.</returns>
1153
        public static bool TryToNetmask(byte cidr, AddressFamily family, out IPAddress netmask)
1154
        {
6,000,849✔
1155
            IPNetwork2.InternalToNetmask(true, cidr, family, out IPAddress netmask2);
6,000,849✔
1156
            bool parsed = netmask2 != null;
6,000,849✔
1157
            netmask = netmask2;
6,000,849✔
1158

1159
            return parsed;
6,000,849✔
1160
        }
6,000,849✔
1161

1162
#if TRAVISCI
1163
        public
1164
#else
1165
        internal
1166
#endif
1167
            static void InternalToNetmask(bool tryParse, byte cidr, AddressFamily family, out IPAddress netmask)
1168
        {
6,000,865✔
1169
            if (family != AddressFamily.InterNetwork
6,000,865✔
1170
                && family != AddressFamily.InterNetworkV6)
6,000,865✔
1171
            {
2✔
1172
                if (tryParse == false)
2✔
1173
                {
1✔
1174
                    throw new ArgumentException("family");
1✔
1175
                }
1176

1177
                netmask = null;
1✔
1178
                return;
1✔
1179
            }
1180

1181
            // 20180217 lduchosal
1182
            // impossible to reach code, byte cannot be negative :
1183
            //
1184
            // if (cidr < 0) {
1185
            //     if (tryParse == false) {
1186
            //         throw new ArgumentOutOfRangeException("cidr");
1187
            //     }
1188
            //     netmask = null;
1189
            //     return;
1190
            // }
1191
            int maxCidr = family == Sockets.AddressFamily.InterNetwork ? 32 : 128;
6,000,863✔
1192
            if (cidr > maxCidr)
6,000,863✔
1193
            {
10✔
1194
                if (tryParse == false)
10✔
1195
                {
3✔
1196
                    throw new ArgumentOutOfRangeException("cidr");
3✔
1197
                }
1198

1199
                netmask = null;
7✔
1200
                return;
7✔
1201
            }
1202

1203
            BigInteger mask = IPNetwork2.ToUint(cidr, family);
6,000,853✔
1204
            var netmask2 = IPNetwork2.ToIPAddress(mask, family);
6,000,853✔
1205
            netmask = netmask2;
6,000,853✔
1206

1207
            return;
6,000,853✔
1208
        }
6,000,861✔
1209

1210
        #endregion
1211

1212
        #endregion
1213

1214
        #region utils
1215

1216
        #region BitsSet
1217

1218
        /// <summary>
1219
        /// Count bits set to 1 in netmask.
1220
        /// </summary>
1221
        /// <see href="http://stackoverflow.com/questions/109023/best-algorithm-to-count-the-number-of-set-bits-in-a-32-bit-integer"/>
1222
        /// <param name="netmask">A number representing the netmask to count bits from.</param>
1223
        /// <param name="family">Either IPv4 or IPv6.</param>
1224
        /// <returns>The number of bytes set to 1.</returns>
1225
        private static byte BitsSet(BigInteger netmask, AddressFamily family)
1226
        {
6,000,957✔
1227
            string s = netmask.ToBinaryString();
6,000,957✔
1228

1229
            return (byte)s.Replace("0", string.Empty)
6,000,957✔
1230
                .ToCharArray()
6,000,957✔
1231
                .Length;
6,000,957✔
1232
        }
6,000,957✔
1233

1234
        /// <summary>
1235
        /// Count bits set to 1 in netmask.
1236
        /// </summary>
1237
        /// <param name="netmask">A number representing the netmask to count bits from.</param>
1238
        /// <returns>The number of bytes set to 1.</returns>
1239
        public static uint BitsSet(IPAddress netmask)
1240
        {
8✔
1241
            var uintNetmask = IPNetwork2.ToBigInteger(netmask);
8✔
1242
            uint bits = IPNetwork2.BitsSet(uintNetmask, netmask.AddressFamily);
8✔
1243

1244
            return bits;
8✔
1245
        }
8✔
1246

1247
        #endregion
1248

1249
        #region ValidNetmask
1250

1251
        /// <summary>
1252
        /// return true if netmask is a valid netmask
1253
        /// 255.255.255.0, 255.0.0.0, 255.255.240.0, ...
1254
        /// </summary>
1255
        /// <see href="http://www.actionsnip.com/snippets/tomo_atlacatl/calculate-if-a-netmask-is-valid--as2-"/>
1256
        /// <param name="netmask">A number representing the netmask to validate.</param>
1257
        /// <returns>true if netmask is a valid IP Netmask; otherwise, false.</returns>
1258
        public static bool ValidNetmask(IPAddress netmask)
1259
        {
11✔
1260
            if (netmask == null)
11✔
1261
            {
1✔
1262
                throw new ArgumentNullException("netmask");
1✔
1263
            }
1264

1265
            var uintNetmask = IPNetwork2.ToBigInteger(netmask);
10✔
1266
            bool valid = IPNetwork2.InternalValidNetmask(uintNetmask, netmask.AddressFamily);
10✔
1267

1268
            return valid;
10✔
1269
        }
10✔
1270

1271
#if TRAVISCI
1272
        public
1273
#else
1274
        internal
1275
#endif
1276
            static bool InternalValidNetmask(BigInteger netmask, AddressFamily family)
1277
        {
6,000,966✔
1278
            if (family != AddressFamily.InterNetwork
6,000,966✔
1279
                && family != AddressFamily.InterNetworkV6)
6,000,966✔
1280
            {
1✔
1281
                throw new ArgumentException("family");
1✔
1282
            }
1283

1284
            BigInteger mask = family == AddressFamily.InterNetwork
6,000,965✔
1285
                ? new BigInteger(0x0ffffffff)
6,000,965✔
1286
                : new BigInteger(new byte[]
6,000,965✔
1287
                {
6,000,965✔
1288
                    0xff, 0xff, 0xff, 0xff,
6,000,965✔
1289
                    0xff, 0xff, 0xff, 0xff,
6,000,965✔
1290
                    0xff, 0xff, 0xff, 0xff,
6,000,965✔
1291
                    0xff, 0xff, 0xff, 0xff,
6,000,965✔
1292
                    0x00,
6,000,965✔
1293
                });
6,000,965✔
1294

1295
            BigInteger neg = (~netmask) & mask;
6,000,965✔
1296
            bool isNetmask = ((neg + 1) & neg) == 0;
6,000,965✔
1297

1298
            return isNetmask;
6,000,965✔
1299
        }
6,000,965✔
1300

1301
        #endregion
1302

1303
        #region ToIPAddress
1304

1305
        /// <summary>
1306
        /// Transform a uint ipaddress into IPAddress object.
1307
        /// </summary>
1308
        /// <param name="ipaddress">A number representing an ip address to convert.</param>
1309
        /// <param name="family">Either IPv4 or IPv6.</param>
1310
        /// <returns>An ip adress.</returns>
1311
        public static IPAddress ToIPAddress(BigInteger ipaddress, AddressFamily family)
1312
        {
12,209,630✔
1313
            int width = family == AddressFamily.InterNetwork ? 4 : 16;
12,209,630✔
1314
            byte[] bytes = ipaddress.ToByteArray();
12,209,630✔
1315
            byte[] bytes2 = new byte[width];
12,209,630✔
1316
            int copy = bytes.Length > width ? width : bytes.Length;
12,209,630✔
1317
            Array.Copy(bytes, 0, bytes2, 0, copy);
12,209,630✔
1318
            Array.Reverse(bytes2);
12,209,630✔
1319

1320
            byte[] sized = Resize(bytes2, family);
12,209,630✔
1321
            var ip = new IPAddress(sized);
12,209,628✔
1322
            return ip;
12,209,628✔
1323
        }
12,209,628✔
1324

1325
#if TRAVISCI
1326
        public
1327
#else
1328
        internal
1329
#endif
1330
            static byte[] Resize(byte[] bytes, AddressFamily family)
1331
        {
12,209,631✔
1332
            if (family != AddressFamily.InterNetwork
12,209,631✔
1333
                && family != AddressFamily.InterNetworkV6)
12,209,631✔
1334
            {
2✔
1335
                throw new ArgumentException("family");
2✔
1336
            }
1337

1338
            int width = family == AddressFamily.InterNetwork ? 4 : 16;
12,209,629✔
1339

1340
            if (bytes.Length > width)
12,209,629✔
1341
            {
1✔
1342
                throw new ArgumentException("bytes");
1✔
1343
            }
1344

1345
            byte[] result = new byte[width];
12,209,628✔
1346
            Array.Copy(bytes, 0, result, 0, bytes.Length);
12,209,628✔
1347

1348
            return result;
12,209,628✔
1349
        }
12,209,628✔
1350

1351
        #endregion
1352

1353
        #endregion
1354

1355
        #region contains
1356

1357
        /// <summary>
1358
        /// return true if ipaddress is contained in network.
1359
        /// </summary>
1360
        /// <param name="contains">A string containing an ip address to convert.</param>
1361
        /// <returns>true if ipaddress is contained into the IP Network; otherwise, false.</returns>
1362
        public bool Contains(IPAddress contains)
1363
        {
282✔
1364
            if (contains == null)
282✔
1365
            {
2✔
1366
                throw new ArgumentNullException("contains");
2✔
1367
            }
1368

1369
            if (this.AddressFamily != contains.AddressFamily)
280✔
1370
            {
1✔
1371
                return false;
1✔
1372
            }
1373

1374
            BigInteger uintNetwork = this._network;
279✔
1375
            BigInteger uintBroadcast = this._broadcast; // CreateBroadcast(ref uintNetwork, this._netmask, this._family);
279✔
1376
            var uintAddress = IPNetwork2.ToBigInteger(contains);
279✔
1377

1378
            bool result = uintAddress >= uintNetwork
279✔
1379
                && uintAddress <= uintBroadcast;
279✔
1380

1381
            return result;
279✔
1382
        }
280✔
1383

1384
        /// <summary>
1385
        /// Determines whether the given IP address is part of the given IP network.
1386
        /// </summary>
1387
        /// <param name="network">The IP network.</param>
1388
        /// <param name="ipaddress">The IP address.</param>
1389
        /// <returns>
1390
        /// <c>true</c> if the IP address is part of the IP network; otherwise, <c>false</c>.
1391
        /// </returns>
1392
        [Obsolete("static Contains is deprecated, please use instance Contains.")]
1393
        public static bool Contains(IPNetwork2 network, IPAddress ipaddress)
1394
        {
2✔
1395
            if (network == null)
2✔
1396
            {
1✔
1397
                throw new ArgumentNullException("network");
1✔
1398
            }
1399

1400
            return network.Contains(ipaddress);
1✔
1401
        }
1✔
1402

1403
        /// <summary>
1404
        /// return true is network2 is fully contained in network.
1405
        /// </summary>
1406
        /// <param name="contains">The network to test.</param>
1407
        /// <returns>It returns the boolean value. If network2 is in IPNetwork then it returns True, otherwise returns False.</returns>
1408
        public bool Contains(IPNetwork2 contains)
1409
        {
264,304✔
1410
            if (contains == null)
264,304✔
1411
            {
1✔
1412
                throw new ArgumentNullException("contains");
1✔
1413
            }
1414

1415
            BigInteger uintNetwork = this._network;
264,303✔
1416
            BigInteger uintBroadcast = this._broadcast; // CreateBroadcast(ref uintNetwork, this._netmask, this._family);
264,303✔
1417

1418
            BigInteger uintFirst = contains._network;
264,303✔
1419
            BigInteger uintLast = contains._broadcast; // CreateBroadcast(ref uintFirst, network2._netmask, network2._family);
264,303✔
1420

1421
            bool result = uintFirst >= uintNetwork
264,303✔
1422
                && uintLast <= uintBroadcast;
264,303✔
1423

1424
            return result;
264,303✔
1425
        }
264,303✔
1426

1427
        /// <summary>
1428
        /// Determines if the given <paramref name="network"/> contains the specified <paramref name="network2"/>.
1429
        /// </summary>
1430
        /// <param name="network">The network to check for containment.</param>
1431
        /// <param name="network2">The network to check if it is contained.</param>
1432
        /// <returns>
1433
        /// <c>true</c> if the <paramref name="network"/> contains the <paramref name="network2"/>; otherwise, <c>false</c>.
1434
        /// </returns>
1435
        [Obsolete("static Contains is deprecated, please use instance Contains.")]
1436
        public static bool Contains(IPNetwork2 network, IPNetwork2 network2)
1437
        {
2✔
1438
            if (network == null)
2✔
1439
            {
1✔
1440
                throw new ArgumentNullException("network");
1✔
1441
            }
1442

1443
            return network.Contains(network2);
1✔
1444
        }
1✔
1445

1446
        private static BigInteger CreateBroadcast(ref BigInteger network, BigInteger netmask, AddressFamily family)
1447
        {
133,911✔
1448
            int width = family == AddressFamily.InterNetwork ? 4 : 16;
133,911✔
1449
            BigInteger uintBroadcast = network + netmask.PositiveReverse(width);
133,911✔
1450

1451
            return uintBroadcast;
133,911✔
1452
        }
133,911✔
1453

1454
        #endregion
1455

1456
        #region overlap
1457

1458
        /// <summary>
1459
        /// return true is network2 overlap network.
1460
        /// </summary>
1461
        /// <param name="network2">The network to test.</param>
1462
        /// <returns>true if network2 overlaps into the IP Network; otherwise, false.</returns>
1463
        public bool Overlap(IPNetwork2 network2)
1464
        {
16✔
1465
            if (network2 == null)
16✔
1466
            {
2✔
1467
                throw new ArgumentNullException("network2");
2✔
1468
            }
1469

1470
            BigInteger uintNetwork = this._network;
14✔
1471
            BigInteger uintBroadcast = this._broadcast;
14✔
1472

1473
            BigInteger uintFirst = network2._network;
14✔
1474
            BigInteger uintLast = network2._broadcast;
14✔
1475

1476
            bool overlap =
14✔
1477
                (uintFirst >= uintNetwork && uintFirst <= uintBroadcast)
14✔
1478
                || (uintLast >= uintNetwork && uintLast <= uintBroadcast)
14✔
1479
                || (uintFirst <= uintNetwork && uintLast >= uintBroadcast)
14✔
1480
                || (uintFirst >= uintNetwork && uintLast <= uintBroadcast);
14✔
1481

1482
            return overlap;
14✔
1483
        }
14✔
1484

1485
        /// <summary>
1486
        /// Determines if two IPNetwork2 objects overlap each other.
1487
        /// </summary>
1488
        /// <param name="network">The first IPNetwork2 object.</param>
1489
        /// <param name="network2">The second IPNetwork2 object.</param>
1490
        /// <returns>Returns true if the two IPNetwork2 objects overlap, otherwise false.</returns>
1491
        [Obsolete("static Overlap is deprecated, please use instance Overlap.")]
1492
        public static bool Overlap(IPNetwork2 network, IPNetwork2 network2)
1493
        {
2✔
1494
            if (network == null)
2✔
1495
            {
1✔
1496
                throw new ArgumentNullException("network");
1✔
1497
            }
1498

1499
            return network.Overlap(network2);
1✔
1500
        }
1✔
1501

1502
        #endregion
1503

1504
        #region ToString
1505

1506
        /// <summary>
1507
        /// Returns a string representation of the object.
1508
        /// </summary>
1509
        /// <returns>
1510
        /// A string representation of the object which includes the Network and Cidr values separated by a "/".
1511
        /// </returns>
1512
        public override string ToString()
1513
        {
6,002,532✔
1514
            return string.Format("{0}/{1}", this.Network, this.Cidr);
6,002,532✔
1515
        }
6,002,532✔
1516

1517
        #endregion
1518

1519
        #region IANA block
1520

1521
        private static readonly Lazy<IPNetwork2> _iana_ablock_reserved = new Lazy<IPNetwork2>(() => IPNetwork2.Parse("10.0.0.0/8"));
2✔
1522
        private static readonly Lazy<IPNetwork2> _iana_bblock_reserved = new Lazy<IPNetwork2>(() => IPNetwork2.Parse("172.16.0.0/12"));
2✔
1523
        private static readonly Lazy<IPNetwork2> _iana_cblock_reserved = new Lazy<IPNetwork2>(() => IPNetwork2.Parse("192.168.0.0/16"));
2✔
1524

1525
        /// <summary>
1526
        /// Gets 10.0.0.0/8.
1527
        /// </summary>
1528
        /// <returns>The IANA reserved IPNetwork 10.0.0.0/8.</returns>
1529
        public static IPNetwork2 IANA_ABLK_RESERVED1
1530
        {
1531
            get
1532
            {
28✔
1533
                return _iana_ablock_reserved.Value;
28✔
1534
            }
28✔
1535
        }
1536

1537
        /// <summary>
1538
        /// Gets 172.12.0.0/12.
1539
        /// </summary>
1540
        /// <returns>The IANA reserved IPNetwork 172.12.0.0/12.</returns>
1541
        public static IPNetwork2 IANA_BBLK_RESERVED1
1542
        {
1543
            get
1544
            {
8✔
1545
                return _iana_bblock_reserved.Value;
8✔
1546
            }
8✔
1547
        }
1548

1549
        /// <summary>
1550
        /// Gets 192.168.0.0/16.
1551
        /// </summary>
1552
        /// <returns>The IANA reserved IPNetwork 192.168.0.0/16.</returns>
1553
        public static IPNetwork2 IANA_CBLK_RESERVED1
1554
        {
1555
            get
1556
            {
14✔
1557
                return _iana_cblock_reserved.Value;
14✔
1558
            }
14✔
1559
        }
1560

1561
        /// <summary>
1562
        /// return true if ipaddress is contained in
1563
        /// IANA_ABLK_RESERVED1, IANA_BBLK_RESERVED1, IANA_CBLK_RESERVED1.
1564
        /// </summary>
1565
        /// <param name="ipaddress">A string containing an ip address to convert.</param>
1566
        /// <returns>true if ipaddress is a IANA reserverd IP Netowkr ; otherwise, false.</returns>
1567
        public static bool IsIANAReserved(IPAddress ipaddress)
1568
        {
5✔
1569
            if (ipaddress == null)
5✔
1570
            {
1✔
1571
                throw new ArgumentNullException("ipaddress");
1✔
1572
            }
1573

1574
            return IPNetwork2.IANA_ABLK_RESERVED1.Contains(ipaddress)
4✔
1575
                || IPNetwork2.IANA_BBLK_RESERVED1.Contains(ipaddress)
4✔
1576
                || IPNetwork2.IANA_CBLK_RESERVED1.Contains(ipaddress);
4✔
1577
        }
4✔
1578

1579
        /// <summary>
1580
        /// return true if ipnetwork is contained in
1581
        /// IANA_ABLK_RESERVED1, IANA_BBLK_RESERVED1, IANA_CBLK_RESERVED1.
1582
        /// </summary>
1583
        /// <returns>true if the ipnetwork is a IANA reserverd IP Netowkr ; otherwise, false.</returns>
1584
        public bool IsIANAReserved()
1585
        {
6✔
1586
            return IPNetwork2.IANA_ABLK_RESERVED1.Contains(this)
6✔
1587
                || IPNetwork2.IANA_BBLK_RESERVED1.Contains(this)
6✔
1588
                || IPNetwork2.IANA_CBLK_RESERVED1.Contains(this);
6✔
1589
        }
6✔
1590

1591
        /// <summary>
1592
        /// Determines whether the specified IP network is reserved according to the IANA Reserved ranges.
1593
        /// </summary>
1594
        /// <param name="ipnetwork">The IP network to check.</param>
1595
        /// <returns>
1596
        /// <c>true</c> if the specified IP network is reserved according to the IANA Reserved ranges; otherwise, <c>false</c>.
1597
        /// </returns>
1598
        /// <remarks>
1599
        /// <para>
1600
        /// This method is obsolete and should not be used. Please use the instance method <see cref="IsIANAReserved"/> instead.
1601
        /// </para>
1602
        /// <para>
1603
        /// Throws an <see cref="ArgumentNullException"/> if <paramref name="ipnetwork"/> is <c>null</c>.
1604
        /// </para>
1605
        /// </remarks>
1606
        [Obsolete("static IsIANAReserved is deprecated, please use instance IsIANAReserved.")]
1607
        public static bool IsIANAReserved(IPNetwork2 ipnetwork)
1608
        {
2✔
1609
            if (ipnetwork == null)
2✔
1610
            {
1✔
1611
                throw new ArgumentNullException("ipnetwork");
1✔
1612
            }
1613

1614
            return ipnetwork.IsIANAReserved();
1✔
1615
        }
1✔
1616

1617
        #endregion
1618

1619
        #region Subnet
1620

1621
        /// <summary>
1622
        /// Subnet a network into multiple nets of cidr mask
1623
        /// Subnet 192.168.0.0/24 into cidr 25 gives 192.168.0.0/25, 192.168.0.128/25
1624
        /// Subnet 10.0.0.0/8 into cidr 9 gives 10.0.0.0/9, 10.128.0.0/9.
1625
        /// </summary>
1626
        /// <param name="cidr">A byte representing the CIDR to be used to subnet the current IPNetwork.</param>
1627
        /// <returns>A IPNetworkCollection splitted by CIDR.</returns>
1628
        public IPNetworkCollection Subnet(byte cidr)
1629
        {
159✔
1630
            IPNetwork2.InternalSubnet(false, this, cidr, out IPNetworkCollection ipnetworkCollection);
159✔
1631

1632
            return ipnetworkCollection;
155✔
1633
        }
155✔
1634

1635
        /// <summary>
1636
        /// Subnet method is used to divide the given IP network into subnets with the specified CIDR.
1637
        /// </summary>
1638
        /// <param name="network">The IP network to be subnetted.</param>
1639
        /// <param name="cidr">The CIDR (Classless Inter-Domain Routing) value used to subnet the network.</param>
1640
        /// <returns>
1641
        /// A collection of subnets created from the given network using the specified CIDR.
1642
        /// </returns>
1643
        [Obsolete("static Subnet is deprecated, please use instance Subnet.")]
1644
        public static IPNetworkCollection Subnet(IPNetwork2 network, byte cidr)
1645
        {
2✔
1646
            if (network == null)
2✔
1647
            {
1✔
1648
                throw new ArgumentNullException("network");
1✔
1649
            }
1650

1651
            return network.Subnet(cidr);
1✔
1652
        }
1✔
1653

1654
        /// <summary>
1655
        /// Subnet a network into multiple nets of cidr mask
1656
        /// Subnet 192.168.0.0/24 into cidr 25 gives 192.168.0.0/25, 192.168.0.128/25
1657
        /// Subnet 10.0.0.0/8 into cidr 9 gives 10.0.0.0/9, 10.128.0.0/9.
1658
        /// </summary>
1659
        /// <param name="cidr">A byte representing the CIDR to be used to subnet the current IPNetwork.</param>
1660
        /// <param name="ipnetworkCollection">The resulting subnetted IPNetwork.</param>
1661
        /// <returns>true if network was split successfully; otherwise, false.</returns>
1662
        public bool TrySubnet(byte cidr, out IPNetworkCollection ipnetworkCollection)
1663
        {
10✔
1664
            IPNetwork2.InternalSubnet(true, this, cidr, out IPNetworkCollection inc);
10✔
1665
            if (inc == null)
10✔
1666
            {
4✔
1667
                ipnetworkCollection = null;
4✔
1668
                return false;
4✔
1669
            }
1670

1671
            ipnetworkCollection = inc;
6✔
1672
            return true;
6✔
1673
        }
10✔
1674

1675
        /// <summary>
1676
        /// Subnet a network into multiple nets of cidr mask
1677
        /// Subnet 192.168.0.0/24 into cidr 25 gives 192.168.0.0/25, 192.168.0.128/25
1678
        /// Subnet 10.0.0.0/8 into cidr 9 gives 10.0.0.0/9, 10.128.0.0/9.
1679
        /// </summary>
1680
        /// <param name="network"></param>
1681
        /// <param name="cidr">A byte representing the CIDR to be used to subnet the current IPNetwork.</param>
1682
        /// <param name="ipnetworkCollection">The resulting subnetted IPNetwork.</param>
1683
        /// <returns>true if network was split successfully; otherwise, false.</returns>
1684
        [Obsolete("static TrySubnet is deprecated, please use instance TrySubnet.")]
1685
        public static bool TrySubnet(IPNetwork2 network, byte cidr, out IPNetworkCollection ipnetworkCollection)
1686
        {
2✔
1687
            if (network == null)
2✔
1688
            {
1✔
1689
                throw new ArgumentNullException("network");
1✔
1690
            }
1691

1692
            return network.TrySubnet(cidr, out ipnetworkCollection);
1✔
1693
        }
1✔
1694

1695
#if TRAVISCI
1696
        public
1697
#else
1698
        internal
1699
#endif
1700
            static void InternalSubnet(bool trySubnet, IPNetwork2 network, byte cidr, out IPNetworkCollection ipnetworkCollection)
1701
        {
171✔
1702
            if (network == null)
171✔
1703
            {
2✔
1704
                if (trySubnet == false)
2✔
1705
                {
1✔
1706
                    throw new ArgumentNullException("network");
1✔
1707
                }
1708

1709
                ipnetworkCollection = null;
1✔
1710
                return;
1✔
1711
            }
1712

1713
            int maxCidr = network._family == Sockets.AddressFamily.InterNetwork ? 32 : 128;
169✔
1714
            if (cidr > maxCidr)
169✔
1715
            {
4✔
1716
                if (trySubnet == false)
4✔
1717
                {
2✔
1718
                    throw new ArgumentOutOfRangeException("cidr");
2✔
1719
                }
1720

1721
                ipnetworkCollection = null;
2✔
1722
                return;
2✔
1723
            }
1724

1725
            if (cidr < network.Cidr)
165✔
1726
            {
4✔
1727
                if (trySubnet == false)
4✔
1728
                {
2✔
1729
                    throw new ArgumentException("cidr");
2✔
1730
                }
1731

1732
                ipnetworkCollection = null;
2✔
1733
                return;
2✔
1734
            }
1735

1736
            ipnetworkCollection = new IPNetworkCollection(network, cidr);
161✔
1737
            return;
161✔
1738
        }
166✔
1739

1740
        #endregion
1741

1742
        #region Supernet
1743

1744
        /// <summary>
1745
        /// Supernet two consecutive cidr equal subnet into a single one
1746
        /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
1747
        /// 10.1.0.0/16 + 10.0.0.0/16 = 10.0.0.0/15
1748
        /// 192.168.0.0/24 + 192.168.0.0/25 = 192.168.0.0/24.
1749
        /// </summary>
1750
        /// <param name="network2">The network to supernet with.</param>
1751
        /// <returns>A supernetted IP Network.</returns>
1752
        public IPNetwork2 Supernet(IPNetwork2 network2)
1753
        {
10✔
1754
            IPNetwork2.InternalSupernet(false, this, network2, out IPNetwork2 supernet);
10✔
1755
            return supernet;
5✔
1756
        }
5✔
1757

1758
        /// <summary>
1759
        /// Supernet two consecutive cidr equal subnet into a single one
1760
        /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
1761
        /// 10.1.0.0/16 + 10.0.0.0/16 = 10.0.0.0/15
1762
        /// 192.168.0.0/24 + 192.168.0.0/25 = 192.168.0.0/24.
1763
        /// </summary>
1764
        /// <param name="network"></param>
1765
        /// <param name="network2">The network to supernet with.</param>
1766
        /// <returns>A supernetted IP Network.</returns>
1767
        [Obsolete("static Supernet is deprecated, please use instance Supernet.")]
1768
        public static IPNetwork2 Supernet(IPNetwork2 network, IPNetwork2 network2)
1769
        {
1✔
1770
            return network.Supernet(network2);
1✔
1771
        }
1✔
1772

1773
        /// <summary>
1774
        /// Try to supernet two consecutive cidr equal subnet into a single one
1775
        /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
1776
        /// 10.1.0.0/16 + 10.0.0.0/16 = 10.0.0.0/15
1777
        /// 192.168.0.0/24 + 192.168.0.0/25 = 192.168.0.0/24.
1778
        /// </summary>
1779
        /// <param name="network2">The network to supernet with.</param>
1780
        /// <param name="supernet">The resulting IPNetwork.</param>
1781
        /// <returns>true if network2 was supernetted successfully; otherwise, false.</returns>
1782
        public bool TrySupernet(IPNetwork2 network2, out IPNetwork2 supernet)
1783
        {
132,131✔
1784
            IPNetwork2.InternalSupernet(true, this, network2, out IPNetwork2 outSupernet);
132,131✔
1785
            bool parsed = outSupernet != null;
132,131✔
1786
            supernet = outSupernet;
132,131✔
1787
            return parsed;
132,131✔
1788
        }
132,131✔
1789

1790
        /// <summary>
1791
        /// Try to supernet two consecutive cidr equal subnet into a single one
1792
        /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
1793
        /// 10.1.0.0/16 + 10.0.0.0/16 = 10.0.0.0/15
1794
        /// 192.168.0.0/24 + 192.168.0.0/25 = 192.168.0.0/24.
1795
        /// </summary>
1796
        /// <param name="network"></param>
1797
        /// <param name="network2">The network to supernet with.</param>
1798
        /// <param name="supernet">The resulting IPNetwork.</param>
1799
        /// <returns>true if network2 was supernetted successfully; otherwise, false.</returns>
1800
        [Obsolete("static TrySupernet is deprecated, please use instance TrySupernet.")]
1801
        public static bool TrySupernet(IPNetwork2 network, IPNetwork2 network2, out IPNetwork2 supernet)
1802
        {
3✔
1803
            if (network == null)
3✔
1804
            {
2✔
1805
                throw new ArgumentNullException("network");
2✔
1806
            }
1807

1808
            return network.TrySupernet(network2, out supernet);
1✔
1809
        }
1✔
1810

1811
#if TRAVISCI
1812
        public
1813
#else
1814
        internal
1815
#endif
1816
            static void InternalSupernet(bool trySupernet, IPNetwork2 network1, IPNetwork2 network2, out IPNetwork2 supernet)
1817
        {
132,143✔
1818
            if (network1 == null)
132,143✔
1819
            {
2✔
1820
                if (trySupernet == false)
2✔
1821
                {
1✔
1822
                    throw new ArgumentNullException("network1");
1✔
1823
                }
1824

1825
                supernet = null;
1✔
1826
                return;
1✔
1827
            }
1828

1829
            if (network2 == null)
132,141✔
1830
            {
3✔
1831
                if (trySupernet == false)
3✔
1832
                {
1✔
1833
                    throw new ArgumentNullException("network2");
1✔
1834
                }
1835

1836
                supernet = null;
2✔
1837
                return;
2✔
1838
            }
1839

1840
            if (network1.Contains(network2))
132,138✔
1841
            {
9✔
1842
                supernet = new IPNetwork2(network1._network, network1._family, network1.Cidr);
9✔
1843
                return;
9✔
1844
            }
1845

1846
            if (network2.Contains(network1))
132,129✔
1847
            {
3✔
1848
                supernet = new IPNetwork2(network2._network, network2._family, network2.Cidr);
3✔
1849
                return;
3✔
1850
            }
1851

1852
            if (network1._cidr != network2._cidr)
132,126✔
1853
            {
66,039✔
1854
                if (trySupernet == false)
66,039✔
1855
                {
1✔
1856
                    throw new ArgumentException("cidr");
1✔
1857
                }
1858

1859
                supernet = null;
66,038✔
1860
                return;
66,038✔
1861
            }
1862

1863
            IPNetwork2 first = (network1._network < network2._network) ? network1 : network2;
66,087✔
1864
            IPNetwork2 last = (network1._network > network2._network) ? network1 : network2;
66,087✔
1865

1866
            // Starting from here :
1867
            // network1 and network2 have the same cidr,
1868
            // network1 does not contain network2,
1869
            // network2 does not contain network1,
1870
            // first is the lower subnet
1871
            // last is the higher subnet
1872
            if ((first._broadcast + 1) != last._network)
66,087✔
1873
            {
10✔
1874
                if (trySupernet == false)
10✔
1875
                {
2✔
1876
                    throw new ArgumentOutOfRangeException("network1");
2✔
1877
                }
1878

1879
                supernet = null;
8✔
1880
                return;
8✔
1881
            }
1882

1883
            BigInteger uintSupernet = first._network;
66,077✔
1884
            byte cidrSupernet = (byte)(first._cidr - 1);
66,077✔
1885

1886
            var networkSupernet = new IPNetwork2(uintSupernet, first._family, cidrSupernet);
66,077✔
1887
            if (networkSupernet._network != first._network)
66,077✔
1888
            {
7✔
1889
                if (trySupernet == false)
7✔
1890
                {
1✔
1891
                    throw new ArgumentException("network");
1✔
1892
                }
1893

1894
                supernet = null;
6✔
1895
                return;
6✔
1896
            }
1897

1898
            supernet = networkSupernet;
66,070✔
1899
            return;
66,070✔
1900
        }
132,137✔
1901

1902
        #endregion
1903

1904
        #region GetHashCode
1905

1906
        /// <inheritdoc />
1907
        public override int GetHashCode()
1908
        {
6,000,033✔
1909
            return this._hashCode;
6,000,033✔
1910
        }
6,000,033✔
1911

1912
        /// <summary>
1913
        /// 20221105 : ldvhcosal
1914
        /// GetHashCode uses mutable attributes. That introduce undefined behaviour on Hashtable and dictionary.
1915
        /// </summary>
1916
        /// <returns>An number representing the hashCode.</returns>
1917
        private int ComputeHashCode()
1918
        {
8,135,892✔
1919
            return string.Format(
8,135,892✔
1920
                "{0}|{1}|{2}",
8,135,892✔
1921
                this._family.GetHashCode(),
8,135,892✔
1922
                this._network.GetHashCode(),
8,135,892✔
1923
                this._cidr.GetHashCode()).GetHashCode();
8,135,892✔
1924
        }
8,135,892✔
1925

1926
        #endregion
1927

1928
        #region SupernetArray
1929

1930
        /// <summary>
1931
        /// Supernet a list of subnet
1932
        /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
1933
        /// 192.168.0.0/24 + 192.168.1.0/24 + 192.168.2.0/24 + 192.168.3.0/24 = 192.168.0.0/22.
1934
        /// </summary>
1935
        /// <param name="ipnetworks">A list of IPNetwork to merge into common supernets.</param>
1936
        /// <returns>The result of IPNetwork if merges succeed, the first ipnetwork otherwise.</returns>
1937
        public static IPNetwork2[] Supernet(IPNetwork2[] ipnetworks)
1938
        {
15✔
1939
            InternalSupernet(false, ipnetworks, out IPNetwork2[] supernet);
15✔
1940
            return supernet;
14✔
1941
        }
14✔
1942

1943
        /// <summary>
1944
        /// Supernet a list of subnet
1945
        /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
1946
        /// 192.168.0.0/24 + 192.168.1.0/24 + 192.168.2.0/24 + 192.168.3.0/24 = 192.168.0.0/22.
1947
        /// </summary>
1948
        /// <param name="ipnetworks">A list of IPNetwork to merge into common supernets.</param>
1949
        /// <param name="supernet">The result of IPNetwork merges.</param>
1950
        /// <returns>true if ipnetworks was supernetted successfully; otherwise, false.</returns>
1951
        public static bool TrySupernet(IPNetwork2[] ipnetworks, out IPNetwork2[] supernet)
1952
        {
7✔
1953
            bool supernetted = InternalSupernet(true, ipnetworks, out supernet);
7✔
1954
            return supernetted;
7✔
1955
        }
7✔
1956

1957
#if TRAVISCI
1958
        public
1959
#else
1960
        internal
1961
#endif
1962
        static bool InternalSupernet(bool trySupernet, IPNetwork2[] ipnetworks, out IPNetwork2[] supernet)
1963
        {
22✔
1964
            if (ipnetworks == null)
22✔
1965
            {
3✔
1966
                if (trySupernet == false)
3✔
1967
                {
1✔
1968
                    throw new ArgumentNullException("ipnetworks");
1✔
1969
                }
1970

1971
                supernet = null;
2✔
1972
                return false;
2✔
1973
            }
1974

1975
            if (ipnetworks.Length <= 0)
19✔
1976
            {
1✔
1977
                supernet = new IPNetwork2[0];
1✔
1978
                return true;
1✔
1979
            }
1980

1981
            var supernetted = new List<IPNetwork2>();
18✔
1982
            List<IPNetwork2> ipns = IPNetwork2.Array2List(ipnetworks);
18✔
1983
            Stack<IPNetwork2> current = IPNetwork2.List2Stack(ipns);
18✔
1984
            int previousCount = 0;
18✔
1985
            int currentCount = current.Count;
18✔
1986

1987
            while (previousCount != currentCount)
83✔
1988
            {
65✔
1989
                supernetted.Clear();
65✔
1990
                while (current.Count > 1)
132,181✔
1991
                {
132,116✔
1992
                    IPNetwork2 ipn1 = current.Pop();
132,116✔
1993
                    IPNetwork2 ipn2 = current.Peek();
132,116✔
1994

1995
                    bool success = ipn1.TrySupernet(ipn2, out IPNetwork2 outNetwork);
132,116✔
1996
                    if (success)
132,116✔
1997
                    {
66,072✔
1998
                        current.Pop();
66,072✔
1999
                        current.Push(outNetwork);
66,072✔
2000
                    }
66,072✔
2001
                    else
2002
                    {
66,044✔
2003
                        supernetted.Add(ipn1);
66,044✔
2004
                    }
66,044✔
2005
                }
132,116✔
2006

2007
                if (current.Count == 1)
65✔
2008
                {
65✔
2009
                    supernetted.Add(current.Pop());
65✔
2010
                }
65✔
2011

2012
                previousCount = currentCount;
65✔
2013
                currentCount = supernetted.Count;
65✔
2014
                current = IPNetwork2.List2Stack(supernetted);
65✔
2015
            }
65✔
2016

2017
            supernet = supernetted.ToArray();
18✔
2018
            return true;
18✔
2019
        }
21✔
2020

2021
        private static Stack<IPNetwork2> List2Stack(List<IPNetwork2> list)
2022
        {
83✔
2023
            var stack = new Stack<IPNetwork2>();
83✔
2024
            list.ForEach(new Action<IPNetwork2>(
83✔
2025
                delegate(IPNetwork2 ipn)
83✔
2026
                {
132,209✔
2027
                    stack.Push(ipn);
132,209✔
2028
                }));
132,292✔
2029
            return stack;
83✔
2030
        }
83✔
2031

2032
        private static List<IPNetwork2> Array2List(IPNetwork2[] array)
2033
        {
18✔
2034
            var ipns = new List<IPNetwork2>();
18✔
2035
            ipns.AddRange(array);
18✔
2036
            IPNetwork2.RemoveNull(ipns);
18✔
2037
            ipns.Sort(new Comparison<IPNetwork2>(
18✔
2038
                delegate(IPNetwork2 ipn1, IPNetwork2 ipn2)
18✔
2039
                {
850,489✔
2040
                    int networkCompare = ipn1._network.CompareTo(ipn2._network);
850,489✔
2041
                    if (networkCompare == 0)
850,489✔
2042
                    {
1✔
2043
                        int cidrCompare = ipn1._cidr.CompareTo(ipn2._cidr);
1✔
2044
                        return cidrCompare;
1✔
2045
                    }
18✔
2046

18✔
2047
                    return networkCompare;
850,488✔
2048
                }));
850,507✔
2049
            ipns.Reverse();
18✔
2050

2051
            return ipns;
18✔
2052
        }
18✔
2053

2054
        private static void RemoveNull(List<IPNetwork2> ipns)
2055
        {
18✔
2056
            ipns.RemoveAll(new Predicate<IPNetwork2>(
18✔
2057
                delegate(IPNetwork2 ipn)
18✔
2058
                {
66,104✔
2059
                    if (ipn == null)
66,104✔
2060
                    {
4✔
2061
                        return true;
4✔
2062
                    }
18✔
2063

18✔
2064
                    return false;
66,100✔
2065
                }));
66,122✔
2066
        }
18✔
2067

2068
        #endregion
2069

2070
        #region WideSubnet
2071

2072
        /// <summary>
2073
        /// Finds the widest subnet that can contain both the start and end IP addresses.
2074
        /// </summary>
2075
        /// <param name="start">The starting IP address.</param>
2076
        /// <param name="end">The ending IP address.</param>
2077
        /// <returns>The widest subnet that contains both the start and end IP addresses.</returns>
2078
        /// <exception cref="ArgumentNullException">Thrown when either the start or end IP address is null or empty.</exception>
2079
        /// <exception cref="ArgumentException">Thrown when the start or end IP addresses are not valid.</exception>
2080
        /// <exception cref="NotSupportedException">Thrown when the start and end IP addresses have different address families.</exception>
2081
        public static IPNetwork2 WideSubnet(string start, string end)
2082
        {
12✔
2083
            if (string.IsNullOrEmpty(start))
12✔
2084
            {
1✔
2085
                throw new ArgumentNullException("start");
1✔
2086
            }
2087

2088
            if (string.IsNullOrEmpty(end))
11✔
2089
            {
1✔
2090
                throw new ArgumentNullException("end");
1✔
2091
            }
2092

2093
            if (!IPAddress.TryParse(start, out IPAddress startIP))
10✔
2094
            {
1✔
2095
                throw new ArgumentException("start");
1✔
2096
            }
2097

2098
            if (!IPAddress.TryParse(end, out IPAddress endIP))
9✔
2099
            {
1✔
2100
                throw new ArgumentException("end");
1✔
2101
            }
2102

2103
            if (startIP.AddressFamily != endIP.AddressFamily)
8✔
2104
            {
1✔
2105
                throw new NotSupportedException("MixedAddressFamily");
1✔
2106
            }
2107

2108
            var ipnetwork = new IPNetwork2(0, startIP.AddressFamily, 0);
7✔
2109
            for (byte cidr = 32; cidr >= 0; cidr--)
226✔
2110
            {
113✔
2111
                var wideSubnet = IPNetwork2.Parse(start, cidr);
113✔
2112
                if (wideSubnet.Contains(endIP))
113✔
2113
                {
7✔
2114
                    ipnetwork = wideSubnet;
7✔
2115
                    break;
7✔
2116
                }
2117
            }
106✔
2118

2119
            return ipnetwork;
7✔
2120
        }
7✔
2121

2122
        /// <summary>
2123
        /// Attempts to find the widest subnet that contains both the start and end IP addresses. objects.
2124
        /// </summary>
2125
        /// <param name="ipnetworks">An array of IPNetwork2 objects to wide subnet.</param>
2126
        /// <param name="ipnetwork">When this method returns, contains the wide subnet of the IPNetwork2 objects, if wide subnet was successful; otherwise, null.</param>
2127
        /// <returns>true if wide subnet was successful; otherwise, false.</returns>
2128
        public static bool TryWideSubnet(IPNetwork2[] ipnetworks, out IPNetwork2 ipnetwork)
2129
        {
6✔
2130
            IPNetwork2.InternalWideSubnet(true, ipnetworks, out IPNetwork2 ipn);
6✔
2131
            if (ipn == null)
6✔
2132
            {
2✔
2133
                ipnetwork = null;
2✔
2134
                return false;
2✔
2135
            }
2136

2137
            ipnetwork = ipn;
4✔
2138

2139
            return true;
4✔
2140
        }
6✔
2141

2142
        /// <summary>
2143
        /// Finds the widest subnet from an array of IP networks. </summary> <param name="ipnetworks">An array of IPNetwork2 objects representing the IP networks.</param> <returns>The widest subnet as an IPNetwork2 object.</returns>
2144
        /// /
2145
        public static IPNetwork2 WideSubnet(IPNetwork2[] ipnetworks)
2146
        {
6✔
2147
            IPNetwork2.InternalWideSubnet(false, ipnetworks, out IPNetwork2 ipn);
6✔
2148
            return ipn;
3✔
2149
        }
3✔
2150

2151
        internal static void InternalWideSubnet(bool tryWide, IPNetwork2[] ipnetworks, out IPNetwork2 ipnetwork)
2152
        {
12✔
2153
            if (ipnetworks == null)
12✔
2154
            {
2✔
2155
                if (tryWide == false)
2✔
2156
                {
1✔
2157
                    throw new ArgumentNullException("ipnetworks");
1✔
2158
                }
2159

2160
                ipnetwork = null;
1✔
2161
                return;
1✔
2162
            }
2163

2164
            IPNetwork2[] nnin = Array.FindAll<IPNetwork2>(ipnetworks, new Predicate<IPNetwork2>(
10✔
2165
                delegate(IPNetwork2 ipnet)
10✔
2166
                {
23✔
2167
                    return ipnet != null;
23✔
2168
                }));
33✔
2169

2170
            if (nnin.Length <= 0)
10✔
2171
            {
2✔
2172
                if (tryWide == false)
2✔
2173
                {
1✔
2174
                    throw new ArgumentException("ipnetworks");
1✔
2175
                }
2176

2177
                ipnetwork = null;
1✔
2178
                return;
1✔
2179
            }
2180

2181
            if (nnin.Length == 1)
8✔
2182
            {
1✔
2183
                IPNetwork2 ipn0 = nnin[0];
1✔
2184
                ipnetwork = ipn0;
1✔
2185
                return;
1✔
2186
            }
2187

2188
            Array.Sort<IPNetwork2>(nnin);
7✔
2189
            IPNetwork2 nnin0 = nnin[0];
7✔
2190
            BigInteger uintNnin0 = nnin0._ipaddress;
7✔
2191

2192
            IPNetwork2 nninX = nnin[nnin.Length - 1];
7✔
2193
            IPAddress ipaddressX = nninX.Broadcast;
7✔
2194

2195
            AddressFamily family = ipnetworks[0]._family;
7✔
2196
            foreach (IPNetwork2 ipnx in ipnetworks)
64✔
2197
            {
22✔
2198
                if (ipnx._family != family)
22✔
2199
                {
1✔
2200
                    throw new ArgumentException("MixedAddressFamily");
1✔
2201
                }
2202
            }
21✔
2203

2204
            var ipn = new IPNetwork2(0, family, 0);
6✔
2205
            for (byte cidr = nnin0._cidr; cidr >= 0; cidr--)
264✔
2206
            {
132✔
2207
                var wideSubnet = new IPNetwork2(uintNnin0, family, cidr);
132✔
2208
                if (wideSubnet.Contains(ipaddressX))
132✔
2209
                {
6✔
2210
                    ipn = wideSubnet;
6✔
2211
                    break;
6✔
2212
                }
2213
            }
126✔
2214

2215
            ipnetwork = ipn;
6✔
2216
            return;
6✔
2217
        }
9✔
2218

2219
        #endregion
2220

2221
        #region Print
2222

2223
        /// <summary>
2224
        /// Print an ipnetwork in a clear representation string.
2225
        /// </summary>
2226
        /// <returns>Dump an IPNetwork representation as string.</returns>
2227
        public string Print()
2228
        {
2✔
2229
            using (var sw = new StringWriter())
2✔
2230
            {
2✔
2231
                sw.WriteLine("IPNetwork   : {0}", this.ToString());
2✔
2232
                sw.WriteLine("Network     : {0}", this.Network);
2✔
2233
                sw.WriteLine("Netmask     : {0}", this.Netmask);
2✔
2234
                sw.WriteLine("Cidr        : {0}", this.Cidr);
2✔
2235
                sw.WriteLine("Broadcast   : {0}", this.Broadcast);
2✔
2236
                sw.WriteLine("FirstUsable : {0}", this.FirstUsable);
2✔
2237
                sw.WriteLine("LastUsable  : {0}", this.LastUsable);
2✔
2238
                sw.WriteLine("Usable      : {0}", this.Usable);
2✔
2239

2240
                return sw.ToString();
2✔
2241
            }
2242
        }
2✔
2243

2244
        /// <summary>
2245
        /// Print an ipnetwork in a clear representation string.
2246
        /// </summary>
2247
        /// <returns>Dump an IPNetwork representation as string.</returns>
2248
        [Obsolete("static Print is deprecated, please use instance Print.")]
2249
        public static string Print(IPNetwork2 ipnetwork)
2250
        {
2✔
2251
            if (ipnetwork == null)
2✔
2252
            {
1✔
2253
                throw new ArgumentNullException("ipnetwork");
1✔
2254
            }
2255

2256
            return ipnetwork.Print();
1✔
2257
        }
1✔
2258

2259
        #endregion
2260

2261
        #region TryGuessCidr
2262

2263
        /// <summary>
2264
        /// Delegate to CidrGuess ClassFull guessing of cidr.
2265
        /// </summary>
2266
        /// <param name="ip">A string representing an IPAdress that will be used to guess the corresponding CIDR.</param>
2267
        /// <param name="cidr">The resulting CIDR as byte.</param>
2268
        /// <returns>true if cidr was guessed successfully; otherwise, false.</returns>
2269
        public static bool TryGuessCidr(string ip, out byte cidr)
2270
        {
9✔
2271
            return CidrGuess.ClassFull.TryGuessCidr(ip, out cidr);
9✔
2272
        }
9✔
2273

2274
        /// <summary>
2275
        /// Try to parse cidr. Have to be >= 0 and &lt;= 32 or 128.
2276
        /// </summary>
2277
        /// <param name="sidr">A string representing a byte CIRD (/24).</param>
2278
        /// <param name="family">Either IPv4 or IPv6.</param>
2279
        /// <param name="cidr">The resulting CIDR as byte.</param>
2280
        /// <returns>true if cidr was converted successfully; otherwise, false.</returns>
2281
        public static bool TryParseCidr(string sidr, AddressFamily family, out byte? cidr)
2282
        {
11✔
2283
            byte b = 0;
11✔
2284
            if (!byte.TryParse(sidr, out b))
11✔
2285
            {
2✔
2286
                cidr = null;
2✔
2287
                return false;
2✔
2288
            }
2289

2290
            if (!IPNetwork2.TryToNetmask(b, family, out IPAddress netmask))
9✔
2291
            {
2✔
2292
                cidr = null;
2✔
2293
                return false;
2✔
2294
            }
2295

2296
            cidr = b;
7✔
2297
            return true;
7✔
2298
        }
11✔
2299

2300
        #endregion
2301

2302
        #region ListIPAddress
2303

2304
        /// <summary>
2305
        /// List all ip addresses in a subnet.
2306
        /// </summary>
2307
        /// <param name="ipnetwork">The network to list IPAdresses.</param>
2308
        /// <returns>All the IPAdresses contained in ipnetwork.</returns>
2309
        [Obsolete("static ListIPAddress is deprecated, please use instance ListIPAddress.")]
2310
        public static IPAddressCollection ListIPAddress(IPNetwork2 ipnetwork)
2311
        {
1✔
2312
            return ipnetwork.ListIPAddress();
1✔
2313
        }
1✔
2314

2315
        /// <summary>
2316
        /// List all ip addresses in a subnet.
2317
        /// </summary>
2318
        /// <param name="filter">Filter IPAdresses from IPNetwork.</param>
2319
        /// <returns>The filterted IPAdresses contained in ipnetwork.</returns>
2320
        public IPAddressCollection ListIPAddress(FilterEnum filter = FilterEnum.All)
2321
        {
32✔
2322
            return new IPAddressCollection(this, filter);
32✔
2323
        }
32✔
2324

2325
        #endregion
2326

2327
        #region IComparable<IPNetwork> Members
2328

2329
        /// <summary>
2330
        /// Compares two IPNetwork2 instances.
2331
        /// </summary>
2332
        /// <param name="left">The first IPNetwork2 instance to compare.</param>
2333
        /// <param name="right">The second IPNetwork2 instance to compare.</param>
2334
        /// <returns>
2335
        /// A value indicating the relative order of the two IPNetwork2 instances.
2336
        /// Zero if the instances are equal.
2337
        /// A negative value if <paramref name="left"/> is less than <paramref name="right"/>.
2338
        /// A positive value if <paramref name="left"/> is greater than <paramref name="right"/>.
2339
        /// </returns>
2340
        public static int Compare(IPNetwork2 left, IPNetwork2 right)
2341
        {
727,424✔
2342
            // two null IPNetworks are equal
2343
            if (ReferenceEquals(left, null) && ReferenceEquals(right, null))
727,424✔
2344
            {
66,150✔
2345
                return 0;
66,150✔
2346
            }
2347

2348
            // two same IPNetworks are equal
2349
            if (ReferenceEquals(left, right))
661,274✔
2350
            {
8✔
2351
                return 0;
8✔
2352
            }
2353

2354
            // null is always sorted first
2355
            if (ReferenceEquals(left, null))
661,266✔
2356
            {
1✔
2357
                return -1;
1✔
2358
            }
2359

2360
            if (ReferenceEquals(right, null))
661,265✔
2361
            {
661,088✔
2362
                return 1;
661,088✔
2363
            }
2364

2365
            // first test family
2366
            int result = left._family.CompareTo(right._family);
177✔
2367
            if (result != 0)
177✔
2368
            {
2✔
2369
                return result;
2✔
2370
            }
2371

2372
            // second test the network
2373
            result = left._network.CompareTo(right._network);
175✔
2374
            if (result != 0)
175✔
2375
            {
44✔
2376
                return result;
44✔
2377
            }
2378

2379
            // then test the cidr
2380
            result = left._cidr.CompareTo(right._cidr);
131✔
2381
            return result;
131✔
2382
        }
727,424✔
2383

2384
        /// <summary>
2385
        /// Compare two ipnetworks.
2386
        /// </summary>
2387
        /// <param name="other">The other network to compare to.</param>
2388
        /// <returns>A signed number indicating the relative values of this instance and value..</returns>
2389
        public int CompareTo(IPNetwork2 other)
2390
        {
38✔
2391
            return Compare(this, other);
38✔
2392
        }
38✔
2393

2394
        /// <summary>
2395
        /// Compare two ipnetworks.
2396
        /// </summary>
2397
        /// <param name="obj">The other object to compare to.</param>
2398
        /// <returns>A signed number indicating the relative values of this instance and value..</returns>
2399
        public int CompareTo(object obj)
2400
        {
3✔
2401
            // null is at less
2402
            if (obj == null)
3✔
2403
            {
1✔
2404
                return 1;
1✔
2405
            }
2406

2407
            // convert to a proper Cidr object
2408
            var other = obj as IPNetwork2;
2✔
2409

2410
            // type problem if null
2411
            if (other == null)
2✔
2412
            {
1✔
2413
                throw new ArgumentException(
1✔
2414
                    "The supplied parameter is an invalid type. Please supply an IPNetwork type.",
1✔
2415
                    "obj");
1✔
2416
            }
2417

2418
            // perform the comparision
2419
            return this.CompareTo(other);
1✔
2420
        }
2✔
2421

2422
        #endregion
2423

2424
        #region IEquatable<IPNetwork> Members
2425

2426
        /// <summary>
2427
        /// Compare two ipnetworks.
2428
        /// </summary>
2429
        /// <param name="left">An IPNetwork to compare.</param>
2430
        /// <param name="right">An other IPNetwork to compare to.</param>
2431
        /// <returns>true if obj has the same value as this instance; otherwise, false.</returns>
2432
        public static bool Equals(IPNetwork2 left, IPNetwork2 right)
2433
        {
727,380✔
2434
            return Compare(left, right) == 0;
727,380✔
2435
        }
727,380✔
2436

2437
        /// <summary>
2438
        /// Compare two ipnetworks.
2439
        /// </summary>
2440
        /// <param name="other">An IPNetwork to compare to this instance.</param>
2441
        /// <returns>true if obj has the same value as this instance; otherwise, false.</returns>
2442
        public bool Equals(IPNetwork2 other)
2443
        {
9✔
2444
            return Equals(this, other);
9✔
2445
        }
9✔
2446

2447
        /// <summary>
2448
        /// Compare two ipnetworks.
2449
        /// </summary>
2450
        /// <param name="obj">An object value to compare to this instance.</param>
2451
        /// <returns>true if obj has the same value as this instance; otherwise, false.</returns>
2452
        public override bool Equals(object obj)
2453
        {
134✔
2454
            return Equals(this, obj as IPNetwork2);
134✔
2455
        }
134✔
2456

2457
        #endregion
2458

2459
        #region Operators
2460

2461
        /// <summary>
2462
        /// Compares two IPNetwork.
2463
        /// </summary>
2464
        /// <param name="left">left instance.</param>
2465
        /// <param name="right">Right instance.</param>
2466
        /// <returns>true if left equals right; otherwise, false.</returns>
2467
        public static bool operator ==(IPNetwork2 left, IPNetwork2 right)
2468
        {
594,906✔
2469
            return Equals(left, right);
594,906✔
2470
        }
594,906✔
2471

2472
        /// <summary>
2473
        /// Compares two IPNetwork.
2474
        /// </summary>
2475
        /// <param name="left">left instance.</param>
2476
        /// <param name="right">Right instance.</param>
2477
        /// <returns>true if left does not equals right; otherwise, false.</returns>
2478
        public static bool operator !=(IPNetwork2 left, IPNetwork2 right)
2479
        {
132,331✔
2480
            return !Equals(left, right);
132,331✔
2481
        }
132,331✔
2482

2483
        /// <summary>
2484
        /// Compares two IPNetwork.
2485
        /// </summary>
2486
        /// <param name="left">left instance.</param>
2487
        /// <param name="right">Right instance.</param>
2488
        /// <returns>true if left is less than right; otherwise, false.</returns>
2489
        public static bool operator <(IPNetwork2 left, IPNetwork2 right)
2490
        {
2✔
2491
            return Compare(left, right) < 0;
2✔
2492
        }
2✔
2493

2494
        /// <summary>
2495
        /// Compares two IPNetwork.
2496
        /// </summary>
2497
        /// <param name="left">left instance.</param>
2498
        /// <param name="right">Right instance.</param>
2499
        /// <returns>true if left is greater than right; otherwise, false.</returns>
2500
        public static bool operator >(IPNetwork2 left, IPNetwork2 right)
2501
        {
2✔
2502
            return Compare(left, right) > 0;
2✔
2503
        }
2✔
2504

2505
        #endregion
2506

2507
        #region XmlSerialization
2508

2509
        /// <summary>
2510
        /// Initializes a new instance of the <see cref="IPNetwork2"/> class.
2511
        /// Created for DataContractSerialization. Better use static methods IPNetwork.Parse() to create IPNetworks.
2512
        /// </summary>
2513
        public IPNetwork2()
2514
            : this(0, AddressFamily.InterNetwork, 0)
2,000,003✔
2515
        {
2,000,003✔
2516
        }
2,000,003✔
2517

2518
        #endregion
2519

2520
        #region ISerializable
2521
        internal struct IPNetworkInteral
2522
        {
2523
            public BigInteger IPAddress;
2524
            public byte Cidr;
2525
            public AddressFamily AddressFamily;
2526
        }
2527

2528
        private IPNetwork2(SerializationInfo info, StreamingContext context)
4,000,005✔
2529
        {
4,000,005✔
2530
            string sipnetwork = (string)info.GetValue("IPNetwork", typeof(string));
4,000,005✔
2531
            var ipnetwork = IPNetwork2.Parse(sipnetwork);
4,000,005✔
2532

2533
            this._ipaddress = ipnetwork._ipaddress;
4,000,005✔
2534
            this._cidr = ipnetwork._cidr;
4,000,005✔
2535
            this._family = ipnetwork._family;
4,000,005✔
2536
        }
4,000,005✔
2537

2538
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
2539
        {
4,000,005✔
2540
            info.AddValue("IPNetwork", this.ToString());
4,000,005✔
2541
        }
4,000,005✔
2542

2543
        #endregion
2544

2545
        #region WildcardMask
2546

2547
        /// <summary>
2548
        /// Gets netmask Inverse
2549
        /// https://en.wikipedia.org/wiki/Wildcard_mask
2550
        ///
2551
        /// A wildcard mask is a mask of bits that indicates which parts of an IP address are available for examination.
2552
        /// In the Cisco IOS,[1] they are used in several places, for example:
2553
        ///    To indicate the size of a network or subnet for some routing protocols, such as OSPF.
2554
        ///    To indicate what IP addresses should be permitted or denied in access control lists(ACLs).
2555
        ///
2556
        /// A wildcard mask can be thought of as an inverted subnet mask.For example,
2557
        /// a subnet mask of 255.255.255.0 (binary equivalent = 11111111.11111111.11111111.00000000)
2558
        /// inverts to a wildcard mask of 0.0.0.255 (binary equivalent = 00000000.00000000.00000000.11111111).
2559
        ///
2560
        /// A wild card mask is a matching rule.[2] The rule for a wildcard mask is:
2561
        ///     0 means that the equivalent bit must match
2562
        ///     1 means that the equivalent bit does not matter
2563
        ///
2564
        /// Any wildcard bit-pattern can be masked for examination.For example, a wildcard mask of 0.0.0.254
2565
        /// (binary equivalent = 00000000.00000000.00000000.11111110) applied to IP address 10.10.10.2
2566
        /// (00001010.00001010.00001010.00000010) will match even-numbered IP addresses 10.10.10.0, 10.10.10.2,
2567
        /// 10.10.10.4, 10.10.10.6 etc.
2568
        ///
2569
        /// Same mask applied to 10.10.10.1 (00001010.00001010.00001010.00000001) will match
2570
        /// odd-numbered IP addresses 10.10.10.1, 10.10.10.3, 10.10.10.5 etc.
2571
        ///
2572
        /// A network and wildcard mask combination of 1.1.1.1 0.0.0.0 would match an interface configured
2573
        /// exactly with 1.1.1.1 only, and nothing else.
2574
        ///
2575
        /// Wildcard masks are used in situations where subnet masks may not apply.For example,
2576
        /// when two affected hosts fall in different subnets, the use of a wildcard mask will
2577
        /// group them together.
2578
        ///
2579
        /// List of wildcard masks
2580
        /// Slash Netmask Wildcard mask
2581
        /// /32   255.255.255.255    0.0.0.0
2582
        /// /31   255.255.255.254    0.0.0.1
2583
        /// /30   255.255.255.252    0.0.0.3
2584
        /// /29   255.255.255.248    0.0.0.7
2585
        /// /28   255.255.255.240    0.0.0.15
2586
        /// /27   255.255.255.224    0.0.0.31
2587
        /// /26   255.255.255.192    0.0.0.63
2588
        /// /25   255.255.255.128    0.0.0.127
2589
        /// /24   255.255.255.0      0.0.0.255
2590
        /// /23   255.255.254.0      0.0.1.255
2591
        /// /22   255.255.252.0      0.0.3.255
2592
        /// /21   255.255.248.0      0.0.7.255
2593
        /// /20   255.255.240.0      0.0.15.255
2594
        /// /19   255.255.224.0      0.0.31.255
2595
        /// /18   255.255.192.0      0.0.63.255
2596
        /// /17   255.255.128.0      0.0.127.255
2597
        /// /16   255.255.0.0        0.0.255.255
2598
        /// /15   255.254.0.0        0.1.255.255
2599
        /// /14   255.252.0.0        0.3.255.255
2600
        /// /13   255.248.0.0        0.7.255.255
2601
        /// /12   255.240.0.0        0.15.255.255
2602
        /// /11   255.224.0.0        0.31.255.255
2603
        /// /10   255.192.0.0        0.63.255.255
2604
        /// /9    255.128.0.0        0.127.255.255
2605
        /// /8    255.0.0.0          0.255.255.255
2606
        /// /7    254.0.0.0          1.255.255.255
2607
        /// /6    252.0.0.0          3.255.255.255
2608
        /// /5    248.0.0.0          7.255.255.255
2609
        /// /4    240.0.0.0          15.255.255.255
2610
        /// /3    224.0.0.0          31.255.255.255
2611
        /// /2    192.0.0.0          63.255.255.255
2612
        /// /1    128.0.0.0          127.255.255.255
2613
        /// /0    0.0.0.0            255.255.255.255.
2614
        ///
2615
        /// </summary>
2616
        public IPAddress WildcardMask
2617
        {
2618
            get
2619
            {
202✔
2620
                byte cidr = this._family == AddressFamily.InterNetwork ? (byte)32 : (byte)128;
202✔
2621
                BigInteger netmask = IPNetwork2.ToUint(cidr, this._family);
202✔
2622
                BigInteger wildcardmask = netmask - this._netmask;
202✔
2623

2624
                return IPNetwork2.ToIPAddress(wildcardmask, this._family);
202✔
2625
            }
202✔
2626
        }
2627
        #endregion
2628
    }
2629
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc