diff --git a/include/Bitmap.h b/include/Bitmap.h new file mode 100644 index 0000000000..698df7c781 --- /dev/null +++ b/include/Bitmap.h @@ -0,0 +1,140 @@ +/* + * + * (C) 2013-25 - ntop.org + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _BITMAP_H_ +#define _BITMAP_H_ + +#include "ntop_includes.h" + +/** + * @brief Generic bitmap class template building a bitmap as multiple 64-bit bitmaps + * @tparam N Number of u_int64_t elements in the bitmap array + */ +template class Bitmap { + private: + u_int64_t bitmap[N]; + + public: + Bitmap() { reset(); } + Bitmap(char *list) { + reset(); + setBits(list); + }; + + static inline u_int numBits() { return N * 64; }; + + void reset() { memset(bitmap, 0, sizeof(bitmap)); } + + void setBit(u_int16_t id) { + size_t idx = id >> 6; + u_int8_t offset = id & 0x3F; + if (idx < N) + bitmap[idx] |= ((u_int64_t)1) << offset; + } + + void setBits(char *list) { + char *item, *tmp = NULL; + + item = strtok_r(list, ",", &tmp); + + while (item) { + int id = atoi(item); + setBit(id); + item = strtok_r(NULL, ",", &tmp); + } + } + + void clearBit(u_int16_t id) { + size_t idx = id >> 6; /* id / 64 */ + u_int8_t offset = id & 0x3F; /* id % 64 */ + if (idx < N) + bitmap[idx] &= ~(((u_int64_t)1) << offset); + } + + bool isSetBit(u_int16_t id) const { + size_t idx = id >> 6; + u_int8_t offset = id & 0x3F; + if (idx < N) + return (((bitmap[idx] >> offset) & 1) ? true : false); + return false; + } + + /* Return the first bit set, starting from start */ + int getNext(u_int16_t start) { + size_t start_idx = start >> 6; + u_int8_t start_offset = start & 0x3F; + + for (size_t i = start_idx; i < N; i++) { + int bit = Utils::bitmapGetNext(bitmap[i], (i == start_idx) ? start_offset : 0); + if (bit >= 0) { + return (i << 6) + bit; + } + } + + return -1; + } + + void bitmapOr(const Bitmap b) { + for (size_t i = 0; i < N; i++) { + bitmap[i] |= b.bitmap[i]; + } + } + + void set(const Bitmap *b) { + memcpy(bitmap, b->bitmap, sizeof(bitmap)); + } + + bool equal(const Bitmap *b) const { + return (memcmp(bitmap, b->bitmap, sizeof(bitmap)) == 0); + } + + void lua(lua_State *vm, const char *label) const; + + const char *toHexString(char *buf, ssize_t buf_len) const { + char *ptr = buf; + ssize_t remaining = buf_len; + + /* Write hex values in reverse order (most significant first) */ + for (int i = N - 1; i >= 0; i--) { + int written = snprintf(ptr, remaining, "%016lX", (unsigned long)bitmap[i]); + if (written >= remaining) break; + ptr += written; + remaining -= written; + } + + /* Remove heading zeroes but keep HEX byte-aligned (SQLite doesn't like + * heading zeroes when inserting blob literals) */ + u_int shifts = 0; + for (u_int pos = 0; pos < strlen(buf) - 2; pos += 2) { + u_int8_t cur_byte = 0; + + sscanf(&buf[pos], "%02hhX", &cur_byte); + if (cur_byte > 0) break; + shifts += 2; + } + + if (shifts > 0) memmove(buf, &buf[shifts], buf_len - shifts); + + return buf; + } +}; + +#endif /* _BITMAP_H_ */ diff --git a/include/Bitmap128.h b/include/Bitmap128.h index 00550586aa..a9f8dfa19c 100644 --- a/include/Bitmap128.h +++ b/include/Bitmap128.h @@ -24,30 +24,7 @@ #include "ntop_includes.h" -class Bitmap128 { - private: - u_int64_t bitmap[2]; - - public: - Bitmap128() { reset(); } - Bitmap128(char *list) { - reset(); - setBits(list); - }; - - static inline u_int numBits() { return sizeof(bitmap) * 8; }; - void reset(); - void setBit(u_int8_t id); - void setBits(char *list); /* Parse a comma-separate list of bit positions */ - void clearBit(u_int8_t id); - bool isSetBit(u_int8_t id) const; - int getNext(u_int8_t start); - void bitmapOr(const Bitmap128 b); - void set(const Bitmap128 *b); - bool equal(const Bitmap128 *b) const; - - void lua(lua_State *vm, const char *label) const; - const char *toHexString(char *buf, ssize_t buf_len) const; -}; +/* Bitmap128 is now implemented as a generic Bitmap with 2x uint64 */ +typedef Bitmap<2> Bitmap128; #endif /* _BITMAP128_H_ */ diff --git a/include/Bitmap4096.h b/include/Bitmap4096.h new file mode 100644 index 0000000000..f134d191d9 --- /dev/null +++ b/include/Bitmap4096.h @@ -0,0 +1,30 @@ +/* + * + * (C) 2013-25 - ntop.org + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _BITMAP4096_H_ +#define _BITMAP4096_H_ + +#include "ntop_includes.h" + +/* Bitmap128 is implemented as a generic Bitmap with 64x uint64 */ +typedef Bitmap<64> Bitmap4096; + +#endif /* _BITMAP4096_H_ */ diff --git a/include/ntop_includes.h b/include/ntop_includes.h index d4425867b5..c708d6879d 100644 --- a/include/ntop_includes.h +++ b/include/ntop_includes.h @@ -249,7 +249,9 @@ using namespace std; #include "ProtoStats.h" #include "FlowRiskAlerts.h" #include "Utils.h" +#include "Bitmap.h" #include "Bitmap128.h" +#include "Bitmap4096.h" #include "NtopGlobals.h" #include "Alert.h" #include "AlertableEntity.h" diff --git a/src/Bitmap.cpp b/src/Bitmap.cpp new file mode 100644 index 0000000000..b09421bcf7 --- /dev/null +++ b/src/Bitmap.cpp @@ -0,0 +1,42 @@ +/* + * + * (C) 2013-25 - ntop.org + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "ntop_includes.h" + +template void Bitmap::lua(lua_State *vm, const char *label) const { + lua_newtable(vm); + + for (u_int i = 0; i < numBits(); i++) { + if (isSetBit(i)) { + lua_pushboolean(vm, true); /* The boolean indicating this bit is set */ + lua_pushinteger(vm, i); /* The integer bit id, used as key of this lua table */ + lua_insert(vm, -2); + lua_settable(vm, -3); + } + } + + lua_pushstring(vm, label); + lua_insert(vm, -2); + lua_settable(vm, -3); +} + +template class Bitmap<2>; // Bitmap128 +template class Bitmap<64>; // Bitmap4096 diff --git a/src/Bitmap128.cpp b/src/Bitmap128.cpp deleted file mode 100644 index 8037f13c71..0000000000 --- a/src/Bitmap128.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * - * (C) 2013-25 - ntop.org - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include "ntop_includes.h" - -/* ****************************************** */ - -void Bitmap128::reset() { memset(bitmap, 0, sizeof(bitmap)); } - -/* ****************************************** */ - -void Bitmap128::setBits(char *list) { - char *item, *tmp = NULL; - - item = strtok_r(list, ",", &tmp); - - while (item) { - int id = atoi(item); - setBit(id); - item = strtok_r(NULL, ",", &tmp); - } -} - -/* ****************************************** */ - -void Bitmap128::setBit(u_int8_t id) { - if (id < 64) - bitmap[0] = Utils::bitmapSet(bitmap[0], id); - else if (id < numBits()) - bitmap[1] = Utils::bitmapSet(bitmap[1], id - 64); -} - -/* ****************************************** */ - -void Bitmap128::clearBit(u_int8_t id) { - if (id < 64) - bitmap[0] = Utils::bitmapClear(bitmap[0], id); - else if (id < numBits()) - bitmap[1] = Utils::bitmapClear(bitmap[1], id - 64); -} - -/* ****************************************** */ - -bool Bitmap128::isSetBit(u_int8_t id) const { - if (id < 64) - return (Utils::bitmapIsSet(bitmap[0], id)); - else if (id < numBits()) - return (Utils::bitmapIsSet(bitmap[1], id - 64)); - else - return (0); -} - -/* ****************************************** */ - -/* Return the first bit set, starting from start */ -int Bitmap128::getNext(u_int8_t start) { - int i = -1; - - if (start < 64) { - i = Utils::bitmapGetNext(bitmap[0], start); - if (i >= 0) return i; - i = Utils::bitmapGetNext(bitmap[1], 0); - if (i >= 0) return i + 64; - } else { - i = Utils::bitmapGetNext(bitmap[1], start - 64); - if (i >= 0) return i + 64; - } - - return i; -} - -/* ****************************************** */ - -void Bitmap128::bitmapOr(const Bitmap128 b) { - bitmap[0] |= b.bitmap[0], bitmap[1] |= b.bitmap[1]; -} - -/* ****************************************** */ - -void Bitmap128::set(const Bitmap128 *b) { - memcpy(bitmap, b->bitmap, sizeof(bitmap)); -} - -/* ****************************************** */ - -bool Bitmap128::equal(const Bitmap128 *b) const { - return ((memcmp(bitmap, b->bitmap, sizeof(bitmap)) == 0) ? true : false); -} - -/* ****************************************** */ - -void Bitmap128::lua(lua_State *vm, const char *label) const { - lua_newtable(vm); - - for (u_int i = 0; i < numBits(); i++) { - if (isSetBit(i)) { - lua_pushboolean(vm, true); /* The boolean indicating this risk is set */ - lua_pushinteger(vm, i); /* The integer risk id, used as key of this lua table */ - lua_insert(vm, -2); - lua_settable(vm, -3); - } - } - - lua_pushstring(vm, label); - lua_insert(vm, -2); - lua_settable(vm, -3); -} - -/* ****************************************** */ - -const char *Bitmap128::toHexString(char *buf, ssize_t buf_len) const { - u_int shifts = 0; - - snprintf(buf, buf_len, "%016lX%016lX", (unsigned long)bitmap[1], - (unsigned long)bitmap[0]); - - /* Remove heading zeroes but keep HEX byte-aligned (SQLite doesn't like - * heading zeroes when inserting blob literals) */ - for (u_int pos = 0; pos < strlen(buf) - 2; pos += 2) { - uint8_t cur_byte = 0; - - sscanf(&buf[pos], "%02hhX", &cur_byte); - if (cur_byte > 0) break; - shifts += 2; - } - - if (shifts > 0) memmove(buf, &buf[shifts], buf_len - shifts); - - return buf; -}