bridge.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. /* $Id: bridge.c 2195 2009-02-04 21:17:45Z aturner $ */
  2. /*
  3. * Copyright (c) 2001-2005 Aaron Turner.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the names of the copyright owners nor the names of its
  16. * contributors may be used to endorse or promote products derived from
  17. * this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  20. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  23. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  25. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  27. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  28. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  29. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #include "config.h"
  32. #include "defines.h"
  33. #include "common.h"
  34. #include <sys/time.h>
  35. #include <signal.h>
  36. #include <string.h>
  37. #include <netinet/in.h>
  38. #include <time.h>
  39. #include <errno.h>
  40. #include <stdlib.h>
  41. #ifdef HAVE_BPF
  42. #include <sys/select.h> /* necessary for using select() for BPF devices */
  43. #endif
  44. #include "tcpbridge.h"
  45. #include "bridge.h"
  46. #include "send_packets.h"
  47. #include "tcpedit/tcpedit.h"
  48. extern tcpbridge_opt_t options;
  49. extern struct timeval begin, end;
  50. extern COUNTER bytes_sent, failed, pkts_sent;
  51. extern volatile int didsig;
  52. #ifdef DEBUG
  53. extern int debug;
  54. #endif
  55. static int live_callback(struct live_data_t *,
  56. struct pcap_pkthdr *, const u_char *);
  57. /**
  58. * First, prep our RB Tree which tracks where each (source)
  59. * MAC really lives so we don't create really nasty network
  60. * storms.
  61. */
  62. static struct macsrc_t *new_node(void);
  63. RB_HEAD(macsrc_tree, macsrc_t) macsrc_root;
  64. static int
  65. rbmacsrc_comp(struct macsrc_t *a, struct macsrc_t *b)
  66. {
  67. return (memcmp(a->key, b->key, ETHER_ADDR_LEN));
  68. }
  69. RB_PROTOTYPE(macsrc_tree, macsrc_t, node, rbmacsrc_comp)
  70. RB_GENERATE(macsrc_tree, macsrc_t, node, rbmacsrc_comp)
  71. /**
  72. * redblack init
  73. */
  74. void
  75. rbinit(void)
  76. {
  77. RB_INIT(&macsrc_root);
  78. }
  79. /**
  80. * create a new node... Malloc's memory
  81. */
  82. struct macsrc_t *
  83. new_node(void)
  84. {
  85. struct macsrc_t *node;
  86. node = (struct macsrc_t *)safe_malloc(sizeof(struct macsrc_t));
  87. memset(node, '\0', sizeof(struct macsrc_t));
  88. return (node);
  89. }
  90. /**
  91. * main loop for bridging in only one direction
  92. * optimized to not use poll(), but rather libpcap's builtin pcap_loop()
  93. */
  94. static void
  95. do_bridge_unidirectional(tcpbridge_opt_t *options, tcpedit_t *tcpedit)
  96. {
  97. struct live_data_t livedata;
  98. int retcode;
  99. assert(options);
  100. assert(tcpedit);
  101. livedata.tcpedit = tcpedit;
  102. livedata.source = PCAP_INT1;
  103. livedata.pcap = options->pcap1;
  104. livedata.options = options;
  105. if ((retcode = pcap_loop(options->pcap1, options->limit_send,
  106. (pcap_handler)live_callback, (u_char *) &livedata)) < 0) {
  107. warnx("Error in pcap_loop(): %s", pcap_geterr(options->pcap1));
  108. }
  109. }
  110. #ifndef HAVE_BPF
  111. /**
  112. * main loop for bridging in both directions. Since we dealing with two handles
  113. * we need to poll() on them which isn't the most efficent.
  114. *
  115. * Note that this function is only used on systems which do not have a BPF
  116. * device because poll() behaves poorly with /dev/bpf
  117. */
  118. static void
  119. do_bridge_bidirectional(tcpbridge_opt_t *options, tcpedit_t *tcpedit)
  120. {
  121. struct pollfd polls[2]; /* one for left & right pcap */
  122. int pollresult, pollcount, timeout;
  123. struct live_data_t livedata;
  124. assert(options);
  125. assert(tcpedit);
  126. livedata.tcpedit = tcpedit;
  127. livedata.options = options;
  128. /*
  129. * loop until ctrl-C or we've sent enough packets
  130. * note that if -L wasn't specified, limit_send is
  131. * set to 0 so this will loop infinately
  132. */
  133. while ((options->limit_send == 0) || (options->limit_send > pkts_sent)) {
  134. if (didsig)
  135. break;
  136. dbgx(3, "limit_send: " COUNTER_SPEC " \t pkts_sent: " COUNTER_SPEC,
  137. options->limit_send, pkts_sent);
  138. /* reset the result codes */
  139. polls[PCAP_INT1].revents = 0;
  140. polls[PCAP_INT1].events = POLLIN;
  141. polls[PCAP_INT1].fd = pcap_fileno(options->pcap1);
  142. polls[PCAP_INT2].revents = 0;
  143. polls[PCAP_INT2].events = POLLIN;
  144. polls[PCAP_INT2].fd = pcap_fileno(options->pcap2);
  145. timeout = options->poll_timeout;
  146. pollcount = 2;
  147. /* poll for a packet on the two interfaces */
  148. pollresult = poll(polls, pollcount, timeout);
  149. /* poll has returned, process the result */
  150. if (pollresult > 0) {
  151. dbgx(3, "pollresult: %d", pollresult);
  152. /* success, got one or more packets */
  153. if (polls[PCAP_INT1].revents > 0) {
  154. dbg(5, "Processing first interface");
  155. livedata.source = PCAP_INT1;
  156. livedata.pcap = options->pcap1;
  157. pcap_dispatch(options->pcap1, -1, (pcap_handler) live_callback,
  158. (u_char *) &livedata);
  159. }
  160. /* check the other interface?? */
  161. if (polls[PCAP_INT2].revents > 0) {
  162. dbg(5, "Processing second interface");
  163. livedata.source = PCAP_INT2;
  164. livedata.pcap = options->pcap2;
  165. pcap_dispatch(options->pcap2, -1, (pcap_handler) live_callback,
  166. (u_char *) &livedata);
  167. }
  168. }
  169. else if (pollresult == 0) {
  170. dbg(3, "poll timeout exceeded...");
  171. /* do something here? */
  172. }
  173. else {
  174. /* poll error, probably a Ctrl-C */
  175. warnx("poll() error: %s", strerror(errno));
  176. }
  177. /* go back to the top of the loop */
  178. }
  179. } /* do_bridge_bidirectional() */
  180. #elif defined HAVE_BPF && defined HAVE_PCAP_SETNONBLOCK
  181. /**
  182. * main loop for bridging in both directions with BPF. We'll be using
  183. * select() because that works better on older *BSD and OSX
  184. *
  185. * See this for details behind this maddness:
  186. * http://article.gmane.org/gmane.network.tcpdump.devel/3581
  187. */
  188. static void
  189. do_bridge_bidirectional(tcpbridge_opt_t *options, tcpedit_t *tcpedit)
  190. {
  191. fd_set readfds, writefds, errorfds;
  192. struct live_data_t livedata;
  193. int fd, nfds, ret;
  194. struct timeval timeout = { 0, 100 }; /* default to 100ms timeout */
  195. char ebuf[PCAP_ERRBUF_SIZE];
  196. assert(options);
  197. assert(tcpedit);
  198. livedata.tcpedit = tcpedit;
  199. livedata.options = options;
  200. /*
  201. * loop until ctrl-C or we've sent enough packets
  202. * note that if -L wasn't specified, limit_send is
  203. * set to 0 so this will loop infinately
  204. */
  205. while ((options->limit_send == 0) || (options->limit_send > pkts_sent)) {
  206. if (didsig)
  207. break;
  208. dbgx(3, "limit_send: " COUNTER_SPEC " \t pkts_sent: " COUNTER_SPEC,
  209. options->limit_send, pkts_sent);
  210. /* reset the result codes */
  211. FD_ZERO(&readfds);
  212. FD_ZERO(&writefds);
  213. FD_ZERO(&errorfds);
  214. /* set for reading */
  215. #ifdef HAVE_PCAP_GET_SELECTABLE_FD
  216. fd = pcap_get_selectable_fd(options->pcap1);
  217. #else
  218. fd = pcap_fileno(options->pcap1);
  219. #endif
  220. if ((pcap_setnonblock(options->pcap1, 1, ebuf)) < 0)
  221. errx(1, "Unable to set %s into nonblocking mode: %s", options->intf1, ebuf);
  222. FD_SET(fd, &readfds);
  223. #ifdef HAVE_PCAP_GET_SELECTABLE_FD
  224. fd = pcap_get_selectable_fd(options->pcap2);
  225. #else
  226. fd = pcap_fileno(options->pcap2);
  227. #endif
  228. if ((pcap_setnonblock(options->pcap2, 1, ebuf)) < 0)
  229. errx(1, "Unable to set %s into nonblocking mode: %s", options->intf2, ebuf);
  230. FD_SET(fd, &readfds);
  231. nfds = 2;
  232. /* wait for a packet on the two interfaces */
  233. ret = select(nfds, &readfds, &writefds, &errorfds, &timeout);
  234. /*
  235. * There is a problem with OS X and certian *BSD's when using
  236. * select() on a character device like /dev/bpf. Hence we always
  237. * must attempt to read off each fd after the timeout. This is why
  238. * we put the fd's in nonblocking mode above!
  239. */
  240. dbg(5, "Processing first interface");
  241. livedata.source = PCAP_INT1;
  242. livedata.pcap = options->pcap1;
  243. pcap_dispatch(options->pcap1, -1, (pcap_handler) live_callback,
  244. (u_char *) &livedata);
  245. dbg(5, "Processing second interface");
  246. livedata.source = PCAP_INT2;
  247. livedata.pcap = options->pcap2;
  248. pcap_dispatch(options->pcap2, -1, (pcap_handler) live_callback,
  249. (u_char *) &livedata);
  250. /* go back to the top of the loop */
  251. }
  252. }
  253. #else
  254. #error "Your system needs a libpcap with pcap_setnonblock(). Please upgrade libpcap."
  255. #endif
  256. /**
  257. * Main entry point to bridging. Does some initial setup and then calls the
  258. * correct loop (unidirectional or bidirectional)
  259. */
  260. void
  261. do_bridge(tcpbridge_opt_t *options, tcpedit_t *tcpedit)
  262. {
  263. /* do we apply a bpf filter? */
  264. if (options->bpf.filter != NULL) {
  265. /* compile filter */
  266. dbgx(2, "Try to compile pcap bpf filter: %s", options->bpf.filter);
  267. if (pcap_compile(options->pcap1, &options->bpf.program, options->bpf.filter, options->bpf.optimize, 0) != 0) {
  268. errx(-1, "Error compiling BPF filter: %s", pcap_geterr(options->pcap1));
  269. }
  270. /* apply filter */
  271. pcap_setfilter(options->pcap1, &options->bpf.program);
  272. /* same for other interface if applicable */
  273. if (options->unidir == 0) {
  274. /* compile filter */
  275. dbgx(2, "Try to compile pcap bpf filter: %s", options->bpf.filter);
  276. if (pcap_compile(options->pcap2, &options->bpf.program, options->bpf.filter, options->bpf.optimize, 0) != 0) {
  277. errx(-1, "Error compiling BPF filter: %s", pcap_geterr(options->pcap2));
  278. }
  279. /* apply filter */
  280. pcap_setfilter(options->pcap2, &options->bpf.program);
  281. }
  282. }
  283. /* register signals */
  284. didsig = 0;
  285. (void)signal(SIGINT, catcher);
  286. if (options->unidir == 1) {
  287. do_bridge_unidirectional(options, tcpedit);
  288. } else {
  289. do_bridge_bidirectional(options, tcpedit);
  290. }
  291. packet_stats(&begin, &end, bytes_sent, pkts_sent, failed);
  292. }
  293. /**
  294. * This is the callback we use with pcap_dispatch to process
  295. * each packet recieved by libpcap on the two interfaces.
  296. * Need to return > 0 to denote success
  297. */
  298. static int
  299. live_callback(struct live_data_t *livedata, struct pcap_pkthdr *pkthdr,
  300. const u_char * nextpkt)
  301. {
  302. ipv4_hdr_t *ip_hdr = NULL;
  303. pcap_t *send = NULL;
  304. static u_char *pktdata = NULL; /* full packet buffer */
  305. int cache_mode, retcode;
  306. static unsigned long packetnum = 0;
  307. struct macsrc_t *node, finder; /* rb tree nodes */
  308. #ifdef DEBUG
  309. u_char dstmac[ETHER_ADDR_LEN];
  310. #endif
  311. u_int16_t l2proto;
  312. packetnum++;
  313. dbgx(2, "packet %lu caplen %d", packetnum, pkthdr->caplen);
  314. /* only malloc the first time */
  315. if (pktdata == NULL) {
  316. /* create packet buffers */
  317. pktdata = (u_char *)safe_malloc(MAXPACKET);
  318. } else {
  319. /* zero out the old packet info */
  320. memset(pktdata, '\0', MAXPACKET);
  321. }
  322. /* copy the packet to our buffer */
  323. memcpy(pktdata, nextpkt, pkthdr->caplen);
  324. #ifdef ENABLE_VERBOSE
  325. /* decode packet? */
  326. if (livedata->options->verbose)
  327. tcpdump_print(livedata->options->tcpdump, pkthdr, nextpkt);
  328. #endif
  329. /* lookup our source MAC in the tree */
  330. memcpy(&finder.key, &pktdata[ETHER_ADDR_LEN], ETHER_ADDR_LEN);
  331. #ifdef DEBUG
  332. memcpy(&dstmac, pktdata, ETHER_ADDR_LEN);
  333. dbgx(1, "SRC MAC: " MAC_FORMAT "\tDST MAC: " MAC_FORMAT,
  334. MAC_STR(finder.key), MAC_STR(dstmac));
  335. #endif
  336. /* first, is this a packet sent locally? If so, ignore it */
  337. if ((memcmp(livedata->options->intf1_mac, &finder.key, ETHER_ADDR_LEN)) == 0) {
  338. dbgx(1, "Packet matches the MAC of %s, skipping.", livedata->options->intf1);
  339. return (1);
  340. }
  341. else if ((memcmp(livedata->options->intf2_mac, &finder.key, ETHER_ADDR_LEN)) == 0) {
  342. dbgx(1, "Packet matches the MAC of %s, skipping.", livedata->options->intf2);
  343. return (1);
  344. }
  345. node = RB_FIND(macsrc_tree, &macsrc_root, &finder);
  346. /* if we can't find the node, build a new one */
  347. if (node == NULL) {
  348. dbg(1, "Unable to find MAC in the tree");
  349. node = new_node();
  350. node->source = livedata->source;
  351. memcpy(&node->key, &finder.key, ETHER_ADDR_LEN);
  352. RB_INSERT(macsrc_tree, &macsrc_root, node);
  353. }
  354. /* otherwise compare sources */
  355. else if (node->source != livedata->source) {
  356. dbg(1, "Found the dest MAC in the tree and it doesn't match this source NIC... skipping packet");
  357. /*
  358. * IMPORTANT!!!
  359. * Never send a packet out the same interface we sourced it on!
  360. */
  361. return (1);
  362. }
  363. /* what is our cache mode? */
  364. cache_mode = livedata->source == PCAP_INT1 ? TCPR_DIR_C2S : TCPR_DIR_S2C;
  365. l2proto = tcpedit_l3proto(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len);
  366. dbgx(2, "Packet protocol: %04hx", l2proto);
  367. /* should we skip this packet based on CIDR match? */
  368. if (l2proto == ETHERTYPE_IP) {
  369. dbg(3, "Packet is IP");
  370. ip_hdr = (ipv4_hdr_t *)tcpedit_l3data(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len);
  371. /* look for include or exclude CIDR match */
  372. if (livedata->options->xX.cidr != NULL) {
  373. if (!process_xX_by_cidr(livedata->options->xX.mode, livedata->options->xX.cidr, ip_hdr)) {
  374. dbg(2, "Skipping packet due to CIDR match");
  375. return (1);
  376. }
  377. }
  378. }
  379. if ((retcode = tcpedit_packet(livedata->tcpedit, &pkthdr, &pktdata, cache_mode)) < 0) {
  380. if (retcode == TCPEDIT_SOFT_ERROR) {
  381. return 1;
  382. } else { /* TCPEDIT_ERROR */
  383. return -1;
  384. }
  385. }
  386. /*
  387. * send packets out the OTHER interface
  388. * and update the dst mac if necessary
  389. */
  390. switch(node->source) {
  391. case PCAP_INT1:
  392. dbgx(2, "Packet source was %s... sending out on %s", livedata->options->intf1,
  393. livedata->options->intf2);
  394. send = livedata->options->pcap2;
  395. break;
  396. case PCAP_INT2:
  397. dbgx(2, "Packet source was %s... sending out on %s", livedata->options->intf2,
  398. livedata->options->intf1);
  399. send = livedata->options->pcap1;
  400. break;
  401. default:
  402. errx(-1, "wtf? our node->source != PCAP_INT1 and != PCAP_INT2: %c",
  403. node->source);
  404. }
  405. /*
  406. * write packet out on the network
  407. */
  408. if (pcap_sendpacket(send, pktdata, pkthdr->caplen) < 0)
  409. errx(-1, "Unable to send packet out %s: %s",
  410. send == livedata->options->pcap1 ? livedata->options->intf1 : livedata->options->intf2, pcap_geterr(send));
  411. bytes_sent += pkthdr->caplen;
  412. pkts_sent++;
  413. dbgx(1, "Sent packet " COUNTER_SPEC, pkts_sent);
  414. return (1);
  415. } /* live_callback() */