File: libcidr.txt

package info (click to toggle)
libcidr 1.2.3-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster, forky, sid, trixie
  • size: 956 kB
  • sloc: ansic: 2,800; perl: 333; makefile: 262; sh: 90; awk: 9
file content (903 lines) | stat: -rw-r--r-- 39,421 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
Summary

   libcidr is a library to make it easier to handle IP addresses and
   blocks, and manipulate them in various ways.

   The core of the library is a pair of functions that take a human
   readable string and turn it into our internal representation of a CIDR
   address block (cidr_from_str() ), and one to take that internal
   representation and turn it into a human-readable string (cidr_to_str()
   ). There are a large number of options for how to format that string,
   as well.

   Additionally, there are functions to compare different CIDR blocks, to
   determine if they're equal, or if one is contained within the other.
   This functionality can be useful for writing access-control code, or
   client-dependant configuration, or similar things. There are functions
   to manipulate address blocks and determine attributes of them, like
   network/broadcast addresses, the range of host addresses, the number of
   available host addresses, etc. There are functions to split a CIDR
   block into the two smaller blocks it contains, or to derive the parent
   block that it is itself contained within. And there are functions to
   translate to and from in_addr-type structures, which the operating
   system commonly uses to represent addresses for handle socket
   connections and so forth.

   In short, just about anything you might do in a program with IP
   addressing, whether referring to individual hosts, or to any sized
   subnets, libcidr is designed to simplify handling. It's not a DNS
   library, nor is it a socket abstraction layer. It's just a set of
   functions for manipulating raw IP addresses in various ways.

   The functions generally follow standard C conventions. They tend to
   return 0 or a pointer when acting properly, and -1 or NULL when
   something went wrong (unless the function usage suggests other returns,
   of course, as in cidr_get_pflen() ). They set errno when returning an
   error; the error codes each function can return are documented with the
   function.

   libcidr doesn't use any threading itself. It should, however, be safe
   to use in any threaded program if used sensibly. Only a very few
   functions use static strings, and those that do (cidr_version() and
   cidr_numaddr() and its related functions being the only ones I can
   think of) tend to be constant strings as well, so they wouldn't be
   changing. Of course, you don't want to cidr_free() a CIDR in one thread
   while you're still using it in another, but if you do, it's not
   libcidr's fault.

   For the current version or any extra information, see the libcidr
   project homepage, at
   <http://www.over-yonder.net/~fullermd/projects/libcidr>.

   This reference manual is build using the codelibrary SGML DTD, which is
   specifically designed for documenting libraries. See the codelibrary
   homepage at
   <http://www.over-yonder.net/~fullermd/projects/sgml/codelibrary> for
   more details on it.

Contents

Data structures:

     * CIDR (Internal)

Functions:

     * cidr_addr_broadcast()
     * cidr_addr_hostmax()
     * cidr_addr_hostmin()
     * cidr_addr_network()
     * cidr_alloc()
     * cidr_contains()
     * cidr_dup()
     * cidr_equals()
     * cidr_free()
     * cidr_from_inaddr()
     * cidr_from_in6addr()
     * cidr_from_str()
     * cidr_get_addr()
     * cidr_get_mask()
     * cidr_get_pflen()
     * cidr_get_proto()
     * cidr_is_v4mapped()
     * cidr_net_subnets()
     * cidr_net_supernet()
     * cidr_numaddr()
     * cidr_numaddr_pflen()
     * cidr_numhost()
     * cidr_numhost_pflen()
     * cidr_to_inaddr()
     * cidr_to_in6addr()
     * cidr_to_str()
     * cidr_version()

Data structures

     * CIDR: A single CIDR-format IP block
       This datatype is intended for internal use only
          + Note:
            Use the cidr_free() function to free the memory associated
            with this datatype, and the cidr_alloc() function to allocate
            and initialize the structure.
          + Members:
               o int version: The structure version. This is reserved for
                 future use, and put in to hold its place at the start of
                 the array.
               o uint8_t addr[16]: The 16 octets that make up an IP
                 address. For v6 addresses, all are used. For v4
                 addresses, only the last 4 are really used. The prior 2
                 octets are filled in with all-ones, so that the internal
                 representation matches the v4-compat IPv6 addressing
                 block. This is useful when, for instance, using
                 cidr_to_in6addr() , in that it gives you the expected
                 result.
               o uint8_t mask[16]: The 16 octets that make up an IP
                 netmask. For v4 addresses, only the last 4 are really
                 used; the rest are intialized to all-bits-one however,
                 which is correct in spirit.
               o int proto: The protocol the address described is.
                 Currently possible values are CIDR_IPV4 and CIDR_IPV6. I
                 think that's pretty self-explanatory.

Functions

     * cidr_addr_broadcast(): Find the broadcast address
          + Summary:
            Generate a CIDR structure describing the broadcast address of
            the passed-in netblock.
            Note that using this with an IPv6 netblock is technically
            asking for something that doesn't exist, since IPv6 doesn't
            have subnet broadcast addresses. This function will still
            return the all-1's address though, on the assumption that if
            you're asking the question, it's the answer you want.
            An additional somewhat specialized case is that of an IPv4 /31
            or IPv6 /127. Depending on your interpretation and usage, this
            is either a useless subnet since it only contains network and
            broadcast and no hosts, or a subnet that holds 2 hosts with
            neither network or broadcast address (commonly used for
            point-to-point links). As a result, cidr_addr_broadcast() and
            cidr_addr_network() will give answers as if it were a
            host-less subnet, while cidr_addr_hostmax() and
            cidr_addr_hostmin() will answer as though it were a 2-host
            subnet. It can be seen as a little strange for
            cidr_addr_broadcast() and cidr_addr_hostmax() to give the same
            answer, but as above, libcidr assumes that if you ask the
            question, you want the answer that makes sense in that
            context.
            Similar caveats apply to calling these on a v4 /32 or v6 /128.
            Ask a silly question, get a silly answer :)
            The returned structure should be cleaned up using cidr_free()
            .
          + Arguments:
               o const CIDR * addr: A CIDR structure describing an
                 arbitrary netblock.
          + Returns:
            CIDR *
            Returns a pointer to a CIDR structure describing the broadcast
            address on success. Returns NULL on failure.
          + Error codes:
               o

                    EFAULT
                            Given NULL

               o Note:
                 cidr_addr_broadcast() can also fail and set errno for any
                 of the reasons listed for cidr_alloc() .
     * cidr_addr_hostmax(): Find the highest host address
          + Summary:
            Generate a CIDR structure describing the highest-numbered
            address available for a host IP in the given netblock.
            See the discussion under cidr_addr_broadcast() concerning
            near- amd maximal-prefix-length blocks for edge case details.
            The returned structure should be cleaned up using cidr_free()
            .
          + Arguments:
               o const CIDR * addr: A CIDR structure describing an
                 arbitrary netblock.
          + Returns:
            CIDR *
            Returns a pointer to a CIDR structure describing the max host
            address on success. Returns NULL on failure.
          + Error codes:
               o Note:
                 cidr_addr_hostmax() can fail and set errno for any of the
                 reasons listed for cidr_addr_broadcast() .
     * cidr_addr_hostmin(): Find the lowest host address
          + Summary:
            Generate a CIDR structure describing the lowest-numbered
            address available for a host IP in the given netblock.
            See the discussion under cidr_addr_broadcast() concerning
            near- amd maximal-prefix-length blocks for edge case details.
            The returned structure should be cleaned up using cidr_free()
            .
          + Arguments:
               o const CIDR * addr: A CIDR structure describing an
                 arbitrary netblock.
          + Returns:
            CIDR *
            Returns a pointer to a CIDR structure describing the min host
            address on success. Returns NULL on failure.
          + Error codes:
               o Note:
                 cidr_addr_hostmin() can fail and set errno for any of the
                 reasons listed for cidr_addr_network() .
     * cidr_addr_network(): Find the network address
          + Summary:
            Generate a CIDR structure describing the network address of
            the passed-in netblock.
            See the discussion under cidr_addr_broadcast() concerning
            near- amd maximal-prefix-length blocks for edge case details.
            The returned structure should be cleaned up using cidr_free()
            .
          + Arguments:
               o const CIDR * addr: A CIDR structure describing an
                 arbitrary netblock.
          + Returns:
            CIDR *
            Returns a pointer to a CIDR structure describing the network
            address on success. Returns NULL on failure.
          + Error codes:
               o

                    EFAULT
                            Given NULL

               o Note:
                 cidr_addr_network() can also fail and set errno for any
                 of the reasons listed for cidr_alloc() .
     * cidr_alloc(): Create a CIDR
          + Summary:
            Allocate memory for a CIDR structure and initialize the
            necessary pieces.
            The returned structure should be cleaned up using cidr_free()
            .
            Note that you should probably never need to call this function
            yourself; you'll generally get your CIDR structures as a
            return from a function like cidr_from_str() or
            cidr_from_inaddr() .
          + Arguments:
               o None
          + Returns:
            CIDR *
            Returns a pointer to an initialized CIDR structure on success.
            Returns NULL on failure.
          + Error codes:
               o

                    ENOMEM
                            malloc() failed

     * cidr_contains(): Compare netblocks
          + Summary:
            This function is passed two CIDR structures describing a pair
            of netblocks. It then determines if the latter is wholly
            contained within the former.
            A common use-case of this will generally involve the second
            "block" actually being a host (/32 or /128) address, as when
            you're implementing ACL's. But that's really just a specific
            case of the second block being any other size; there's nothing
            special or magical about it. As far as libcidr is concerned,
            they're just two netblocks.
          + Arguments:
               o const CIDR * big: The netblock which may (or may not)
                 contain the second arg.
               o const CIDR * little: The netblock which may (or may not)
                 be contained within the first arg.
          + Returns:
            int
            Returns 0 if little is wholly contained within big. Returns -1
            if it's not, or if an error occured.
          + Error codes:
               o

                    0
                            No error (little not in big)

               o

                    EFAULT
                            Passed NULL

               o

                    EINVAL
                            Invalid argument

               o

                    ENOENT
                            Internal error (shouldn't happen)

               o

                    EPROTO
                            Protocols don't match

     * cidr_dup(): Duplicate a netblock
          + Summary:
            Allocate a CIDR , and fill it in with a duplicate of the
            information given.
            The returned structure should be cleaned up using cidr_free()
            .
          + Arguments:
               o const CIDR * src: A CIDR structure to be copied.
          + Returns:
            CIDR *
            Returns a CIDR struct containing a copy of src. Returns NULL
            on failure.
          + Error codes:
               o Note:
                 cidr_dup() can fail and set errno for any of the reasons
                 listed for cidr_alloc() .
     * cidr_equals(): Compare two blocks for equality
          + Summary:
            This function is passed two CIDR structures describing a pair
            of netblocks. It checks to see if they happen to describe the
            same netblock.
          + Arguments:
               o const CIDR * one: One netblock.
               o const CIDR * two: Another netblock.
          + Returns:
            int
            Returns 0 if the two CIDR structs describe the same netblock.
            Returns -1 otherwise.
     * cidr_free(): Free a CIDR structure.
          + Summary:
            Takes a CIDR structure and free() 's all its component parts.
          + Arguments:
               o CIDR * tofree: A single CIDR structure which has outlived
                 its usefulness.
          + Returns:
            void
     * cidr_from_inaddr(): Parse a struct in_addr
          + Summary:
            Takes a populated struct in_addr, as you'd get from accept()
            or getaddrinfo() or similar functions. Parses it out and
            generates a CIDR structure based on it. Note that an in_addr
            only contains a host address, so the netmask is initialized to
            all-1's (/32).
          + Arguments:
               o const struct in_addr * uaddr: A populated struct in_addr,
                 from whatever source obtained.
          + Returns:
            CIDR *
            Returns a pointer to a populated CIDR containing the address
            in the passed-in struct in_addr. The netmask is initialized to
            all-1's, and the protocol to IPv4. Use cidr_free() to free the
            structure when you're finished with it. Returns NULL on error.
          + Error codes:
               o

                    EFAULT
                            Passed NULL

               o Note:
                 cidr_from_inaddr() can also fail and set errno for any of
                 the reasons listed for cidr_alloc() .
     * cidr_from_in6addr(): Parse a struct in6_addr
          + Summary:
            Takes a populated struct in6_addr, as you'd get from accept()
            or getaddrinfo() or similar functions. Parses it out and
            generates a CIDR structure based on it. Note that a in6_addr
            only contains a host address, so the netmask is initialized to
            all-1's (/128).
          + Arguments:
               o const struct in6_addr * uaddr: A populated struct
                 in6_addr, from whatever source obtained.
          + Returns:
            CIDR *
            Returns a pointer to a populated CIDR containing the address
            in the passed-in struct in6_addr. The netmask is initialized
            to all-1's, and the protocol to IPv6 (though it may contain an
            IPv4-mapped address). Use cidr_free() to free the structure
            when you're finished with it. Returns NULL on error.
          + Error codes:
               o

                    EFAULT
                            Passed NULL

               o Note:
                 cidr_from_inaddr() can also fail and set errno for any of
                 the reasons listed for cidr_alloc() .
     * cidr_from_str(): Parse a human-readable string
          + Summary:
            Takes in a netblock description as a human-readable string,
            and creates a CIDR structure from it.
            This is probably the most intricate function in the library.
            It accepts addresses in "address/mask" format. 'address' is an
            IP address in valid written form. For IPv4, it's 1 through 4
            period-separated pieces, expressed in octal, hex, or decimal,
            with the last octet being treated as an 8, 16, 24, or 32-bit
            quantity depending on whether there are 4, 3, 2, or 1 pieces
            given (respectively). Of course, you're nuts for using that
            flexibility. For IPv6, it's nice and simple; 8 colon-separated
            double-octets, excepting that the last 4 octets can be
            expressed as a 4-piece dotted-decimal, like an IPv4 address
            (the full flexibility of the IPv4 parsing engine is not
            available, however; intentionally, though that may change if
            necessary). 'mask' can be either a prefix length (/0-/32 for
            IPv4, /0-/128 for IPv6), or a netmask written in the standard
            form for the address family.
            IPv6 addresses can be specified in fully expanded form, or
            with ::-style contraction. IPv4-mapped IPv6 addresses
            (::ffff:a.b.c.d), will be treated as IPv6 addresses. The mask
            can be left off, in which case addresses are treated as host
            addresses (/32 or /128, depending on address family).
            Also, cidr_from_str() will parse DNS PTR-record-style address
            formats. That is, representations like "4.3.2.1.in-addr.arpa"
            for IPv4, and an extremely long and annoying form ending in
            .ip6.arpa for IPv6. cidr_from_str() also understands the
            deprecated RFC1886 form of IPv6 PTR records, which ends in
            .ip6.int, though cidr_to_str() will only generate the current
            RFC3152-style .ip6.arpa version. Note also that while
            cidr_to_str() treats all addresses as host addresses when
            building the PTR string (ignoring the netmask),
            cidr_from_str() will fill in the netmask bits as appropriate
            for the string given; any octets (or half-octets, in the IPv6
            form) that are left off the beginning will have their netmask
            bits set to 0.
            It's not the intention of the author that this function
            necessarily be able to decipher any possible address format.
            However, the capabilities given should parse any rational
            address specification, and many irrational ones (like hex/oct
            and collapsed v4 addresses). The intention is rather to
            support the ways the addresses and netmasks are commonly
            written and read, so that a human-readable form can quickly be
            transformed into a format that libcidr can then use in its
            various ways, whether through comparing addresses with
            functions like cidr_contains() , or generating references and
            stats about a netblock with functions like
            cidr_addr_broadcast() and cidr_numhost() , or simply spitting
            it out in different human-readable forms with cidr_to_str() .
          + Arguments:
               o const char * addr: A string containing some
                 human-readable IP block.
          + Returns:
            CIDR *
            Returns a pointer to a populated CIDR describing (hopefully)
            the block you talked about in the string. Use cidr_free() to
            free the structure when you're finished with it. Returns NULL
            on error.
          + Error codes:
               o

                    EFAULT
                            Passed NULL

               o

                    EINVAL
                            Can't parse the input string

               o

                    ENOENT
                            Internal error (shouldn't happen)

               o Note:
                 cidr_from_str() can also fail and set errno for any of
                 the reasons listed for cidr_alloc() or cidr_get_pflen() .
     * cidr_get_addr(): Return address bits
          + Summary:
            Return the address bits which compose the address. This should
            be used in preference to simply referencing inside the CIDR
            manually in external code, since the structure might change on
            you.
            Generally, if you think you need to call this, you should
            probably rethink what you're doing. Most of the time, one of
            the formatted outputs from cidr_to_str() or one of the
            manipulation functions like cidr_addr_hostmin() is what you
            want. Still, there are times when you're interesting in
            manipulating the address by yourself as a bunch of binary bits
            (the cidrcalc example program does this), so this function
            should be used instead of groping around in the structure
            manually.
          + Arguments:
               o const CIDR * addr: An arbitrary netblock.
          + Returns:
            uint8_t *
            Returns a pointer to an 16-element array of uint8_t's
            representing the address. This array must be free() 'd when
            you're through with it. Returns NULL on error.
          + Error codes:
               o

                    EFAULT
                            Passed NULL

               o

                    ENOMEM
                            malloc() failed

     * cidr_get_mask(): Return netmask bits
          + Summary:
            Return the netmask bits which of the given netblock. This
            should be used in preference to simply referencing inside the
            CIDR manually in external code, since the structure might
            change on you.
            See further notes about the desirability of using this
            function above in the notes for cidr_get_addr() .
          + Arguments:
               o const CIDR * addr: An arbitrary netblock.
          + Returns:
            uint8_t *
            Returns a pointer to an 16-element array of uint8_t's
            representing the netmask. This array must be free() 'd when
            you're through with it. Returns NULL on error.
          + Error codes:
               o

                    EFAULT
                            Passed NULL

               o

                    ENOMEM
                            malloc() failed

     * cidr_get_pflen(): Network bits in the netmask
          + Summary:
            Poke around the netmask of the passed-in CIDR structure and
            determine how many bits there are in the netmask, as
            appropriate to the address family.
          + Arguments:
               o const CIDR * block: An arbitrary netblock.
          + Returns:
            int
            Returns the number of network bits in the netmask (0-32 for
            IPv4, 0-128 for IPv6). Returns -1 on error.
          + Error codes:
               o

                    EFAULT
                            Passed NULL

               o

                    EINVAL
                            Invalid (non-contiguous) netmask

               o

                    ENOENT
                            Internal error (shouldn't happen)

     * cidr_get_proto(): Find a netblock's protocol family
          + Summary:
            Returns the protocol family of an address using one of the
            defined constants. The current choices are CIDR_IPV4 and
            CIDR_IPV6.
          + Arguments:
               o const CIDR * addr: An arbitrary netblock.
          + Returns:
            int
            Returns the address family of the given netblock.
          + Error codes:
               o

                    EFAULT
                            Passed NULL

     * cidr_is_v4mapped(): Is address IPv4-mapped IPv6 address?
          + Summary:
            An IPv6 address may be in the network range reserved for
            IPv4-mapped addresses. This function will tell you whether it
            is or not. Note that an IPv4 CIDR is NOT considered an
            IPv4-mapped address, and so will return failure.
          + Arguments:
               o const CIDR * addr: An arbitrary netblock.
          + Returns:
            int
            Returns 0 if the address is an IPv4-mapped IPv6 address.
            Returns -1 otherwise.
     * cidr_net_subnets(): Divide a netblock
          + Summary:
            Take in a netblock, and derive the two netblocks which it
            divides up into. Return them in an array.
          + Arguments:
               o const CIDR * addr: The netblock to subdivide.
          + Returns:
            CIDR **
            Returns a 2-element array of CIDR structs, containing the two
            subnets of addr. Each of the elements should be cleaned up
            with cidr_free() , and the array itself then cleaned up with
            free() . Returns NULL on failure.
          + Error codes:
               o

                    0
                            No error (already a /32 or /128)

               o

                    EFAULT
                            Passed NULL argument

               o

                    ENOMEM
                            malloc() failed

               o Note:
                 cidr_net_subnets() can also fail and set errno for any of
                 the reasons listed for cidr_addr_network() or cidr_dup()
                 .
     * cidr_net_supernet(): Undivide a netblock
          + Summary:
            Take in a netblock, and derive the parent netblock in which it
            fits.
          + Arguments:
               o const CIDR * addr: The netblock to find the parent of.
          + Returns:
            CIDR *
            Returns a CIDR struct defining the parent network of addr.
            Clean this up with cidr_free() when you're finished with it.
            Returns NULL on failure.
          + Error codes:
               o

                    0
                            No error (already a /0)

               o

                    EFAULT
                            Passed NULL argument

               o Note:
                 cidr_net_supernet() can also fail and set errno for any
                 of the reasons listed for cidr_dup() .
     * cidr_numaddr(): Addresses in a netblock
          + Summary:
            Determine the total number of addresses in a netblock
            (including the network and broadcast addresses).
            This function returns a pointer to a pre-formatted string
            because we're potentially returning a value up to 2**128. I
            don't feel like trying to portably do 128-bit arithmetic. Do
            you?
          + Arguments:
               o const CIDR * addr: An arbitrary netblock.
          + Returns:
            const char *
            Returns a pointer to a string containing the number of
            addresses in the netblock. Note that this is a static string;
            it should not be overwritten, and doesn't need to be free()
            'd. Make a copy if you want to manipulate it. Returns NULL on
            error.
          + Error codes:
               o

                    EFAULT
                            Passed NULL

               o Note:
                 cidr_numaddr() can also also fail and set errno for any
                 of the reasons listed for cidr_numaddr_pflen() .
     * cidr_numaddr_pflen(): Addresses in a prefix length
          + Summary:
            Determine the total number of addresses in a netblock with the
            given prefix length (including the network and broadcast
            addresses).
            Note that this takes an IPv6 prefix length; that is, 0-128. If
            you're interested in an IPv4 address with a given prefix
            length, add 96 to it when you call this function.
            See the note in cidr_numaddr() for why we're returning a
            string and not a number.
          + Arguments:
               o int pflen: A prefix length (0-128).
          + Returns:
            const char *
            Returns a pointer to a string containing the number of
            addresses in the netblock. Note that this is a static string;
            it should not be overwritten, and doesn't need to be free()
            'd. Make a copy if you want to manipulate it. Returns NULL on
            error.
          + Error codes:
               o

                    EINVAL
                            Invalid prefix length

     * cidr_numhost(): Host addresses in a netblock
          + Summary:
            Determine the total number of host addresses in a netblock
            (excluding the network and broadcast addresses).
            See the note in cidr_numaddr() for why we're returning a
            string and not a number.
          + Arguments:
               o const CIDR * addr: An arbitrary netblock.
          + Returns:
            const char *
            Returns a pointer to a string containing the number of host
            addresses in the netblock. Note that this is a static string;
            it should not be overwritten, and doesn't need to be free()
            'd. Make a copy if you want to manipulate it. Returns NULL on
            error.
          + Error codes:
               o

                    EFAULT
                            Passed NULL

               o Note:
                 cidr_numhost() can also also fail and set errno for any
                 of the reasons listed for cidr_numhost_pflen() .
     * cidr_numhost_pflen(): Host addresses in a prefix length
          + Summary:
            Determine the total number of host addresses in a netblock
            with the given prefix length (excluding the network and
            broadcast addresses).
            Note that this takes an IPv6 prefix length; that is, 0-128. If
            you're interested in an IPv4 address with a given prefix
            length, add 96 to it when you call this function.
            See the note in cidr_numaddr() for why we're returning a
            string and not a number.
          + Arguments:
               o int pflen: A prefix length (0-128).
          + Returns:
            const char *
            Returns a pointer to a string containing the number of host
            addresses in the netblock. Note that this is a static string;
            it should not be overwritten, and doesn't need to be free()
            'd. Make a copy if you want to manipulate it. Returns NULL on
            error.
          + Error codes:
               o

                    EINVAL
                            Invalid prefix length

     * cidr_to_inaddr(): Create a struct in_addr
          + Summary:
            Takes in a CIDR and creates a struct in_addr from it. This
            struct can then be used in connect() or similar
            network-related functions. If the users passes in a struct
            in_addr, it will be filled in. Otherwise, one will be
            allocated and returned.
          + Arguments:
               o const CIDR * addr: A CIDR structure describing the host
                 to be translated into a struct in_addr. Note that the
                 netmask is irrelevant and will be ignored.
                 cidr_to_inaddr() supports only IPv4 addresses, as the
                 underlying structure only does.
               o struct in_addr * uptr: A pointer to a pre-allocated
                 struct in_addr, or NULL. If non-NULL, the pointed-at
                 structure will be filled in. If NULL, a new structure
                 will be allocated, filled in, and returned.
          + Returns:
            struct in_addr *
            Returns a pointer to the filled-in struct in_addr. If the user
            passed one in, this will just point to the same place and can
            profitably be ignored. If the user passed in NULL, this will
            point to the struct in_addr we allocated, which should be
            free() 'd by the user when they're finished with it. Returns
            NULL on error.
          + Error codes:
               o

                    EFAULT
                            Passed NULL

               o

                    ENOMEM
                            malloc() failed

               o

                    EPROTOTYPE
                            Bad protocol type (must be IPv4)

     * cidr_to_in6addr(): Create a struct in6_addr
          + Summary:
            Takes in a CIDR and creates a struct in6_addr from it. This
            struct can then be used in connect() or similar
            network-related functions. If the users passes in a struct
            in6_addr, it will be filled in. Otherwise, one will be
            allocated and returned.
          + Arguments:
               o const CIDR * addr: A CIDR structure describing the host
                 to be translated into a struct in6_addr. Note that the
                 netmask is irrelevant and will be ignored.
                 cidr_to_in6addr() supports both IPv4 and IPv6 addresses,
                 as the underlying structure does as well. IPv4 addresses
                 are treated as v4-mapped IPv6 addresses.
               o struct in6_addr * uptr: A pointer to a pre-allocated
                 struct in6_addr, or NULL. If non-NULL, the pointed-at
                 structure will be filled in. If NULL, a new structure
                 will be allocated, filled in, and returned.
          + Returns:
            struct in6_addr *
            Returns a pointer to the filled-in struct in6_addr. If the
            user passed one in, this will just point to the same place and
            can profitably be ignored. If the user passed in NULL, this
            will point to the struct in6_addr we allocated, which should
            be free() 'd by the user when they're finished with it.
            Returns NULL on error.
          + Error codes:
               o

                    EFAULT
                            Passed NULL

               o

                    ENOMEM
                            malloc() failed

               o

                    EPROTOTYPE
                            Bad protocol type (must be IPv4 or IPv6)

     * cidr_to_str(): Create a human-readable netblock description
          + Summary:
            Takes in a CIDR structure, and generates up a human-readable
            string describing the netblock. This function has a lot of
            flexibility, depending on the flags passed to it. The default
            output is "address/pflen" form, with the address in a
            reasonably compact form, and the prefix length given
            numerically. Flags alter the output in various ways, and are
            set as bitmasks, so they can be combined however you wish.
            They can be used in any combination that makes sense, and a
            large number of combinations that don't.
            The current flags are:
            CIDR_NOFLAGS: A stand-in for when you just want the default
            output
            CIDR_NOCOMPACT: Don't do ::-style IPv6 compaction
            CIDR_VERBOSE: Show leading 0's in octets [v6 only]
            CIDR_USEV6: Use IPv4-mapped address form for IPv4 addresses
            (::ffff:a.b.c.d)
            CIDR_USEV4COMPAT: Use IPv4-compat form (::a.b.c.d) instead of
            IPv4-mapped form (only meaningful in combination with
            CIDR_USEV6)
            CIDR_NETMASK: Return a netmask in standard form after the
            slash, instead of the prefix length. Note that the form of the
            netmask can thus be altered by the various flags that alter
            how the address is displayed.
            CIDR_ONLYADDR: Show only the address, without the
            prefix/netmask
            CIDR_ONLYPFLEN: Show only the prefix length (or netmask, when
            combined with CIDR_NETMASK), without the address.
            CIDR_WILDCARD: Show a Cisco-style wildcard mask instead of the
            netmask (only meaningful in combination with CIDR_NETMASK)
            CIDR_FORCEV6: Forces treating the CIDR as an IPv6 address, no
            matter what it really is. This doesn't do any conversion or
            translation; just treats the raw data as if it were IPv6.
            CIDR_FORCEV4: Forces treating the CIDR as an IPv4 address, no
            matter what it really is. This doesn't do any conversion or
            translation; just treats the raw data as if it were IPv4.
            CIDR_REVERSE: Generates a .in-addr.arpa or .ip6.arpa-style PTR
            record name for the given block. Note that this always treats
            it solely as an address; the netmask is ignored. See some
            notes in cidr_from_str() for details of the asymmetric
            treatment of this form of address representation relating to
            the netmask.
            Many combinations can give somewhat surprising results, but
            they should allow any of a host of manipulations to output
            just the data you might be interested in. The "mkstr" test
            program in the source tree is extremely useful for manual
            testing of the various flags to see visually what they do, and
            is a lot quicker than trying to code them all to test it out.
            Use it to your advantage.
          + Arguments:
               o const CIDR * block: The CIDR structure to generate a
                 string form of. The address family will be autodetected.
               o int flags: A bitmask of the various possible flags the
                 function accepts.
          + Returns:
            char *
            Returns a pointer to a string containing the representation of
            the network. Be sure to free() it when you're finished.
          + Error codes:
               o

                    EINVAL
                            Invalid argument (bad block or flags)

               o

                    ENOENT
                            Internal error (shouldn't happen)

               o

                    ENOMEM
                            malloc() failed

               o Note:
                 cidr_to_str() can also fail and set errno for any of the
                 reasons listed for cidr_alloc() or cidr_get_pflen() .
     * cidr_version(): Library version
          + Summary:
            Returns a static string describing the library release
            version.
          + Arguments:
               o None
          + Returns:
            const char *
            Returns a pointer to a static string describing the library
            version number. It shouldn't be overwritten or free() 'd.