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

lduchosal / ipnetwork / 730

29 Mar 2025 02:04PM UTC coverage: 93.279% (+0.008%) from 93.271%
730

push

appveyor

web-flow
Feat: upgrade to net9 (#348)

* Feat: upgrade net9
* Feat: net9 for github workflow build
* Feat: net9 for appveyor
* Fix: file scoped namespace
* Fix: implicit new
* Chore: latestmajor langversion

1596 of 1711 relevant lines covered (93.28%)

826874.15 hits per line

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

81.51
/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 System.Diagnostics;
8
using System.IO;
9
using System.Numerics;
10
using System.Reflection;
11
using Gnu.Getopt;
12

13

14
using System.Collections.Generic;
15

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

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

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

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

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

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

1✔
97
            ac.Action = ActionEnum.SubtractNetwork;
1✔
98
            ac.SubtractNetwork = ipnetwork;
1✔
99
        }),
1✔
100
    };
1✔
101

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

110
        if (ac.Action == ActionEnum.Subnet)
11✔
111
        {
1✔
112
            Program.SubnetNetworks(ac);
1✔
113
        }
1✔
114
        else if (ac.Action == ActionEnum.Supernet)
10✔
115
        {
1✔
116
            Program.SupernetNetworks(ac);
1✔
117
        }
1✔
118
        else if (ac.Action == ActionEnum.WideSupernet)
9✔
119
        {
×
120
            Program.WideSupernetNetworks(ac);
×
121
        }
×
122
        else if (ac.Action == ActionEnum.PrintNetworks)
9✔
123
        {
5✔
124
            Program.PrintNetworks(ac);
5✔
125
        }
5✔
126
        else if (ac.Action == ActionEnum.ContainNetwork)
4✔
127
        {
1✔
128
            Program.ContainNetwork(ac);
1✔
129
        }
1✔
130
        else if (ac.Action == ActionEnum.OverlapNetwork)
3✔
131
        {
1✔
132
            Program.OverlapNetwork(ac);
1✔
133
        }
1✔
134
        else if (ac.Action == ActionEnum.ListIPAddress)
2✔
135
        {
×
136
            Program.ListIPAddress(ac);
×
137
        }
×
138
        else
139
        {
2✔
140
            Program.Usage();
2✔
141
        }
2✔
142
    }
11✔
143

144
    private static void ListIPAddress(ProgramContext ac)
145
    {
×
146
        foreach (IPNetwork2 ipnetwork in ac.Networks)
×
147
        {
×
148
            foreach (IPAddress ipaddress in ipnetwork.ListIPAddress())
×
149
            {
×
150
                Console.WriteLine("{0}", ipaddress.ToString());
×
151
            }
×
152
        }
×
153
    }
×
154

155
    private static void ContainNetwork(ProgramContext ac)
156
    {
1✔
157
        foreach (IPNetwork2 ipnetwork in ac.Networks)
5✔
158
        {
1✔
159
            bool contain = ac.ContainNetwork.Contains(ipnetwork);
1✔
160
            Console.WriteLine("{0} contains {1} : {2}", ac.ContainNetwork, ipnetwork, contain);
1✔
161
        }
1✔
162
    }
1✔
163

164
    private static void OverlapNetwork(ProgramContext ac)
165
    {
1✔
166
        foreach (IPNetwork2 ipnetwork in ac.Networks)
5✔
167
        {
1✔
168
            bool overlap = ac.OverlapNetwork.Overlap(ipnetwork);
1✔
169
            Console.WriteLine("{0} overlaps {1} : {2}", ac.OverlapNetwork, ipnetwork, overlap);
1✔
170
        }
1✔
171
    }
1✔
172

173
    private static void WideSupernetNetworks(ProgramContext ac)
174
    {
×
175
        if (!IPNetwork2.TryWideSubnet(ac.Networks, out IPNetwork2 widesubnet))
×
176
        {
×
177
            Console.WriteLine("Unable to wide subnet these networks");
×
178
        }
×
179

180
        Program.PrintNetwork(ac, widesubnet);
×
181
    }
×
182

183
    private static void SupernetNetworks(ProgramContext ac)
184
    {
1✔
185
        if (!IPNetwork2.TrySupernet(ac.Networks, out IPNetwork2[] supernet))
1✔
186
        {
×
187
            Console.WriteLine("Unable to supernet these networks");
×
188
        }
×
189

190
        Program.PrintNetworks(ac, supernet, supernet.Length);
1✔
191
    }
1✔
192

193
    private static void PrintNetworks(ProgramContext ac, IEnumerable<IPNetwork2> ipnetworks, BigInteger networkLength)
194
    {
2✔
195
        int i = 0;
2✔
196
        foreach (IPNetwork2 ipn in ipnetworks)
524✔
197
        {
259✔
198
            i++;
259✔
199
            Program.PrintNetwork(ac, ipn);
259✔
200
            Program.PrintSeparator(networkLength, i);
259✔
201
        }
259✔
202
    }
2✔
203

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

218
            Program.PrintNetworks(ac, ipnetworks, ipnetworks.Count);
1✔
219
            Program.PrintSeparator(networkLength, i);
1✔
220
        }
1✔
221
    }
1✔
222

223
    // private static void PrintSeparator(Array network, int index) {
224
    //    if (network.Length > 1 && index != network.Length) {
225
    //        Console.WriteLine("--");
226
    //    }
227
    // }
228
    private static void PrintSeparator(BigInteger max, BigInteger index)
229
    {
270✔
230
        if (max > 1 && index != max)
270✔
231
        {
262✔
232
            Console.WriteLine("--");
262✔
233
        }
262✔
234
    }
270✔
235

236
    private static void PrintNetworks(ProgramContext ac)
237
    {
5✔
238
        int i = 0;
5✔
239
        foreach (IPNetwork2 ipnetwork in ac.Networks)
35✔
240
        {
10✔
241
            i++;
10✔
242
            Program.PrintNetwork(ac, ipnetwork);
10✔
243
            Program.PrintSeparator(ac.Networks.Length, i);
10✔
244
        }
10✔
245
    }
5✔
246

247
    private static void PrintNetwork(ProgramContext ac, IPNetwork2 ipn)
248
    {
269✔
249
        using (var sw = new StringWriter())
269✔
250
        {
269✔
251
            if (ac.IPNetwork)
269✔
252
            {
267✔
253
                sw.WriteLine("IPNetwork   : {0}", ipn.ToString());
267✔
254
            }
267✔
255

256
            if (ac.Network)
269✔
257
            {
263✔
258
                sw.WriteLine("Network     : {0}", ipn.Network.ToString());
263✔
259
            }
263✔
260

261
            if (ac.Netmask)
269✔
262
            {
263✔
263
                sw.WriteLine("Netmask     : {0}", ipn.Netmask.ToString());
263✔
264
            }
263✔
265

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

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

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

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

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

291
            if (ac.Total)
269✔
292
            {
261✔
293
                sw.WriteLine("Total       : {0}", ipn.Total);
261✔
294
            }
261✔
295

296
            Console.Write(sw.ToString());
269✔
297
        }
269✔
298
    }
269✔
299

300
    static Program()
301
    {
1✔
302
        foreach (ArgParsed ap in Program.ArgsList)
43✔
303
        {
20✔
304
            Program.Args.Add(ap.Arg, ap);
20✔
305
        }
20✔
306
    }
1✔
307

308
    private static ProgramContext ParseArgs(string[] args)
309
    {
11✔
310
        int c;
311
        var g = new Getopt("ipnetwork", args, "inmcbfltud:Dhs:wWxC:o:S:");
11✔
312
        var ac = new ProgramContext();
11✔
313

314
        while ((c = g.getopt()) != -1)
36✔
315
        {
25✔
316
            string optArg = g.Optarg;
25✔
317
            Program.Args[c].Run(ac, optArg);
25✔
318
        }
25✔
319

320
        var ipnetworks = new List<string>();
11✔
321
        for (int i = g.Optind; i < args.Length; i++)
72✔
322
        {
25✔
323
            if (!string.IsNullOrEmpty(args[i]))
25✔
324
            {
25✔
325
                ipnetworks.Add(args[i]);
25✔
326
            }
25✔
327
        }
25✔
328

329
        ac.NetworksString = ipnetworks.ToArray();
11✔
330
        Program.ParseIPNetworks(ac);
11✔
331

332
        if (ac.Networks.Length == 0)
11✔
333
        {
1✔
334
            Console.WriteLine("Provide at least one ipnetwork");
1✔
335
            ac.Action = ActionEnum.Usage;
1✔
336
        }
1✔
337

338
        if (ac.Action == ActionEnum.Supernet
11✔
339
            && ipnetworks.Count < 2)
11✔
340
        {
×
341
            Console.WriteLine("Supernet action required at least two ipnetworks");
×
342
            ac.Action = ActionEnum.Usage;
×
343
        }
×
344

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

352
        if (Program.PrintNoValue(ac))
11✔
353
        {
8✔
354
            Program.PrintAll(ac);
8✔
355
        }
8✔
356

357
        if (g.Optind == 0)
11✔
358
        {
3✔
359
            Program.PrintAll(ac);
3✔
360
        }
3✔
361

362
        return ac;
11✔
363
    }
11✔
364

365
    private static void ParseIPNetworks(ProgramContext ac)
366
    {
11✔
367
        var ipnetworks = new List<IPNetwork2>();
11✔
368
        foreach (string ips in ac.NetworksString)
83✔
369
        {
25✔
370
            if (!Program.TryParseIPNetwork(ips, ac.CidrParse, ac.CidrParsed, out IPNetwork2 ipnetwork))
25✔
371
            {
1✔
372
                Console.WriteLine("Unable to parse ipnetwork {0}", ips);
1✔
373
                continue;
1✔
374
            }
375

376
            ipnetworks.Add(ipnetwork);
24✔
377
        }
24✔
378

379
        ac.Networks = ipnetworks.ToArray();
11✔
380
    }
11✔
381

382
    private static bool TryParseIPNetwork(string ip, CidrParseEnum cidrParseEnum, byte cidr, out IPNetwork2 ipn)
383
    {
28✔
384
        IPNetwork2 ipnetwork = null;
28✔
385
        if (cidrParseEnum == CidrParseEnum.Default)
28✔
386
        {
×
387
            if (!IPNetwork2.TryParse(ip, out ipnetwork))
×
388
            {
×
389
                ipn = null;
×
390
                return false;
×
391
            }
392
        }
×
393
        else if (cidrParseEnum == CidrParseEnum.Value)
28✔
394
        {
28✔
395
            if (!IPNetwork2.TryParse(ip, cidr, out ipnetwork))
28✔
396
            {
22✔
397
                if (!IPNetwork2.TryParse(ip, out ipnetwork))
22✔
398
                {
1✔
399
                    ipn = null;
1✔
400
                    return false;
1✔
401
                }
402
            }
21✔
403
        }
27✔
404

405
        ipn = ipnetwork;
27✔
406
        return true;
27✔
407
    }
28✔
408

409
    private static bool PrintNoValue(ProgramContext ac)
410
    {
11✔
411
        if (ac == null)
11✔
412
        {
×
413
            throw new ArgumentNullException(nameof(ac));
×
414
        }
415

416
        return ac.IPNetwork == false
11✔
417
               && ac.Network == false
11✔
418
               && ac.Netmask == false
11✔
419
               && ac.Cidr == false
11✔
420
               && ac.Broadcast == false
11✔
421
               && ac.FirstUsable == false
11✔
422
               && ac.LastUsable == false
11✔
423
               && ac.Total == false
11✔
424
               && ac.Usable == false;
11✔
425
    }
11✔
426

427
    private static void PrintAll(ProgramContext ac)
428
    {
11✔
429
        if (ac == null)
11✔
430
        {
×
431
            throw new ArgumentNullException(nameof(ac));
×
432
        }
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
    {
2✔
447
        Assembly assembly = Assembly.GetEntryAssembly()
2✔
448
                            ?? Assembly.GetExecutingAssembly()
2✔
449
                            ?? Assembly.GetCallingAssembly()
2✔
450
            ;
2✔
451
        var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
2✔
452
        string version = fvi.FileVersion;
2✔
453

454
        Console.WriteLine(
2✔
455
            "Usage: ipnetwork [-inmcbflu] [-d cidr|-D] [-h|-s cidr|-S|-w|-W|-x|-C network|-o network] networks ...");
2✔
456
        Console.WriteLine("Version: {0}", version);
2✔
457
        Console.WriteLine();
2✔
458
        Console.WriteLine("Print options");
2✔
459
        Console.WriteLine("\t-i : network");
2✔
460
        Console.WriteLine("\t-n : network address");
2✔
461
        Console.WriteLine("\t-m : netmask");
2✔
462
        Console.WriteLine("\t-c : cidr");
2✔
463
        Console.WriteLine("\t-b : broadcast");
2✔
464
        Console.WriteLine("\t-f : first usable ip address");
2✔
465
        Console.WriteLine("\t-l : last usable ip address");
2✔
466
        Console.WriteLine("\t-u : number of usable ip addresses");
2✔
467
        Console.WriteLine("\t-t : total number of ip addresses");
2✔
468
        Console.WriteLine();
2✔
469
        Console.WriteLine("Parse options");
2✔
470
        Console.WriteLine("\t-d cidr : use cidr if not provided (default /32)");
2✔
471
        Console.WriteLine("\t-D      : IPv4 only - use default cidr (ClassA/8, ClassB/16, ClassC/24)");
2✔
472
        Console.WriteLine();
2✔
473
        Console.WriteLine("Actions");
2✔
474
        Console.WriteLine("\t-h         : help message");
2✔
475
        Console.WriteLine("\t-s cidr    : split network into cidr subnets");
2✔
476
        Console.WriteLine("\t-w         : supernet networks into smallest possible subnets");
2✔
477
        Console.WriteLine("\t-W         : supernet networks into one single subnet");
2✔
478
        Console.WriteLine("\t-x         : list all ipaddresses in networks");
2✔
479
        Console.WriteLine("\t-C network : network contain networks");
2✔
480
        Console.WriteLine("\t-o network : network overlap networks");
2✔
481
        Console.WriteLine("\t-S network : subtract network from subnet");
2✔
482
        Console.WriteLine(string.Empty);
2✔
483
        Console.WriteLine("networks  : one or more network addresses ");
2✔
484
        Console.WriteLine(
2✔
485
            "            (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 )");
2✔
486
    }
2✔
487
}
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