1386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
2386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * rtpw.c
3386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
4386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * rtp word sender/receiver
5386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
6386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * David A. McGrew
7386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Cisco Systems, Inc.
8386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
9386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * This app is a simple RTP application intended only for testing
10386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * libsrtp.  It reads one word at a time from /usr/dict/words (or
11386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * whatever file is specified as DICT_FILE), and sends one word out
12386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * each USEC_RATE microseconds.  Secure RTP protections can be
13386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * applied.  See the usage() function for more details.
14386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
15386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
16386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
17386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
18386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
19386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Copyright (c) 2001-2006, Cisco Systems, Inc.
20386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * All rights reserved.
21386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
22386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Redistribution and use in source and binary forms, with or without
23386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * modification, are permitted provided that the following conditions
24386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * are met:
25386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
26386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   Redistributions of source code must retain the above copyright
27386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   notice, this list of conditions and the following disclaimer.
28386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
29386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   Redistributions in binary form must reproduce the above
30386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   copyright notice, this list of conditions and the following
31386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   disclaimer in the documentation and/or other materials provided
32386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   with the distribution.
33386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
34386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   Neither the name of the Cisco Systems, Inc. nor the names of its
35386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   contributors may be used to endorse or promote products derived
36386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   from this software without specific prior written permission.
37386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
38386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
39386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
40386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
41386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
42386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
43386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
45386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * OF THE POSSIBILITY OF SUCH DAMAGE.
50386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
51386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
52386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
53386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
54386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "datatypes.h"
55386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "getopt_s.h"       /* for local getopt()  */
56386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
57386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include <stdio.h>          /* for printf, fprintf */
58386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include <stdlib.h>         /* for atoi()          */
59386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include <errno.h>
60386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include <unistd.h>         /* for close()         */
61386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
62386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include <string.h>         /* for strncpy()       */
63386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include <time.h>	    /* for usleep()        */
64386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef HAVE_SYS_SOCKET_H
65386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# include <sys/socket.h>
66386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
67386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef HAVE_NETINET_IN_H
68386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# include <netinet/in.h>
69386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#elif defined HAVE_WINSOCK2_H
70386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# include <winsock2.h>
71386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# include <ws2tcpip.h>
72386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# define RTPW_USE_WINSOCK2	1
73386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
74386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef HAVE_ARPA_INET_H
75386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# include <arpa/inet.h>
76386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
77386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
78386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "srtp.h"
79386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "rtp.h"
80386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
81386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef RTPW_USE_WINSOCK2
82386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# define DICT_FILE        "words.txt"
83386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else
84386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# define DICT_FILE        "/usr/share/dict/words"
85386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
86386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define USEC_RATE        (5e5)
87386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define MAX_WORD_LEN     128
88386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a))
89386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define MAX_KEY_LEN      64
90386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define MASTER_KEY_LEN   30
91386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
92386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
93386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifndef HAVE_USLEEP
94386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# ifdef HAVE_WINDOWS_H
95386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#  define usleep(us)	Sleep((us)/1000)
96386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# else
97386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#  define usleep(us)	sleep((us)/1000000)
98386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# endif
99386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
100386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
101386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
102386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
103386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the function usage() prints an error message describing how this
104386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * program should be called, then calls exit()
105386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
106386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
107386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarivoid
108386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariusage(char *prog_name);
109386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
110386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
111386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * leave_group(...) de-registers from a multicast group
112386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
113386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
114386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarivoid
115386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarileave_group(int sock, struct ip_mreq mreq, char *name);
116386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
117386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
118386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
119386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * program_type distinguishes the [s]rtp sender and receiver cases
120386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
121386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
122386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaritypedef enum { sender, receiver, unknown } program_type;
123386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
124386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariint
125386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarimain (int argc, char *argv[]) {
126386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  char *dictfile = DICT_FILE;
127386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  FILE *dict;
128386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  char word[MAX_WORD_LEN];
129386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  int sock, ret;
130386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  struct in_addr rcvr_addr;
131386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  struct sockaddr_in name;
132386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  struct ip_mreq mreq;
133386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if BEW
134386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  struct sockaddr_in local;
135386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
136386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  program_type prog_type = unknown;
137386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  sec_serv_t sec_servs = sec_serv_none;
138386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  unsigned char ttl = 5;
139386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  int c;
140386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  char *input_key = NULL;
141386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  char *address = NULL;
142386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  char key[MAX_KEY_LEN];
143386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  unsigned short port = 0;
144386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  rtp_sender_t snd;
145386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  srtp_policy_t policy;
146386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  err_status_t status;
147386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  int len;
148386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  int do_list_mods = 0;
149386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */
150386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef RTPW_USE_WINSOCK2
151386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  WORD wVersionRequested = MAKEWORD(2, 0);
152386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  WSADATA wsaData;
153386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
154386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  ret = WSAStartup(wVersionRequested, &wsaData);
155386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (ret != 0) {
156386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    fprintf(stderr, "error: WSAStartup() failed: %d\n", ret);
157386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    exit(1);
158386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
159386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
160386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
161386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* initialize srtp library */
162386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  status = srtp_init();
163386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (status) {
164386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    printf("error: srtp initialization failed with error code %d\n", status);
165386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    exit(1);
166386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
167386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
168386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* check args */
169386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  while (1) {
170386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    c = getopt_s(argc, argv, "k:rsaeld:");
171386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (c == -1) {
172386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      break;
173386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
174386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    switch (c) {
175386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    case 'k':
176386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      input_key = optarg_s;
177386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      break;
178386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    case 'e':
179386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      sec_servs |= sec_serv_conf;
180386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      break;
181386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    case 'a':
182386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      sec_servs |= sec_serv_auth;
183386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      break;
184386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    case 'r':
185386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      prog_type = receiver;
186386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      break;
187386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    case 's':
188386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      prog_type = sender;
189386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      break;
190386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    case 'd':
191386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      status = crypto_kernel_set_debug_module(optarg_s, 1);
192386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      if (status) {
193386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari        printf("error: set debug module (%s) failed\n", optarg_s);
194386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari        exit(1);
195386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      }
196386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      break;
197386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    case 'l':
198386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      do_list_mods = 1;
199386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      break;
200386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    default:
201386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      usage(argv[0]);
202386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
203386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
204386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
205386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (prog_type == unknown) {
206386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (do_list_mods) {
207386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      status = crypto_kernel_list_debug_modules();
208386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      if (status) {
209386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	printf("error: list of debug modules failed\n");
210386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	exit(1);
211386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      }
212386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      return 0;
213386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    } else {
214386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      printf("error: neither sender [-s] nor receiver [-r] specified\n");
215386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      usage(argv[0]);
216386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
217386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
218386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
219386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if ((sec_servs && !input_key) || (!sec_servs && input_key)) {
220386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /*
221386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * a key must be provided if and only if security services have
222386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * been requested
223386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     */
224386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    usage(argv[0]);
225386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
226386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
227386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (argc != optind_s + 2) {
228386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* wrong number of arguments */
229386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    usage(argv[0]);
230386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
231386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
232386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* get address from arg */
233386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  address = argv[optind_s++];
234386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
235386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* get port from arg */
236386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  port = atoi(argv[optind_s++]);
237386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
238386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* set address */
239386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef HAVE_INET_ATON
240386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (0 == inet_aton(address, &rcvr_addr)) {
241386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0], address);
242386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    exit(1);
243386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
244386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (rcvr_addr.s_addr == INADDR_NONE) {
245386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    fprintf(stderr, "%s: address error", argv[0]);
246386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    exit(1);
247386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
248386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else
249386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  rcvr_addr.s_addr = inet_addr(address);
250386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (0xffffffff == rcvr_addr.s_addr) {
251386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0], address);
252386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    exit(1);
253386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
254386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
255386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
256386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* open socket */
257386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
258386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (sock < 0) {
259386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    int err;
260386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef RTPW_USE_WINSOCK2
261386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    err = WSAGetLastError();
262386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else
263386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    err = errno;
264386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
265386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    fprintf(stderr, "%s: couldn't open socket: %d\n", argv[0], err);
266386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    exit(1);
267386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
268386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
269386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  name.sin_addr   = rcvr_addr;
270386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  name.sin_family = PF_INET;
271386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  name.sin_port   = htons(port);
272386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
273386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
274386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (prog_type == sender) {
275386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      ret = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
276386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  	               sizeof(ttl));
277386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      if (ret < 0) {
278386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	fprintf(stderr, "%s: Failed to set TTL for multicast group", argv[0]);
279386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	perror("");
280386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	exit(1);
281386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      }
282386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
283386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
284386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    mreq.imr_multiaddr.s_addr = rcvr_addr.s_addr;
285386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
286386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&mreq,
287386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari		     sizeof(mreq));
288386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (ret < 0) {
289386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      fprintf(stderr, "%s: Failed to join multicast group", argv[0]);
290386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      perror("");
291386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      exit(1);
292386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
293386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
294386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
295386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* report security services selected on the command line */
296386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  printf("security services: ");
297386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (sec_servs & sec_serv_conf)
298386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    printf("confidentiality ");
299386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (sec_servs & sec_serv_auth)
300386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    printf("message authentication");
301386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (sec_servs == sec_serv_none)
302386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    printf("none");
303386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  printf("\n");
304386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
305386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* set up the srtp policy and master key */
306386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (sec_servs) {
307386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /*
308386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * create policy structure, using the default mechanisms but
309386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * with only the security services requested on the command line,
310386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * using the right SSRC value
311386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     */
312386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    switch (sec_servs) {
313386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    case sec_serv_conf_and_auth:
314386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      crypto_policy_set_rtp_default(&policy.rtp);
315386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      crypto_policy_set_rtcp_default(&policy.rtcp);
316386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      break;
317386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    case sec_serv_conf:
318386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
319386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      crypto_policy_set_rtcp_default(&policy.rtcp);
320386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      break;
321386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    case sec_serv_auth:
322386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
323386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      crypto_policy_set_rtcp_default(&policy.rtcp);
324386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      break;
325386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    default:
326386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      printf("error: unknown security service requested\n");
327386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      return -1;
328386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
329386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.ssrc.type  = ssrc_specific;
330386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.ssrc.value = ssrc;
331386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.key  = (uint8_t *) key;
332386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.next = NULL;
333386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.window_size = 128;
334386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.allow_repeat_tx = 0;
335386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtp.sec_serv = sec_servs;
336386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtcp.sec_serv = sec_serv_none;  /* we don't do RTCP anyway */
337386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
338386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /*
339386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * read key from hexadecimal on command line into an octet string
340386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     */
341386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    len = hex_string_to_octet_string(key, input_key, MASTER_KEY_LEN*2);
342386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
343386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* check that hex string is the right length */
344386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (len < MASTER_KEY_LEN*2) {
345386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      fprintf(stderr,
346386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      "error: too few digits in key/salt "
347386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      "(should be %d hexadecimal digits, found %d)\n",
348386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      MASTER_KEY_LEN*2, len);
349386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      exit(1);
350386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
351386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (strlen(input_key) > MASTER_KEY_LEN*2) {
352386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      fprintf(stderr,
353386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      "error: too many digits in key/salt "
354386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      "(should be %d hexadecimal digits, found %u)\n",
355386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      MASTER_KEY_LEN*2, (unsigned)strlen(input_key));
356386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      exit(1);
357386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
358386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
359386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    printf("set master key/salt to %s/", octet_string_hex_string(key, 16));
360386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    printf("%s\n", octet_string_hex_string(key+16, 14));
361386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
362386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  } else {
363386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /*
364386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * we're not providing security services, so set the policy to the
365386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * null policy
366386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     *
367386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * Note that this policy does not conform to the SRTP
368386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * specification, since RTCP authentication is required.  However,
369386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * the effect of this policy is to turn off SRTP, so that this
370386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * application is now a vanilla-flavored RTP application.
371386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     */
372386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.key                 = (uint8_t *)key;
373386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.ssrc.type           = ssrc_specific;
374386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.ssrc.value          = ssrc;
375386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtp.cipher_type     = NULL_CIPHER;
376386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtp.cipher_key_len  = 0;
377386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtp.auth_type       = NULL_AUTH;
378386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtp.auth_key_len    = 0;
379386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtp.auth_tag_len    = 0;
380386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtp.sec_serv        = sec_serv_none;
381386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtcp.cipher_type    = NULL_CIPHER;
382386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtcp.cipher_key_len = 0;
383386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtcp.auth_type      = NULL_AUTH;
384386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtcp.auth_key_len   = 0;
385386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtcp.auth_tag_len   = 0;
386386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.rtcp.sec_serv       = sec_serv_none;
387386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.window_size         = 0;
388386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.allow_repeat_tx     = 0;
389386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    policy.next                = NULL;
390386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
391386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
392386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (prog_type == sender) {
393386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
394386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if BEW
395386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* bind to local socket (to match crypto policy, if need be) */
396386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    memset(&local, 0, sizeof(struct sockaddr_in));
397386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    local.sin_addr.s_addr = htonl(INADDR_ANY);
398386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    local.sin_port = htons(port);
399386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    ret = bind(sock, (struct sockaddr *) &local, sizeof(struct sockaddr_in));
400386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (ret < 0) {
401386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      fprintf(stderr, "%s: bind failed\n", argv[0]);
402386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      perror("");
403386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      exit(1);
404386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
405386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif /* BEW */
406386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
407386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* initialize sender's rtp and srtp contexts */
408386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    snd = rtp_sender_alloc();
409386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (snd == NULL) {
410386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      fprintf(stderr, "error: malloc() failed\n");
411386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      exit(1);
412386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
413386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    rtp_sender_init(snd, sock, name, ssrc);
414386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    status = rtp_sender_init_srtp(snd, &policy);
415386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (status) {
416386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      fprintf(stderr,
417386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      "error: srtp_create() failed with code %d\n",
418386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      status);
419386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      exit(1);
420386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
421386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
422386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* open dictionary */
423386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    dict = fopen (dictfile, "r");
424386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (dict == NULL) {
425386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      fprintf(stderr, "%s: couldn't open file %s\n", argv[0], dictfile);
426386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
427386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  	leave_group(sock, mreq, argv[0]);
428386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      }
429386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      exit(1);
430386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
431386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
432386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* read words from dictionary, then send them off */
433386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    while (fgets(word, MAX_WORD_LEN, dict) != NULL) {
434386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      len = strlen(word) + 1;  /* plus one for null */
435386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
436386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      if (len > MAX_WORD_LEN)
437386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	printf("error: word %s too large to send\n", word);
438386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      else {
439386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	rtp_sendto(snd, word, len);
440386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari        printf("sending word: %s", word);
441386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      }
442386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      usleep(USEC_RATE);
443386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
444386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
445386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  } else  { /* prog_type == receiver */
446386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    rtp_receiver_t rcvr;
447386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
448386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0) {
449386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      close(sock);
450386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      fprintf(stderr, "%s: socket bind error\n", argv[0]);
451386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      perror(NULL);
452386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
453386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    	leave_group(sock, mreq, argv[0]);
454386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      }
455386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      exit(1);
456386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
457386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
458386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    rcvr = rtp_receiver_alloc();
459386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (rcvr == NULL) {
460386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      fprintf(stderr, "error: malloc() failed\n");
461386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      exit(1);
462386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
463386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    rtp_receiver_init(rcvr, sock, name, ssrc);
464386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    status = rtp_receiver_init_srtp(rcvr, &policy);
465386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (status) {
466386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      fprintf(stderr,
467386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      "error: srtp_create() failed with code %d\n",
468386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      status);
469386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      exit(1);
470386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
471386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
472386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* get next word and loop */
473386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    while (1) {
474386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      len = MAX_WORD_LEN;
475386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      if (rtp_recvfrom(rcvr, word, &len) > -1)
476386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	printf("\tword: %s", word);
477386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
478386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
479386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
480386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
481386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
482386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    leave_group(sock, mreq, argv[0]);
483386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
484386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
485386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef RTPW_USE_WINSOCK2
486386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  WSACleanup();
487386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
488386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
489386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  return 0;
490386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
491386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
492386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
493386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarivoid
494386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariusage(char *string) {
495386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
496386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  printf("usage: %s [-d <debug>]* [-k <key> [-a][-e]] "
497386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	 "[-s | -r] dest_ip dest_port\n"
498386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	 "or     %s -l\n"
499386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	 "where  -a use message authentication\n"
500386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	 "       -e use encryption\n"
501386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	 "       -k <key>  sets the srtp master key\n"
502386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	 "       -s act as rtp sender\n"
503386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	 "       -r act as rtp receiver\n"
504386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	 "       -l list debug modules\n"
505386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	 "       -d <debug> turn on debugging for module <debug>\n",
506386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	 string, string);
507386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  exit(1);
508386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
509386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
510386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
511386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
512386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarivoid
513386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarileave_group(int sock, struct ip_mreq mreq, char *name) {
514386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  int ret;
515386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
516386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  ret = setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void*)&mreq,
517386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari		   sizeof(mreq));
518386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (ret < 0) {
519386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	fprintf(stderr, "%s: Failed to leave multicast group", name);
520386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	perror("");
521386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
522386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
523386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
524