2 * Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
17 /* $Id: portset.c,v 1.2.2.3 2008/06/24 23:26:49 marka Exp $ */
24 #include <isc/portset.h>
25 #include <isc/string.h>
26 #include <isc/types.h>
29 #define ISC_PORTSET_BUFSIZE (65536 / (sizeof(isc_uint32_t) * 8))
32 * Internal representation of portset. It's an array of 32-bit integers, each
33 * bit corresponding to a single port in the ascending order. For example,
34 * the second most significant bit of buf[0] corresponds to port 1.
37 unsigned int nports
; /*%< number of ports in the set */
38 isc_uint32_t buf
[ISC_PORTSET_BUFSIZE
];
41 static inline isc_boolean_t
42 portset_isset(isc_portset_t
*portset
, in_port_t port
) {
43 return (ISC_TF((portset
->buf
[port
>> 5] & (1 << (port
& 31))) != 0));
47 portset_add(isc_portset_t
*portset
, in_port_t port
) {
48 if (!portset_isset(portset
, port
)) {
50 portset
->buf
[port
>> 5] |= (1 << (port
& 31));
55 portset_remove(isc_portset_t
*portset
, in_port_t port
) {
56 if (portset_isset(portset
, port
)) {
58 portset
->buf
[port
>> 5] &= ~(1 << (port
& 31));
63 isc_portset_create(isc_mem_t
*mctx
, isc_portset_t
**portsetp
) {
64 isc_portset_t
*portset
;
66 REQUIRE(portsetp
!= NULL
&& *portsetp
== NULL
);
68 portset
= isc_mem_get(mctx
, sizeof(*portset
));
70 return (ISC_R_NOMEMORY
);
72 /* Make the set 'empty' by default */
73 memset(portset
, 0, sizeof(*portset
));
76 return (ISC_R_SUCCESS
);
80 isc_portset_destroy(isc_mem_t
*mctx
, isc_portset_t
**portsetp
) {
81 isc_portset_t
*portset
;
83 REQUIRE(portsetp
!= NULL
);
86 isc_mem_put(mctx
, portset
, sizeof(*portset
));
90 isc_portset_isset(isc_portset_t
*portset
, in_port_t port
) {
91 REQUIRE(portset
!= NULL
);
93 return (portset_isset(portset
, port
));
97 isc_portset_nports(isc_portset_t
*portset
) {
98 REQUIRE(portset
!= NULL
);
100 return (portset
->nports
);
104 isc_portset_add(isc_portset_t
*portset
, in_port_t port
) {
105 REQUIRE(portset
!= NULL
);
107 portset_add(portset
, port
);
111 isc_portset_remove(isc_portset_t
*portset
, in_port_t port
) {
112 portset_remove(portset
, port
);
116 isc_portset_addrange(isc_portset_t
*portset
, in_port_t port_lo
,
121 REQUIRE(portset
!= NULL
);
122 REQUIRE(port_lo
<= port_hi
);
126 portset_add(portset
, p
);
127 } while (p
++ < port_hi
);
131 isc_portset_removerange(isc_portset_t
*portset
, in_port_t port_lo
,
136 REQUIRE(portset
!= NULL
);
137 REQUIRE(port_lo
<= port_hi
);
141 portset_remove(portset
, p
);
142 } while (p
++ < port_hi
);