ref: 2ad189c0a88b07264a8af70e3343dfff8e9500d2
parent: 358e843adc005ef54b163dc12d777bb104a7d860
author: Giacomo Vacca <giacomo.vacca@gmail.com>
date: Thu Jan 12 06:42:46 EST 2017
opusrtp: add extract (from file) option Signed-off-by: Ralph Giles <giles@thaumas.net>
--- a/src/opusrtp.c
+++ b/src/opusrtp.c
@@ -787,6 +787,72 @@
}
}
+int extract(const char* input_file)
+{
+ state *params;
+ pcap_t *pcap;
+ char errbuf[PCAP_ERRBUF_SIZE];
+ ogg_packet *op;
+
+ if ((pcap = pcap_open_offline(input_file, errbuf)) == NULL)
+ {
+ fprintf(stderr,"\nError opening dump file\n");
+ return -1;
+ }
+
+ params = malloc(sizeof(state));
+ if (!params) {
+ fprintf(stderr, "Couldn't allocate param struct.\n");
+ return -1;
+ }
+ params->linktype = pcap_datalink(pcap);
+ params->stream = malloc(sizeof(ogg_stream_state));
+ if (!params->stream) {
+ fprintf(stderr, "Couldn't allocate stream struct.\n");
+ free(params);
+ return -1;
+ }
+ if (ogg_stream_init(params->stream, rand()) < 0) {
+ fprintf(stderr, "Couldn't initialize Ogg stream state.\n");
+ free(params->stream);
+ free(params);
+ return -1;
+ }
+ params->out = fopen("rtpdump.opus", "wb");
+ if (!params->out) {
+ fprintf(stderr, "Couldn't open output file.\n");
+ free(params->stream);
+ free(params);
+ return -2;
+ }
+ params->seq = 0;
+ params->granulepos = 0;
+
+ /* write stream headers */
+ op = op_opushead();
+ ogg_stream_packetin(params->stream, op);
+ op_free(op);
+ op = op_opustags();
+ ogg_stream_packetin(params->stream, op);
+ op_free(op);
+ ogg_flush(params);
+
+ fprintf(stderr, "Capturing packets\n");
+ // read and dispatch packets until EOF is reached
+ pcap_loop(pcap, 0, write_packet, (u_char *)params);
+
+ /* write outstanding data */
+ ogg_flush(params);
+
+ /* clean up */
+ fclose(params->out);
+ ogg_stream_destroy(params->stream);
+ free(params);
+ pcap_close(pcap);
+
+ return 0;
+}
+
/* use libpcap to capture packets and write them to a file */
int sniff(char *device)
{
@@ -867,7 +933,7 @@
void usage(char *exe)
{
- printf("Usage: %s [--sniff] <file.opus> [<file2.opus>]\n", exe);
+ printf("Usage: %s [--extract file.pcap] [--sniff] <file.opus> [<file2.opus>]\n", exe);
printf("\n");
printf("Sends and receives Opus audio RTP streams.\n");
printf("\nGeneral Options:\n");
@@ -877,6 +943,7 @@
printf(" -d, --destination Destination address (default 127.0.0.1)\n");
printf(" -p, --port Destination port (default 1234)\n");
printf(" --sniff Sniff and record Opus RTP streams\n");
+ printf(" -e, --extract Extract from input pcap file (default input.pcap)\n");
printf("\n");
printf("By default, the given file(s) will be sent over RTP.\n");
}
@@ -885,6 +952,7 @@
{
int option, i;
const char *dest = "127.0.0.1";
+ const char *input_pcap = "input.pcap";
int port = 1234;
struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
@@ -893,6 +961,7 @@
{"destination", required_argument, NULL, 'd'},
{"port", required_argument, NULL, 'p'},
{"sniff", no_argument, NULL, 0},
+ {"extract", required_argument, NULL, 'e'},
{0, 0, 0, 0}
};
@@ -921,6 +990,11 @@
case 'd':
if (optarg)
dest = optarg;
+ break;
+ case 'e':
+ if (optarg)
+ input_pcap = optarg;
+ extract(input_pcap);
break;
case 'p':
if (optarg)