1
0

do_packets.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. /* $Id: do_packets.c 882 2004-11-07 04:16:26Z aturner $ */
  2. /*
  3. * Copyright (c) 2001-2004 Aaron Turner, Matt Bing.
  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 <libnet.h>
  33. #ifdef HAVE_PCAPNAV
  34. #include <pcapnav.h>
  35. #else
  36. #include "fakepcapnav.h"
  37. #endif
  38. #include <sys/time.h>
  39. #include <sys/types.h>
  40. #include <signal.h>
  41. #include <string.h>
  42. #include <netinet/in.h>
  43. #include <time.h>
  44. #ifdef HAVE_SYS_POLL_H
  45. #include <sys/poll.h>
  46. #elif HAVE_POLL_H
  47. #include <poll.h>
  48. #else
  49. #include "fakepoll.h"
  50. #endif
  51. #include "tcpreplay.h"
  52. #include "tcpdump.h"
  53. #include "cidr.h"
  54. #include "portmap.h"
  55. #include "cache.h"
  56. #include "err.h"
  57. #include "do_packets.h"
  58. #include "edit_packet.h"
  59. #include "timer.h"
  60. #include "list.h"
  61. #include "xX.h"
  62. extern struct options options;
  63. extern char *cachedata, *intf, *intf2;
  64. extern CIDR *cidrdata;
  65. extern PORTMAP *portmap_data;
  66. extern struct timeval begin, end;
  67. extern u_int64_t bytes_sent, failed, pkts_sent;
  68. extern u_int64_t cache_packets;
  69. extern volatile int didsig;
  70. extern int l2len, maxpacket;
  71. extern int include_exclude_mode;
  72. extern CIDR *xX_cidr;
  73. extern LIST *xX_list;
  74. extern tcpdump_t tcpdump;
  75. #ifdef DEBUG
  76. extern int debug;
  77. #endif
  78. void packet_stats(); /* from tcpreplay.c */
  79. /*
  80. * we've got a race condition, this is our workaround
  81. */
  82. void
  83. catcher(int signo)
  84. {
  85. /* stdio in signal handlers cause a race, instead we set a flag */
  86. if (signo == SIGINT)
  87. didsig = 1;
  88. }
  89. /*
  90. * when we're sending only one packet at a time via <ENTER>
  91. * then there's no race and we can quit now
  92. * also called when didsig is set
  93. */
  94. void
  95. break_now(int signo)
  96. {
  97. if (signo == SIGINT || didsig) {
  98. printf("\n");
  99. /* kill tcpdump child if required */
  100. if (tcpdump.pid)
  101. if (kill(tcpdump.pid, SIGTERM) != 0)
  102. kill(tcpdump.pid, SIGKILL);
  103. packet_stats();
  104. exit(1);
  105. }
  106. }
  107. /*
  108. * the main loop function. This is where we figure out
  109. * what to do with each packet
  110. */
  111. void
  112. do_packets(pcapnav_t * pcapnav, pcap_t * pcap, u_int32_t linktype,
  113. int l2enabled, char *l2data, int l2len)
  114. {
  115. eth_hdr_t *eth_hdr = NULL;
  116. ip_hdr_t *ip_hdr = NULL;
  117. arp_hdr_t *arp_hdr = NULL;
  118. libnet_t *l = NULL;
  119. struct pcap_pkthdr pkthdr; /* libpcap packet info */
  120. const u_char *nextpkt = NULL; /* packet buffer from libpcap */
  121. u_char *pktdata = NULL; /* full packet buffer */
  122. #ifdef FORCE_ALIGN
  123. u_char *ipbuff = NULL; /* IP header and above buffer */
  124. #endif
  125. struct timeval last;
  126. static int firsttime = 1;
  127. int ret, newl2len;
  128. u_int64_t packetnum = 0;
  129. #ifdef HAVE_PCAPNAV
  130. pcapnav_result_t pcapnav_result = 0;
  131. #endif
  132. char datadumpbuff[MAXPACKET]; /* data dumper buffer */
  133. int datalen = 0; /* data dumper length */
  134. int newchar = 0;
  135. int needtorecalc = 0; /* did the packet change? if so, checksum */
  136. struct pollfd poller[1]; /* use poll to read from the keyboard */
  137. /* create packet buffers */
  138. if ((pktdata = (u_char *) malloc(maxpacket)) == NULL)
  139. errx(1, "Unable to malloc pktdata buffer");
  140. #ifdef FORCE_ALIGN
  141. if ((ipbuff = (u_char *) malloc(maxpacket)) == NULL)
  142. errx(1, "Unable to malloc ipbuff buffer");
  143. #endif
  144. /* register signals */
  145. didsig = 0;
  146. if (!options.one_at_a_time) {
  147. (void)signal(SIGINT, catcher);
  148. }
  149. else {
  150. (void)signal(SIGINT, break_now);
  151. }
  152. if (firsttime) {
  153. timerclear(&last);
  154. firsttime = 0;
  155. }
  156. #ifdef HAVE_PCAPNAV
  157. /* only support jumping w/ files */
  158. if ((pcapnav != NULL) && (options.offset)) {
  159. /* jump to the next packet >= the offset */
  160. if (pcapnav_goto_offset(pcapnav, (off_t)options.offset, PCAPNAV_CMP_GEQ)
  161. != PCAPNAV_DEFINITELY)
  162. warnx("Unable to get a definate jump offset "
  163. "pcapnav_goto_offset(): %d\n", pcapnav_result);
  164. }
  165. #endif
  166. /* get the pcap handler for the main loop */
  167. pcap = pcapnav_pcap(pcapnav);
  168. /* MAIN LOOP
  169. * Keep sending while we have packets or until
  170. * we've sent enough packets
  171. */
  172. while (((nextpkt = pcap_next(pcap, &pkthdr)) != NULL) &&
  173. (options.limit_send != pkts_sent)) {
  174. /* die? */
  175. if (didsig)
  176. break_now(0);
  177. dbg(2, "packets sent %llu", pkts_sent);
  178. packetnum++;
  179. dbg(2, "packet %llu caplen %d", packetnum, pkthdr.caplen);
  180. /* zero out the old packet info */
  181. memset(pktdata, '\0', maxpacket);
  182. needtorecalc = 0;
  183. /* Rewrite any Layer 2 data */
  184. if ((newl2len = rewrite_l2(&pkthdr, pktdata, nextpkt,
  185. linktype, l2enabled, l2data, l2len)) == 0)
  186. continue;
  187. l2len = newl2len;
  188. /* look for include or exclude LIST match */
  189. if (xX_list != NULL) {
  190. if (include_exclude_mode < xXExclude) {
  191. if (!check_list(xX_list, (packetnum))) {
  192. continue;
  193. }
  194. }
  195. else if (check_list(xX_list, (packetnum))) {
  196. continue;
  197. }
  198. }
  199. eth_hdr = (eth_hdr_t *) pktdata;
  200. /* does packet have an IP header? if so set our pointer to it */
  201. if (ntohs(eth_hdr->ether_type) == ETHERTYPE_IP) {
  202. #ifdef FORCE_ALIGN
  203. /*
  204. * copy layer 3 and up to our temp packet buffer
  205. * for now on, we have to edit the packetbuff because
  206. * just before we send the packet, we copy the packetbuff
  207. * back onto the pkt.data + l2len buffer
  208. * we do all this work to prevent byte alignment issues
  209. */
  210. ip_hdr = (ip_hdr_t *) ipbuff;
  211. memcpy(ip_hdr, (&pktdata[l2len]), pkthdr.caplen - l2len);
  212. #else
  213. /*
  214. * on non-strict byte align systems, don't need to memcpy(),
  215. * just point to 14 bytes into the existing buffer
  216. */
  217. ip_hdr = (ip_hdr_t *) (&pktdata[l2len]);
  218. #endif
  219. /* look for include or exclude CIDR match */
  220. if (xX_cidr != NULL) {
  221. if (!process_xX_by_cidr(include_exclude_mode, xX_cidr, ip_hdr)) {
  222. continue;
  223. }
  224. }
  225. }
  226. else {
  227. /* non-IP packets have a NULL ip_hdr struct */
  228. ip_hdr = NULL;
  229. }
  230. /* check for martians? */
  231. if (options.no_martians && (ip_hdr != NULL)) {
  232. switch ((ntohl(ip_hdr->ip_dst.s_addr) & 0xff000000) >> 24) {
  233. case 0:
  234. case 127:
  235. case 255:
  236. dbg(1, "Skipping martian. Packet #%llu", packetnum);
  237. /* then skip the packet */
  238. continue;
  239. default:
  240. /* continue processing */
  241. break;
  242. }
  243. }
  244. /* Dual nic processing */
  245. if (options.intf2 != NULL) {
  246. if (cachedata != NULL) {
  247. l = (LIBNET *) cache_mode(cachedata, packetnum, eth_hdr);
  248. }
  249. else if (options.cidr) {
  250. l = (LIBNET *) cidr_mode(eth_hdr, ip_hdr);
  251. }
  252. else {
  253. errx(1, "do_packets(): Strange, we should of never of gotten here");
  254. }
  255. }
  256. else {
  257. /* normal single nic operation */
  258. l = options.intf1;
  259. /* check for destination MAC rewriting */
  260. if (memcmp(options.intf1_mac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  261. memcpy(eth_hdr->ether_dhost, options.intf1_mac, ETHER_ADDR_LEN);
  262. }
  263. if (memcmp(options.intf1_smac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  264. memcpy(eth_hdr->ether_shost, options.intf1_smac, ETHER_ADDR_LEN);
  265. }
  266. }
  267. /* sometimes we should not send the packet */
  268. if (l == CACHE_NOSEND)
  269. continue;
  270. /* rewrite IP addresses */
  271. if (options.rewriteip) {
  272. /* IP packets */
  273. if (ip_hdr != NULL) {
  274. needtorecalc += rewrite_ipl3(ip_hdr, l);
  275. }
  276. /* ARP packets */
  277. else if (ntohs(eth_hdr->ether_type) == ETHERTYPE_ARP) {
  278. arp_hdr = (arp_hdr_t *)(&pktdata[l2len]);
  279. /* unlike, rewrite_ipl3, we don't care if the packet changed
  280. * because we never need to recalc the checksums for an ARP
  281. * packet. So ignore the return value
  282. */
  283. rewrite_iparp(arp_hdr, l);
  284. }
  285. }
  286. /* rewrite ports */
  287. if (options.rewriteports && (ip_hdr != NULL)) {
  288. needtorecalc += rewrite_ports(portmap_data, &ip_hdr);
  289. }
  290. /* Untruncate packet? Only for IP packets */
  291. if ((options.trunc) && (ip_hdr != NULL)) {
  292. needtorecalc += untrunc_packet(&pkthdr, pktdata, ip_hdr, l, l2len);
  293. }
  294. /* do we need to spoof the src/dst IP address? */
  295. if ((options.seed) && (ip_hdr != NULL)) {
  296. needtorecalc += randomize_ips(&pkthdr, pktdata, ip_hdr, l, l2len);
  297. }
  298. /* do we need to force fixing checksums? */
  299. if ((options.fixchecksums || needtorecalc) && (ip_hdr != NULL)) {
  300. fix_checksums(&pkthdr, ip_hdr, l);
  301. }
  302. #ifdef STRICT_ALIGN
  303. /*
  304. * put back the layer 3 and above back in the pkt.data buffer
  305. * we can't edit the packet at layer 3 or above beyond this point
  306. */
  307. memcpy(&pktdata[l2len], ip_hdr, pkthdr.caplen - l2len);
  308. #endif
  309. /* do we need to print the packet via tcpdump? */
  310. if (options.verbose)
  311. tcpdump_print(&tcpdump, &pkthdr, pktdata);
  312. if ((!options.topspeed) && (!options.one_at_a_time)) {
  313. /* we have to cast the ts, since OpenBSD sucks
  314. * had to be special and use bpf_timeval
  315. */
  316. do_sleep((struct timeval *)&pkthdr.ts, &last, pkthdr.caplen);
  317. }
  318. else if (options.one_at_a_time) {
  319. printf("**** Press <ENTER> to send the next packet out %s\n",
  320. l == options.intf1 ? intf : intf2);
  321. poller[0].fd = STDIN_FILENO;
  322. poller[0].events = POLLIN;
  323. poller[0].revents = 0;
  324. /* wait for the input */
  325. if (poll(poller, 1, -1) < 0)
  326. errx(1, "do_packets(): Error reading from stdin: %s", strerror(errno));
  327. /* read to the end of the line */
  328. do {
  329. newchar = getc(stdin);
  330. } while (newchar != '\n');
  331. }
  332. /* in one output mode always use primary nic/file */
  333. if (options.one_output)
  334. l = options.intf1;
  335. /* Physically send the packet or write to file */
  336. if (options.savepcap != NULL || options.datadump_mode) {
  337. /* figure out the correct offsets/data len */
  338. if (options.datadump_mode) {
  339. memset(datadumpbuff, '\0', MAXPACKET);
  340. datalen =
  341. extract_data(pktdata, pkthdr.caplen, l2len, &datadumpbuff);
  342. }
  343. /* interface 1 */
  344. if (l == options.intf1) {
  345. if (options.datadump_mode) { /* data only? */
  346. if (datalen) {
  347. if (write(options.datadumpfile, datadumpbuff, datalen)
  348. == -1)
  349. warnx("error writing data to primary dump file: %s",
  350. strerror(errno));
  351. }
  352. }
  353. else { /* full packet */
  354. pcap_dump((u_char *) options.savedumper, &pkthdr, pktdata);
  355. }
  356. }
  357. /* interface 2 */
  358. else {
  359. if (options.datadump_mode) { /* data only? */
  360. if (datalen) {
  361. if (write(options.datadumpfile2, datadumpbuff, datalen)
  362. == -1)
  363. warnx
  364. ("error writing data to secondary dump file: %s",
  365. strerror(errno));
  366. }
  367. }
  368. else { /* full packet */
  369. pcap_dump((u_char *) options.savedumper2, &pkthdr, pktdata);
  370. }
  371. }
  372. }
  373. else {
  374. /* write packet out on network */
  375. do {
  376. ret = libnet_adv_write_link(l, pktdata, pkthdr.caplen);
  377. if (ret == -1) {
  378. /* Make note of failed writes due to full buffers */
  379. if (errno == ENOBUFS) {
  380. failed++;
  381. }
  382. else {
  383. errx(1, "libnet_adv_write_link(): %s", strerror(errno));
  384. }
  385. }
  386. /* keep trying if fail, unless user Ctrl-C's */
  387. } while (ret == -1 && !didsig);
  388. }
  389. bytes_sent += pkthdr.caplen;
  390. pkts_sent++;
  391. /* again, OpenBSD is special, so use memcpy() rather then a
  392. * straight assignment
  393. */
  394. memcpy(&last, &pkthdr.ts, sizeof(struct timeval));
  395. } /* while() */
  396. /* free buffers */
  397. free(pktdata);
  398. #ifdef FORCE_ALIGN
  399. free(ipbuff);
  400. #endif
  401. /*
  402. * if we exited our while() loop, we need to exit
  403. * gracefully
  404. */
  405. if (options.limit_send == pkts_sent) {
  406. packet_stats();
  407. exit(1);
  408. }
  409. }
  410. /*
  411. * determines based upon the cachedata which interface the given packet
  412. * should go out. Also rewrites any layer 2 data we might need to adjust.
  413. * Returns a void cased pointer to the options.intfX of the corresponding
  414. * interface.
  415. */
  416. void *
  417. cache_mode(char *cachedata, u_int64_t packet_num, eth_hdr_t * eth_hdr)
  418. {
  419. void *l = NULL;
  420. int result;
  421. if (packet_num > cache_packets)
  422. errx(1, "Exceeded number of packets in cache file.");
  423. result = check_cache(cachedata, packet_num);
  424. if (result == CACHE_NOSEND) {
  425. dbg(2, "Cache: Not sending packet %d.", packet_num);
  426. return NULL;
  427. }
  428. else if (result == CACHE_PRIMARY) {
  429. dbg(2, "Cache: Sending packet %d out primary interface.", packet_num);
  430. l = options.intf1;
  431. /* check for dest/src MAC rewriting */
  432. if (memcmp(options.intf1_mac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  433. memcpy(eth_hdr->ether_dhost, options.intf1_mac, ETHER_ADDR_LEN);
  434. }
  435. if (memcmp(options.intf1_smac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  436. memcpy(eth_hdr->ether_shost, options.intf1_smac, ETHER_ADDR_LEN);
  437. }
  438. }
  439. else if (result == CACHE_SECONDARY) {
  440. dbg(2, "Cache: Sending packet %d out secondary interface.", packet_num);
  441. l = options.intf2;
  442. /* check for dest/src MAC rewriting */
  443. if (memcmp(options.intf2_mac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  444. memcpy(eth_hdr->ether_dhost, options.intf2_mac, ETHER_ADDR_LEN);
  445. }
  446. if (memcmp(options.intf2_smac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  447. memcpy(eth_hdr->ether_shost, options.intf2_smac, ETHER_ADDR_LEN);
  448. }
  449. }
  450. else {
  451. errx(1, "check_cache() returned an error. Aborting...");
  452. }
  453. return l;
  454. }
  455. /*
  456. * determines based upon the cidrdata which interface the given packet
  457. * should go out. Also rewrites any layer 2 data we might need to adjust.
  458. * Returns a void cased pointer to the options.intfX of the corresponding
  459. * interface.
  460. */
  461. void *
  462. cidr_mode(eth_hdr_t * eth_hdr, ip_hdr_t * ip_hdr)
  463. {
  464. void *l = NULL;
  465. if (ip_hdr == NULL) {
  466. /* non IP packets go out intf1 */
  467. l = options.intf1;
  468. /* check for dest/src MAC rewriting */
  469. if (memcmp(options.intf1_mac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  470. memcpy(eth_hdr->ether_dhost, options.intf1_mac, ETHER_ADDR_LEN);
  471. }
  472. if (memcmp(options.intf1_smac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  473. memcpy(eth_hdr->ether_shost, options.intf1_smac, ETHER_ADDR_LEN);
  474. }
  475. }
  476. else if (check_ip_CIDR(cidrdata, ip_hdr->ip_src.s_addr)) {
  477. /* set interface to send out packet */
  478. l = options.intf1;
  479. /* check for dest/src MAC rewriting */
  480. if (memcmp(options.intf1_mac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  481. memcpy(eth_hdr->ether_dhost, options.intf1_mac, ETHER_ADDR_LEN);
  482. }
  483. if (memcmp(options.intf1_smac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  484. memcpy(eth_hdr->ether_shost, options.intf1_smac, ETHER_ADDR_LEN);
  485. }
  486. }
  487. else {
  488. /* override interface to send out packet */
  489. l = options.intf2;
  490. /* check for dest/src MAC rewriting */
  491. if (memcmp(options.intf2_mac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  492. memcpy(eth_hdr->ether_dhost, options.intf2_mac, ETHER_ADDR_LEN);
  493. }
  494. if (memcmp(options.intf2_smac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
  495. memcpy(eth_hdr->ether_shost, options.intf2_smac, ETHER_ADDR_LEN);
  496. }
  497. }
  498. return l;
  499. }
  500. /*
  501. * Given the timestamp on the current packet and the last packet sent,
  502. * calculate the appropriate amount of time to sleep and do so.
  503. */
  504. void
  505. do_sleep(struct timeval *time, struct timeval *last, int len)
  506. {
  507. static struct timeval didsleep = { 0, 0 };
  508. static struct timeval start = { 0, 0 };
  509. struct timeval nap, now, delta;
  510. struct timespec ignore, sleep;
  511. float n;
  512. if (gettimeofday(&now, NULL) < 0) {
  513. err(1, "gettimeofday");
  514. }
  515. /* First time through for this file */
  516. if (!timerisset(last)) {
  517. start = now;
  518. timerclear(&delta);
  519. timerclear(&didsleep);
  520. }
  521. else {
  522. timersub(&now, &start, &delta);
  523. }
  524. if (options.mult) {
  525. /*
  526. * Replay packets a factor of the time they were originally sent.
  527. */
  528. if (timerisset(last) && timercmp(time, last, >)) {
  529. timersub(time, last, &nap);
  530. }
  531. else {
  532. /*
  533. * Don't sleep if this is our first packet, or if the
  534. * this packet appears to have been sent before the
  535. * last packet.
  536. */
  537. timerclear(&nap);
  538. }
  539. timerdiv(&nap, options.mult);
  540. }
  541. else if (options.rate) {
  542. /*
  543. * Ignore the time supplied by the capture file and send data at
  544. * a constant 'rate' (bytes per second).
  545. */
  546. if (timerisset(last)) {
  547. n = (float)len / (float)options.rate;
  548. nap.tv_sec = n;
  549. nap.tv_usec = (n - nap.tv_sec) * 1000000;
  550. }
  551. else {
  552. timerclear(&nap);
  553. }
  554. }
  555. else if (options.packetrate) {
  556. float pr;
  557. pr = 1 / options.packetrate;
  558. nap.tv_sec = pr;
  559. pr -= nap.tv_sec;
  560. nap.tv_usec = pr * 1000000;
  561. }
  562. timeradd(&didsleep, &nap, &didsleep);
  563. if (timercmp(&didsleep, &delta, >)) {
  564. timersub(&didsleep, &delta, &nap);
  565. sleep.tv_sec = nap.tv_sec;
  566. sleep.tv_nsec = nap.tv_usec * 1000; /* convert ms to ns */
  567. if (nanosleep(&sleep, &ignore) == -1) {
  568. warnx("nanosleep error: %s", strerror(errno));
  569. }
  570. }
  571. }