tcpreplay.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291
  1. /* $Id: tcpreplay.c 884 2004-11-08 17:04:47Z aturner $ */
  2. /*
  3. * Copyright (c) 2001-2004 Aaron Turner, Matt Bing.
  4. * All rights reserved.
  5. *
  6. * Copyright (c) 1999 Anzen Computing. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. All advertising materials mentioning features or use of this software
  18. * must display the following acknowledgement:
  19. * This product includes software developed by Anzen Computing, Inc.
  20. * 4. Neither the names of the copyright owners nor the names of its
  21. * contributors may be used to endorse or promote products derived from
  22. * this software without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  25. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  26. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  27. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  28. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  30. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  31. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  32. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  33. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  34. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. */
  36. #include "config.h"
  37. #include <ctype.h>
  38. #include <fcntl.h>
  39. #include <libnet.h>
  40. #ifdef HAVE_PCAPNAV
  41. #include <pcapnav.h>
  42. #else
  43. #include "fakepcapnav.h"
  44. #endif
  45. #include <pcap.h>
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include <sys/types.h>
  50. #include <unistd.h>
  51. #include "tcpreplay.h"
  52. #include "tcpdump.h"
  53. #include "cache.h"
  54. #include "cidr.h"
  55. #include "portmap.h"
  56. #include "list.h"
  57. #include "err.h"
  58. #include "do_packets.h"
  59. #include "xX.h"
  60. #include "signal_handler.h"
  61. #include "replay_live.h"
  62. #include "utils.h"
  63. #include "edit_packet.h"
  64. #include "fakepcap.h"
  65. struct options options;
  66. char *cachedata = NULL;
  67. CIDR *cidrdata = NULL;
  68. CIDRMAP *cidrmap_data1 = NULL, *cidrmap_data2 = NULL;
  69. PORTMAP *portmap_data = NULL;
  70. struct timeval begin, end;
  71. u_int64_t bytes_sent, failed, pkts_sent;
  72. char *cache_file = NULL, *intf = NULL, *intf2 = NULL;
  73. int cache_bit, cache_byte;
  74. u_int64_t cache_packets;
  75. volatile int didsig;
  76. struct bpf_program bpf;
  77. int include_exclude_mode = 0;
  78. CIDR *xX_cidr = NULL;
  79. LIST *xX_list = NULL;
  80. char l2data[L2DATALEN] = "";
  81. int l2len = LIBNET_ETH_H;
  82. int maxpacket = 0;
  83. /* we get this from libpcap */
  84. extern char pcap_version[];
  85. #ifdef HAVE_TCPDUMP
  86. /* tcpdump handle */
  87. tcpdump_t tcpdump;
  88. #endif
  89. #ifdef DEBUG
  90. int debug = 0;
  91. #endif
  92. void replay_file(char *path, int l2enabled, char *l2data, int l2len);
  93. void replay_live(char *iface, int l2enabled, char *l2data, int l2len);
  94. void validate_l2(char *name, int l2enabled, char *l2data, int l2len, int linktype);
  95. void usage(void);
  96. void version(void);
  97. void configfile(char *file);
  98. void init(void);
  99. void apply_filter(pcap_t *pcap);
  100. int
  101. main(int argc, char *argv[])
  102. {
  103. char ebuf[256];
  104. int ch, i, nat_interface = 0;
  105. int l2enabled = 0;
  106. void *xX = NULL;
  107. char errbuf[PCAP_ERRBUF_SIZE];
  108. init(); /* init our globals */
  109. while ((ch =
  110. getopt(argc, argv,
  111. "bc:C:De:f:Fhi:I:j:J:k:K:l:L:m:MnN:o:Op:Pr:Rs:S:t:Tu:Vw:W:x:X:12:4:"
  112. #ifdef HAVE_TCPDUMP
  113. "vA:"
  114. #endif
  115. #ifdef DEBUG
  116. "d:"
  117. #endif
  118. )) != -1)
  119. switch (ch) {
  120. case 'b': /* sniff/send bi-directionally */
  121. options.sniff_bridge = 1;
  122. options.topspeed = 1;
  123. break;
  124. case 'c': /* cache file */
  125. cache_file = optarg;
  126. cache_packets = read_cache(&cachedata, cache_file);
  127. break;
  128. case 'C': /* cidr matching */
  129. options.cidr = 1;
  130. if (!parse_cidr(&cidrdata, optarg, ","))
  131. errx(1, "Unable to parse -C");
  132. break;
  133. #ifdef DEBUG
  134. case 'd': /* enable debug */
  135. debug = atoi(optarg);
  136. break;
  137. #endif
  138. case 'D': /* dump only data (no headers) to file (-w/-W) */
  139. options.datadump_mode = 1;
  140. options.topspeed = 1;
  141. break;
  142. case 'e': /* rewrite IP's to two end points */
  143. options.rewriteip ++;
  144. if (!parse_endpoints(&cidrmap_data1, &cidrmap_data2, optarg))
  145. errx(1, "Unable to parse -e");
  146. break;
  147. case 'f': /* config file */
  148. configfile(optarg);
  149. break;
  150. case 'F': /* force fixing checksums */
  151. options.fixchecksums = 1;
  152. break;
  153. case 'i': /* interface */
  154. intf = optarg;
  155. break;
  156. case 'I': /* primary dest mac */
  157. mac2hex(optarg, options.intf1_mac, sizeof(options.intf1_mac));
  158. if (memcmp(options.intf1_mac, NULL_MAC, LIBNET_ETH_H) == 0)
  159. errx(1, "Invalid mac address: %s", optarg);
  160. break;
  161. case 'j': /* secondary interface */
  162. intf2 = optarg;
  163. break;
  164. case 'J': /* secondary dest mac */
  165. mac2hex(optarg, options.intf2_mac, sizeof(options.intf2_mac));
  166. if (memcmp(options.intf2_mac, NULL_MAC, LIBNET_ETH_H) == 0)
  167. errx(1, "Invalid mac address: %s", optarg);
  168. break;
  169. case 'k': /* primary source mac */
  170. mac2hex(optarg, options.intf1_smac, sizeof(options.intf1_smac));
  171. if (memcmp(options.intf1_smac, NULL_MAC, LIBNET_ETH_H) == 0)
  172. errx(1, "Invalid mac address: %s", optarg);
  173. break;
  174. case 'K': /* secondary source mac */
  175. mac2hex(optarg, options.intf2_smac, sizeof(options.intf2_smac));
  176. if (memcmp(options.intf2_smac, NULL_MAC, LIBNET_ETH_H) == 0)
  177. errx(1, "Invalid mac address: %s", optarg);
  178. break;
  179. case 'l': /* loop count */
  180. options.n_iter = atoi(optarg);
  181. if (options.n_iter < 0)
  182. errx(1, "Invalid loop count: %s", optarg);
  183. break;
  184. case 'L': /* limit sending X packets */
  185. options.limit_send = strtoull(optarg, NULL, 0);
  186. if (options.limit_send <= 0)
  187. errx(1, "-L <limit> must be positive");
  188. break;
  189. case 'm': /* multiplier */
  190. options.mult = atof(optarg);
  191. if (options.mult <= 0)
  192. errx(1, "Invalid multiplier: %s", optarg);
  193. options.rate = 0.0;
  194. options.packetrate = 0.0;
  195. options.one_at_a_time = 0;
  196. options.topspeed = 0;
  197. break;
  198. case 'M': /* disable sending martians */
  199. options.no_martians = 1;
  200. break;
  201. case 'n': /* don't be nosy, non-promisc mode */
  202. options.promisc = 0;
  203. break;
  204. case 'N': /* rewrite IP addresses using our pseudo-nat */
  205. options.rewriteip ++;
  206. nat_interface ++;
  207. /* first -N is primary nic */
  208. if (nat_interface == 1) {
  209. if (! parse_cidr_map(&cidrmap_data1, optarg))
  210. errx(1, "Invalid primary NAT string");
  211. } else { /* after that, secondary nic */
  212. if (! parse_cidr_map(&cidrmap_data2, optarg))
  213. errx(1, "Invalid secondary NAT string");
  214. }
  215. break;
  216. case 'o': /* starting offset */
  217. #ifdef HAVE_PCAPNAV
  218. options.offset = strtoull(optarg, NULL, 0);
  219. #else
  220. errx(1,
  221. "tcpreplay was not compiled with libpcapnav. Unable to use -o");
  222. #endif
  223. break;
  224. case 'O': /* One interface/file */
  225. options.one_output = 1;
  226. break;
  227. case 'p': /* packets/sec */
  228. options.packetrate = atof(optarg);
  229. if (options.packetrate <= 0)
  230. errx(1, "Invalid packetrate value: %s", optarg);
  231. options.rate = 0.0;
  232. options.mult = 0.0;
  233. options.one_at_a_time = 0;
  234. options.topspeed = 0;
  235. break;
  236. case 'P': /* print our PID */
  237. fprintf(stderr, "PID: %hu\n", getpid());
  238. break;
  239. case 'r': /* target rate */
  240. options.rate = atof(optarg);
  241. if (options.rate <= 0)
  242. errx(1, "Invalid rate: %s", optarg);
  243. /* convert to bytes */
  244. options.rate = (options.rate * (1024 * 1024)) / 8;
  245. options.mult = 0.0;
  246. options.packetrate = 0.0;
  247. options.one_at_a_time = 0;
  248. options.topspeed = 0;
  249. break;
  250. case 'R': /* replay at top speed */
  251. options.topspeed = 1;
  252. options.mult = 0.0;
  253. options.rate = 0.0;
  254. options.one_at_a_time = 0;
  255. options.packetrate = 0.0;
  256. break;
  257. case 's':
  258. options.seed = atoi(optarg);
  259. break;
  260. case 'S': /* enable live replay mode w/ snaplen */
  261. options.sniff_snaplen = atoi(optarg);
  262. if ((options.sniff_snaplen < 0) || (options.sniff_snaplen > MAX_SNAPLEN)) {
  263. errx(1, "Invalid snaplen: %d", options.sniff_snaplen);
  264. }
  265. else if (options.sniff_snaplen == 0) {
  266. options.sniff_snaplen = MAX_SNAPLEN;
  267. }
  268. break;
  269. case 't': /* MTU */
  270. options.mtu = atoi(optarg);
  271. break;
  272. case 'T': /* Truncate frames > MTU */
  273. options.truncate = 1;
  274. break;
  275. case 'w': /* write packets to file */
  276. if (!options.datadump_mode) {
  277. if ((options.savepcap =
  278. pcap_open_dead(DLT_EN10MB, 0xffff)) == NULL)
  279. errx(1, "error setting primary output file linktype");
  280. if ((options.savedumper =
  281. pcap_dump_open(options.savepcap, optarg)) == NULL)
  282. errx(1, "pcap_dump_open() error: %s",
  283. pcap_geterr(options.savepcap));
  284. warnx("saving primary packets in %s", optarg);
  285. }
  286. else {
  287. if ((options.datadumpfile =
  288. creat(optarg,
  289. S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
  290. errx(1, "error creating primary output file: %s\n%s",
  291. optarg, strerror(errno));
  292. warnx("saving primary data in %s", optarg);
  293. }
  294. break;
  295. case 'W': /* write packets to second file */
  296. /* don't bother opening a second file in one_output mode */
  297. if (options.one_output)
  298. break;
  299. if (!options.datadump_mode) {
  300. if ((options.savepcap2 =
  301. pcap_open_dead(DLT_EN10MB, 0xffff)) == NULL)
  302. errx(1, "error setting secondary output file linktype");
  303. if ((options.savedumper2 =
  304. pcap_dump_open(options.savepcap2, optarg)) == NULL)
  305. errx(1, "pcap_dump_open() error: %s",
  306. pcap_geterr(options.savepcap2));
  307. warnx("saving secondary packets in %s", optarg);
  308. }
  309. else {
  310. if ((options.datadumpfile2 =
  311. creat(optarg,
  312. S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
  313. errx(1, "error creating secondary output file: %s\n%s",
  314. optarg, strerror(errno));
  315. warnx("saving secondary data in %s", optarg);
  316. }
  317. break;
  318. case 'u': /* untruncate packet */
  319. if (strcmp("pad", optarg) == 0) {
  320. options.trunc = PAD_PACKET;
  321. }
  322. else if (strcmp("trunc", optarg) == 0) {
  323. options.trunc = TRUNC_PACKET;
  324. }
  325. else {
  326. errx(1, "Invalid untruncate option: %s", optarg);
  327. }
  328. options.fixchecksums = 0; /* untruncating already does this */
  329. break;
  330. #ifdef HAVE_TCPDUMP
  331. case 'v': /* verbose: print packet decodes via tcpdump */
  332. options.verbose = 1;
  333. break;
  334. case 'A':
  335. tcpdump.args = optarg;
  336. break;
  337. #endif
  338. case 'V': /* print version info */
  339. version();
  340. break;
  341. case 'x': /* include mode */
  342. if (include_exclude_mode != 0)
  343. errx(1, "Error: Can only specify -x OR -X");
  344. include_exclude_mode = 'x';
  345. if ((include_exclude_mode =
  346. parse_xX_str(include_exclude_mode, optarg, &xX)) == 0)
  347. errx(1, "Unable to parse -x: %s", optarg);
  348. if (include_exclude_mode & xXPacket) {
  349. xX_list = (LIST *) xX;
  350. } else if (! (include_exclude_mode & xXBPF)) {
  351. xX_cidr = (CIDR *) xX;
  352. }
  353. break;
  354. case 'X': /* exclude mode */
  355. if (include_exclude_mode != 0)
  356. errx(1, "Error: Can only specify -x OR -X");
  357. include_exclude_mode = 'X';
  358. if ((include_exclude_mode =
  359. parse_xX_str(include_exclude_mode, optarg, &xX)) == 0)
  360. errx(1, "Unable to parse -X: %s", optarg);
  361. if (include_exclude_mode & xXPacket) {
  362. xX_list = (LIST *) xX;
  363. } else {
  364. xX_cidr = (CIDR *) xX;
  365. }
  366. break;
  367. case '1': /* replay one packet at a time */
  368. options.one_at_a_time = 1;
  369. options.mult = 0.0;
  370. options.rate = 0.0;
  371. options.packetrate = 0;
  372. options.topspeed = 0;
  373. break;
  374. case '2': /* layer 2 header file */
  375. l2enabled = 1;
  376. l2len = read_hexstring(optarg, l2data, L2DATALEN);
  377. break;
  378. case '4':
  379. options.rewriteports = 1;
  380. if (! parse_portmap(&portmap_data, optarg))
  381. errx(1, "Invalid port mapping");
  382. break;
  383. default:
  384. usage();
  385. }
  386. argc -= optind;
  387. argv += optind;
  388. if ((argc == 0) && (!options.sniff_bridge))
  389. errx(1, "Must specify one or more pcap files to process");
  390. if (argc > 1)
  391. for (i = 0; i < argc; i++)
  392. if (!strcmp("-", argv[i]))
  393. errx(1, "stdin must be the only file specified");
  394. if (intf == NULL)
  395. errx(1, "Must specify a primary interface");
  396. if ((intf2 == NULL) && (cache_file != NULL))
  397. errx(1, "Needs secondary interface with cache");
  398. if ((intf2 != NULL) && (!options.sniff_bridge) &&
  399. (!options.cidr && (cache_file == NULL)))
  400. errx(1, "Needs cache or cidr match with secondary interface");
  401. if (options.sniff_bridge && (options.savepcap ||
  402. options.savedumper ||
  403. options.savepcap2 || options.savedumper2)) {
  404. errx(1, "Bridge mode excludes saving packets or data to file");
  405. }
  406. if ((intf2 != NULL) && options.datadump_mode && (!options.one_output) &&
  407. ((options.datadumpfile == 0) || (options.datadumpfile2 == 0)))
  408. errx(1,
  409. "You must specify two output files when splitting traffic in data dump mode");
  410. if ((options.offset) && (options.sniff_snaplen != -1)) {
  411. errx(1, "You can't specify an offset when sniffing a live network");
  412. }
  413. if ((!options.promisc) && (options.sniff_snaplen == -1)) {
  414. errx(1,
  415. "Not nosy can't be specified except when sniffing a live network");
  416. }
  417. if ((options.sniff_bridge) && (options.sniff_snaplen == -1)) {
  418. errx(1, "Bridging requires sniff mode (-S <snaplen>)");
  419. }
  420. if ((options.sniff_bridge) && (intf2 == NULL)) {
  421. errx(1, "Bridging requires a secondary interface");
  422. }
  423. if ((options.sniff_snaplen != -1) && options.one_at_a_time) {
  424. errx(1, "Sniffing live traffic excludes one at a time mode");
  425. }
  426. if (options.one_output && options.sniff_bridge) {
  427. errx(1, "One output mode and bridge mode are incompatible");
  428. }
  429. if ((options.rewriteip > 1) && (options.rewriteip != nat_interface)) {
  430. errx(1, "Using both -N and -e are not supported");
  431. }
  432. if (options.seed != 0) {
  433. srand(options.seed);
  434. options.seed = random();
  435. dbg(1, "random() picked: %d", options.seed);
  436. }
  437. /*
  438. * If we have one and only one -N, then use the same map data
  439. * for both interfaces/files
  440. */
  441. if ((cidrmap_data1 != NULL) && (cidrmap_data2 == NULL))
  442. cidrmap_data2 = cidrmap_data1;
  443. /*
  444. * some options are limited if we change the type of header
  445. * we're making a half-assed assumption that any header
  446. * length = LIBNET_ETH_H is actually 802.3. This will
  447. * prolly bite some poor slob later using some wierd
  448. * header type in their pcaps, but I don't really care right now
  449. */
  450. if (l2len != LIBNET_ETH_H) {
  451. /*
  452. * we can't untruncate packets with a different lenght
  453. * ethernet header because we don't take the lenghts
  454. * into account when doing the pointer math
  455. */
  456. if (options.trunc)
  457. errx(1, "You can't use -u with non-802.3 frames");
  458. /*
  459. * we also can't rewrite macs for non-802.3
  460. */
  461. if ((memcmp(options.intf1_mac, NULL_MAC, LIBNET_ETH_H) == 0) ||
  462. (memcmp(options.intf2_mac, NULL_MAC, LIBNET_ETH_H) == 0))
  463. errx(1,
  464. "You can't rewrite destination MAC's with non-802.3 frames");
  465. }
  466. /* open interfaces for writing */
  467. if ((options.intf1 = libnet_init(LIBNET_LINK_ADV, intf, ebuf)) == NULL)
  468. errx(1, "Libnet can't open %s: %s", intf, ebuf);
  469. if (intf2 != NULL) {
  470. if ((options.intf2 = libnet_init(LIBNET_LINK_ADV, intf2, ebuf)) == NULL)
  471. errx(1, "Libnet can't open %s: %s", intf2, ebuf);
  472. }
  473. /* open bridge interfaces for reading */
  474. if (options.sniff_bridge) {
  475. if ((options.listen1 =
  476. pcap_open_live(intf, options.sniff_snaplen,
  477. options.promisc, PCAP_TIMEOUT, errbuf)) == NULL) {
  478. errx(1, "Libpcap can't open %s: %s", intf, errbuf);
  479. }
  480. apply_filter(options.listen1);
  481. if ((options.listen2 =
  482. pcap_open_live(intf2, options.sniff_snaplen,
  483. options.promisc, PCAP_TIMEOUT, errbuf)) == NULL) {
  484. errx(1, "Libpcap can't open %s: %s", intf2, errbuf);
  485. }
  486. apply_filter(options.listen2);
  487. /* sanity checks for the linktype */
  488. if (pcap_datalink(options.listen1) != pcap_datalink(options.listen2)) {
  489. errx(1, "Unable to bridge different datalink types");
  490. }
  491. /* abort on non-supported link types */
  492. if (pcap_datalink(options.listen1) == DLT_LINUX_SLL) {
  493. errx(1, "Unable to bridge Linux Cooked Capture format");
  494. }
  495. else if (pcap_datalink(options.listen1) == DLT_NULL) {
  496. errx(1, "Unable to bridge BSD loopback format");
  497. }
  498. else if (pcap_datalink(options.listen1) == DLT_LOOP) {
  499. errx(1, "Unable to bridge loopback interface");
  500. }
  501. /*
  502. * only need to validate once since we're guaranteed both interfaces
  503. * use the same link type
  504. */
  505. validate_l2(intf, l2enabled, l2data, l2len,
  506. pcap_datalink(options.listen1));
  507. warnx("listening on: %s %s", intf, intf2);
  508. }
  509. if (options.savepcap == NULL)
  510. warnx("sending on: %s %s", intf, intf2 == NULL ? "" : intf2);
  511. /* init the signal handlers */
  512. init_signal_handlers();
  513. if (gettimeofday(&begin, NULL) < 0)
  514. err(1, "gettimeofday() failed");
  515. /* don't use the standard main loop in bridge mode */
  516. if (options.sniff_bridge) {
  517. cache_byte = 0;
  518. cache_bit = 0;
  519. do_bridge(options.listen1, options.listen2, l2enabled, l2data, l2len);
  520. pcap_close(options.listen1);
  521. pcap_close(options.listen2);
  522. libnet_destroy(options.intf1);
  523. libnet_destroy(options.intf2);
  524. exit(0);
  525. }
  526. /* main loop for non-bridge mode */
  527. if (options.n_iter > 0) {
  528. while (options.n_iter--) { /* limited loop */
  529. for (i = 0; i < argc; i++) {
  530. /* reset cache markers for each iteration */
  531. cache_byte = 0;
  532. cache_bit = 0;
  533. /* replay file or live network depending on snaplen */
  534. if (options.sniff_snaplen == -1) {
  535. replay_file(argv[i], l2enabled, l2data, l2len);
  536. }
  537. else {
  538. replay_live(argv[i], l2enabled, l2data, l2len);
  539. }
  540. }
  541. }
  542. }
  543. else {
  544. /* loop forever */
  545. while (1) {
  546. for (i = 0; i < argc; i++) {
  547. /* reset cache markers for each iteration */
  548. cache_byte = 0;
  549. cache_bit = 0;
  550. /* replay file or live network depending on snaplen */
  551. if (options.sniff_snaplen == -1) {
  552. replay_file(argv[i], l2enabled, l2data, l2len);
  553. }
  554. else {
  555. replay_live(argv[i], l2enabled, l2data, l2len);
  556. }
  557. }
  558. }
  559. }
  560. if (bytes_sent > 0)
  561. packet_stats();
  562. /* save the pcap write file */
  563. if (options.savepcap != NULL)
  564. pcap_dump_close(options.savedumper);
  565. if (options.savepcap2 != NULL)
  566. pcap_dump_close(options.savedumper2);
  567. /* close the data dump files */
  568. if (options.datadumpfile)
  569. close(options.datadumpfile);
  570. if (options.datadumpfile2)
  571. close(options.datadumpfile2);
  572. return 0;
  573. } /* main() */
  574. /*
  575. * replay a live network on another interface
  576. * but only in a single direction (non-bridge mode)
  577. */
  578. void
  579. replay_live(char *iface, int l2enabled, char *l2data, int l2len)
  580. {
  581. pcap_t *pcap = NULL;
  582. u_int32_t linktype = 0;
  583. char errbuf[PCAP_ERRBUF_SIZE];
  584. /* if no interface specified, pick one */
  585. if ((!iface || !*iface) && !(iface = pcap_lookupdev(errbuf))) {
  586. errx(1, "Error determing live capture device : %s", errbuf);
  587. }
  588. if (strcmp(intf, iface) == 0) {
  589. warnx("WARNING: Listening and sending on the same interface!");
  590. }
  591. /* open the interface */
  592. if ((pcap = pcap_open_live(iface, options.sniff_snaplen,
  593. options.promisc, 0, errbuf)) == NULL) {
  594. errx(1, "Error opening live capture: %s", errbuf);
  595. }
  596. linktype = pcap_datalink(pcap);
  597. validate_l2(iface, l2enabled, l2data, l2len, linktype);
  598. /* do we apply a bpf filter? */
  599. if (options.bpf_filter != NULL) {
  600. if (pcap_compile(pcap, &bpf, options.bpf_filter,
  601. options.bpf_optimize, 0) != 0) {
  602. errx(1, "Error compiling BPF filter: %s", pcap_geterr(pcap));
  603. }
  604. if (pcap_setfilter(pcap, &bpf) != 0)
  605. errx(1, "Unable to apply BPF filter: %s", pcap_geterr(pcap));
  606. }
  607. do_packets(NULL, pcap, linktype, l2enabled, l2data, l2len);
  608. pcap_close(pcap);
  609. }
  610. /*
  611. * replay a pcap file out an interface
  612. */
  613. void
  614. replay_file(char *path, int l2enabled, char *l2data, int l2len)
  615. {
  616. pcap_t *pcap = NULL;
  617. pcapnav_t *pcapnav = NULL;
  618. u_int32_t linktype = 0;
  619. pcapnav_init();
  620. #ifdef HAVE_TCPDUMP
  621. if (options.verbose) {
  622. tcpdump.filename = path;
  623. tcpdump_open(&tcpdump);
  624. }
  625. #endif
  626. if ((pcapnav = pcapnav_open_offline(path)) == NULL) {
  627. errx(1, "Error opening file %s: %s", path, strerror(errno));
  628. }
  629. pcap = pcapnav_pcap(pcapnav);
  630. linktype = pcap_datalink(pcap);
  631. validate_l2(path, l2enabled, l2data, l2len, linktype);
  632. apply_filter(pcapnav_pcap(pcapnav));
  633. do_packets(pcapnav, NULL, linktype, l2enabled, l2data, l2len);
  634. pcapnav_close(pcapnav);
  635. #ifdef HAVE_TCPDUMP
  636. tcpdump_close(&tcpdump);
  637. #endif
  638. }
  639. /*
  640. * applys a BPF filter if applicable
  641. */
  642. void
  643. apply_filter(pcap_t * pcap)
  644. {
  645. /* do we apply a bpf filter? */
  646. if (options.bpf_filter != NULL) {
  647. if (pcap_compile(pcap, &bpf, options.bpf_filter,
  648. options.bpf_optimize, 0) != 0) {
  649. errx(1, "Error compiling BPF filter: %s", pcap_geterr(pcap));
  650. }
  651. pcap_setfilter(pcap, &bpf);
  652. }
  653. }
  654. /*
  655. * if linktype not DLT_EN10MB we have to see if we can send the frames
  656. * if DLT_LINUX_SLL AND (options.intf1_mac OR l2enabled), then OK
  657. * else if l2enabled, then ok
  658. */
  659. void
  660. validate_l2(char *name, int l2enabled, char *l2data, int l2len, int linktype)
  661. {
  662. dbg(1, "Linktype is %s\n", pcap_datalink_val_to_description(linktype));
  663. switch (linktype) {
  664. case DLT_EN10MB:
  665. /* nothing to do here */
  666. break;
  667. case DLT_LINUX_SLL:
  668. /* single output mode */
  669. if (! options.intf2) {
  670. /* if SLL, then either -2 or -I are ok */
  671. if ((memcmp(options.intf1_mac, NULL_MAC, LIBNET_ETH_H) == 0) && (!l2enabled)) {
  672. warnx("Unable to process pcap without -2 or -I: %s", name);
  673. return;
  674. }
  675. }
  676. /* dual output mode */
  677. else {
  678. /* if using dual interfaces, make sure -2 or -J & -I) is set */
  679. if (((memcmp(options.intf2_mac, NULL_MAC, LIBNET_ETH_H) == 0) ||
  680. (memcmp(options.intf1_mac, NULL_MAC, LIBNET_ETH_H) == 0)) &&
  681. (! l2enabled)) {
  682. errx(1, "Unable to process pcap with -j without -2 or -I & -J: %s", name);
  683. return;
  684. }
  685. }
  686. break;
  687. case DLT_CHDLC:
  688. /* Cisco HDLC (used at least for SONET) */
  689. /*
  690. * HDLC has a 4byte header, a 2 byte address type (0x0f00 is unicast
  691. * is all I know) and a 2 byte protocol type
  692. */
  693. /* single output mode */
  694. if (! options.intf2) {
  695. /* Need either a full l2 header or -I & -k */
  696. if (((memcmp(options.intf1_mac, NULL_MAC, LIBNET_ETH_H) == 0) ||
  697. (memcmp(options.intf1_smac, NULL_MAC, LIBNET_ETH_H) == 0)) &&
  698. (! l2enabled)) {
  699. errx(1, "Unable to process pcap without -2 or -I and -k: %s", name);
  700. return;
  701. }
  702. }
  703. /* dual output mode */
  704. else {
  705. /* Need to have a l2 header or -J, -K, -I, -k */
  706. if (((memcmp(options.intf1_mac, NULL_MAC, LIBNET_ETH_H) == 0) ||
  707. (memcmp(options.intf1_smac, NULL_MAC, LIBNET_ETH_H) == 0) ||
  708. (memcmp(options.intf2_mac, NULL_MAC, LIBNET_ETH_H) == 0) ||
  709. (memcmp(options.intf2_smac, NULL_MAC, LIBNET_ETH_H) == 0)) &&
  710. (! l2enabled)) {
  711. errx(1, "Unable to process pcap with -j without -2 or -J, -I, -K & -k: %s", name);
  712. return;
  713. }
  714. }
  715. break;
  716. case DLT_RAW:
  717. if (!l2enabled) {
  718. errx(1, "Unable to process pcap without -2: %s", name);
  719. return;
  720. }
  721. break;
  722. default:
  723. errx(1, "validate_l2(): Unsupported datalink type: %s (0x%x)",
  724. pcap_datalink_val_to_description(linktype), linktype);
  725. break;
  726. }
  727. /* calculate the maxpacket based on the l2len, linktype and mtu */
  728. if (l2enabled) {
  729. /* custom L2 header */
  730. dbg(1, "Using custom L2 header to calculate max frame size");
  731. maxpacket = options.mtu + l2len;
  732. }
  733. else if (linktype == DLT_EN10MB) {
  734. /* ethernet */
  735. dbg(1, "Using Ethernet to calculate max frame size");
  736. maxpacket = options.mtu + LIBNET_ETH_H;
  737. }
  738. else {
  739. /* oh fuck, we don't know what the hell this is, we'll just assume ethernet */
  740. maxpacket = options.mtu + LIBNET_ETH_H;
  741. warnx("Unable to determine layer 2 encapsulation, assuming ethernet\n"
  742. "You may need to increase the MTU (-t <size>) if you get errors");
  743. }
  744. }
  745. /*
  746. * parse the configfile, and put all the values into options
  747. */
  748. void
  749. configfile(char *file)
  750. {
  751. FILE *fp;
  752. char *argv[MAX_ARGS], buf[BUFSIZ];
  753. int argc, i;
  754. void *xX;
  755. int nat_interface = 0;
  756. if ((fp = fopen(file, "r")) == NULL)
  757. errx(1, "Could not open config file %s", file);
  758. for (i = 1; fgets(buf, sizeof(buf), fp) != NULL; i++) {
  759. if (*buf == '#' || *buf == '\r' || *buf == '\n')
  760. continue;
  761. if ((argc = argv_create(buf, MAX_ARGS, argv)) < 1) {
  762. warnx("couldn't parse arguments (line %d)", i);
  763. break;
  764. }
  765. #define ARGS(x, y) ( (!strcmp(argv[0], x)) && (argc == y) )
  766. if (ARGS("sniff_bridge", 1)) {
  767. options.sniff_bridge = 1;
  768. }
  769. else if (ARGS("cachefile", 2)) {
  770. cache_file = strdup(argv[1]);
  771. cache_packets = read_cache(&cachedata, cache_file);
  772. }
  773. else if (ARGS("cidr", 2)) {
  774. options.cidr = 1;
  775. if (!parse_cidr(&cidrdata, argv[1], ","))
  776. usage();
  777. }
  778. else if (ARGS("endpoints", 2)) {
  779. options.rewriteip ++;
  780. if (!parse_endpoints(&cidrmap_data1, &cidrmap_data2, argv[1]))
  781. usage();
  782. }
  783. #ifdef DEBUG
  784. else if (ARGS("debug", 1)) {
  785. debug = 1;
  786. }
  787. #endif
  788. else if (ARGS("datadump_mode", 1)) {
  789. options.datadump_mode = 1;
  790. }
  791. else if (ARGS("fixchecksums", 1)) {
  792. options.fixchecksums = 1;
  793. }
  794. else if (ARGS("l2data", 2)) {
  795. l2len = read_hexstring(argv[1], l2data, L2DATALEN);
  796. }
  797. else if (ARGS("intf", 2)) {
  798. intf = strdup(argv[1]);
  799. }
  800. else if (ARGS("primary_mac", 2)) {
  801. mac2hex(argv[1], options.intf1_mac, sizeof(options.intf1_mac));
  802. if (memcmp(options.intf1_mac, NULL_MAC, LIBNET_ETH_H) == 0)
  803. errx(1, "Invalid mac address: %s", argv[1]);
  804. }
  805. else if (ARGS("primary_smac", 2)) {
  806. mac2hex(argv[1], options.intf1_smac, sizeof(options.intf1_smac));
  807. if (memcmp(options.intf1_smac, NULL_MAC, LIBNET_ETH_H) == 0)
  808. errx(1, "Invalid mac address: %s", argv[1]);
  809. }
  810. else if (ARGS("second_intf", 2)) {
  811. intf2 = strdup(argv[1]);
  812. }
  813. else if (ARGS("second_mac", 2)) {
  814. mac2hex(argv[1], options.intf2_mac, sizeof(options.intf2_mac));
  815. if (memcmp(options.intf2_mac, NULL_MAC, LIBNET_ETH_H) == 0)
  816. errx(1, "Invalid mac address: %s", argv[1]);
  817. }
  818. else if (ARGS("second_smac", 2)) {
  819. mac2hex(argv[1], options.intf2_smac, sizeof(options.intf2_smac));
  820. if (memcmp(options.intf2_smac, NULL_MAC, LIBNET_ETH_H) == 0)
  821. errx(1, "Invalid mac address: %s", argv[1]);
  822. }
  823. else if (ARGS("loop", 2)) {
  824. options.n_iter = atoi(argv[1]);
  825. if (options.n_iter < 0)
  826. errx(1, "Invalid loop count: %s", argv[1]);
  827. }
  828. else if (ARGS("limit_send", 2)) {
  829. options.limit_send = strtoull(argv[1], NULL, 0);
  830. if (options.limit_send <= 0)
  831. errx(1, "limit_send <limit> must be positive");
  832. }
  833. else if (ARGS("multiplier", 2)) {
  834. options.mult = atof(argv[1]);
  835. if (options.mult <= 0)
  836. errx(1, "Invalid multiplier: %s", argv[1]);
  837. options.rate = 0.0;
  838. }
  839. else if (ARGS("no_martians", 1)) {
  840. options.no_martians = 1;
  841. }
  842. else if (ARGS("nat", 2)) {
  843. options.rewriteip ++;
  844. nat_interface ++;
  845. if (nat_interface == 1) {
  846. if (! parse_cidr_map(&cidrmap_data1, argv[1]))
  847. errx(1, "Invalid primary NAT string");
  848. } else {
  849. if (! parse_cidr_map(&cidrmap_data2, argv[1]))
  850. errx(1, "Invalid secondary NAT string");
  851. }
  852. }
  853. else if (ARGS("portmap", 2)) {
  854. options.rewriteports = 1;
  855. if (! parse_portmap(&portmap_data, argv[1]))
  856. errx(1, "Invalid port mapping");
  857. }
  858. #ifdef HAVE_PCAPNAV
  859. else if (ARGS("offset", 2)) {
  860. options.offset = strtoull(argv[1], NULL, 0);
  861. }
  862. #endif
  863. else if (ARGS("one_output", 1)) {
  864. options.one_output = 1;
  865. }
  866. else if (ARGS("one_at_a_time", 1)) {
  867. options.one_at_a_time = 1;
  868. options.rate = 0.0;
  869. options.mult = 0.0;
  870. options.topspeed = 0;
  871. options.packetrate = 0;
  872. }
  873. else if (ARGS("rate", 2)) {
  874. options.rate = atof(argv[1]);
  875. if (options.rate <= 0)
  876. errx(1, "Invalid rate: %s", argv[1]);
  877. /* convert to bytes */
  878. options.rate = (options.rate * (1024 * 1024)) / 8;
  879. options.mult = 0.0;
  880. options.topspeed = 0;
  881. options.packetrate = 0;
  882. }
  883. else if (ARGS("topspeed", 1)) {
  884. options.topspeed = 1;
  885. options.rate = 0.0;
  886. options.packetrate = 0;
  887. options.mult = 0.0;
  888. options.one_at_a_time = 0;
  889. }
  890. else if (ARGS("mtu", 2)) {
  891. options.mtu = atoi(argv[1]);
  892. }
  893. else if (ARGS("not_nosy", 1)) {
  894. options.promisc = 0;
  895. }
  896. else if (ARGS("truncate", 1)) {
  897. options.truncate = 1;
  898. }
  899. else if (ARGS("untruncate", 2)) {
  900. if (strcmp("pad", argv[1]) == 0) {
  901. options.trunc = PAD_PACKET;
  902. }
  903. else if (strcmp("trunc", argv[1]) == 0) {
  904. options.trunc = TRUNC_PACKET;
  905. }
  906. else {
  907. errx(1, "Invalid untruncate option: %s", argv[1]);
  908. }
  909. }
  910. else if (ARGS("seed", 2)) {
  911. options.seed = atol(argv[1]);
  912. }
  913. else if (ARGS("sniff_snaplen", 2)) {
  914. options.sniff_snaplen = atoi(argv[1]);
  915. if ((options.sniff_snaplen < 0) || (options.sniff_snaplen > MAX_SNAPLEN)) {
  916. errx(1, "Invalid sniff snaplen: %d", options.sniff_snaplen);
  917. }
  918. else if (options.sniff_snaplen == 0) {
  919. options.sniff_snaplen = MAX_SNAPLEN;
  920. }
  921. }
  922. else if (ARGS("packetrate", 2)) {
  923. options.packetrate = atof(argv[1]);
  924. if (options.packetrate < 0)
  925. errx(1, "Invalid packetrate option: %s", argv[1]);
  926. options.rate = 0.0;
  927. options.mult = 0.0;
  928. options.topspeed = 0;
  929. options.one_at_a_time = 0;
  930. }
  931. else if (ARGS("include", 2)) {
  932. if (include_exclude_mode != 0)
  933. errx(1,
  934. "Error: Can only specify include (-x) OR exclude (-X) ");
  935. include_exclude_mode = 'x';
  936. if ((include_exclude_mode =
  937. parse_xX_str(include_exclude_mode, argv[1], &xX)) == 0)
  938. errx(1, "Unable to parse include: %s", optarg);
  939. if (include_exclude_mode & xXPacket) {
  940. xX_list = (LIST *) xX;
  941. }
  942. else if (!include_exclude_mode & xXBPF) {
  943. xX_cidr = (CIDR *) xX;
  944. }
  945. }
  946. else if (ARGS("exclude", 2)) {
  947. if (include_exclude_mode != 0)
  948. errx(1, "Error: Can only specify include (-x) OR exclude (-X)");
  949. include_exclude_mode = 'X';
  950. if ((include_exclude_mode =
  951. parse_xX_str(include_exclude_mode, argv[1], &xX)) == 0)
  952. errx(1, "Unable to parse exclude: %s", optarg);
  953. if (include_exclude_mode & xXPacket) {
  954. xX_list = (LIST *) xX;
  955. }
  956. else if (!include_exclude_mode & xXBPF) {
  957. xX_cidr = (CIDR *) xX;
  958. }
  959. }
  960. else if (ARGS("primary_write", 2)) {
  961. if (!options.datadump_mode) {
  962. if ((options.savepcap =
  963. pcap_open_dead(DLT_EN10MB, 0xffff)) == NULL)
  964. errx(1, "error setting primary output file linktype");
  965. if ((options.savedumper =
  966. pcap_dump_open(options.savepcap, argv[1])) == NULL)
  967. errx(1, "pcap_dump_open() error: %s",
  968. pcap_geterr(options.savepcap));
  969. warnx("saving primary packets in %s", argv[1]);
  970. }
  971. else {
  972. if ((options.datadumpfile =
  973. creat(argv[1],
  974. S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) {
  975. errx(1, "error creating primary output file: %s\n%s",
  976. argv[1], strerror(errno));
  977. warnx("saving primary data in %s", argv[1]);
  978. }
  979. }
  980. }
  981. else if (ARGS("second_write", 2)) {
  982. if (!options.datadump_mode) {
  983. if ((options.savepcap2 =
  984. pcap_open_dead(DLT_EN10MB, 0xffff)) == NULL)
  985. errx(1, "error setting secondary output file linktype");
  986. if ((options.savedumper2 =
  987. pcap_dump_open(options.savepcap2, argv[1])) == NULL)
  988. errx(1, "pcap_dump_open() error: %s",
  989. pcap_geterr(options.savepcap2));
  990. warnx("saving secondary packets in %s", argv[1]);
  991. }
  992. else {
  993. if ((options.datadumpfile2 =
  994. creat(argv[1],
  995. S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
  996. errx(1, "error creating secondary output file: %s\n%s",
  997. argv[1], strerror(errno));
  998. warnx("saving secondary data in %s", argv[1]);
  999. }
  1000. }
  1001. else if (ARGS("verbose", 1)) {
  1002. options.verbose = 1;
  1003. }
  1004. else if (ARGS("tcpdump_args", 2)) {
  1005. tcpdump.args = argv[1];
  1006. }
  1007. else {
  1008. errx(1, "Skipping unrecognized: %s", argv[0]);
  1009. }
  1010. }
  1011. }
  1012. void
  1013. version(void)
  1014. {
  1015. fprintf(stderr, "tcpreplay version: %s", VERSION);
  1016. #ifdef DEBUG
  1017. fprintf(stderr, " (debug)\n");
  1018. #else
  1019. fprintf(stderr, "\n");
  1020. #endif
  1021. fprintf(stderr, "Cache file supported: %s\n", CACHEVERSION);
  1022. fprintf(stderr, "Compiled against libnet: %s\n", LIBNET_VERSION);
  1023. fprintf(stderr, "Compiled against libpcap: %s\n", pcap_version);
  1024. #ifdef HAVE_PCAPNAV
  1025. fprintf(stderr, "Compiled against libpcapnav: %s\n", PCAPNAV_VERSION);
  1026. #else
  1027. fprintf(stderr, "Not compiled against libpcapnav.\n");
  1028. #endif
  1029. #ifdef HAVE_TCPDUMP
  1030. fprintf(stderr, "Using tcpdump located in: %s\n", TCPDUMP_BINARY);
  1031. #else
  1032. fprintf(stderr, "Not using tcpdump.\n");
  1033. #endif
  1034. exit(0);
  1035. }
  1036. void
  1037. usage(void)
  1038. {
  1039. printf("Usage: tcpreplay [args] <file(s)>\n"
  1040. "-A \"<args>\"\t\tPass arguments to tcpdump decoder (use w/ -v)\n"
  1041. "-b\t\t\tBridge two broadcast domains in sniffer mode\n"
  1042. "-c <cachefile>\t\tSplit traffic via cache file\n"
  1043. "-C <CIDR1,CIDR2,...>\tSplit traffic by matching src IP\n");
  1044. #ifdef DEBUG
  1045. printf("-d <level>\t\tEnable debug output to STDERR\n");
  1046. #endif
  1047. printf("-D\t\t\tData dump mode (set this BEFORE -w and -W)\n"
  1048. "-e <ip1:ip2>\t\tSpecify IP endpoint rewriting\n"
  1049. "-f <configfile>\t\tSpecify configuration file\n"
  1050. "-F\t\t\tFix IP, TCP, UDP and ICMP checksums\n"
  1051. "-h\t\t\tHelp\n"
  1052. "-i <nic>\t\tPrimary interface to send traffic out of\n"
  1053. "-I <mac>\t\tRewrite dest MAC on primary interface\n"
  1054. "-j <nic>\t\tSecondary interface to send traffic out of\n"
  1055. "-J <mac>\t\tRewrite dest MAC on secondary interface\n"
  1056. "-k <mac>\t\tRewrite source MAC on primary interface\n"
  1057. "-K <mac>\t\tRewrite source MAC on secondary interface\n");
  1058. printf("-l <loop>\t\tSpecify number of times to loop\n"
  1059. "-L <limit>\t\tSpecify the maximum number of packets to send\n"
  1060. "-m <multiple>\t\tSet replay speed to given multiple\n"
  1061. "-M\t\t\tDisable sending martian IP packets\n"
  1062. "-n\t\t\tNot nosy mode (not promisc in sniff/bridge mode)\n"
  1063. "-N <CIDR1:CIDR2,...>\tRewrite IP's via pseudo-NAT\n"
  1064. #ifdef HAVE_PCAPNAV
  1065. "-o <offset>\t\tStarting byte offset\n"
  1066. #endif
  1067. "-O\t\t\tOne output mode\n"
  1068. "-p <packetrate>\t\tSet replay speed to given rate (packets/sec)\n");
  1069. printf("-P\t\t\tPrint PID\n"
  1070. "-r <rate>\t\tSet replay speed to given rate (Mbps)\n"
  1071. "-R\t\t\tSet replay speed to as fast as possible\n"
  1072. "-s <seed>\t\tRandomize src/dst IP addresses w/ given seed\n"
  1073. "-S <snaplen>\t\tSniff interface(s) and set the snaplen length\n"
  1074. "-t <mtu>\t\tOverride MTU (defaults to 1500)\n"
  1075. "-T\t\t\tTruncate packets > MTU so they can be sent\n"
  1076. "-u pad|trunc\t\tPad/Truncate packets which are larger than the snaplen\n"
  1077. "-v\t\t\tVerbose: print packet decodes for each packet sent\n"
  1078. "-V\t\t\tVersion\n");
  1079. printf("-w <file>\t\tWrite (primary) packets or data to file\n"
  1080. "-W <file>\t\tWrite secondary packets or data to file\n"
  1081. "-x <match>\t\tOnly send the packets specified\n"
  1082. "-X <match>\t\tSend all the packets except those specified\n"
  1083. "-1\t\t\tSend one packet per key press\n"
  1084. "-2 <datafile>\t\tLayer 2 data\n"
  1085. "-4 <PORT1:PORT2,...>\tRewrite port numbers\n"
  1086. "<file1> <file2> ...\tFile list to replay\n");
  1087. exit(1);
  1088. }
  1089. /*
  1090. * Initialize globals
  1091. */
  1092. void
  1093. init(void)
  1094. {
  1095. bytes_sent = failed = pkts_sent = 0;
  1096. intf = intf2 = NULL;
  1097. memset(&options, 0, sizeof(options));
  1098. /* Default mode is to replay pcap once in real-time */
  1099. options.mult = 1.0;
  1100. options.n_iter = 1;
  1101. options.rate = 0.0;
  1102. options.packetrate = 0.0;
  1103. /* set the default MTU size */
  1104. options.mtu = DEFAULT_MTU;
  1105. /* set the bpf optimize */
  1106. options.bpf_optimize = BPF_OPTIMIZE;
  1107. /* sniff mode options */
  1108. options.sniff_snaplen = -1; /* disabled */
  1109. options.promisc = 1; /* listen in promisc mode by default */
  1110. /* poll timeout (in ms) defaults to infinate */
  1111. options.poll_timeout = -1;
  1112. /* disable limit send */
  1113. options.limit_send = -1;
  1114. /* init the RBTree */
  1115. rbinit();
  1116. #ifdef HAVE_TCPDUMP
  1117. /* clear out tcpdump struct */
  1118. memset(&tcpdump, '\0', sizeof(tcpdump_t));
  1119. #endif
  1120. cache_bit = cache_byte = 0;
  1121. if (fcntl(STDERR_FILENO, F_SETFL, O_NONBLOCK) < 0)
  1122. warnx("Unable to set STDERR to non-blocking: %s", strerror(errno));
  1123. }
  1124. void
  1125. packet_stats()
  1126. {
  1127. float bytes_sec = 0.0, mb_sec = 0.0;
  1128. int pkts_sec = 0;
  1129. char bits[3];
  1130. if (gettimeofday(&end, NULL) < 0)
  1131. err(1, "gettimeofday");
  1132. timersub(&end, &begin, &begin);
  1133. if (timerisset(&begin)) {
  1134. if (bytes_sent) {
  1135. bytes_sec =
  1136. bytes_sent / (begin.tv_sec + (float)begin.tv_usec / 1000000);
  1137. mb_sec = (bytes_sec * 8) / (1024 * 1024);
  1138. }
  1139. if (pkts_sent)
  1140. pkts_sec =
  1141. pkts_sent / (begin.tv_sec + (float)begin.tv_usec / 1000000);
  1142. }
  1143. snprintf(bits, sizeof(bits), "%d", begin.tv_usec);
  1144. fprintf(stderr, " %llu packets (%llu bytes) sent in %d.%s seconds\n",
  1145. pkts_sent, bytes_sent, begin.tv_sec, bits);
  1146. fprintf(stderr, " %.1f bytes/sec %.2f megabits/sec %d packets/sec\n",
  1147. bytes_sec, mb_sec, pkts_sec);
  1148. if (failed) {
  1149. fprintf(stderr,
  1150. " %llu write attempts failed from full buffers and were repeated\n",
  1151. failed);
  1152. }
  1153. }