@@ -28,6 +28,8 @@ SOFTWARE.
28
28
#include < netinet/udp.h>
29
29
#include < pcap/pcap.h>
30
30
#include < unistd.h>
31
+ #include < sys/socket.h>
32
+ #include < arpa/inet.h>
31
33
32
34
int main (int argc, char *argv[]) {
33
35
static const char usage[] =
@@ -36,15 +38,23 @@ int main(int argc, char *argv[]) {
36
38
" -i iface interface to send packets through\n "
37
39
" -l enable loopback\n "
38
40
" -s speed replay speed relative to pcap timestamps\n "
41
+ " -d delay usec; e.g. 1,000 is 1 ms\n "
42
+ " -f freq delay every <freq> packets sent\n "
43
+ " -g group group <group> packets together, e.g. 1 or 6\n "
44
+ " -r repeat at end of pcap file\n "
39
45
" -t ttl packet ttl" ;
40
46
41
47
int ifindex = 0 ;
42
48
int loopback = 0 ;
43
- double speed = 1 ;
49
+ // double speed = 1;
44
50
int ttl = -1 ;
51
+ int delay = 100 ; // 0.1 ms
52
+ int freq = 50 ; // delay every 50 packets
53
+ int repeat = 0 ;
54
+ int group = 1 ;
45
55
46
56
int opt;
47
- while ((opt = getopt (argc, argv, " i:ls:t:" )) != -1 ) {
57
+ while ((opt = getopt (argc, argv, " i:ls:t:rd:f:g: " )) != -1 ) {
48
58
switch (opt) {
49
59
case ' i' :
50
60
ifindex = if_nametoindex (optarg);
@@ -56,8 +66,20 @@ int main(int argc, char *argv[]) {
56
66
case ' l' :
57
67
loopback = 1 ;
58
68
break ;
59
- case ' s' :
60
- speed = std::stod (optarg);
69
+ case ' r' :
70
+ repeat = 1 ;
71
+ break ;
72
+ // case 's':
73
+ // speed = std::stod(optarg);
74
+ // break;
75
+ case ' d' :
76
+ delay = std::stoi (optarg);
77
+ break ;
78
+ case ' f' :
79
+ freq = std::stoi (optarg);
80
+ break ;
81
+ case ' g' :
82
+ group = std::stoi (optarg);
61
83
break ;
62
84
case ' t' :
63
85
ttl = std::stoi (optarg);
@@ -104,6 +126,9 @@ int main(int argc, char *argv[]) {
104
126
}
105
127
}
106
128
129
+ time_t last_time = time (NULL );
130
+ REPEAT:;
131
+
107
132
char errbuf[PCAP_ERRBUF_SIZE];
108
133
pcap_t *handle = pcap_open_offline (argv[optind], errbuf);
109
134
if (handle == nullptr ) {
@@ -114,7 +139,17 @@ int main(int argc, char *argv[]) {
114
139
pcap_pkthdr header;
115
140
const u_char *p;
116
141
timeval tv = {0 , 0 };
142
+ unsigned long count = 0 ;
143
+ unsigned long sent = 0 ;
144
+ unsigned long last_count = 0 ;
145
+ unsigned long last_sent = 0 ;
146
+ #define JUMBO_MAX_BYTES (9001 )
147
+ char jumbo[JUMBO_MAX_BYTES];
148
+ int jumbo_appends = 0 ;
149
+ int jumbo_used = 0 ;
150
+ printf (" - starting sending loop\n " );
117
151
while ((p = pcap_next (handle, &header))) {
152
+ p += 2 ; // see https://www.eecis.udel.edu/~sunshine/expcs/code/pcap_packet_read.c
118
153
if (header.len != header.caplen ) {
119
154
continue ;
120
155
}
@@ -137,23 +172,41 @@ int main(int argc, char *argv[]) {
137
172
}
138
173
timeval diff;
139
174
timersub (&header.ts , &tv, &diff);
140
- usleep ((diff.tv_sec * 1000000 + diff.tv_usec ) * speed);
175
+ // do not use original timings usleep((diff.tv_sec * 1000000 + diff.tv_usec) * speed);
141
176
142
177
ssize_t len = ntohs (udp->len ) - 8 ;
143
178
const u_char *d = &p[sizeof (ether_header) + ip->ihl * 4 + sizeof (udphdr)];
144
179
180
+ if (jumbo_used + len > JUMBO_MAX_BYTES){ printf (" ERROR: jumbo overflow detected!\n " ); exit (0 ); }
181
+ memcpy (&jumbo[jumbo_used], d, len);
182
+ jumbo_appends ++;
183
+ jumbo_used += len;
184
+ if (jumbo_appends == group) { // 6 for MTU 9,001 byte packet
185
+
145
186
sockaddr_in addr;
146
187
memset (&addr, 0 , sizeof (addr));
147
188
addr.sin_family = AF_INET;
148
189
addr.sin_port = udp->dest ;
149
- addr.sin_addr = {ip->daddr };
150
- auto n = sendto (fd, d, len, 0 , reinterpret_cast <sockaddr *>(&addr),
190
+ // addr.sin_addr = {ip->daddr};
191
+ addr.sin_addr .s_addr = inet_addr (" 10.130.18.8" ); // force send packets to this IP!
192
+ auto n = sendto (fd, &jumbo[0 ], jumbo_used, 0 , reinterpret_cast <sockaddr *>(&addr),
151
193
sizeof (addr));
152
- if (n != len ) {
194
+ if (n != jumbo_used ) {
153
195
std::cerr << " sendto: " << strerror (errno) << std::endl;
154
196
return 1 ;
155
197
}
198
+ sent += jumbo_used;
199
+ if ((++ count % 100 ) == 0 ) { time_t this_time = time (NULL ); if (this_time != last_time) { last_time = this_time; printf (" - sent %lu bytes in %lu packets\n " , sent - last_sent, count - last_count); last_sent = sent; last_count = count; }}
200
+ if ((count % freq) == 0 ) { usleep (delay); } // delay=100 means sleep for 0.1 ms
201
+ // if (count == 152) { exit(0); }
202
+
203
+ jumbo_appends = 0 ;
204
+ jumbo_used = 0 ;
205
+ }
156
206
}
207
+ printf (" - sent %lu bytes in %lu packets total\n " , sent, count);
208
+
209
+ if (repeat) { pcap_close (handle); goto REPEAT; }
157
210
158
211
return 0 ;
159
212
}
0 commit comments