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.4KB

  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 <time.h>
  21. #include <pthread.h>
  22. #include <sys/socket.h>
  23. #include <netinet/in.h>
  24. #include <arpa/inet.h>
  25. #include <libnfnetlink/libnfnetlink.h>
  26. #include <libnetfilter_conntrack/libnetfilter_conntrack.h>
  27. #include "configfile.h"
  28. #include "logging.h"
  29. #include "hashtable.h"
  30. #define DEFAULT_HASHSIZE 127
  31. #define DEFAULT_NETMASK "255.255.255.255"
  32. static pthread_t ct_thread;
  33. static struct nfct_handle *cth;
  34. static struct hash_table *table[2];
  35. static int hash_select = 0;
  36. static struct in_addr netmask;
  37. static int conntrack_event_cb(void *arg, unsigned int flags, int type, void *privdata)
  38. {
  39. struct nfct_conntrack *ct = (struct nfct_conntrack *)arg;
  40. if (ct->tuple[NFCT_DIR_ORIGINAL].l3protonum != AF_INET)
  41. return 0;
  42. struct hash_entry *entry = malloc(sizeof(struct hash_entry));
  43. if (entry == NULL) {
  44. log_print(LOG_WARN, "conntrack_event_cb: out of memory");
  45. return -1;
  46. }
  47. entry->src_ip = (ct->tuple[NFCT_DIR_ORIGINAL].src.v4 & netmask.s_addr);
  48. entry->protonum = ct->tuple[NFCT_DIR_ORIGINAL].protonum;
  49. entry->dst_port = ct->tuple[NFCT_DIR_ORIGINAL].l4dst.tcp.port;
  50. entry->flags = ct->status & (IPS_EXPECTED || IPS_SEEN_REPLY || IPS_ASSURED || IPS_CONFIRMED);
  51. entry->src_bytes = ct->counters[NFCT_DIR_ORIGINAL].bytes;
  52. entry->dst_bytes = ct->counters[NFCT_DIR_REPLY].bytes;
  53. hash_add(table[hash_select], entry);
  54. return 0;
  55. }
  56. struct hash_table * conntrack_get_hash(void)
  57. {
  58. /*
  59. * switch hashtable
  60. * -> conntrack_event_cb will use the empty hash next time, and we dump now the full one
  61. * -> if conntrack_event_cb is running *now* (on the full hash), we have to wait a bit
  62. * -> but since we are faster than dump intervall, conntrack_event_cb never waits
  63. */
  64. int used_hash = hash_select;
  65. hash_select ^= 0x01;
  66. return table[used_hash];
  67. }
  68. int conntrack_init(void)
  69. {
  70. const char *mask = config_get_string("global", "netmask", DEFAULT_NETMASK);
  71. if (inet_aton(mask, &netmask) == 0) {
  72. log_print(LOG_ERROR, "conntrack_init: invalid netmask");
  73. return -1;
  74. }
  75. cth = nfct_open(CONNTRACK, NF_NETLINK_CONNTRACK_DESTROY);
  76. if (cth == NULL) {
  77. log_print(LOG_ERROR, "conntrack_init: nfct_open()");
  78. return -1;
  79. }
  80. int size = config_get_int("global", "hashsize", DEFAULT_HASHSIZE);
  81. table[0] = create_hash(size);
  82. if (table[0] == NULL) {
  83. log_print(LOG_ERROR, "conntrack_init: create_hash(0)");
  84. nfct_close(cth);
  85. return -1;
  86. }
  87. table[1] = create_hash(size);
  88. if (table[1] == NULL) {
  89. log_print(LOG_ERROR, "conntrack_init: create_hash(1)");
  90. destroy_hash(table[0]);
  91. nfct_close(cth);
  92. return -1;
  93. }
  94. nfct_register_callback(cth, conntrack_event_cb, NULL);
  95. return 0;
  96. }
  97. static int event_thread(void *arg)
  98. {
  99. nfct_event_conntrack(cth);
  100. return 0;
  101. }
  102. int conntrack_start_event_thread(void)
  103. {
  104. /* startup conntrack event listener */
  105. pthread_attr_t attr;
  106. pthread_attr_init(&attr);
  107. pthread_attr_setstacksize(&attr, 65536);
  108. pthread_create(&ct_thread, &attr, (void *)&event_thread, NULL);
  109. return 0;
  110. }
  111. int conntrack_close(void)
  112. {
  113. if (ct_thread)
  114. pthread_cancel(ct_thread);
  115. destroy_hash(table[1]);
  116. destroy_hash(table[0]);
  117. nfct_close(cth);
  118. return 0;
  119. }