diff options
author | gnn <gnn@FreeBSD.org> | 2014-10-11 21:43:05 +0000 |
---|---|---|
committer | gnn <gnn@FreeBSD.org> | 2014-10-11 21:43:05 +0000 |
commit | 3dea4f4aeebd33f2ac012cdfe4ff09d9b9392a76 (patch) | |
tree | 89c077aefbec6205d277fe3f9638ea0333e87666 /tools | |
parent | a9647f4732da9b517eec6d174a7c1f2441443729 (diff) | |
download | FreeBSD-src-3dea4f4aeebd33f2ac012cdfe4ff09d9b9392a76.zip FreeBSD-src-3dea4f4aeebd33f2ac012cdfe4ff09d9b9392a76.tar.gz |
Add a new option, -P, to pkt-gen which reads a single packet from a stored
pcap file and transmits it instead of the default UDP packet.
Reviewed by: luigi
MFC after: 2 weeks
Diffstat (limited to 'tools')
-rw-r--r-- | tools/tools/netmap/pkt-gen.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/tools/tools/netmap/pkt-gen.c b/tools/tools/netmap/pkt-gen.c index c7cd874..6063f04 100644 --- a/tools/tools/netmap/pkt-gen.c +++ b/tools/tools/netmap/pkt-gen.c @@ -202,6 +202,7 @@ struct glob_arg { int dummy_send; int virt_header; /* send also the virt_header */ int extra_bufs; /* goes in nr_arg3 */ + char *packet_file; /* -P option */ }; enum dev_type { DEV_NONE, DEV_NETMAP, DEV_PCAP, DEV_TAP }; @@ -224,6 +225,7 @@ struct targ { int affinity; struct pkt pkt; + void *frame; }; @@ -613,6 +615,28 @@ initialize_packet(struct targ *targ) indirect_payload : default_payload; int i, l0 = strlen(payload); + char errbuf[PCAP_ERRBUF_SIZE]; + pcap_t *file; + struct pcap_pkthdr *header; + const unsigned char *packet; + + /* Read a packet from a PCAP file if asked. */ + if (targ->g->packet_file != NULL) { + if ((file = pcap_open_offline(targ->g->packet_file, + errbuf)) == NULL) + D("failed to open pcap file %s", + targ->g->packet_file); + if (pcap_next_ex(file, &header, &packet) < 0) + D("failed to read packet from %s", + targ->g->packet_file); + if ((targ->frame = malloc(header->caplen)) == NULL) + D("out of memory"); + bcopy(packet, (unsigned char *)targ->frame, header->caplen); + targ->g->pkt_size = header->caplen; + pcap_close(file); + return; + } + /* create a nice NUL-terminated string */ for (i = 0; i < paylen; i += l0) { if (l0 > paylen - i) @@ -783,7 +807,6 @@ pinger_body(void *data) frame += sizeof(targ->pkt.vh) - targ->g->virt_header; size = targ->g->pkt_size + targ->g->virt_header; - if (targ->g->nthreads > 1) { D("can only ping with 1 thread"); return NULL; @@ -1038,10 +1061,15 @@ sender_body(void *data) void *frame; int size; - frame = pkt; - frame += sizeof(pkt->vh) - targ->g->virt_header; - size = targ->g->pkt_size + targ->g->virt_header; - + if (targ->frame == NULL) { + frame = pkt; + frame += sizeof(pkt->vh) - targ->g->virt_header; + size = targ->g->pkt_size + targ->g->virt_header; + } else { + frame = targ->frame; + size = targ->g->pkt_size; + } + D("start, fd %d main_fd %d", targ->fd, targ->g->main_fd); if (setaffinity(targ->thread, targ->affinity)) goto quit; @@ -1366,6 +1394,7 @@ usage(void) "\t-R rate in packets per second\n" "\t-X dump payload\n" "\t-H len add empty virtio-net-header with size 'len'\n" + "\t-P file load packet from pcap file" "", cmd); @@ -1638,7 +1667,7 @@ main(int arc, char **argv) g.virt_header = 0; while ( (ch = getopt(arc, argv, - "a:f:F:n:i:Il:d:s:D:S:b:c:o:p:T:w:WvR:XC:H:e:m:")) != -1) { + "a:f:F:n:i:Il:d:s:D:S:b:c:o:p:T:w:WvR:XC:H:e:m:P:")) != -1) { struct sf *fn; switch(ch) { @@ -1781,7 +1810,11 @@ main(int arc, char **argv) D("unrecognized monitor mode %s", optarg); } break; + case 'P': + g.packet_file = strdup(optarg); + break; } + } if (g.ifname == NULL) { |