* Reverting rtpw.c to master state
diff --git a/test/rtpw.c b/test/rtpw.c
index 7084efa..aacf034 100644
--- a/test/rtpw.c
+++ b/test/rtpw.c
@@ -15,7 +15,7 @@
*/
/*
- *
+ *
* Copyright (c) 2001-2006, Cisco Systems, Inc.
* All rights reserved.
*
@@ -64,11 +64,7 @@
#include <signal.h> /* for signal() */
#include <string.h> /* for strncpy() */
-#include <time.h> /* for usleep() */
-
-#include <assert.h> /* for assert() */
-
-#include <pcap.h> /* for pcap functions and datatypes */
+#include <time.h> /* for usleep() */
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* for close() */
@@ -81,7 +77,7 @@
#elif defined HAVE_WINSOCK2_H
# include <winsock2.h>
# include <ws2tcpip.h>
-# define RTPW_USE_WINSOCK2 1
+# define RTPW_USE_WINSOCK2 1
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
@@ -89,7 +85,6 @@
#include "srtp.h"
#include "rtp.h"
-#include "rtp_decoder.h"
#include "crypto_kernel.h"
#ifdef RTPW_USE_WINSOCK2
@@ -98,26 +93,19 @@
# define DICT_FILE "/usr/share/dict/words"
#endif
#define USEC_RATE (5e5)
-#define MAX_WORD_LEN 128
+#define MAX_WORD_LEN 128
#define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a))
#define MAX_KEY_LEN 96
-#define MAX_FILTER 256
+
#ifndef HAVE_USLEEP
# ifdef HAVE_WINDOWS_H
-# define usleep(us) Sleep((us)/1000)
+# define usleep(us) Sleep((us)/1000)
# else
-# define usleep(us) sleep((us)/1000000)
+# define usleep(us) sleep((us)/1000000)
# endif
#endif
-unsigned char shiftb64(unsigned char c);
-
-void decode_block(char *in, unsigned char *out);
-/*
- * decode base64 key
- */
-char *decode_sdes(char *in, char *out);
/*
* the function usage() prints an error message describing how this
@@ -151,20 +139,17 @@
* program_type distinguishes the [s]rtp sender and receiver cases
*/
-typedef enum { sender, receiver, decoder, unknown } program_type;
+typedef enum { sender, receiver, unknown } program_type;
int
main (int argc, char *argv[]) {
char *dictfile = DICT_FILE;
FILE *dict;
char word[MAX_WORD_LEN];
- int sock = 0, ret;
+ int sock, ret;
struct in_addr rcvr_addr;
struct sockaddr_in name;
struct ip_mreq mreq;
- char errbuf[PCAP_ERRBUF_SIZE];
- bpf_u_int32 pcap_net = 0;
- pcap_t *pcap_handle;
#if BEW
struct sockaddr_in local;
#endif
@@ -178,10 +163,7 @@
char *input_key = NULL;
char *address = NULL;
char key[MAX_KEY_LEN];
- struct bpf_program fp;
- char filter_exp[MAX_FILTER] = "";
unsigned short port = 0;
- rtp_decoder_t dec;
rtp_sender_t snd;
srtp_policy_t policy;
err_status_t status;
@@ -214,16 +196,11 @@
/* check args */
while (1) {
- c = getopt_s(argc, argv, "b:k:rspgt:ae:ld:");
+ c = getopt_s(argc, argv, "k:rsgt:ae:ld:");
if (c == -1) {
break;
}
switch (c) {
- case 'b':
- fprintf(stderr, "Decoding\n");
- decode_sdes(optarg_s, input_key);
- fprintf(stderr, "Decoded\n");
- break;
case 'k':
input_key = optarg_s;
break;
@@ -233,14 +210,13 @@
printf("error: encryption key size must be 128 or 256 (%d)\n", key_size);
exit(1);
}
- input_key = malloc(key_size);
sec_servs |= sec_serv_conf;
break;
case 't':
tag_size = atoi(optarg_s);
if (tag_size != 8 && tag_size != 16) {
- fprintf(stderr, "error: GCM tag size must be 8 or 16 (%d)\n", tag_size);
- //exit(1);
+ printf("error: GCM tag size must be 8 or 16 (%d)\n", tag_size);
+ exit(1);
}
break;
case 'a':
@@ -256,10 +232,6 @@
case 's':
prog_type = sender;
break;
- case 'p':
- prog_type = decoder;
- fprintf(stderr, "Choosing decoder\n");
- break;
case 'd':
status = crypto_kernel_set_debug_module(optarg_s, 1);
if (status) {
@@ -279,12 +251,12 @@
if (do_list_mods) {
status = crypto_kernel_list_debug_modules();
if (status) {
- printf("error: list of debug modules failed\n");
- exit(1);
+ printf("error: list of debug modules failed\n");
+ exit(1);
}
return 0;
} else {
- printf("error: neither sender [-s] receiver [-r] nor pcap decoder [-p] specified\n");
+ printf("error: neither sender [-s] nor receiver [-r] specified\n");
usage(argv[0]);
}
}
@@ -294,97 +266,86 @@
* a key must be provided if and only if security services have
* been requested
*/
- if(input_key == NULL){
- fprintf(stderr, "key not provided\n");
- }
- if(!sec_servs){
- fprintf(stderr, "no secservs\n");
- }
- fprintf(stderr, "provided\n");
usage(argv[0]);
}
-
- if (prog_type == receiver || prog_type == sender) {
- if (argc != optind_s + 2) {
- /* wrong number of arguments */
- usage(argv[0]);
- }
+
+ if (argc != optind_s + 2) {
+ /* wrong number of arguments */
+ usage(argv[0]);
+ }
-
- /* get address from arg */
- address = argv[optind_s++];
+ /* get address from arg */
+ address = argv[optind_s++];
- /* get port from arg */
- port = atoi(argv[optind_s++]);
+ /* get port from arg */
+ port = atoi(argv[optind_s++]);
- /* set address */
- #ifdef HAVE_INET_ATON
- if (0 == inet_aton(address, &rcvr_addr)) {
- fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0], address);
- exit(1);
- }
- if (rcvr_addr.s_addr == INADDR_NONE) {
- fprintf(stderr, "%s: address error", argv[0]);
- exit(1);
- }
- #else
- rcvr_addr.s_addr = inet_addr(address);
- if (0xffffffff == rcvr_addr.s_addr) {
- fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0], address);
- exit(1);
- }
- #endif
+ /* set address */
+#ifdef HAVE_INET_ATON
+ if (0 == inet_aton(address, &rcvr_addr)) {
+ fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0], address);
+ exit(1);
+ }
+ if (rcvr_addr.s_addr == INADDR_NONE) {
+ fprintf(stderr, "%s: address error", argv[0]);
+ exit(1);
+ }
+#else
+ rcvr_addr.s_addr = inet_addr(address);
+ if (0xffffffff == rcvr_addr.s_addr) {
+ fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0], address);
+ exit(1);
+ }
+#endif
- /* open socket */
- sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (sock < 0) {
- int err;
- #ifdef RTPW_USE_WINSOCK2
- err = WSAGetLastError();
- #else
- err = errno;
- #endif
- fprintf(stderr, "%s: couldn't open socket: %d\n", argv[0], err);
- exit(1);
- }
+ /* open socket */
+ sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock < 0) {
+ int err;
+#ifdef RTPW_USE_WINSOCK2
+ err = WSAGetLastError();
+#else
+ err = errno;
+#endif
+ fprintf(stderr, "%s: couldn't open socket: %d\n", argv[0], err);
+ exit(1);
+ }
- name.sin_addr = rcvr_addr;
- name.sin_family = PF_INET;
- name.sin_port = htons(port);
+ name.sin_addr = rcvr_addr;
+ name.sin_family = PF_INET;
+ name.sin_port = htons(port);
- if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
- if (prog_type == sender) {
- ret = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
- sizeof(ttl));
- if (ret < 0) {
- fprintf(stderr, "%s: Failed to set TTL for multicast group", argv[0]);
- perror("");
- exit(1);
- }
- }
+ if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
+ if (prog_type == sender) {
+ ret = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
+ sizeof(ttl));
+ if (ret < 0) {
+ fprintf(stderr, "%s: Failed to set TTL for multicast group", argv[0]);
+ perror("");
+ exit(1);
+ }
+ }
- mreq.imr_multiaddr.s_addr = rcvr_addr.s_addr;
- mreq.imr_interface.s_addr = htonl(INADDR_ANY);
- ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&mreq,
- sizeof(mreq));
- if (ret < 0) {
- fprintf(stderr, "%s: Failed to join multicast group", argv[0]);
- perror("");
- exit(1);
- }
- }
- }
-
+ mreq.imr_multiaddr.s_addr = rcvr_addr.s_addr;
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+ ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&mreq,
+ sizeof(mreq));
+ if (ret < 0) {
+ fprintf(stderr, "%s: Failed to join multicast group", argv[0]);
+ perror("");
+ exit(1);
+ }
+ }
/* report security services selected on the command line */
- fprintf(stderr, "security services: ");
+ printf("security services: ");
if (sec_servs & sec_serv_conf)
- fprintf(stderr, "confidentiality ");
+ printf("confidentiality ");
if (sec_servs & sec_serv_auth)
- fprintf(stderr, "message authentication");
+ printf("message authentication");
if (sec_servs == sec_serv_none)
- fprintf(stderr, "none");
- fprintf(stderr, "\n");
+ printf("none");
+ printf("\n");
/* set up the srtp policy and master key */
if (sec_servs) {
@@ -397,66 +358,66 @@
case sec_serv_conf_and_auth:
if (gcm_on) {
#ifdef OPENSSL
- switch (key_size) {
- case 128:
- crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
- crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
- break;
- case 256:
- crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
- crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
- break;
- }
+ switch (key_size) {
+ case 128:
+ crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
+ crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
+ break;
+ case 256:
+ crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
+ crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
+ break;
+ }
#else
- printf("error: GCM mode only supported when using the OpenSSL crypto engine.\n");
- return 0;
+ printf("error: GCM mode only supported when using the OpenSSL crypto engine.\n");
+ return 0;
#endif
} else {
- switch (key_size) {
- case 128:
+ switch (key_size) {
+ case 128:
crypto_policy_set_rtp_default(&policy.rtp);
crypto_policy_set_rtcp_default(&policy.rtcp);
- break;
- case 256:
+ break;
+ case 256:
crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
crypto_policy_set_rtcp_default(&policy.rtcp);
- break;
- }
+ break;
+ }
}
break;
case sec_serv_conf:
if (gcm_on) {
- printf("error: GCM mode must always be used with auth enabled\n");
- return -1;
+ printf("error: GCM mode must always be used with auth enabled\n");
+ return -1;
} else {
- switch (key_size) {
- case 128:
+ switch (key_size) {
+ case 128:
crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
crypto_policy_set_rtcp_default(&policy.rtcp);
- break;
- case 256:
+ break;
+ case 256:
crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
crypto_policy_set_rtcp_default(&policy.rtcp);
- break;
- }
+ break;
+ }
}
break;
case sec_serv_auth:
if (gcm_on) {
#ifdef OPENSSL
- switch (key_size) {
- case 128:
- crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
- crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtcp);
- break;
- case 256:
- crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
- crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtcp);
- break;
- }
+ switch (key_size) {
+ case 128:
+ crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
+ crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtcp);
+ break;
+ case 256:
+ crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
+ crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtcp);
+ break;
+ }
#else
- printf("error: GCM mode only supported when using the OpenSSL crypto engine.\n");
- return 0;
+ printf("error: GCM mode only supported when using the OpenSSL crypto engine.\n");
+ return 0;
#endif
} else {
crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
@@ -467,20 +428,18 @@
printf("error: unknown security service requested\n");
return -1;
}
-
+ policy.ssrc.type = ssrc_specific;
+ policy.ssrc.value = ssrc;
policy.key = (uint8_t *) key;
policy.ekt = NULL;
policy.next = NULL;
policy.window_size = 128;
policy.allow_repeat_tx = 0;
policy.rtp.sec_serv = sec_servs;
- policy.rtcp.sec_serv = sec_servs; //sec_serv_none; /* we don't do RTCP anyway */
- fprintf(stderr, "setting tag len %d\n", tag_size);
-policy.rtp.auth_tag_len = tag_size;
-
+ policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */
+
if (gcm_on && tag_size != 8) {
- fprintf(stderr, "setted tag len %d\n", tag_size);
- policy.rtp.auth_tag_len = tag_size;
+ policy.rtp.auth_tag_len = tag_size;
}
/*
@@ -491,21 +450,21 @@
/* check that hex string is the right length */
if (len < policy.rtp.cipher_key_len*2) {
fprintf(stderr,
- "error: too few digits in key/salt "
- "(should be %d hexadecimal digits, found %d)\n",
- policy.rtp.cipher_key_len*2, len);
+ "error: too few digits in key/salt "
+ "(should be %d hexadecimal digits, found %d)\n",
+ policy.rtp.cipher_key_len*2, len);
exit(1);
}
if (strlen(input_key) > policy.rtp.cipher_key_len*2) {
fprintf(stderr,
- "error: too many digits in key/salt "
- "(should be %d hexadecimal digits, found %u)\n",
- policy.rtp.cipher_key_len*2, (unsigned)strlen(input_key));
+ "error: too many digits in key/salt "
+ "(should be %d hexadecimal digits, found %u)\n",
+ policy.rtp.cipher_key_len*2, (unsigned)strlen(input_key));
exit(1);
}
- fprintf(stderr, "set master key/salt to %s/", octet_string_hex_string(key, 16));
- fprintf(stderr, "%s\n", octet_string_hex_string(key+16, 14));
+ printf("set master key/salt to %s/", octet_string_hex_string(key, 16));
+ printf("%s\n", octet_string_hex_string(key+16, 14));
} else {
/*
@@ -563,8 +522,8 @@
status = rtp_sender_init_srtp(snd, &policy);
if (status) {
fprintf(stderr,
- "error: srtp_create() failed with code %d\n",
- status);
+ "error: srtp_create() failed with code %d\n",
+ status);
exit(1);
}
@@ -573,7 +532,7 @@
if (dict == NULL) {
fprintf(stderr, "%s: couldn't open file %s\n", argv[0], dictfile);
if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
- leave_group(sock, mreq, argv[0]);
+ leave_group(sock, mreq, argv[0]);
}
exit(1);
}
@@ -583,9 +542,9 @@
len = strlen(word) + 1; /* plus one for null */
if (len > MAX_WORD_LEN)
- printf("error: word %s too large to send\n", word);
+ printf("error: word %s too large to send\n", word);
else {
- rtp_sendto(snd, word, len);
+ rtp_sendto(snd, word, len);
printf("sending word: %s", word);
}
usleep(USEC_RATE);
@@ -595,7 +554,7 @@
rtp_sender_dealloc(snd);
fclose(dict);
- } else if (prog_type == receiver) {
+ } else { /* prog_type == receiver */
rtp_receiver_t rcvr;
if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0) {
@@ -603,7 +562,7 @@
fprintf(stderr, "%s: socket bind error\n", argv[0]);
perror(NULL);
if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
- leave_group(sock, mreq, argv[0]);
+ leave_group(sock, mreq, argv[0]);
}
exit(1);
}
@@ -617,8 +576,8 @@
status = rtp_receiver_init_srtp(rcvr, &policy);
if (status) {
fprintf(stderr,
- "error: srtp_create() failed with code %d\n",
- status);
+ "error: srtp_create() failed with code %d\n",
+ status);
exit(1);
}
@@ -626,59 +585,27 @@
while (!interrupted) {
len = MAX_WORD_LEN;
if (rtp_recvfrom(rcvr, word, &len) > -1)
- printf("\tword: %s\n", word);
+ printf("\tword: %s\n", word);
}
+
rtp_receiver_deinit_srtp(rcvr);
rtp_receiver_dealloc(rcvr);
+ }
- } else if(prog_type == decoder){
- pcap_handle = pcap_open_offline("-", errbuf);
-
- if (!pcap_handle) {
- fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf);
- exit(1);
- }
- assert(pcap_handle != NULL);
- if ((pcap_compile(pcap_handle, &fp, filter_exp, 1, pcap_net)) == -1){
- fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp,
- pcap_geterr(pcap_handle));
- return (2);
- }
- if (pcap_setfilter(pcap_handle, &fp) == -1){
- fprintf(stderr, "couldn't install filter %s: %s\n", filter_exp,
- pcap_geterr(pcap_handle));
- return (2);
- }
- dec = rtp_decoder_alloc();
- if (dec == NULL) {
- fprintf(stderr, "error: malloc() failed\n");
- exit(1);
- }
- fprintf(stderr, "Starting decoder\n");
- rtp_decoder_init(dec, policy);
-
- pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);
-
- rtp_decoder_deinit_srtp(dec);
- rtp_decoder_dealloc(dec);
+ if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
+ leave_group(sock, mreq, argv[0]);
}
- if (prog_type == receiver || prog_type == sender) {
- if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
- leave_group(sock, mreq, argv[0]);
- }
-
#ifdef RTPW_USE_WINSOCK2
- ret = closesocket(sock);
+ ret = closesocket(sock);
#else
- ret = close(sock);
+ ret = close(sock);
#endif
- if (ret < 0) {
- fprintf(stderr, "%s: Failed to close socket", argv[0]);
- perror("");
- }
+ if (ret < 0) {
+ fprintf(stderr, "%s: Failed to close socket", argv[0]);
+ perror("");
+ }
- }
status = srtp_shutdown();
if (status) {
printf("error: srtp shutdown failed with error code %d\n", status);
@@ -697,19 +624,18 @@
usage(char *string) {
printf("usage: %s [-d <debug>]* [-k <key> [-a][-e]] "
- "[-s | -r | -p] [dest_ip dest_port]\n"
- "or %s -l\n"
- "where -a use message authentication\n"
- " -e <key size> use encryption (use 128 or 256 for key size)\n"
- " -g Use AES-GCM mode (must be used with -e)\n"
- " -t <tag size> Tag size to use in GCM mode (use 8 or 16)\n"
- " -k <key> sets the srtp master key\n"
- " -s act as rtp sender\n"
- " -r act as rtp receiver\n"
- " -p act as pcap file decrypter\n"
- " -l list debug modules\n"
- " -d <debug> turn on debugging for module <debug>\n",
- string, string);
+ "[-s | -r] dest_ip dest_port\n"
+ "or %s -l\n"
+ "where -a use message authentication\n"
+ " -e <key size> use encryption (use 128 or 256 for key size)\n"
+ " -g Use AES-GCM mode (must be used with -e)\n"
+ " -t <tag size> Tag size to use in GCM mode (use 8 or 16)\n"
+ " -k <key> sets the srtp master key\n"
+ " -s act as rtp sender\n"
+ " -r act as rtp receiver\n"
+ " -l list debug modules\n"
+ " -d <debug> turn on debugging for module <debug>\n",
+ string, string);
exit(1);
}
@@ -720,10 +646,10 @@
int ret;
ret = setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void*)&mreq,
- sizeof(mreq));
+ sizeof(mreq));
if (ret < 0) {
- fprintf(stderr, "%s: Failed to leave multicast group", name);
- perror("");
+ fprintf(stderr, "%s: Failed to leave multicast group", name);
+ perror("");
}
}
@@ -764,40 +690,4 @@
}
#endif
return 0;
-}
-
-static const char b64chars[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-unsigned char shiftb64(unsigned char c) {
- char *p = strchr(b64chars, c);
- assert(p);
- return p-b64chars;
-}
-
-void decode_block(char *in, unsigned char *out) {
- unsigned char shifts[4];
- int i;
-
- for (i = 0; i < 4; i++) {
- shifts[i] = shiftb64(in[i]);
- }
-
- out[0] = (shifts[0]<<2)|(shifts[1]>>4);
- out[1] = (shifts[1]<<4)|(shifts[2]>>2);
- out[2] = (shifts[2]<<6)|shifts[3];
-}
-
-char *decode_sdes(char *in, char *out) {
- int i;
- size_t len = strlen((char *) in);
- assert(len == 40);
- unsigned char raw[30];
-
- for (i = 0; 4*i < len; i++) {
- decode_block(in+4*i, raw+3*i);
- }
-
- memcpy(out, octet_string_hex_string(raw, 30), 60);
- return out;
-}
+}
\ No newline at end of file