1 /* 2 ** Copyright (C) 2001-2020 by Carnegie Mellon University. 3 ** 4 ** @OPENSOURCE_LICENSE_START@ 5 ** See license information in ../../LICENSE.txt 6 ** @OPENSOURCE_LICENSE_END@ 7 */ 8 9 /* 10 * iptree.h 11 * 12 * THIS FILE AND ALL FUNCTIONS/MACROS/STUCTURES IT DECLARES/DEFINES 13 * ARE DEPRECATED AS OF SiLK 3.10.0. USE skipset.h INSTEAD. 14 * 15 * 16 * Michael Collins 17 * May 6th, 2003 18 * 19 * This is a tree structure for ip addresses containing a bitmap of 20 * ip addresses. 21 * 22 */ 23 #ifndef _IPTREE_H 24 #define _IPTREE_H 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 #include <silk/silk.h> 30 31 RCSIDENTVAR(rcsID_IPTREE_H, "$SiLK: iptree.h ef14e54179be 2020-04-14 21:57:45Z mthomas $"); 32 33 #include <silk/silk_types.h> 34 #include <silk/skipset.h> 35 36 /** 37 * @file 38 * 39 * An skIPTree is the form of the IPset used in SiLK versions prior 40 * to SiLK-3.0. 41 * 42 * This file is part of libsilk. 43 */ 44 45 /** 46 * Return values for skIPTree* functions. 47 */ 48 typedef enum skIPTreeErrors_en { 49 /** Success */ 50 SKIP_OK = 0, 51 /** Unable to allocate memory */ 52 SKIP_ERR_ALLOC, 53 /** Empty input value */ 54 SKIP_ERR_BADINPUT, 55 /** Error in read/write */ 56 SKIP_ERR_FILEIO, 57 /** Input is not an IPset */ 58 SKIP_ERR_FILETYPE, 59 /** Input IPset is not empty */ 60 SKIP_ERR_NONEMPTY, 61 /** Error opening file */ 62 SKIP_ERR_OPEN, 63 /** IPsets do not support IPv6 addresses */ 64 SKIP_ERR_IPV6, 65 /** This application does not support the new IPset file format */ 66 SKIP_ERR_FILEVERSION 67 } skIPTreeErrors_t; 68 69 70 typedef skipset_iterator_t skIPTreeIterator_t; 71 72 typedef skipset_iterator_t skIPTreeCIDRBlockIterator_t; 73 74 struct skIPTreeCIDRBlock_st { 75 uint32_t addr; 76 uint32_t mask; 77 }; 78 typedef struct skIPTreeCIDRBlock_st skIPTreeCIDRBlock_t; 79 80 81 /* FUNCTION PROTOTYPES */ 82 83 /** 84 * Add the IP Address 'addr' to the binary IPSet 'ipset'. Returns 85 * SKIP_OK for success, or SKIP_ERR_ALLOC if there is not enough 86 * memory to allocate space for the new IP address. 87 */ 88 int 89 skIPTreeAddAddress( 90 skIPTree_t *ipset, 91 uint32_t addr); 92 93 94 /** 95 * Add all the addresses in the IPWildcard 'ipwild' to the IPset 96 * 'ipset'. 97 * 98 * When 'ipwild' contains IPv6 addresses, map each address within 99 * the ::ffff:0:0/96 netblock to an IPv4 address and add it to 100 * 'ipset'. This behavior is new as of SiLK 3.9.0. In prior 101 * releases of SiLK, the entire contents of the wildcard was 102 * ignored and SKIP_ERR_IPV6 was returned when 'ipwild' contained 103 * any IPv6 addresses. 104 * 105 * Returns SKIP_OK for success or SKIP_ERR_ALLOC if there is a 106 * memory allocation error. 107 */ 108 int 109 skIPTreeAddIPWildcard( 110 skIPTree_t *ipset, 111 const skIPWildcard_t *ipwild); 112 113 114 /** 115 * Return 1 if the IPv4 address 'ipv4' is in the IPset 'ipset'; 116 * otherwise, return 0. 117 */ 118 int 119 skIPTreeCheckAddress( 120 const skIPTree_t *ipset, 121 uint32_t ipv4); 122 123 124 /** 125 * Return 1 if the IPsets 'ipset1' and 'ipset2' have any IPs in 126 * common; otherwise, return 0. 127 */ 128 int 129 skIPTreeCheckIntersectIPTree( 130 const skIPTree_t *ipset1, 131 const skIPTree_t *ipset2); 132 133 134 /** 135 * Return 1 if the IPset 'ipset' and IPWildcard 'ipwild' have any 136 * IPs in common; otherwise, return 0. 137 * 138 * When 'ipwild' contains IPv6 addresses, map each address within 139 * the ::ffff:0:0/96 netblock to an IPv4 address and determine if 140 * it appears in 'ipset'. This behavior is new as of SiLK 3.9.0. 141 * In prior relases of SiLK, the entire contents of the wildcard 142 * was ignored and 0 was returned when 'ipwild' contained any IPv6 143 * addresses. 144 */ 145 int 146 skIPTreeCheckIntersectIPWildcard( 147 const skIPTree_t *ipset, 148 const skIPWildcard_t *ipwild); 149 150 151 /** 152 * Like skIPTreeCheckIntersectIPTree(), except compares the in-core 153 * IPset 'ipset' with the IPset contained in the file 'ipset_path'. 154 * Returns 1 if the IPsets have an IPs in common; returns 0 if they 155 * do not or to signify an error, in which case the error code will 156 * be put into the memory referenced 'err_code', if that value is 157 * non-NULL. 158 */ 159 int 160 skIPTreeCheckIntersectIPTreeFile( 161 const skIPTree_t *ipset, 162 const char *ipset_path, 163 skIPTreeErrors_t *err_code); 164 165 166 /** 167 * Returns a count of the number of IP addresses marked in the 168 * 'ipset'. 169 */ 170 uint64_t 171 skIPTreeCountIPs( 172 const skIPTree_t *ipset); 173 174 175 /** 176 * Allocation and creation function; initializes a new ipset at the 177 * space specified by '*ipset' and sets the contents to empty. 178 * 179 * Returns SKIP_OK if everything went well, else SKIP_ERR_ALLOC 180 * on a malloc failure, or SKIP_ERR_BADINPUT if ipset was NULL. 181 * 182 * skIPTreeDelete() is the corresponding free function. 183 */ 184 int 185 skIPTreeCreate( 186 skIPTree_t **ipset); 187 188 189 /** 190 * Frees the space associated with *ipset and sets *ipset to 191 * NULL. Does nothing if 'ipset' or '*ipset' is NULL. 192 */ 193 void 194 skIPTreeDelete( 195 skIPTree_t **ipset); 196 197 198 /** 199 * Perform an intersection of 'result_ipset' and 'ipset', with the 200 * result in the 'result_ipset'; i.e., turn off all addresses in 201 * 'result_ipset' that are off in 'ipset'. 202 */ 203 void 204 skIPTreeIntersect( 205 skIPTree_t *result_ipset, 206 const skIPTree_t *ipset); 207 208 209 /** 210 * Create(allocate) a new IPset at the location pointed at by 211 * 'ipset' and fill it with the data that the function reads from 212 * the file 'filename'. 213 * 214 * This function is similar to skIPTreeRead(), except that this 215 * function will create the skstream_t from the specified filename. 216 * 217 * In addition to the possible return values listed for 218 * skIPTreeRead(), this function may return: 219 * SKIP_ERR_OPEN - error in opening the file 220 */ 221 int 222 skIPTreeLoad( 223 skIPTree_t **ipset, 224 const char *filename); 225 226 227 /** 228 * Modify in place the specified 'ipset' so it contains at most 1 229 * IP address for every block of bitmask length 'mask', a value 230 * from 1 to 32. If the 'ipset' has any IP active within each 231 * block, all IPs in that block are turned off except for the IP at 232 * the start of the block. 233 * 234 * Specify mask==16 with an IPset containing these IPs: 235 * 10.0.0.23 236 * 10.0.1.0/24 237 * 10.7.1.0/24 238 * 20.20.0.243 239 * produces an IPset with these three IPs: 240 * 10.0.0.0 241 * 10.7.0.0 242 * 20.20.0.0 243 */ 244 void 245 skIPTreeMask( 246 skIPTree_t *ipset, 247 uint32_t mask); 248 249 250 /** 251 * Print, to the stream 'stream', a textual representation of the 252 * IPset given by 'ipset'. The parameter 'ip_format' decribes how 253 * to print the ipset (see utils.h). If 'as_cidr' is non-zero, the 254 * output will be in CIDR notation. 255 */ 256 void 257 skIPTreePrint( 258 const skIPTree_t *ipset, 259 skstream_t *stream, 260 skipaddr_flags_t ip_format, 261 int as_cidr); 262 263 264 /** 265 * Allocate a new IPset at the location pointed at by 'ipset' and 266 * fill it with the data that the function reads from the stream 267 * 'stream'. 'stream' should be bound to a file and open. 268 * 269 * Returns one of the following: 270 * SKIP_OK on success 271 * SKIP_ERR_BADINPUT - one of the input values is NULL 272 * SKIP_ERR_ALLOC - failure to allocate memory. 273 * SKIP_ERR_NONEMPTY - the '*ipset' is not empty 274 * SKIP_ERR_FILETYPE - the file is not of the correct type 275 * SKIP_ERR_FILEIO - error during a read call 276 * 277 * On failure, 'ipset' is set back to null and deleted. 278 */ 279 int 280 skIPTreeRead( 281 skIPTree_t **ipset, 282 skstream_t *stream); 283 284 285 /** 286 * Remove all IPs from an IPset. 287 */ 288 int 289 skIPTreeRemoveAll( 290 skIPTree_t *ipset); 291 292 293 /** 294 * Write the IPset at 'ipset' to the disk file 'filename'; the 295 * disk format is specified in iptree.api. 296 * 297 * This function is similar to skIPTreeWrite(), except this 298 * function writes directly to a file using the default compression 299 * method. 300 * 301 * In addition to the possible return values listed for 302 * skIPTreeWrite(), this function may return: 303 * SKIP_ERR_OPEN - error in opening the file 304 */ 305 int 306 skIPTreeSave( 307 const skIPTree_t *ipset, 308 const char *filename); 309 310 311 /** 312 * Return a text string describing 'err_code'. 313 */ 314 const char * 315 skIPTreeStrError( 316 int err_code); 317 318 319 /** 320 * Subtract 'ipset' from 'result_ipset' with the result in the 321 * 'result_ipset'; i.e., if an address is off in 'ipset', do not 322 * modify the value in 'result_ipset', otherwise, turn off that 323 * address in 'result_ipset'. 324 */ 325 void 326 skIPTreeSubtract( 327 skIPTree_t *result_ipset, 328 const skIPTree_t *ipset); 329 330 331 /** 332 * Perform the union of 'result_ipset' and 'ipset', with the result 333 * in 'result_ipset'; i.e., merge 'ipset' into 'result_ipset'. 334 * Returns 0 on success, or 1 on memory allocation error. 335 */ 336 int 337 skIPTreeUnion( 338 skIPTree_t *result_ipset, 339 const skIPTree_t *ipset); 340 341 342 /** 343 * Write the IPset at 'ipset' the output stream 'stream'. 'stream' 344 * should be bound to a file and open. The caller may set the 345 * compression method of the stream before calling this function. 346 * If not set, the default compression method is used. 347 * 348 * Returns one of the following values: 349 * SKIP_OK on success. 350 * SKIP_ERR_OPEN if the file already exists. 351 * SKIP_ERR_FILEIO if there's an error writing the data to disk. 352 * SKIP_ERR_ALLOC on a memory allocatin problem for the ipset. 353 */ 354 int 355 skIPTreeWrite( 356 const skIPTree_t *ipset, 357 skstream_t *stream); 358 359 360 361 /* 362 * Iteration over the members of an IPset 363 */ 364 365 366 /** 367 * Bind the IPset iterator 'iter' to iterate over all the entries 368 * in the IPSet 'ipset'. Return 0 on success, non-zero otherwise. 369 */ 370 int 371 skIPTreeIteratorBind( 372 skIPTreeIterator_t *iter, 373 const skIPTree_t *ipset); 374 375 376 /** 377 * Create a new iterator at the address pointed to by 'out_iter' 378 * and bind it to iterate over all the entries in the IPSet 379 * 'ipset'. Return 0 on success, non-zero otherwise. 380 */ 381 int 382 skIPTreeIteratorCreate( 383 skIPTreeIterator_t **out_iter, 384 const skIPTree_t *ipset); 385 386 387 /** 388 * Destroy the iterator pointed to by 'out_iter'. Does nothing if 389 * 'out_iter' or the location it points to is NULL. 390 */ 391 void 392 skIPTreeIteratorDestroy( 393 skIPTreeIterator_t **out_iter); 394 395 396 /** 397 * If there are more entries in the IPSet, put the 398 * next IP Address into the location referenced by 'out_addr' and 399 * return SK_ITERATOR_OK. Otherwise, to not modify 'out_addr' 400 * and return SK_ITERATOR_NO_MORE_ENTRIES. 401 */ 402 skIteratorStatus_t 403 skIPTreeIteratorNext( 404 uint32_t *out_addr, 405 skIPTreeIterator_t *iter); 406 407 408 /** 409 * Reset the iterator 'iter' to begin looping through the entries 410 * in the IPSet again. 411 */ 412 void 413 skIPTreeIteratorReset( 414 skIPTreeIterator_t *iter); 415 416 417 418 /* 419 * Iteration over the CIDR Blocks of an IPset 420 */ 421 422 423 /** 424 * Bind the IPset CIDR Block iterator 'iter' to iterate over all 425 * the CIDR blocks in the IPSet 'ipset'. Return 0 on success, 426 * non-zero otherwise. 427 */ 428 int 429 skIPTreeCIDRBlockIteratorBind( 430 skIPTreeCIDRBlockIterator_t *iter, 431 const skIPTree_t *ipset); 432 433 434 /** 435 * Create a new CIDR Block iterator at the address pointed to by 436 * 'out_iter' and bind it to iterate over all the CIDR Blocks in 437 * the IPSet 'ipset'. Return 0 on success, non-zero otherwise. 438 */ 439 int 440 skIPTreeCIDRBlockIteratorCreate( 441 skIPTreeCIDRBlockIterator_t **out_iter, 442 const skIPTree_t *ipset); 443 444 445 /** 446 * Destroy the iterator pointed to by 'out_iter'. Does nothing if 447 * 'out_iter' or the location it points to is NULL. 448 */ 449 #if 1 450 #define skIPTreeCIDRBlockIteratorDestroy skIPTreeIteratorDestroy 451 #else 452 void 453 skIPTreeCIDRBlockIteratorDestroy( 454 skIPTreeCIDRBlockIterator_t **out_iter); 455 #endif 456 457 458 /** 459 * If there are more CIDR Blocks in the IPSet, fill 460 * next CIDR Block pointer 'out_cidr' with that CIDR Block and 461 * return SK_ITERATOR_OK. Otherwise, do not modify 'out_cidr' 462 * and return SK_ITERATOR_NO_MORE_ENTRIES. 463 */ 464 skIteratorStatus_t 465 skIPTreeCIDRBlockIteratorNext( 466 skIPTreeCIDRBlock_t *out_cidr, 467 skIPTreeCIDRBlockIterator_t *iter); 468 469 470 /** 471 * Reset the iterator 'iter' to begin looping through the entries 472 * in the IPSet again. 473 */ 474 #if 1 475 #define skIPTreeCIDRBlockIteratorReset skIPTreeIteratorReset 476 #else 477 void 478 skIPTreeCIDRBlockIteratorReset( 479 skIPTreeCIDRBlockIterator_t *iter); 480 #endif 481 482 483 #ifdef __cplusplus 484 } 485 #endif 486 #endif /* _IPTREE_H */ 487 488 /* 489 ** Local Variables: 490 ** mode:c 491 ** indent-tabs-mode:nil 492 ** c-basic-offset:4 493 ** End: 494 */ 495