1 /* $Id$ */
2 
3 
4 /*
5  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
6  *   Copyright (c) 2013-2018 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
7  *
8  *   The Tcpreplay Suite of tools is free software: you can redistribute it
9  *   and/or modify it under the terms of the GNU General Public License as
10  *   published by the Free Software Foundation, either version 3 of the
11  *   License, or with the authors permission any later version.
12  *
13  *   The Tcpreplay Suite is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with the Tcpreplay Suite.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "config.h"
23 #include "defines.h"
24 #include "common.h"
25 
26 #include <sys/time.h>
27 #include <sys/types.h>
28 #include <signal.h>
29 #include <string.h>
30 #include <netinet/in.h>
31 #include <errno.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 
36 #include "tcpreplay_api.h"
37 #include "timestamp_trace.h"
38 #include "../lib/sll.h"
39 
40 #ifdef HAVE_NETMAP
41 #ifdef HAVE_SYS_POLL_H
42 #include <sys/poll.h>
43 #endif
44 #include <sys/ioctl.h>
45 #include <net/netmap.h>
46 #include <net/netmap_user.h>
47 #endif /* HAVE_NETMAP */
48 
49 #ifdef TCPREPLAY
50 
51 #ifdef TCPREPLAY_EDIT
52 #include "tcpreplay_edit_opts.h"
53 #include "tcpedit/tcpedit.h"
54 extern tcpedit_t *tcpedit;
55 #else
56 #include "tcpreplay_opts.h"
57 #endif /* TCPREPLAY_EDIT */
58 
59 #endif /* TCPREPLAY */
60 
61 #include "send_packets.h"
62 #include "sleep.h"
63 
64 #ifdef DEBUG
65 extern int debug;
66 #endif
67 
68 static void calc_sleep_time(tcpreplay_t *ctx, struct timeval *pkt_time,
69         struct timeval *last, COUNTER len,
70         sendpacket_t *sp, COUNTER counter, timestamp_t *sent_timestamp,
71         COUNTER start_us, COUNTER *skip_length);
72 static void tcpr_sleep(tcpreplay_t *ctx, sendpacket_t *sp _U_,
73         struct timespec *nap_this_time, struct timeval *now);
74 static u_char *get_next_packet(tcpreplay_t *ctx, pcap_t *pcap,
75         struct pcap_pkthdr *pkthdr,
76         int file_idx,
77         packet_cache_t **prev_packet);
78 static uint32_t get_user_count(tcpreplay_t *ctx, sendpacket_t *sp, COUNTER counter);
79 
wake_send_queues(sendpacket_t * sp _U_,tcpreplay_opt_t * options _U_)80 static inline void wake_send_queues(sendpacket_t *sp _U_,
81 		tcpreplay_opt_t *options _U_)
82 {
83 #ifdef HAVE_NETMAP
84     if (options->netmap)
85         ioctl(sp->handle.fd, NIOCTXSYNC, NULL);   /* flush TX buffer */
86 #endif
87 }
88 
89 static inline int
fast_edit_packet(struct pcap_pkthdr * pkthdr,u_char ** pktdata,COUNTER iteration,bool cached,int datalink)90 fast_edit_packet(struct pcap_pkthdr *pkthdr, u_char **pktdata,
91         COUNTER iteration, bool cached, int datalink)
92 {
93     uint16_t ether_type;
94     ipv4_hdr_t *ip_hdr = NULL;
95     ipv6_hdr_t *ip6_hdr = NULL;
96     uint32_t src_ip, dst_ip;
97     uint32_t src_ip_orig, dst_ip_orig;
98     int l2_len;
99     u_char *packet = *pktdata;
100 
101     l2_len = get_l2len(packet, pkthdr->caplen, datalink);
102     if (l2_len < 0)
103         return -1;
104 
105     ether_type = get_l2protocol(packet, pkthdr->caplen, datalink);
106     switch (ether_type) {
107     case ETHERTYPE_IP:
108         if (pkthdr->caplen < (bpf_u_int32)(l2_len + sizeof(ipv4_hdr_t))) {
109             dbgx(1, "IP packet too short for Unique IP feature: %u", pkthdr->caplen);
110             return -1;
111         }
112         ip_hdr = (ipv4_hdr_t *)(packet + l2_len);
113         src_ip_orig = src_ip = ntohl(ip_hdr->ip_src.s_addr);
114         dst_ip_orig = dst_ip = ntohl(ip_hdr->ip_dst.s_addr);
115         break;
116 
117     case ETHERTYPE_IP6:
118         if (pkthdr->caplen < (bpf_u_int32)(l2_len + sizeof(ipv6_hdr_t))) {
119             dbgx(1, "IP6 packet too short for Unique IP feature: %u", pkthdr->caplen);
120             return -1;
121         }
122         ip6_hdr = (ipv6_hdr_t *)(packet + l2_len);
123         src_ip_orig = src_ip = ntohl(ip6_hdr->ip_src.__u6_addr.__u6_addr32[3]);
124         dst_ip_orig = dst_ip = ntohl(ip6_hdr->ip_dst.__u6_addr.__u6_addr32[3]);
125         break;
126 
127     default:
128         return -1; /* non-IP or packet too short */
129     }
130 
131     dbgx(2, "Layer 3 protocol type is: 0x%04x", ether_type);
132 
133     /* swap src/dst IP's in a manner that does not affect CRC */
134     if ((!cached && dst_ip > src_ip) ||
135             (cached && (dst_ip - iteration) > (src_ip - 1 - iteration))) {
136         if (cached) {
137             --src_ip;
138             ++dst_ip;
139         } else {
140             src_ip -= iteration;
141             dst_ip += iteration;
142         }
143 
144         /* CRC compensations  for wrap conditions */
145         if (src_ip > src_ip_orig && dst_ip > dst_ip_orig) {
146             dbgx(1, "dst_ip > src_ip(" COUNTER_SPEC "): before(1) src_ip=0x%08x dst_ip=0x%08x", iteration, src_ip, dst_ip);
147             --src_ip;
148             dbgx(1, "dst_ip > src_ip(" COUNTER_SPEC "): after(1)  src_ip=0x%08x dst_ip=0x%08x", iteration, src_ip, dst_ip);
149         } else if (dst_ip < dst_ip_orig && src_ip < src_ip_orig) {
150             dbgx(1, "dst_ip > src_ip(" COUNTER_SPEC "): before(2) src_ip=0x%08x dst_ip=0x%08x", iteration, src_ip, dst_ip);
151             ++dst_ip;
152             dbgx(1, "dst_ip > src_ip(" COUNTER_SPEC "): after(2)  src_ip=0x%08x dst_ip=0x%08x", iteration, src_ip, dst_ip);
153         }
154     } else {
155         if (cached) {
156             ++src_ip;
157             --dst_ip;
158         } else {
159             src_ip += iteration;
160             dst_ip -= iteration;
161         }
162 
163         /* CRC compensations  for wrap conditions */
164         if (dst_ip > dst_ip_orig && src_ip > src_ip_orig) {
165             dbgx(1, "src_ip > dst_ip(" COUNTER_SPEC "): before(1) dst_ip=0x%08x src_ip=0x%08x", iteration, dst_ip, src_ip);
166             --dst_ip;
167             dbgx(1, "src_ip > dst_ip(" COUNTER_SPEC "): after(1)  dst_ip=0x%08x src_ip=0x%08x", iteration, dst_ip, src_ip);
168         } else if (src_ip < src_ip_orig && dst_ip < dst_ip_orig) {
169             dbgx(1, "src_ip > dst_ip(" COUNTER_SPEC "): before(2) dst_ip=0x%08x src_ip=0x%08x", iteration, dst_ip, src_ip);
170             ++src_ip;
171             dbgx(1, "src_ip > dst_ip(" COUNTER_SPEC "): after(2)  dst_ip=0x%08x src_ip=0x%08x", iteration, dst_ip, src_ip);
172         }
173     }
174 
175     dbgx(1, "(" COUNTER_SPEC "): final src_ip=0x%08x dst_ip=0x%08x", iteration, src_ip, dst_ip);
176 
177     switch (ether_type) {
178     case ETHERTYPE_IP:
179         ip_hdr->ip_src.s_addr = htonl(src_ip);
180         ip_hdr->ip_dst.s_addr = htonl(dst_ip);
181         break;
182 
183     case ETHERTYPE_IP6:
184         ip6_hdr->ip_src.__u6_addr.__u6_addr32[3] = htonl(src_ip);
185         ip6_hdr->ip_dst.__u6_addr.__u6_addr32[3] = htonl(dst_ip);
186         break;
187     }
188 
189     return 0;
190 }
191 
192 /**
193  * \brief Update flow stats
194  *
195  * Finds out if flow is unique and updates stats.
196  */
update_flow_stats(tcpreplay_t * ctx,sendpacket_t * sp,const struct pcap_pkthdr * pkthdr,const u_char * pktdata,int datalink)197 static inline void update_flow_stats(tcpreplay_t *ctx, sendpacket_t *sp,
198         const struct pcap_pkthdr *pkthdr, const u_char *pktdata, int datalink)
199 {
200     flow_entry_type_t res = flow_decode(ctx->flow_hash_table,
201             pkthdr, pktdata, datalink, ctx->options->flow_expiry);
202 
203     switch (res) {
204     case FLOW_ENTRY_NEW:
205         ++ctx->stats.flows;
206         ++ctx->stats.flows_unique;
207         ++ctx->stats.flow_packets;
208         if (sp) {
209             ++sp->flows;
210             ++sp->flows_unique;
211             ++sp->flow_packets;
212         }
213         break;
214 
215     case FLOW_ENTRY_EXISTING:
216         ++ctx->stats.flow_packets;
217         if (sp)
218             ++sp->flow_packets;
219         break;
220 
221     case FLOW_ENTRY_EXPIRED:
222         ++ctx->stats.flows_expired;
223         ++ctx->stats.flows;
224         ++ctx->stats.flow_packets;
225         if (sp) {
226             ++sp->flows_expired;
227             ++sp->flows;
228             ++sp->flow_packets;
229         }
230          break;
231 
232     case FLOW_ENTRY_NON_IP:
233         ++ctx->stats.flow_non_flow_packets;
234         if (sp)
235             ++sp->flow_non_flow_packets;
236         break;
237 
238     case FLOW_ENTRY_INVALID:
239         ++ctx->stats.flows_invalid_packets;
240         if (sp)
241             ++sp->flows_invalid_packets;
242         break;
243     }
244 }
245 /**
246  * \brief Preloads the memory cache for the given pcap file_idx
247  *
248  * Preloading can be used with or without --loop
249  */
250 void
preload_pcap_file(tcpreplay_t * ctx,int idx)251 preload_pcap_file(tcpreplay_t *ctx, int idx)
252 {
253     tcpreplay_opt_t *options = ctx->options;
254     char *path = options->sources[idx].filename;
255     pcap_t *pcap = NULL;
256     char ebuf[PCAP_ERRBUF_SIZE];
257     const u_char *pktdata = NULL;
258     struct pcap_pkthdr pkthdr;
259     packet_cache_t *cached_packet = NULL;
260     packet_cache_t **prev_packet = &cached_packet;
261     COUNTER packetnum = 0;
262     int dlt;
263 
264     /* close stdin if reading from it (needed for some OS's) */
265     if (strncmp(path, "-", 1) == 0)
266         if (close(1) == -1)
267             warnx("unable to close stdin: %s", strerror(errno));
268 
269     if ((pcap = pcap_open_offline(path, ebuf)) == NULL)
270         errx(-1, "Error opening pcap file: %s", ebuf);
271 
272     dlt = pcap_datalink(pcap);
273     /* loop through the pcap.  get_next_packet() builds the cache for us! */
274     while ((pktdata = get_next_packet(ctx, pcap, &pkthdr, idx, prev_packet)) != NULL) {
275         packetnum++;
276         if (options->flow_stats)
277             update_flow_stats(ctx, NULL, &pkthdr, pktdata, dlt);
278     }
279 
280     /* mark this file as cached */
281     options->file_cache[idx].cached = TRUE;
282     options->file_cache[idx].dlt = dlt;
283     pcap_close(pcap);
284 }
285 
increment_iteration(tcpreplay_t * ctx)286 static void increment_iteration(tcpreplay_t *ctx)
287 {
288     tcpreplay_opt_t *options = ctx->options;
289 
290     ctx->last_unique_iteration = ctx->unique_iteration;
291     ++ctx->iteration;
292     if (options->unique_ip) {
293         assert(options->unique_loops > 0.0);
294         ctx->unique_iteration =
295                 ((ctx->iteration * 1000) / (COUNTER)(options->unique_loops * 1000.0))
296                 + 1;
297     }
298 }
299 
300 /**
301  * the main loop function for tcpreplay.  This is where we figure out
302  * what to do with each packet
303  */
304 void
send_packets(tcpreplay_t * ctx,pcap_t * pcap,int idx)305 send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
306 {
307 
308     struct timeval print_delta, now, last_pkt_ts;
309     tcpreplay_opt_t *options = ctx->options;
310     tcpreplay_stats_t *stats = &ctx->stats;
311     COUNTER packetnum = 0;
312     COUNTER limit_send = options->limit_send;
313     struct pcap_pkthdr pkthdr;
314     u_char *pktdata = NULL;
315     sendpacket_t *sp = ctx->intf1;
316     COUNTER pktlen;
317     packet_cache_t *cached_packet = NULL;
318     packet_cache_t **prev_packet = NULL;
319 #if defined TCPREPLAY && defined TCPREPLAY_EDIT
320     struct pcap_pkthdr *pkthdr_ptr;
321 #endif
322     int datalink = options->file_cache[idx].dlt;
323     COUNTER skip_length = 0;
324     COUNTER end_us;
325     bool preload = options->file_cache[idx].cached;
326     bool top_speed = (options->speed.mode == speed_topspeed ||
327             (options->speed.mode == speed_mbpsrate && options->speed.speed == 0));
328     bool now_is_now = true;
329 
330     gettimeofday(&now, NULL);
331     if (!timerisset(&stats->start_time)) {
332         TIMEVAL_SET(&stats->start_time, &now);
333         if (ctx->options->stats >= 0) {
334             char buf[64];
335             if (format_date_time(&stats->start_time, buf, sizeof(buf)) > 0)
336                 printf("Test start: %s ...\n", buf);
337         }
338     }
339 
340     ctx->skip_packets = 0;
341     timerclear(&last_pkt_ts);
342     timerclear(&stats->first_packet_sent_wall_time);
343     if (options->limit_time > 0)
344         end_us = TIMEVAL_TO_MICROSEC(&stats->start_time) +
345             SEC_TO_MICROSEC(options->limit_time);
346     else
347         end_us = 0;
348 
349     if (options->preload_pcap) {
350         prev_packet = &cached_packet;
351     } else {
352         prev_packet = NULL;
353     }
354 
355     /* MAIN LOOP
356      * Keep sending while we have packets or until
357      * we've sent enough packets
358      */
359     while (!ctx->abort &&
360             (pktdata = get_next_packet(ctx, pcap, &pkthdr, idx, prev_packet)) != NULL) {
361 
362         now_is_now = false;
363         packetnum++;
364 #if defined TCPREPLAY || defined TCPREPLAY_EDIT
365         /* do we use the snaplen (caplen) or the "actual" packet len? */
366         pktlen = options->use_pkthdr_len ? (COUNTER)pkthdr.len : (COUNTER)pkthdr.caplen;
367 #elif TCPBRIDGE
368         pktlen = (COUNTER)pkthdr.caplen;
369 #else
370 #error WTF???  We should not be here!
371 #endif
372 
373         dbgx(2, "packet " COUNTER_SPEC " caplen " COUNTER_SPEC, packetnum, pktlen);
374 
375         /* Dual nic processing */
376         if (ctx->intf2 != NULL) {
377             sp = (sendpacket_t *)cache_mode(ctx, options->cachedata, packetnum);
378 
379             /* sometimes we should not send the packet */
380             if (sp == TCPR_DIR_NOSEND)
381                 continue;
382         }
383 
384 #if defined TCPREPLAY && defined TCPREPLAY_EDIT
385         pkthdr_ptr = &pkthdr;
386         if (tcpedit_packet(tcpedit, &pkthdr_ptr, &pktdata, sp->cache_dir) == -1) {
387             errx(-1, "Error editing packet #" COUNTER_SPEC ": %s", packetnum, tcpedit_geterr(tcpedit));
388         }
389         pktlen = options->use_pkthdr_len ? (COUNTER)pkthdr_ptr->len : (COUNTER)pkthdr_ptr->caplen;
390 #endif
391 
392         if (ctx->options->unique_ip && ctx->unique_iteration &&
393                 ctx->unique_iteration > ctx->last_unique_iteration) {
394             /* edit packet to ensure every pass has unique IP addresses */
395             if (fast_edit_packet(&pkthdr, &pktdata, ctx->unique_iteration - 1,
396                     preload, datalink) == -1) {
397                 ++stats->failed;
398                 continue;
399             }
400         }
401 
402         /* update flow stats */
403         if (options->flow_stats && !preload)
404             update_flow_stats(ctx,
405                     options->cache_packets ? sp : NULL, &pkthdr, pktdata, datalink);
406 
407         /*
408          * this accelerator improves performance by avoiding expensive
409          * time stamps during periods where we have fallen behind in our
410          * sending
411          */
412         if (skip_length && pktlen < skip_length) {
413             skip_length -= pktlen;
414         } else if (ctx->skip_packets) {
415             --ctx->skip_packets;
416         } else {
417             /*
418              * time stamping is expensive, but now is the
419              * time to do it.
420              */
421             dbgx(4, "This packet time: " TIMEVAL_FORMAT, pkthdr.ts.tv_sec,
422                     pkthdr.ts.tv_usec);
423             skip_length = 0;
424             ctx->skip_packets = 0;
425 
426             if (options->speed.mode == speed_multiplier) {
427                 if(!timerisset(&stats->first_packet_sent_wall_time)) {
428                     /* We're sending the first packet, so we have an absolute time reference. */
429                     TIMEVAL_SET(&stats->first_packet_sent_wall_time, &now);
430                     TIMEVAL_SET(&stats->first_packet_pcap_timestamp, &pkthdr.ts);
431                 }
432 
433                 if (!timerisset(&last_pkt_ts)) {
434                     TIMEVAL_SET(&last_pkt_ts, &pkthdr.ts);
435                 } else if (timercmp(&pkthdr.ts, &last_pkt_ts, >)) {
436                     /* pkt_ts_delta is the packet time stamp difference since the first packet */
437                     timersub(&pkthdr.ts, &stats->first_packet_pcap_timestamp, &stats->pkt_ts_delta);
438 
439                     /* time_delta is the wall time difference since sending the first packet */
440                     timersub(&now, &stats->first_packet_sent_wall_time, &stats->time_delta);
441 
442                     TIMEVAL_SET(&last_pkt_ts, &pkthdr.ts);
443                 }
444             }
445 
446             if (!top_speed) {
447                 now_is_now = true;
448                 gettimeofday(&now, NULL);
449             }
450 
451             /*
452              * Only if the current packet is not late.
453              *
454              * This also sets skip_length and skip_packets which will avoid
455              * timestamping for a given number of packets.
456              */
457             calc_sleep_time(ctx, &stats->pkt_ts_delta, &stats->time_delta,
458                     pktlen, sp, packetnum, &stats->end_time,
459                     TIMEVAL_TO_MICROSEC(&stats->start_time), &skip_length);
460 
461             /*
462              * Track the time of the "last packet sent".
463              *
464              * A number of 3rd party tools generate bad timestamps which go backwards
465              * in time.  Hence, don't update the "last" unless pkthdr.ts > last
466              */
467             if (timercmp(&stats->time_delta, &stats->pkt_ts_delta, <))
468                 TIMEVAL_SET(&stats->time_delta, &stats->pkt_ts_delta);
469 
470             /*
471              * we know how long to sleep between sends, now do it.
472              */
473             if (!top_speed)
474                 tcpr_sleep(ctx, sp, &ctx->nap, &now);
475         }
476 
477 #ifdef ENABLE_VERBOSE
478         /* do we need to print the packet via tcpdump? */
479         if (options->verbose)
480             tcpdump_print(options->tcpdump, &pkthdr, pktdata);
481 #endif
482 
483         dbgx(2, "Sending packet #" COUNTER_SPEC, packetnum);
484         /* write packet out on network */
485         if (sendpacket(sp, pktdata, pktlen, &pkthdr) < (int)pktlen) {
486             warnx("Unable to send packet: %s", sendpacket_geterr(sp));
487             break;
488         }
489 
490         /*
491          * Mark the time when we sent the last packet
492          */
493         TIMEVAL_SET(&stats->end_time, &now);
494 
495 #ifdef TIMESTAMP_TRACE
496         add_timestamp_trace_entry(pktlen, &stats->end_time, skip_length);
497 #endif
498 
499         stats->pkts_sent++;
500         stats->bytes_sent += pktlen;
501 
502         /* print stats during the run? */
503         if (options->stats > 0) {
504             if (! timerisset(&stats->last_print)) {
505                 TIMEVAL_SET(&stats->last_print, &now);
506             } else {
507                 timersub(&now, &stats->last_print, &print_delta);
508                 if (print_delta.tv_sec >= options->stats) {
509                     TIMEVAL_SET(&stats->end_time, &now);
510                     packet_stats(stats);
511                     TIMEVAL_SET(&stats->last_print, &now);
512                 }
513             }
514         }
515 
516 #if defined HAVE_NETMAP
517         if (sp->first_packet || timesisset(&ctx->nap)) {
518             wake_send_queues(sp, options);
519             sp->first_packet = false;
520         }
521 #endif
522         /* stop sending based on the duration limit... */
523         if ((end_us > 0 && (COUNTER)TIMEVAL_TO_MICROSEC(&now) > end_us) ||
524                 /* ... or stop sending based on the limit -L? */
525                 (limit_send > 0 && stats->pkts_sent >= limit_send)) {
526             ctx->abort = true;
527         }
528     } /* while */
529 
530 
531 #ifdef HAVE_NETMAP
532     /* when completing test, wait until the last packet is sent */
533     if (options->netmap && (ctx->abort || options->loop == 1)) {
534         while (ctx->intf1 && !netmap_tx_queues_empty(ctx->intf1)) {
535             now_is_now = true;
536             gettimeofday(&now, NULL);
537         }
538 
539         while (ctx->intf2 && !netmap_tx_queues_empty(ctx->intf2)) {
540             now_is_now = true;
541             gettimeofday(&now, NULL);
542         }
543     }
544 #endif /* HAVE_NETMAP */
545 
546     if (!now_is_now)
547         gettimeofday(&now, NULL);
548 
549     TIMEVAL_SET(&stats->end_time, &now);
550 
551     increment_iteration(ctx);
552 }
553 
554 /**
555  * the alternate main loop function for tcpreplay.  This is where we figure out
556  * what to do with each packet when processing two files a the same time
557  */
558 void
send_dual_packets(tcpreplay_t * ctx,pcap_t * pcap1,int cache_file_idx1,pcap_t * pcap2,int cache_file_idx2)559 send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *pcap2, int cache_file_idx2)
560 {
561     struct timeval print_delta, now, last_pkt_ts;
562     tcpreplay_opt_t *options = ctx->options;
563     tcpreplay_stats_t *stats = &ctx->stats;
564     COUNTER packetnum = 0;
565     COUNTER limit_send = options->limit_send;
566     int cache_file_idx;
567     struct pcap_pkthdr pkthdr1, pkthdr2;
568     u_char *pktdata1 = NULL, *pktdata2 = NULL, *pktdata = NULL;
569     sendpacket_t *sp;
570     COUNTER pktlen;
571     packet_cache_t *cached_packet1 = NULL, *cached_packet2 = NULL;
572     packet_cache_t **prev_packet1 = NULL, **prev_packet2 = NULL;
573     struct pcap_pkthdr *pkthdr_ptr;
574     int datalink;
575     COUNTER end_us;
576     COUNTER skip_length = 0;
577     bool top_speed = (options->speed.mode == speed_topspeed ||
578             (options->speed.mode == speed_mbpsrate && options->speed.speed == 0));
579     bool now_is_now = true;
580 
581     gettimeofday(&now, NULL);
582     if (!timerisset(&stats->start_time)) {
583         TIMEVAL_SET(&stats->start_time, &now);
584         if (ctx->options->stats >= 0) {
585             char buf[64];
586             if (format_date_time(&stats->start_time, buf, sizeof(buf)) > 0)
587                 printf("Dual test start: %s ...\n", buf);
588         }
589     }
590 
591     ctx->skip_packets = 0;
592     timerclear(&last_pkt_ts);
593     timerclear(&stats->first_packet_sent_wall_time);
594     if (options->limit_time > 0)
595         end_us = TIMEVAL_TO_MICROSEC(&stats->start_time) +
596             SEC_TO_MICROSEC(options->limit_time);
597     else
598         end_us = 0;
599 
600     if (options->preload_pcap) {
601         prev_packet1 = &cached_packet1;
602         prev_packet2 = &cached_packet2;
603     } else {
604         prev_packet1 = NULL;
605         prev_packet2 = NULL;
606     }
607 
608     pktdata1 = get_next_packet(ctx, pcap1, &pkthdr1, cache_file_idx1, prev_packet1);
609     pktdata2 = get_next_packet(ctx, pcap2, &pkthdr2, cache_file_idx2, prev_packet2);
610 
611     /* MAIN LOOP
612      * Keep sending while we have packets or until
613      * we've sent enough packets
614      */
615     while (!ctx->abort &&
616             !(pktdata1 == NULL && pktdata2 == NULL)) {
617 
618         now_is_now = false;
619         packetnum++;
620 
621         /* figure out which pcap file we need to process next
622          * when get_next_packet() returns null for pktdata, the pkthdr
623          * will still have the old values from the previous call.  This
624          * means we can't always trust the timestamps to tell us which
625          * file to process.
626          */
627         if (pktdata1 == NULL) {
628             /* file 2 is next */
629             sp = ctx->intf2;
630             datalink = options->file_cache[cache_file_idx2].dlt;
631             pkthdr_ptr = &pkthdr2;
632             cache_file_idx = cache_file_idx2;
633             pktdata = pktdata2;
634         } else if (pktdata2 == NULL) {
635             /* file 1 is next */
636             sp = ctx->intf1;
637             datalink = options->file_cache[cache_file_idx1].dlt;
638             pkthdr_ptr = &pkthdr1;
639             cache_file_idx = cache_file_idx1;
640             pktdata = pktdata1;
641         } else if (timercmp(&pkthdr1.ts, &pkthdr2.ts, <=)) {
642             /* file 1 is next */
643             sp = ctx->intf1;
644             datalink = options->file_cache[cache_file_idx1].dlt;
645             pkthdr_ptr = &pkthdr1;
646             cache_file_idx = cache_file_idx1;
647             pktdata = pktdata1;
648         } else {
649             /* file 2 is next */
650             sp = ctx->intf2;
651             datalink = options->file_cache[cache_file_idx2].dlt;
652             pkthdr_ptr = &pkthdr2;
653             cache_file_idx = cache_file_idx2;
654             pktdata = pktdata2;
655         }
656 
657 #if defined TCPREPLAY || defined TCPREPLAY_EDIT
658         /* do we use the snaplen (caplen) or the "actual" packet len? */
659         pktlen = options->use_pkthdr_len ? (COUNTER)pkthdr_ptr->len : (COUNTER)pkthdr_ptr->caplen;
660 #elif TCPBRIDGE
661         pktlen = (COUNTER)pkthdr_ptr->caplen;
662 #else
663 #error WTF???  We should not be here!
664 #endif
665 
666         dbgx(2, "packet " COUNTER_SPEC " caplen " COUNTER_SPEC, packetnum, pktlen);
667 
668 #if defined TCPREPLAY && defined TCPREPLAY_EDIT
669         if (tcpedit_packet(tcpedit, &pkthdr_ptr, &pktdata, sp->cache_dir) == -1) {
670             errx(-1, "Error editing packet #" COUNTER_SPEC ": %s", packetnum, tcpedit_geterr(tcpedit));
671         }
672         pktlen = options->use_pkthdr_len ? (COUNTER)pkthdr_ptr->len : (COUNTER)pkthdr_ptr->caplen;
673 #endif
674 
675         if (ctx->options->unique_ip && ctx->unique_iteration &&
676                 ctx->unique_iteration > ctx->last_unique_iteration) {
677             /* edit packet to ensure every pass is unique */
678             if (fast_edit_packet(pkthdr_ptr, &pktdata, ctx->unique_iteration - 1,
679                     options->file_cache[cache_file_idx].cached, datalink) == -1) {
680                 ++stats->failed;
681                 continue;
682             }
683         }
684 
685         /* update flow stats */
686         if (options->flow_stats && !options->file_cache[cache_file_idx].cached)
687             update_flow_stats(ctx, sp, pkthdr_ptr, pktdata, datalink);
688 
689         /*
690          * this accelerator improves performance by avoiding expensive
691          * time stamps during periods where we have fallen behind in our
692          * sending
693          */
694         if (skip_length && pktlen < skip_length) {
695             skip_length -= pktlen;
696         } else if (ctx->skip_packets) {
697             --ctx->skip_packets;
698         } else {
699             /*
700              * time stamping is expensive, but now is the
701              * time to do it.
702              */
703             dbgx(4, "This packet time: " TIMEVAL_FORMAT, pkthdr_ptr->ts.tv_sec,
704                     pkthdr_ptr->ts.tv_usec);
705             skip_length = 0;
706             ctx->skip_packets = 0;
707 
708             if (options->speed.mode == speed_multiplier) {
709                 if(!timerisset(&stats->first_packet_sent_wall_time)) {
710                     /* We're sending the first packet, so we have an absolute time reference. */
711                     TIMEVAL_SET(&stats->first_packet_sent_wall_time, &now);
712                     TIMEVAL_SET(&stats->first_packet_pcap_timestamp, &pkthdr_ptr->ts);
713                 }
714 
715                 if (!timerisset(&last_pkt_ts)) {
716                     TIMEVAL_SET(&last_pkt_ts, &pkthdr_ptr->ts);
717                 } else if (timercmp(&pkthdr_ptr->ts, &last_pkt_ts, >)) {
718                     /* pkt_ts_delta is the packet time stamp difference since the first packet */
719                     timersub(&pkthdr_ptr->ts, &stats->first_packet_pcap_timestamp, &stats->pkt_ts_delta);
720 
721                     /* time_delta is the wall time difference since sending the first packet */
722                     timersub(&now, &stats->first_packet_sent_wall_time, &stats->time_delta);
723 
724                     TIMEVAL_SET(&last_pkt_ts, &pkthdr_ptr->ts);
725                 }
726             }
727 
728             if (!top_speed) {
729                 gettimeofday(&now, NULL);
730                 now_is_now = true;
731             }
732 
733             /*
734              * Only if the current packet is not late.
735              *
736              * This also sets skip_length and skip_packets which will avoid
737              * timestamping for a given number of packets.
738              */
739             calc_sleep_time(ctx, &stats->pkt_ts_delta, &stats->time_delta,
740                     pktlen, sp, packetnum, &stats->end_time,
741                     TIMEVAL_TO_MICROSEC(&stats->start_time), &skip_length);
742 
743             /*
744              * Track the time of the "last packet sent".
745              *
746              * A number of 3rd party tools generate bad timestamps which go backwards
747              * in time.  Hence, don't update the "last" unless pkthdr_ptr->ts > last
748              */
749             if (timercmp(&stats->time_delta, &stats->pkt_ts_delta, <))
750                 TIMEVAL_SET(&stats->time_delta, &stats->pkt_ts_delta);
751 
752             /*
753              * we know how long to sleep between sends, now do it.
754              */
755             if (!top_speed)
756                 tcpr_sleep(ctx, sp, &ctx->nap, &now);
757         }
758 
759 #ifdef ENABLE_VERBOSE
760         /* do we need to print the packet via tcpdump? */
761         if (options->verbose)
762             tcpdump_print(options->tcpdump, pkthdr_ptr, pktdata);
763 #endif
764 
765         dbgx(2, "Sending packet #" COUNTER_SPEC, packetnum);
766         /* write packet out on network */
767         if (sendpacket(sp, pktdata, pktlen, pkthdr_ptr) < (int)pktlen) {
768             warnx("Unable to send packet: %s", sendpacket_geterr(sp));
769             break;
770         }
771 
772         /*
773          * Mark the time when we sent the last packet
774          */
775         TIMEVAL_SET(&stats->end_time, &now);
776 
777         ++stats->pkts_sent;
778         stats->bytes_sent += pktlen;
779 
780         /* print stats during the run? */
781         if (options->stats > 0) {
782             if (! timerisset(&stats->last_print)) {
783                 TIMEVAL_SET(&stats->last_print, &now);
784             } else {
785                 timersub(&now, &stats->last_print, &print_delta);
786                 if (print_delta.tv_sec >= options->stats) {
787                     TIMEVAL_SET(&stats->end_time, &now);
788                     packet_stats(stats);
789                     TIMEVAL_SET(&stats->last_print, &now);
790                 }
791             }
792         }
793 
794 #if defined HAVE_NETMAP
795         if (sp->first_packet || timesisset(&ctx->nap)) {
796             wake_send_queues(sp, options);
797             sp->first_packet = false;
798         }
799 #endif
800 
801         /* get the next packet for this file handle depending on which we last used */
802         if (sp == ctx->intf2) {
803             pktdata2 = get_next_packet(ctx, pcap2, &pkthdr2, cache_file_idx2, prev_packet2);
804         } else {
805             pktdata1 = get_next_packet(ctx, pcap1, &pkthdr1, cache_file_idx1, prev_packet1);
806         }
807 
808         /* stop sending based on the duration limit... */
809         if ((end_us > 0 && (COUNTER)TIMEVAL_TO_MICROSEC(&now) > end_us) ||
810                 /* ... or stop sending based on the limit -L? */
811                 (limit_send > 0 && stats->pkts_sent >= limit_send)) {
812             ctx->abort = true;
813         }
814     } /* while */
815 
816 #ifdef HAVE_NETMAP
817     /* when completing test, wait until the last packet is sent */
818     if (options->netmap && (ctx->abort || options->loop == 1)) {
819         while (ctx->intf1 && !netmap_tx_queues_empty(ctx->intf1)) {
820             gettimeofday(&now, NULL);
821             now_is_now = true;
822         }
823 
824         while (ctx->intf2 && !netmap_tx_queues_empty(ctx->intf2)) {
825             gettimeofday(&now, NULL);
826             now_is_now = true;
827         }
828     }
829 #endif /* HAVE_NETMAP */
830 
831     if (!now_is_now)
832         gettimeofday(&now, NULL);
833 
834     TIMEVAL_SET(&stats->end_time, &now);
835 
836     increment_iteration(ctx);
837 }
838 
839 
840 
841 /**
842  * Gets the next packet to be sent out. This will either read from the pcap file
843  * or will retrieve the packet from the internal cache.
844  *
845  * The parameter prev_packet is used as the parent of the new entry in the cache list.
846  * This should be NULL on the first call to this function for each file and
847  * will be updated as new entries are added (or retrieved) from the cache list.
848  */
849 u_char *
get_next_packet(tcpreplay_t * ctx,pcap_t * pcap,struct pcap_pkthdr * pkthdr,int idx,packet_cache_t ** prev_packet)850 get_next_packet(tcpreplay_t *ctx, pcap_t *pcap, struct pcap_pkthdr *pkthdr, int idx,
851     packet_cache_t **prev_packet)
852 {
853     tcpreplay_opt_t *options = ctx->options;
854     u_char *pktdata = NULL;
855     uint32_t pktlen;
856 
857     /* pcap may be null in cache mode! */
858     /* packet_cache_t may be null in file read mode! */
859     assert(pkthdr);
860 
861     /*
862      * Check if we're caching files
863      */
864     if (options->preload_pcap && (prev_packet != NULL)) {
865         /*
866          * Yes we are caching files - has this one been cached?
867          */
868         if (options->file_cache[idx].cached) {
869             if (*prev_packet == NULL) {
870                 /*
871                  * Get the first packet in the cache list directly from the file
872                  */
873                 *prev_packet = options->file_cache[idx].packet_cache;
874             } else {
875                 /*
876                  * Get the next packet in the cache list
877                  */
878                 *prev_packet = (*prev_packet)->next;
879             }
880 
881             if (*prev_packet != NULL) {
882                 pktdata = (*prev_packet)->pktdata;
883                 memcpy(pkthdr, &((*prev_packet)->pkthdr), sizeof(struct pcap_pkthdr));
884             }
885         } else {
886             /*
887              * We should read the pcap file, and cache the results
888              */
889             pktdata = safe_pcap_next(pcap, pkthdr);
890             if (pktdata != NULL) {
891                 if (*prev_packet == NULL) {
892                     /*
893                      * Create the first packet in the list
894                      */
895                     *prev_packet = safe_malloc(sizeof(packet_cache_t));
896                     options->file_cache[idx].packet_cache = *prev_packet;
897                 } else {
898                     /*
899                      * Add a packet to the end of the list
900                      */
901                     (*prev_packet)->next = safe_malloc(sizeof(packet_cache_t));
902                     *prev_packet = (*prev_packet)->next;
903                 }
904 
905                 if (*prev_packet != NULL) {
906                     (*prev_packet)->next = NULL;
907                     pktlen = pkthdr->caplen;
908 
909                     (*prev_packet)->pktdata = safe_malloc(pktlen + PACKET_HEADROOM);
910                     memcpy((*prev_packet)->pktdata, pktdata, pktlen);
911                     memcpy(&((*prev_packet)->pkthdr), pkthdr, sizeof(struct pcap_pkthdr));
912                 }
913             }
914         }
915     } else {
916         /*
917          * Read pcap file as normal
918          */
919         pktdata = safe_pcap_next(pcap, pkthdr);
920     }
921 
922     /* this gets casted to a const on the way out */
923     return pktdata;
924 }
925 
926 /**
927  * determines based upon the cachedata which interface the given packet
928  * should go out.  Also rewrites any layer 2 data we might need to adjust.
929  * Returns a void cased pointer to the ctx->intfX of the corresponding
930  * interface or NULL on error
931  */
932 void *
cache_mode(tcpreplay_t * ctx,char * cachedata,COUNTER packet_num)933 cache_mode(tcpreplay_t *ctx, char *cachedata, COUNTER packet_num)
934 {
935     tcpreplay_opt_t *options = ctx->options;
936     void *sp = NULL;
937     int result;
938 
939     if (packet_num > options->cache_packets) {
940         tcpreplay_seterr(ctx, "%s", "Exceeded number of packets in cache file.");
941         return NULL;
942     }
943 
944     result = check_cache(cachedata, packet_num);
945     if (result == TCPR_DIR_NOSEND) {
946         dbgx(2, "Cache: Not sending packet " COUNTER_SPEC ".", packet_num);
947         return NULL;
948     }
949     else if (result == TCPR_DIR_C2S) {
950         dbgx(2, "Cache: Sending packet " COUNTER_SPEC " out primary interface.", packet_num);
951         sp = ctx->intf1;
952     }
953     else if (result == TCPR_DIR_S2C) {
954         dbgx(2, "Cache: Sending packet " COUNTER_SPEC " out secondary interface.", packet_num);
955         sp = ctx->intf2;
956     }
957     else {
958         tcpreplay_seterr(ctx, "Invalid cache value: %i", result);
959         return NULL;
960     }
961 
962     return sp;
963 }
964 
965 
966 /**
967  * Given the timestamp on the current packet and the last packet sent,
968  * calculate the appropriate amount of time to sleep. Sleep time
969  * will be in ctx->nap.
970  */
calc_sleep_time(tcpreplay_t * ctx,struct timeval * pkt_ts_delta,struct timeval * time_delta,COUNTER len,sendpacket_t * sp,COUNTER counter,timestamp_t * sent_timestamp,COUNTER start_us,COUNTER * skip_length)971 static void calc_sleep_time(tcpreplay_t *ctx, struct timeval *pkt_ts_delta,
972         struct timeval *time_delta, COUNTER len,
973         sendpacket_t *sp, COUNTER counter, timestamp_t *sent_timestamp,
974         COUNTER start_us, COUNTER *skip_length)
975 {
976     tcpreplay_opt_t *options = ctx->options;
977     struct timeval nap_for;
978     COUNTER now_us;
979 
980     timesclear(&ctx->nap);
981 
982     /*
983      * pps_multi accelerator.    This uses the existing send accelerator
984      * and hence requires the funky math to get the expected timings.
985      */
986     if (options->speed.mode == speed_packetrate && options->speed.pps_multi) {
987         ctx->skip_packets = options->speed.pps_multi - 1;
988     }
989 
990     /* no last packet sent, just leave */
991     if (ctx->first_time) {
992         ctx->first_time = false;
993         return;
994     }
995 
996     switch(options->speed.mode) {
997     case speed_multiplier:
998         /*
999          * Replay packets a factor of the time they were originally sent.
1000          * Make sure the packet is not late.
1001          */
1002         if (timercmp(pkt_ts_delta, time_delta, >)) {
1003             /* pkt_time_delta has increased, so handle normally */
1004             timersub(pkt_ts_delta, time_delta, &nap_for);
1005             TIMEVAL_TO_TIMESPEC(&nap_for, &ctx->nap);
1006             dbgx(3, "original packet delta time: " TIMESPEC_FORMAT,
1007                     ctx->nap.tv_sec, ctx->nap.tv_nsec);
1008             timesdiv_float(&ctx->nap, options->speed.multiplier);
1009             dbgx(3, "original packet delta/div: " TIMESPEC_FORMAT,
1010                     ctx->nap.tv_sec, ctx->nap.tv_nsec);
1011         }
1012         break;
1013 
1014     case speed_mbpsrate:
1015         /*
1016          * Ignore the time supplied by the capture file and send data at
1017          * a constant 'rate' (bytes per second).
1018          */
1019         now_us = TIMSTAMP_TO_MICROSEC(sent_timestamp);
1020         if (now_us) {
1021             COUNTER next_tx_us;
1022             COUNTER bps = options->speed.speed;
1023             COUNTER bits_sent = ((ctx->stats.bytes_sent + len) * 8);
1024             COUNTER tx_us = now_us - start_us;
1025 
1026             /*
1027              * bits * 1000000 divided by bps = microseconds
1028              *
1029              * ensure there is no overflow in cases where bits_sent is very high
1030              */
1031             if (bits_sent > COUNTER_OVERFLOW_RISK && bps > 500000)
1032                 next_tx_us = (bits_sent * 1000) / bps * 1000;
1033             else
1034                 next_tx_us = (bits_sent * 1000000) / bps;
1035 
1036             if (next_tx_us > tx_us) {
1037                 NANOSEC_TO_TIMESPEC((next_tx_us - tx_us) * 1000, &ctx->nap);
1038             } else if (tx_us > next_tx_us) {
1039                 tx_us = now_us - start_us;
1040                 *skip_length = ((tx_us - next_tx_us) * bps) / 8000000;
1041             }
1042 
1043             update_current_timestamp_trace_entry(ctx->stats.bytes_sent +
1044                     (COUNTER)len, now_us, tx_us, next_tx_us);
1045         }
1046 
1047         dbgx(3, "packet size=" COUNTER_SPEC "\t\tnap=" TIMESPEC_FORMAT, len,
1048                 ctx->nap.tv_sec, ctx->nap.tv_nsec);
1049         break;
1050 
1051     case speed_packetrate:
1052         /*
1053           * Ignore the time supplied by the capture file and send data at
1054           * a constant rate (packets per second).
1055           */
1056          now_us = TIMSTAMP_TO_MICROSEC(sent_timestamp);
1057          if (now_us) {
1058              COUNTER next_tx_us;
1059              COUNTER pph = ctx->options->speed.speed;
1060              COUNTER pkts_sent = ctx->stats.pkts_sent;
1061              COUNTER tx_us = now_us - start_us;
1062              /*
1063               * packets * 1000000 divided by pps = microseconds
1064               * packets per sec (pps) = packets per hour / (60 * 60)
1065               *
1066               * Adjust for long running tests with high PPS to prevent overflow.
1067               * When active, adjusted calculation may add a bit of jitter.
1068               */
1069              if ((pkts_sent < COUNTER_OVERFLOW_RISK))
1070                  next_tx_us = (pkts_sent * 1000000) * (60 * 60) / pph;
1071              else
1072                  next_tx_us = (pkts_sent * 1000000) / pph / (60 * 60);
1073 
1074              if (next_tx_us > tx_us)
1075                  NANOSEC_TO_TIMESPEC((next_tx_us - tx_us) * 1000, &ctx->nap);
1076              else
1077                  ctx->skip_packets = options->speed.pps_multi;
1078 
1079              update_current_timestamp_trace_entry(ctx->stats.bytes_sent +
1080                      (COUNTER)len, now_us, tx_us, next_tx_us);
1081          }
1082 
1083          dbgx(3, "packet count=" COUNTER_SPEC "\t\tnap=" TIMESPEC_FORMAT,
1084                  ctx->stats.pkts_sent, ctx->nap.tv_sec, ctx->nap.tv_nsec);
1085         break;
1086 
1087     case speed_oneatatime:
1088         /* do we skip prompting for a key press? */
1089         if (ctx->skip_packets == 0) {
1090             ctx->skip_packets = get_user_count(ctx, sp, counter);
1091         }
1092 
1093         /* decrement our send counter */
1094         printf("Sending packet " COUNTER_SPEC " out: %s\n", counter,
1095                sp == ctx->intf1 ? options->intf1_name : options->intf2_name);
1096         ctx->skip_packets--;
1097 
1098         /* leave */
1099         break;
1100 
1101     case speed_topspeed:
1102         break;
1103 
1104     default:
1105         errx(-1, "Unknown/supported speed mode: %d", options->speed.mode);
1106         break;
1107     }
1108 }
1109 
tcpr_sleep(tcpreplay_t * ctx,sendpacket_t * sp,struct timespec * nap_this_time,struct timeval * now)1110 static void tcpr_sleep(tcpreplay_t *ctx, sendpacket_t *sp,
1111         struct timespec *nap_this_time, struct timeval *now)
1112 {
1113     tcpreplay_opt_t *options = ctx->options;
1114     bool flush =
1115 #ifdef HAVE_NETMAP
1116             true;
1117 #else
1118             false;
1119 #endif
1120 
1121 
1122     /* don't sleep if nap = {0, 0} */
1123     if (!timesisset(nap_this_time))
1124         return;
1125 
1126     /* do we need to limit the total time we sleep? */
1127     if (timesisset(&(options->maxsleep)) && (timescmp(nap_this_time, &(options->maxsleep), >))) {
1128         dbgx(2, "Was going to sleep for " TIMESPEC_FORMAT " but maxsleeping for " TIMESPEC_FORMAT,
1129             nap_this_time->tv_sec, nap_this_time->tv_nsec, options->maxsleep.tv_sec,
1130             options->maxsleep.tv_nsec);
1131         TIMESPEC_SET(nap_this_time, &options->maxsleep);
1132     }
1133 
1134     if (flush)
1135         wake_send_queues(sp, options);
1136 
1137     dbgx(2, "Sleeping:                   " TIMESPEC_FORMAT,
1138             nap_this_time->tv_sec, nap_this_time->tv_nsec);
1139 
1140     /*
1141      * Depending on the accurate method & packet rate computation method
1142      * We have multiple methods of sleeping, pick the right one...
1143      */
1144     switch (options->accurate) {
1145 #ifdef HAVE_SELECT
1146     case accurate_select:
1147         select_sleep(sp, nap_this_time, now, flush);
1148         break;
1149 #endif
1150 
1151 #if defined HAVE_IOPORT_SLEEP
1152     case accurate_ioport:
1153         ioport_sleep(sp, nap_this_time, now, flush);
1154         break;
1155 #endif
1156 
1157     case accurate_gtod:
1158         gettimeofday_sleep(sp, nap_this_time, now, flush);
1159         break;
1160 
1161     case accurate_nanosleep:
1162         nanosleep_sleep(sp, nap_this_time, now, flush);
1163         break;
1164 
1165     default:
1166         errx(-1, "Unknown timer mode %d", options->accurate);
1167     }
1168 }
1169 
1170 /**
1171  * Ask the user how many packets they want to send.
1172  */
1173 static uint32_t
get_user_count(tcpreplay_t * ctx,sendpacket_t * sp,COUNTER counter)1174 get_user_count(tcpreplay_t *ctx, sendpacket_t *sp, COUNTER counter)
1175 {
1176     tcpreplay_opt_t *options = ctx->options;
1177     struct pollfd poller[1];        /* use poll to read from the keyboard */
1178     char input[EBUF_SIZE];
1179     unsigned long send = 0;
1180 
1181     printf("**** Next packet #" COUNTER_SPEC " out %s.  How many packets do you wish to send? ",
1182         counter, (sp == ctx->intf1 ? options->intf1_name : options->intf2_name));
1183     fflush(NULL);
1184     poller[0].fd = STDIN_FILENO;
1185     poller[0].events = POLLIN | POLLPRI | POLLNVAL;
1186     poller[0].revents = 0;
1187 
1188     if (fcntl(0, F_SETFL, fcntl(0, F_GETFL) & ~O_NONBLOCK))
1189         errx(-1, "Unable to clear non-blocking flag on stdin: %s", strerror(errno));
1190 
1191     /* wait for the input */
1192     if (poll(poller, 1, -1) < 0)
1193         errx(-1, "Error reading user input from stdin: %s", strerror(errno));
1194 
1195     /*
1196      * read to the end of the line or EBUF_SIZE,
1197      * Note, if people are stupid, and type in more text then EBUF_SIZE
1198      * then the next fgets() will pull in that data, which will have poor
1199      * results.  fuck them.
1200      */
1201     if (fgets(input, sizeof(input), stdin) == NULL) {
1202         errx(-1, "Unable to process user input for fd %d: %s", fileno(stdin), strerror(errno));
1203     } else if (strlen(input) > 1) {
1204         send = strtoul(input, NULL, 0);
1205     }
1206 
1207     /* how many packets should we send? */
1208     if (send == 0) {
1209         dbg(1, "Input was less then 1 or non-numeric, assuming 1");
1210 
1211         /* assume send only one packet */
1212         send = 1;
1213     }
1214 
1215     return(uint32_t)send;
1216 }
1217