1 /*
2 * Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
3 * Copyright (c) 2013-2018 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
4 *
5 * The Tcpreplay Suite of tools is free software: you can redistribute it
6 * and/or modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or with the authors permission any later version.
9 *
10 * The Tcpreplay Suite is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with the Tcpreplay Suite. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "config.h"
20 #include "defines.h"
21 #include "common.h"
22 #include "sleep.h"
23
24 #include <sys/types.h>
25 #include <sys/time.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <string.h>
29
30 #ifdef HAVE_SYS_EVENT
31 #include <sys/event.h>
32 #endif
33
34 /* necessary for ioport_sleep() functions */
35 #ifdef HAVE_SYS_IO_H /* Linux */
36 #include <sys/io.h>
37 #elif defined HAVE_ARCHITECTURE_I386_PIO_H /* OS X */
38 #include <architecture/i386/pio.h>
39 #endif
40
41 #if defined HAVE_IOPORT_SLEEP__
42 static int ioport_sleep_value;
43 #endif
44
45 void
ioport_sleep_init(void)46 ioport_sleep_init(void)
47 {
48 #if defined HAVE_IOPORT_SLEEP__
49 ioperm(0x80, 1, 1);
50 ioport_sleep_value = inb(0x80);
51 #else
52 err(-1, "Platform does not support IO Port for timing");
53 #endif
54 }
55
56 void
ioport_sleep(sendpacket_t * sp _U_,const struct timespec * nap _U_,struct timeval * now _U_,bool flush _U_)57 ioport_sleep(sendpacket_t *sp _U_, const struct timespec *nap _U_,
58 struct timeval *now _U_, bool flush _U_)
59 {
60 #if defined HAVE_IOPORT_SLEEP__
61 struct timeval nap_for;
62 u_int32_t usec;
63 time_t i;
64
65 TIMESPEC_TO_TIMEVAL(&nap_for, nap);
66
67 /*
68 * process the seconds, we do this in a loop so we don't have to
69 * use slower 64bit integers or worry about integer overflows.
70 */
71 for (i = 0; i < nap_for.tv_sec; i ++) {
72 usec = SEC_TO_MICROSEC(nap_for.tv_sec);
73 while (usec > 0) {
74 usec --;
75 outb(ioport_sleep_value, 0x80);
76 }
77 }
78
79 /* process the usec */
80 usec = nap->tv_nsec / 1000;
81 usec --; /* fudge factor for all the above */
82 while (usec > 0) {
83 usec --;
84 outb(ioport_sleep_value, 0x80);
85 }
86 #else
87 err(-1, "Platform does not support IO Port for timing");
88 #endif
89
90 #ifdef HAVE_NETMAP
91 if (flush)
92 ioctl(sp->handle.fd, NIOCTXSYNC, NULL); /* flush TX buffer */
93 #endif /* HAVE_NETMAP */
94
95 gettimeofday(now, NULL);
96 }
97