portset.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id: portset.c,v 1.4 2008/06/24 23:24:35 marka Exp $ */
00018 
00019 /*! \file */
00020 
00021 #include <config.h>
00022 
00023 #include <isc/mem.h>
00024 #include <isc/portset.h>
00025 #include <isc/string.h>
00026 #include <isc/types.h>
00027 #include <isc/util.h>
00028 
00029 #define ISC_PORTSET_BUFSIZE (65536 / (sizeof(isc_uint32_t) * 8))
00030 
00031 /*%
00032  * Internal representation of portset.  It's an array of 32-bit integers, each
00033  * bit corresponding to a single port in the ascending order.  For example,
00034  * the second most significant bit of buf[0] corresponds to port 1.
00035  */
00036 struct isc_portset {
00037         unsigned int nports;    /*%< number of ports in the set */
00038         isc_uint32_t buf[ISC_PORTSET_BUFSIZE];
00039 };
00040 
00041 static inline isc_boolean_t
00042 portset_isset(isc_portset_t *portset, in_port_t port) {
00043         return (ISC_TF((portset->buf[port >> 5] & (1 << (port & 31))) != 0));
00044 }
00045 
00046 static inline void
00047 portset_add(isc_portset_t *portset, in_port_t port) {
00048         if (!portset_isset(portset, port)) {
00049                 portset->nports++;
00050                 portset->buf[port >> 5] |= (1 << (port & 31));
00051         }
00052 }
00053 
00054 static inline void
00055 portset_remove(isc_portset_t *portset, in_port_t port) {
00056         if (portset_isset(portset, port)) {
00057                 portset->nports--;
00058                 portset->buf[port >> 5] &= ~(1 << (port & 31));
00059         }
00060 }
00061 
00062 isc_result_t
00063 isc_portset_create(isc_mem_t *mctx, isc_portset_t **portsetp) {
00064         isc_portset_t *portset;
00065 
00066         REQUIRE(portsetp != NULL && *portsetp == NULL);
00067 
00068         portset = isc_mem_get(mctx, sizeof(*portset));
00069         if (portset == NULL)
00070                 return (ISC_R_NOMEMORY);
00071 
00072         /* Make the set 'empty' by default */
00073         memset(portset, 0, sizeof(*portset));
00074         *portsetp = portset;
00075 
00076         return (ISC_R_SUCCESS);
00077 }
00078 
00079 void
00080 isc_portset_destroy(isc_mem_t *mctx, isc_portset_t **portsetp) {
00081         isc_portset_t *portset;
00082 
00083         REQUIRE(portsetp != NULL);
00084         portset = *portsetp;
00085 
00086         isc_mem_put(mctx, portset, sizeof(*portset));
00087 }
00088 
00089 isc_boolean_t
00090 isc_portset_isset(isc_portset_t *portset, in_port_t port) {
00091         REQUIRE(portset != NULL);
00092 
00093         return (portset_isset(portset, port));
00094 }
00095 
00096 unsigned int
00097 isc_portset_nports(isc_portset_t *portset) {
00098         REQUIRE(portset != NULL);
00099 
00100         return (portset->nports);
00101 }
00102 
00103 void
00104 isc_portset_add(isc_portset_t *portset, in_port_t port) {
00105         REQUIRE(portset != NULL);
00106 
00107         portset_add(portset, port);
00108 }
00109 
00110 void
00111 isc_portset_remove(isc_portset_t *portset, in_port_t port) {
00112         portset_remove(portset, port);
00113 }
00114 
00115 void
00116 isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo,
00117                      in_port_t port_hi)
00118 {
00119         in_port_t p;
00120 
00121         REQUIRE(portset != NULL);
00122         REQUIRE(port_lo <= port_hi);
00123 
00124         p = port_lo;
00125         do {
00126                 portset_add(portset, p);
00127         } while (p++ < port_hi);
00128 }
00129 
00130 void
00131 isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo,
00132                         in_port_t port_hi)
00133 {
00134         in_port_t p;
00135 
00136         REQUIRE(portset != NULL);
00137         REQUIRE(port_lo <= port_hi);
00138 
00139         p = port_lo;
00140         do {
00141                 portset_remove(portset, p);
00142         } while (p++ < port_hi);
00143 }

Generated on Tue Apr 28 17:41:05 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha