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

lduchosal / ipnetwork / 22794666362

07 Mar 2026 07:24AM UTC coverage: 93.126% (-0.3%) from 93.427%
22794666362

push

travis-pro

lduchosal
fix: issue #371

639 of 693 branches covered (92.21%)

Branch coverage included in aggregate %.

0 of 7 new or added lines in 1 file covered. (0.0%)

1962 of 2100 relevant lines covered (93.43%)

667287.76 hits per line

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

81.45
/src/ConsoleApplication/Program.cs
1
// <copyright file="Program.cs" company="IPNetwork">
2
// Copyright (c) IPNetwork. All rights reserved.
3
// </copyright>
4

5
namespace System.Net;
6

7
using Gnu.Getopt;
8
using System.Collections.Generic;
9
using System.Diagnostics;
10
using System.IO;
11
using System.Numerics;
12
using System.Reflection;
13

14
/// <summary>
15
/// Console app for IPNetwork.
16
/// </summary>
17
public static class Program
18
{
19
    private static readonly Dictionary<int, ArgParsed> Args = new ();
1✔
20

21
    private static readonly ArgParsed[] ArgsList =
1✔
22
    [
1✔
23
        new ArgParsed('i', (ac, _) => { ac.IPNetwork = true; }),
3✔
24
        new ArgParsed('n', (ac, _) => { ac.Network = true; }),
6✔
25
        new ArgParsed('m', (ac, _) => { ac.Netmask = true; }),
6✔
26
        new ArgParsed('c', (ac, _) => { ac.Cidr = true; }),
6✔
27
        new ArgParsed('b', (ac, _) => { ac.Broadcast = true; }),
6✔
28
        new ArgParsed('f', (ac, _) => { ac.FirstUsable = true; }),
6✔
29
        new ArgParsed('l', (ac, _) => { ac.LastUsable = true; }),
6✔
30
        new ArgParsed('u', (ac, _) => { ac.Usable = true; }),
6✔
31
        new ArgParsed('t', (ac, _) => { ac.Total = true; }),
×
32
        new ArgParsed('w', (ac, _) => { ac.Action = Action.Supernet; }),
3✔
33
        new ArgParsed('W', (ac, _) => { ac.Action = Action.WideSupernet; }),
×
34
        new ArgParsed('h', (ac, _) => { ac.Action = Action.Usage; }),
×
35
        new ArgParsed('x', (ac, _) => { ac.Action = Action.ListIPAddress; }),
3✔
36
        new ArgParsed('?', (_, _) => { }),
4✔
37
        new ArgParsed('D', (ac, _) => { ac.CidrParse = CidrParse.Default; }),
×
38
        new ArgParsed('d', (ac, arg) =>
1✔
39
        {
2✔
40
            if (!IPNetwork2.TryParseCidr(arg, Sockets.AddressFamily.InterNetwork, out byte? cidr))
2!
41
            {
×
42
                Console.WriteLine("Invalid cidr {0}", cidr);
×
43
                ac.Action = Action.Usage;
×
44
                return;
×
45
            }
1✔
46

1✔
47
            ac.CidrParse = CidrParse.Value;
2✔
48
            ac.CidrParsed = (byte)cidr!;
2✔
49
        }),
2✔
50
        new ArgParsed('s', (ac, arg) =>
1✔
51
        {
1✔
52
            if (!IPNetwork2.TryParseCidr(arg, Sockets.AddressFamily.InterNetwork, out byte? cidr))
1!
53
            {
×
54
                Console.WriteLine("Invalid cidr {0}", cidr);
×
55
                ac.Action = Action.Usage;
×
56
                return;
×
57
            }
1✔
58

1✔
59
            ac.Action = Action.Subnet;
1✔
60
            ac.SubnetCidr = (byte)cidr!;
1✔
61
        }),
1✔
62
        new ArgParsed('C', (ac, arg) =>
1✔
63
        {
1✔
64
            if (!TryParseIPNetwork(arg, ac.CidrParse, ac.CidrParsed, out IPNetwork2 ipnetwork))
1!
65
            {
×
66
                Console.WriteLine($"Unable to parse ipnetwork {arg}", arg);
×
67
                ac.Action = Action.Usage;
×
68
                return;
×
69
            }
1✔
70

1✔
71
            ac.Action = Action.ContainNetwork;
1✔
72
            ac.ContainNetwork = ipnetwork;
1✔
73
        }),
1✔
74
        new ArgParsed('o', (ac, arg) =>
1✔
75
        {
1✔
76
            if (!TryParseIPNetwork(arg, ac.CidrParse, ac.CidrParsed, out IPNetwork2 ipnetwork))
1!
77
            {
×
78
                Console.WriteLine("Unable to parse ipnetwork {0}", arg);
×
79
                ac.Action = Action.Usage;
×
80
                return;
×
81
            }
1✔
82

1✔
83
            ac.Action = Action.OverlapNetwork;
1✔
84
            ac.OverlapNetwork = ipnetwork;
1✔
85
        }),
1✔
86
        new ArgParsed('S', (ac, arg) =>
1✔
87
        {
1✔
88
            if (!TryParseIPNetwork(arg, ac.CidrParse, ac.CidrParsed, out IPNetwork2 ipnetwork))
1!
89
            {
×
90
                Console.WriteLine("Unable to parse ipnetwork {0}", arg);
×
91
                ac.Action = Action.Usage;
×
92
                return;
×
93
            }
1✔
94

1✔
95
            ac.Action = Action.SubtractNetwork;
1✔
96
            ac.SubtractNetwork = ipnetwork;
1✔
97
        })
1✔
98
    ];
1✔
99

100
    /// <summary>
101
    /// Program entry point.
102
    /// </summary>
103
    /// <param name="args">program arguments.</param>
104
    public static void Main(string[] args)
105
    {
11✔
106
        ProgramContext ac = ParseArgs(args);
11✔
107

108
        switch (ac.Action)
11!
109
        {
110
            case Action.Subnet:
111
                SubnetNetworks(ac);
1✔
112
                break;
1✔
113
            case Action.Supernet:
114
                SupernetNetworks(ac);
1✔
115
                break;
1✔
116
            case Action.WideSupernet:
117
                WideSupernetNetworks(ac);
×
118
                break;
×
119
            case Action.PrintNetworks:
120
                PrintNetworks(ac);
5✔
121
                break;
5✔
122
            case Action.ContainNetwork:
123
                ContainNetwork(ac);
1✔
124
                break;
1✔
125
            case Action.OverlapNetwork:
126
                OverlapNetwork(ac);
1✔
127
                break;
1✔
128
            case Action.ListIPAddress:
129
                ListIPAddress(ac);
×
130
                break;
×
131
            case Action.SubtractNetwork:
132
                SubtractNetwork(ac);
1✔
133
                break;
1✔
134
            default:
135
                Usage();
1✔
136
                break;
1✔
137
        }
138
    }
11✔
139

140
    private static void ListIPAddress(ProgramContext ac)
141
    {
×
142
        foreach (IPNetwork2 ipnetwork in ac.Networks)
×
143
        {
×
NEW
144
            if (ipnetwork.Cidr < 16)
×
NEW
145
            {
×
NEW
146
                Console.Error.WriteLine(
×
NEW
147
                    "WARNING: listing all IP addresses in {0} ({1} addresses). This may take a very long time.",
×
NEW
148
                    ipnetwork,
×
NEW
149
                    ipnetwork.Total);
×
NEW
150
            }
×
151

152
            foreach (IPAddress ipaddress in ipnetwork.ListIPAddress())
×
153
            {
×
154
                Console.WriteLine("{0}", ipaddress.ToString());
×
155
            }
×
156
        }
×
157
    }
×
158
    
159
    private static void SubtractNetwork(ProgramContext ac)
160
    {
1✔
161
        foreach (IPNetwork2 ipnetwork in ac.Networks)
13✔
162
        {
5✔
163
            foreach (IPNetwork2 subtracted in ipnetwork.Subtract(ac.SubtractNetwork))
25✔
164
            {
5✔
165
                Console.WriteLine("{0}", subtracted);
5✔
166
            }
5✔
167
        }
5✔
168
    }
1✔
169
    
170
    private static void ContainNetwork(ProgramContext ac)
171
    {
1✔
172
        foreach (IPNetwork2 ipnetwork in ac.Networks)
5✔
173
        {
1✔
174
            bool contain = ac.ContainNetwork.Contains(ipnetwork);
1✔
175
            Console.WriteLine("{0} contains {1} : {2}", ac.ContainNetwork, ipnetwork, contain);
1✔
176
        }
1✔
177
    }
1✔
178

179
    private static void OverlapNetwork(ProgramContext ac)
180
    {
1✔
181
        foreach (IPNetwork2 ipnetwork in ac.Networks)
5✔
182
        {
1✔
183
            bool overlap = ac.OverlapNetwork.Overlap(ipnetwork);
1✔
184
            Console.WriteLine("{0} overlaps {1} : {2}", ac.OverlapNetwork, ipnetwork, overlap);
1✔
185
        }
1✔
186
    }
1✔
187

188
    private static void WideSupernetNetworks(ProgramContext ac)
189
    {
×
190
        if (!IPNetwork2.TryWideSubnet(ac.Networks, out IPNetwork2 widesubnet))
×
191
        {
×
192
            Console.WriteLine("Unable to wide subnet these networks");
×
193
        }
×
194

195
        PrintNetwork(ac, widesubnet);
×
196
    }
×
197

198
    private static void SupernetNetworks(ProgramContext ac)
199
    {
1✔
200
        if (!IPNetwork2.TrySupernet(ac.Networks, out IPNetwork2[] supernet))
1!
201
        {
×
202
            Console.WriteLine("Unable to supernet these networks");
×
203
        }
×
204

205
        PrintNetworks(ac, supernet, supernet.Length);
1✔
206
    }
1✔
207

208
    private static void SubnetNetworks(ProgramContext ac)
209
    {
1✔
210
        BigInteger i = 0;
1✔
211
        foreach (IPNetwork2 ipnetwork in ac.Networks)
5✔
212
        {
1✔
213
            i++;
1✔
214
            int networkLength = ac.Networks.Length;
1✔
215
            if (!ipnetwork.TrySubnet(ac.SubnetCidr, out IPNetworkCollection ipnetworks))
1!
216
            {
×
217
                Console.WriteLine("Unable to subnet ipnetwork {0} into cidr {1}", ipnetwork, ac.SubnetCidr);
×
218
                PrintSeparator(networkLength, i);
×
219
                continue;
×
220
            }
221

222
            PrintNetworks(ac, ipnetworks, ipnetworks.Count);
1✔
223
            PrintSeparator(networkLength, i);
1✔
224
        }
1✔
225
    }
1✔
226

227
    private static void PrintSeparator(BigInteger max, BigInteger index)
228
    {
270✔
229
        if (max > 1 && index != max)
270✔
230
        {
262✔
231
            Console.WriteLine("--");
262✔
232
        }
262✔
233
    }
270✔
234
    
235
    private static void PrintNetworks(ProgramContext ac, IEnumerable<IPNetwork2> ipnetworks, BigInteger networkLength)
236
    {
2✔
237
        int i = 0;
2✔
238
        foreach (IPNetwork2 ipn in ipnetworks)
524✔
239
        {
259✔
240
            i++;
259✔
241
            PrintNetwork(ac, ipn);
259✔
242
            PrintSeparator(networkLength, i);
259✔
243
        }
259✔
244
    }
2✔
245
    
246
    private static void PrintNetworks(ProgramContext ac)
247
    {
5✔
248
        int i = 0;
5✔
249
        foreach (IPNetwork2 ipnetwork in ac.Networks)
35✔
250
        {
10✔
251
            i++;
10✔
252
            PrintNetwork(ac, ipnetwork);
10✔
253
            PrintSeparator(ac.Networks.Length, i);
10✔
254
        }
10✔
255
    }
5✔
256

257
    private static void PrintNetwork(ProgramContext ac, IPNetwork2 ipn)
258
    {
269✔
259
        using var sw = new StringWriter();
269✔
260
        if (ac.IPNetwork)
269✔
261
        {
267✔
262
            sw.WriteLine("IPNetwork   : {0}", ipn);
267✔
263
        }
267✔
264

265
        if (ac.Network)
269✔
266
        {
263✔
267
            sw.WriteLine("Network     : {0}", ipn.Network.ToString());
263✔
268
        }
263✔
269

270
        if (ac.Netmask)
269✔
271
        {
263✔
272
            sw.WriteLine("Netmask     : {0}", ipn.Netmask.ToString());
263✔
273
        }
263✔
274

275
        if (ac.Cidr)
269✔
276
        {
263✔
277
            sw.WriteLine("Cidr        : {0}", ipn.Cidr);
263✔
278
        }
263✔
279

280
        if (ac.Broadcast)
269✔
281
        {
263✔
282
            sw.WriteLine("Broadcast   : {0}", ipn.Broadcast.ToString());
263✔
283
        }
263✔
284

285
        if (ac.FirstUsable)
269✔
286
        {
263✔
287
            sw.WriteLine("FirstUsable : {0}", ipn.FirstUsable.ToString());
263✔
288
        }
263✔
289

290
        if (ac.LastUsable)
269✔
291
        {
263✔
292
            sw.WriteLine("LastUsable  : {0}", ipn.LastUsable.ToString());
263✔
293
        }
263✔
294

295
        if (ac.Usable)
269✔
296
        {
263✔
297
            sw.WriteLine("Usable      : {0}", ipn.Usable);
263✔
298
        }
263✔
299

300
        if (ac.Total)
269✔
301
        {
261✔
302
            sw.WriteLine("Total       : {0}", ipn.Total);
261✔
303
        }
261✔
304

305
        Console.Write(sw.ToString());
269✔
306
    }
538✔
307

308
    static Program()
309
    {
1✔
310
        foreach (ArgParsed ap in ArgsList)
43✔
311
        {
20✔
312
            Args.Add(ap.Arg, ap);
20✔
313
        }
20✔
314
    }
1✔
315

316
    private static ProgramContext ParseArgs(string[] args)
317
    {
11✔
318
        int c;
319
        var g = new Getopt("ipnetwork", args, "inmcbfltud:Dhs:wWxC:o:S:");
11✔
320
        var ac = new ProgramContext();
11✔
321

322
        while ((c = g.getopt()) != -1)
36✔
323
        {
25✔
324
            string optArg = g.Optarg;
25✔
325
            Args[c].Run(ac, optArg);
25✔
326
        }
25✔
327

328
        var ipnetworks = new List<string>();
11✔
329
        for (int i = g.Optind; i < args.Length; i++)
72✔
330
        {
25✔
331
            if (!string.IsNullOrEmpty(args[i]))
25✔
332
            {
25✔
333
                ipnetworks.Add(args[i]);
25✔
334
            }
25✔
335
        }
25✔
336

337
        ac.NetworksString = ipnetworks.ToArray();
11✔
338
        ParseIPNetworks(ac);
11✔
339

340
        if (ac.Networks.Length == 0)
11✔
341
        {
1✔
342
            Console.WriteLine("Provide at least one ipnetwork");
1✔
343
            ac.Action = Action.Usage;
1✔
344
        }
1✔
345

346
        if (ac.Action == Action.Supernet
11!
347
            && ipnetworks.Count < 2)
11✔
348
        {
×
349
            Console.WriteLine("Supernet action required at least two ipnetworks");
×
350
            ac.Action = Action.Usage;
×
351
        }
×
352

353
        if (ac.Action == Action.WideSupernet
11!
354
            && ipnetworks.Count < 2)
11✔
355
        {
×
356
            Console.WriteLine("WideSupernet action required at least two ipnetworks");
×
357
            ac.Action = Action.Usage;
×
358
        }
×
359

360
        if (PrintNoValue(ac))
11✔
361
        {
8✔
362
            PrintAll(ac);
8✔
363
        }
8✔
364

365
        if (g.Optind == 0)
11✔
366
        {
3✔
367
            PrintAll(ac);
3✔
368
        }
3✔
369

370
        return ac;
11✔
371
    }
11✔
372

373
    private static void ParseIPNetworks(ProgramContext ac)
374
    {
11✔
375
        var ipnetworks = new List<IPNetwork2>();
11✔
376
        foreach (string ips in ac.NetworksString)
83✔
377
        {
25✔
378
            if (!TryParseIPNetwork(ips, ac.CidrParse, ac.CidrParsed, out IPNetwork2 ipnetwork))
25✔
379
            {
1✔
380
                Console.WriteLine("Unable to parse ipnetwork {0}", ips);
1✔
381
                continue;
1✔
382
            }
383

384
            ipnetworks.Add(ipnetwork);
24✔
385
        }
24✔
386

387
        ac.Networks = ipnetworks.ToArray();
11✔
388
    }
11✔
389

390
    private static bool TryParseIPNetwork(string ip, CidrParse cidrParse, byte cidr, out IPNetwork2 ipn)
391
    {
28✔
392
        IPNetwork2 ipnetwork = null;
28✔
393
        switch (cidrParse)
28!
394
        {
395
            case CidrParse.Default when !IPNetwork2.TryParse(ip, out ipnetwork):
×
396
                ipn = null;
×
397
                return false;
×
398
            case CidrParse.Value:
399
            {
28✔
400
                if (!IPNetwork2.TryParse(ip, cidr, out ipnetwork)
28✔
401
                    && !IPNetwork2.TryParse(ip, out ipnetwork))
28✔
402
                {
1✔
403
                    ipn = null;
1✔
404
                    return false;
1✔
405
                }
406

407
                break;
27✔
408
            }
409
        }
410

411
        ipn = ipnetwork;
27✔
412
        return true;
27✔
413
    }
28✔
414

415
    private static bool PrintNoValue(ProgramContext ac)
416
    {
11✔
417
        ArgumentNullException.ThrowIfNull(ac);
11✔
418

419
        return !ac.IPNetwork 
11✔
420
               && !ac.Network 
11✔
421
               && !ac.Netmask 
11✔
422
               && !ac.Cidr 
11✔
423
               && !ac.Broadcast 
11✔
424
               && !ac.FirstUsable 
11✔
425
               && !ac.LastUsable 
11✔
426
               && !ac.Total 
11✔
427
               && !ac.Usable;
11✔
428
    }
11✔
429

430
    private static void PrintAll(ProgramContext ac)
431
    {
11✔
432
        ArgumentNullException.ThrowIfNull(ac);
11✔
433

434
        ac.IPNetwork = true;
11✔
435
        ac.Network = true;
11✔
436
        ac.Netmask = true;
11✔
437
        ac.Cidr = true;
11✔
438
        ac.Broadcast = true;
11✔
439
        ac.FirstUsable = true;
11✔
440
        ac.LastUsable = true;
11✔
441
        ac.Usable = true;
11✔
442
        ac.Total = true;
11✔
443
    }
11✔
444

445
    private static void Usage()
446
    {
1✔
447
        Assembly assembly = Assembly.GetEntryAssembly()
1!
448
                            ?? Assembly.GetExecutingAssembly()
1✔
449
            ;
1✔
450
        var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
1✔
451
        string version = fvi.FileVersion;
1✔
452

453
        Console.WriteLine(
1✔
454
            "Usage: ipnetwork [-inmcbflu] [-d cidr|-D] [-h|-s cidr|-S network|-w|-W|-x|-C network|-o network] networks ...");
1✔
455
        Console.WriteLine("Version: {0}", version);
1✔
456
        Console.WriteLine();
1✔
457
        Console.WriteLine("Print options");
1✔
458
        Console.WriteLine("\t-i : network");
1✔
459
        Console.WriteLine("\t-n : network address");
1✔
460
        Console.WriteLine("\t-m : netmask");
1✔
461
        Console.WriteLine("\t-c : cidr");
1✔
462
        Console.WriteLine("\t-b : broadcast");
1✔
463
        Console.WriteLine("\t-f : first usable ip address");
1✔
464
        Console.WriteLine("\t-l : last usable ip address");
1✔
465
        Console.WriteLine("\t-u : number of usable ip addresses");
1✔
466
        Console.WriteLine("\t-t : total number of ip addresses");
1✔
467
        Console.WriteLine();
1✔
468
        Console.WriteLine("Parse options");
1✔
469
        Console.WriteLine("\t-d cidr : use cidr if not provided (default /32)");
1✔
470
        Console.WriteLine("\t-D      : IPv4 only - use default cidr (ClassA/8, ClassB/16, ClassC/24)");
1✔
471
        Console.WriteLine();
1✔
472
        Console.WriteLine("Actions");
1✔
473
        Console.WriteLine("\t-h         : help message");
1✔
474
        Console.WriteLine("\t-s cidr    : split network into cidr subnets");
1✔
475
        Console.WriteLine("\t-w         : supernet networks into smallest possible subnets");
1✔
476
        Console.WriteLine("\t-W         : supernet networks into one single subnet");
1✔
477
        Console.WriteLine("\t-x         : list all ip adresses in networks");
1✔
478
        Console.WriteLine("\t-C network : network contain networks");
1✔
479
        Console.WriteLine("\t-o network : network overlap networks");
1✔
480
        Console.WriteLine("\t-S network : subtract network from networks");
1✔
481
        Console.WriteLine(string.Empty);
1✔
482
        Console.WriteLine("networks  : one or more network addresses ");
1✔
483
        Console.WriteLine(
1✔
484
            "            (1.2.3.4 10.0.0.0/8 10.0.0.0/255.0.0.0 2001:db8::/32 2001:db8:1:2:3:4:5:6/128 )");
1✔
485
    }
1✔
486
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc