/src/ec_dispatcher.c

https://github.com/bonsaiviking/ettercap · C · 175 lines · 69 code · 42 blank · 64 comment · 10 complexity · 3dafec35f0a935bba50eaac5735e03ca MD5 · raw file

  1. /*
  2. ettercap -- top half and dispatching module
  3. Copyright (C) ALoR & NaGA
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #include <ec.h>
  17. #include <ec_threads.h>
  18. #include <ec_hook.h>
  19. #include <ec_stats.h>
  20. /* this is the PO queue from bottom to top half */
  21. struct po_queue_entry {
  22. struct packet_object *po;
  23. STAILQ_ENTRY(po_queue_entry) next;
  24. };
  25. static STAILQ_HEAD(, po_queue_entry) po_queue = STAILQ_HEAD_INITIALIZER(po_queue);
  26. /* global mutex on interface */
  27. static pthread_mutex_t po_mutex = PTHREAD_MUTEX_INITIALIZER;
  28. #define PO_QUEUE_LOCK do{ pthread_mutex_lock(&po_mutex); }while(0)
  29. #define PO_QUEUE_UNLOCK do{ pthread_mutex_unlock(&po_mutex); }while(0)
  30. /* proto */
  31. void top_half_queue_add(struct packet_object *po);
  32. EC_THREAD_FUNC(top_half);
  33. /*******************************************/
  34. /*
  35. * top half function
  36. * it is the dispatcher for the various methods
  37. * which need to process packet objects
  38. * created by the bottom_half (capture).
  39. * it read the queue created by top_half_queue_add()
  40. * and deliver the po to all the registered functions
  41. */
  42. EC_THREAD_FUNC(top_half)
  43. {
  44. struct po_queue_entry *e;
  45. u_int pck_len;
  46. /* initialize the thread */
  47. ec_thread_init();
  48. DEBUG_MSG("top_half activated !");
  49. /*
  50. * we don't want profiles in memory.
  51. * remove the hooks and return
  52. */
  53. if (!GBL_CONF->store_profiles) {
  54. DEBUG_MSG("top_half: profile collection disabled");
  55. hook_del(HOOK_PACKET_ARP, &profile_parse);
  56. hook_del(HOOK_PACKET_ICMP, &profile_parse);
  57. hook_del(HOOK_PROTO_DHCP_PROFILE, &profile_parse);
  58. hook_del(HOOK_DISPATCHER, &profile_parse);
  59. }
  60. LOOP {
  61. CANCELLATION_POINT();
  62. /* the queue is updated by other thread, lock it */
  63. PO_QUEUE_LOCK;
  64. /* get the first element */
  65. e = STAILQ_FIRST(&po_queue);
  66. /* the queue is empty, nothing to do... */
  67. if (e == NULL) {
  68. PO_QUEUE_UNLOCK;
  69. usleep(1000);
  70. continue;
  71. }
  72. /* start the counter for the TopHalf */
  73. stats_half_start(&GBL_STATS->th);
  74. /* remove the packet form the queue */
  75. STAILQ_REMOVE_HEAD(&po_queue, e, next);
  76. /* update the queue stats */
  77. stats_queue_del();
  78. /*
  79. * we have extracted the element, unlock the queue
  80. *
  81. * the bottom half MUST be very fast and it cannot
  82. * wait on the top half lock.
  83. */
  84. PO_QUEUE_UNLOCK;
  85. /*
  86. * check if it is the last packet of a file...
  87. * and exit if we are in text only or demonize mode
  88. */
  89. if (e->po->flags & PO_EOF) {
  90. DEBUG_MSG("End of dump file...");
  91. USER_MSG("\nEnd of dump file...\n");
  92. if ((GBL_UI->type == UI_TEXT || GBL_UI->type == UI_DAEMONIZE) && GBL_CONF->close_on_eof)
  93. clean_exit(0);
  94. else {
  95. SAFE_FREE(e);
  96. continue;
  97. }
  98. }
  99. /* HOOK_POINT: DISPATCHER */
  100. hook_point(HOOK_DISPATCHER, e->po);
  101. /* save the len before the free() */
  102. pck_len = e->po->DATA.disp_len;
  103. /* destroy the duplicate packet object */
  104. packet_destroy_object(e->po);
  105. SAFE_FREE(e->po);
  106. SAFE_FREE(e);
  107. /* start the counter for the TopHalf */
  108. stats_half_end(&GBL_STATS->th, pck_len);
  109. }
  110. return NULL;
  111. }
  112. /*
  113. * add a packet to the top half queue.
  114. * this fuction is called by the bottom half thread
  115. */
  116. void top_half_queue_add(struct packet_object *po)
  117. {
  118. struct po_queue_entry *e;
  119. SAFE_CALLOC(e, 1, sizeof(struct po_queue_entry));
  120. e->po = packet_dup(po, PO_DUP_NONE);
  121. PO_QUEUE_LOCK;
  122. /* add the message to the queue */
  123. STAILQ_INSERT_TAIL(&po_queue, e, next);
  124. /* update the stats */
  125. stats_queue_add();
  126. PO_QUEUE_UNLOCK;
  127. }
  128. /* EOF */
  129. // vim:ts=3:expandtab