linux 2.6 conntrack stats
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
4.1KB

  1. /***************************************************************************
  2. * Copyright (C) 07/2007 by Olaf Rempel *
  3. * razzor@kopf-tisch.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; version 2 of the License *
  8. * *
  9. * This program is distributed in the hope that it will be useful, *
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  12. * GNU General Public License for more details. *
  13. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. ***************************************************************************/
  19. #include <stdlib.h>
  20. #include <inttypes.h>
  21. #include <pthread.h>
  22. #include "hashtable.h"
  23. /* see linux/include/linux/jhash.h for details */
  24. #define JHASH_GOLDEN_RATIO 0x9e3779b9
  25. #define __jhash_mix(a, b, c) \
  26. { \
  27. a -= b; a -= c; a ^= (c>>13); \
  28. b -= c; b -= a; b ^= (a<<8); \
  29. c -= a; c -= b; c ^= (b>>13); \
  30. a -= b; a -= c; a ^= (c>>12); \
  31. b -= c; b -= a; b ^= (a<<16); \
  32. c -= a; c -= b; c ^= (b>>5); \
  33. a -= b; a -= c; a ^= (c>>3); \
  34. b -= c; b -= a; b ^= (a<<10); \
  35. c -= a; c -= b; c ^= (b>>15); \
  36. }
  37. struct hash_table * create_hash(uint32_t buckets)
  38. {
  39. struct hash_table *table;
  40. uint32_t i;
  41. table = malloc(sizeof(struct hash_table) +
  42. (sizeof(struct hash_entry *) * buckets));
  43. if (table == NULL)
  44. return NULL;
  45. for (i = 0; i < buckets; i++)
  46. table->bucket[i] = NULL;
  47. table->buckets = buckets;
  48. table->hash_rnd = time(NULL);
  49. pthread_mutex_init(&table->mutex, NULL);
  50. return table;
  51. }
  52. void purge_hash(struct hash_table *table,
  53. void (*callback)(const struct hash_entry *entry, void *privdata),
  54. void *privdata)
  55. {
  56. uint32_t i;
  57. pthread_mutex_lock(&table->mutex);
  58. for (i = 0; i < table->buckets; i++) {
  59. struct hash_entry *entry = table->bucket[i];
  60. while (entry != NULL) {
  61. struct hash_entry *tmp = entry;
  62. if (callback != NULL)
  63. callback(entry, privdata);
  64. entry = entry->next;
  65. free(tmp);
  66. }
  67. table->bucket[i] = NULL;
  68. }
  69. table->hash_rnd = time(NULL);
  70. pthread_mutex_unlock(&table->mutex);
  71. }
  72. void destroy_hash(struct hash_table *table)
  73. {
  74. purge_hash(table, NULL, NULL);
  75. pthread_mutex_destroy(&table->mutex);
  76. free(table);
  77. }
  78. static uint32_t calc_hashkey(const struct hash_entry *entry, uint32_t initval)
  79. {
  80. uint32_t a = entry->src_ip;
  81. uint32_t b = (entry->flags << 8) | entry->protonum;
  82. uint32_t c = entry->dst_port;
  83. a += JHASH_GOLDEN_RATIO;
  84. b += JHASH_GOLDEN_RATIO;
  85. c += initval;
  86. __jhash_mix(a, b, c);
  87. return c;
  88. }
  89. static int cmp_entry(const struct hash_entry *a, const struct hash_entry *b)
  90. {
  91. return (a->src_ip ^ b->src_ip) |
  92. (a->protonum ^ b->protonum) |
  93. (a->dst_port ^ b->dst_port) |
  94. (a->flags ^ b->flags);
  95. }
  96. void hash_add(struct hash_table *table, struct hash_entry *entry)
  97. {
  98. uint32_t key = calc_hashkey(entry, table->hash_rnd) % table->buckets;
  99. pthread_mutex_lock(&table->mutex);
  100. struct hash_entry *search = table->bucket[key];
  101. /* search collision-list */
  102. while (search != NULL) {
  103. if (cmp_entry(entry, search) == 0) {
  104. /* add values */
  105. search->src_bytes += entry->src_bytes;
  106. search->dst_bytes += entry->dst_bytes;
  107. search->count++;
  108. pthread_mutex_unlock(&table->mutex);
  109. /* free entry */
  110. free(entry);
  111. return;
  112. }
  113. search = search->next;
  114. }
  115. /* insert new bucket */
  116. entry->count = 1;
  117. entry->next = table->bucket[key];
  118. table->bucket[key] = entry;
  119. pthread_mutex_unlock(&table->mutex);
  120. }