/src/ec_dissect.c

https://github.com/bonsaiviking/ettercap · C · 316 lines · 152 code · 68 blank · 96 comment · 27 complexity · 46683cb57b73da0c28f0232512968e5f MD5 · raw file

  1. /*
  2. ettercap -- dissector 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_dissect.h>
  18. #include <ec_packet.h>
  19. #include <ec_sslwrap.h>
  20. /* globals */
  21. static SLIST_HEAD (, dissect_entry) dissect_list;
  22. struct dissect_entry {
  23. char *name;
  24. u_int32 type;
  25. u_int8 level;
  26. FUNC_DECODER_PTR(decoder);
  27. SLIST_ENTRY (dissect_entry) next;
  28. };
  29. /* protos */
  30. void dissect_add(char *name, u_int8 level, u_int32 port, FUNC_DECODER_PTR(decoder));
  31. void dissect_del(char *name);
  32. int dissect_modify(int mode, char *name, u_int32 port);
  33. int dissect_match(void *id_sess, void *id_curr);
  34. void dissect_create_session(struct ec_session **s, struct packet_object *po, u_int32 code);
  35. size_t dissect_create_ident(void **i, struct packet_object *po, u_int32 code);
  36. void dissect_wipe_session(struct packet_object *po, u_int32 code);
  37. int dissect_on_port(char *name, u_int16 port);
  38. /*******************************************/
  39. /*
  40. * compare two session ident
  41. *
  42. * return 1 if it matches
  43. */
  44. int dissect_match(void *id_sess, void *id_curr)
  45. {
  46. struct dissect_ident *ids = id_sess;
  47. struct dissect_ident *id = id_curr;
  48. /* sanity check */
  49. BUG_IF(ids == NULL);
  50. BUG_IF(id == NULL);
  51. /*
  52. * is this ident from our level ?
  53. * check the magic !
  54. */
  55. if (ids->magic != id->magic)
  56. return 0;
  57. /* check the protocol */
  58. if (ids->L4_proto != id->L4_proto)
  59. return 0;
  60. /* from source to dest */
  61. if (ids->L4_src == id->L4_src &&
  62. ids->L4_dst == id->L4_dst &&
  63. !ip_addr_cmp(&ids->L3_src, &id->L3_src) &&
  64. !ip_addr_cmp(&ids->L3_dst, &id->L3_dst) )
  65. return 1;
  66. /* from dest to source */
  67. if (ids->L4_src == id->L4_dst &&
  68. ids->L4_dst == id->L4_src &&
  69. !ip_addr_cmp(&ids->L3_src, &id->L3_dst) &&
  70. !ip_addr_cmp(&ids->L3_dst, &id->L3_src) )
  71. return 1;
  72. return 0;
  73. }
  74. /*
  75. * prepare the ident and the pointer to match function
  76. * for a dissector.
  77. */
  78. void dissect_create_session(struct ec_session **s, struct packet_object *po, u_int32 code)
  79. {
  80. void *ident;
  81. DEBUG_MSG("dissect_create_session");
  82. /* allocate the session */
  83. SAFE_CALLOC(*s, 1, sizeof(struct ec_session));
  84. /* create the ident */
  85. (*s)->ident_len = dissect_create_ident(&ident, po, code);
  86. /* link to the session */
  87. (*s)->ident = ident;
  88. /* the matching function */
  89. (*s)->match = &dissect_match;
  90. }
  91. /*
  92. * create the ident for a session
  93. */
  94. size_t dissect_create_ident(void **i, struct packet_object *po, u_int32 code)
  95. {
  96. struct dissect_ident *ident;
  97. /* allocate the ident for that session */
  98. SAFE_CALLOC(ident, 1, sizeof(struct dissect_ident));
  99. /* the magic number (usually the pointer for the function) */
  100. ident->magic = code;
  101. /* prepare the ident */
  102. memcpy(&ident->L3_src, &po->L3.src, sizeof(struct ip_addr));
  103. memcpy(&ident->L3_dst, &po->L3.dst, sizeof(struct ip_addr));
  104. ident->L4_proto = po->L4.proto;
  105. ident->L4_src = po->L4.src;
  106. ident->L4_dst = po->L4.dst;
  107. /* return the ident */
  108. *i = ident;
  109. /* return the length of the ident */
  110. return sizeof(struct dissect_ident);
  111. }
  112. /*
  113. * totally destroy the session bound to this connection
  114. */
  115. void dissect_wipe_session(struct packet_object *po, u_int32 code)
  116. {
  117. void *ident;
  118. struct ec_session *s;
  119. DEBUG_MSG("dissect_wipe_session");
  120. /* create an ident to retrieve the session */
  121. dissect_create_ident(&ident, po, code);
  122. /* retrieve the session and delete it */
  123. if (session_get_and_del(&s, ident, DISSECT_IDENT_LEN) == -ENOTFOUND) {
  124. SAFE_FREE(ident);
  125. return;
  126. }
  127. /* free the session */
  128. session_free(s);
  129. SAFE_FREE(ident);
  130. }
  131. /*
  132. * register a dissector in the dissectors list
  133. * and add it to the decoder list.
  134. * this list is used by dissect_modify during the parsing
  135. * of etter.conf to enable/disable the dissectors via their name.
  136. */
  137. void dissect_add(char *name, u_int8 level, u_int32 port, FUNC_DECODER_PTR(decoder))
  138. {
  139. struct dissect_entry *e;
  140. SAFE_CALLOC(e, 1, sizeof(struct dissect_entry));
  141. e->name = strdup(name);
  142. e->level = level;
  143. e->type = port;
  144. e->decoder = decoder;
  145. SLIST_INSERT_HEAD (&dissect_list, e, next);
  146. /* add the default decoder */
  147. add_decoder(level, port, decoder);
  148. return;
  149. }
  150. /*
  151. * remove all istances of a dissector in the dissectors list
  152. */
  153. void dissect_del(char *name)
  154. {
  155. struct dissect_entry *e, *tmp = NULL;
  156. SLIST_FOREACH_SAFE(e, &dissect_list, next, tmp) {
  157. if (!strcasecmp(e->name, name)) {
  158. del_decoder(e->level, e->type);
  159. SLIST_REMOVE(&dissect_list, e, dissect_entry, next);
  160. SAFE_FREE(e);
  161. }
  162. }
  163. return;
  164. }
  165. /*
  166. * given the name of the dissector add or remove it
  167. * from the decoders' table.
  168. * is it possible to add multiple port with MODE_ADD
  169. */
  170. int dissect_modify(int mode, char *name, u_int32 port)
  171. {
  172. struct dissect_entry *e;
  173. int level;
  174. void *decoder;
  175. SLIST_FOREACH (e, &dissect_list, next) {
  176. if (!strcasecmp(e->name, name)) {
  177. switch (mode) {
  178. case MODE_ADD:
  179. DEBUG_MSG("dissect_modify: %s added on %lu", name, (unsigned long)port);
  180. /* add in the lists */
  181. dissect_add(e->name, e->level, port, e->decoder);
  182. return ESUCCESS;
  183. break;
  184. case MODE_REP:
  185. /* save them because the dissect_del may delete this values */
  186. level = e->level;
  187. decoder = e->decoder;
  188. /* remove all the previous istances */
  189. dissect_del(name);
  190. /* move the ssl wrapper (even if no wrapper) */
  191. sslw_dissect_move(name, port);
  192. /* a value of 0 will disable the dissector */
  193. if (port == 0) {
  194. DEBUG_MSG("dissect_modify: %s disabled", name);
  195. return ESUCCESS;
  196. }
  197. DEBUG_MSG("dissect_modify: %s replaced to %lu", name, (unsigned long)port);
  198. /* add the new value */
  199. dissect_add(name, level, port, decoder);
  200. return ESUCCESS;
  201. break;
  202. }
  203. }
  204. }
  205. return -ENOTFOUND;
  206. }
  207. /*
  208. * return ESUCCESS if the dissector is on
  209. * the specified port
  210. */
  211. int dissect_on_port(char *name, u_int16 port)
  212. {
  213. struct dissect_entry *e;
  214. /*
  215. * return ESUCCESS if at least one port is bound
  216. * to the dissector name
  217. */
  218. SLIST_FOREACH (e, &dissect_list, next) {
  219. if (!strcasecmp(e->name, name) && e->type == port) {
  220. return ESUCCESS;
  221. }
  222. }
  223. return -ENOTFOUND;
  224. }
  225. /*
  226. * return ESUCCESS if the dissector is on
  227. * the specified port of the specified protocol (TCP or UDP)
  228. */
  229. int dissect_on_port_level(char *name, u_int16 port, u_int8 level)
  230. {
  231. struct dissect_entry *e;
  232. /*
  233. * return ESUCCESS if at least one port is bound
  234. * to the dissector name
  235. */
  236. SLIST_FOREACH (e, &dissect_list, next) {
  237. if (!strcasecmp(e->name, name) && e->type == port && e->level == level) {
  238. return ESUCCESS;
  239. }
  240. }
  241. return -ENOTFOUND;
  242. }
  243. /* EOF */
  244. // vim:ts=3:expandtab