comparison utils/sip-out-test.c @ 52:ffb563a17f23

wrote sip-out-test program
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 08 Sep 2022 00:27:48 -0800
parents
children
comparison
equal deleted inserted replaced
51:36a30349b490 52:ffb563a17f23
1 /*
2 * This program is a contraption for testing manually constructed
3 * outgoing SIP calls to BulkVS.
4 */
5
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <sys/time.h>
9 #include <sys/errno.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <strings.h>
16 #include <unistd.h>
17
18 #define MAX_SIP_TX_PACKET 1472
19
20 static struct in_addr local_ip, remote_ip;
21 static unsigned local_sip_port, local_rtp_port, remote_port;
22 static char *invite_filename, *log_filename;
23 static char invite_packet[MAX_SIP_TX_PACKET];
24 static unsigned invite_packet_len;
25 static FILE *logF;
26 static struct timeval curtime;
27
28 static void
29 read_invite_file()
30 {
31 FILE *inf;
32 char linebuf[128], *cp, *dp;
33 int lineno;
34 unsigned size_accum, linelen;
35
36 inf = fopen(invite_filename, "r");
37 if (!inf) {
38 perror(invite_filename);
39 exit(1);
40 }
41 size_accum = 0;
42 dp = invite_packet;
43 for (lineno = 1; fgets(linebuf, sizeof(linebuf), inf); lineno++) {
44 cp = index(linebuf, '\n');
45 if (!cp) {
46 fprintf(stderr,
47 "%s line %d: too long or missing newline\n",
48 invite_filename, lineno);
49 exit(1);
50 }
51 *cp = '\0';
52 linelen = cp - linebuf;
53 if (size_accum + linelen + 2 > MAX_SIP_TX_PACKET) {
54 fprintf(stderr, "%s line %d: packet overflow\n",
55 invite_filename, lineno);
56 exit(1);
57 }
58 bcopy(linebuf, dp, linelen);
59 dp += linelen;
60 *dp++ = '\r';
61 *dp++ = '\n';
62 size_accum += linelen + 2;
63 }
64 fclose(inf);
65 if (!size_accum) {
66 fprintf(stderr, "error: %s is empty\n", invite_filename);
67 exit(1);
68 }
69 invite_packet_len = size_accum;
70 }
71
72 static void
73 log_common(msg, msglen, sin, dir, outf)
74 char *msg, *dir;
75 unsigned msglen;
76 struct sockaddr_in *sin;
77 FILE *outf;
78 {
79 unsigned sec, ms;
80
81 sec = curtime.tv_sec % 86400;
82 ms = curtime.tv_usec / 1000;
83 fprintf(outf, "Msg %s %s:%u %u bytes %02u:%02u:%02u.%03u\n", dir,
84 inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), msglen,
85 sec / 3600, (sec / 60) % 60, sec % 60, ms);
86 fwrite(msg, 1, msglen, outf);
87 putc('\n', outf);
88 fflush(outf);
89 }
90
91 static void
92 log_sip_msg_rx(msg, msglen, sin)
93 char *msg;
94 unsigned msglen;
95 struct sockaddr_in *sin;
96 {
97 log_common(msg, msglen, sin, "from", stdout);
98 if (logF)
99 log_common(msg, msglen, sin, "from", logF);
100 }
101
102 static void
103 log_sip_msg_tx(msg, msglen, sin)
104 char *msg;
105 unsigned msglen;
106 struct sockaddr_in *sin;
107 {
108 log_common(msg, msglen, sin, "to", stdout);
109 if (logF)
110 log_common(msg, msglen, sin, "to", logF);
111 }
112
113 main(argc, argv)
114 char **argv;
115 {
116 struct sockaddr_in sin_local, sin_rtp, sin_rtcp, sin_remote, sin_rx;
117 int sock_sip, sock_rtp, sock_rtcp, max_fd;
118 socklen_t addrlen;
119 fd_set fds;
120 char recv_buf[4096];
121 int rc;
122
123 /* grok command line arguments */
124 if (argc < 7 || argc > 8) {
125 fprintf(stderr,
126 "usage: %s local-ip local-sip local-rtp remote-ip remote-sip inv-file [logfile]\n",
127 argv[0]);
128 exit(1);
129 }
130 local_ip.s_addr = inet_addr(argv[1]);
131 if (local_ip.s_addr == INADDR_NONE) {
132 fprintf(stderr, "error: invalid IP address \"%s\"\n", argv[1]);
133 exit(1);
134 }
135 local_sip_port = atoi(argv[2]);
136 local_rtp_port = atoi(argv[3]);
137 remote_ip.s_addr = inet_addr(argv[4]);
138 if (remote_ip.s_addr == INADDR_NONE) {
139 fprintf(stderr, "error: invalid IP address \"%s\"\n", argv[4]);
140 exit(1);
141 }
142 remote_port = atoi(argv[5]);
143 invite_filename = argv[6];
144 log_filename = argv[7];
145 /* fill sin structures */
146 sin_local.sin_family = AF_INET;
147 sin_local.sin_addr = local_ip;
148 sin_local.sin_port = htons(local_sip_port);
149 sin_rtp.sin_family = AF_INET;
150 sin_rtp.sin_addr = local_ip;
151 sin_rtp.sin_port = htons(local_rtp_port);
152 sin_rtcp.sin_family = AF_INET;
153 sin_rtcp.sin_addr = local_ip;
154 sin_rtcp.sin_port = htons(local_rtp_port+1);
155 sin_remote.sin_family = AF_INET;
156 sin_remote.sin_addr = remote_ip;
157 sin_remote.sin_port = htons(remote_port);
158 /* create and bind sockets */
159 sock_sip = socket(AF_INET, SOCK_DGRAM, 0);
160 if (sock_sip < 0) {
161 perror("socket");
162 exit(1);
163 }
164 rc = bind(sock_sip, (struct sockaddr *) &sin_local,
165 sizeof(struct sockaddr_in));
166 if (rc < 0) {
167 perror("bind");
168 exit(1);
169 }
170 sock_rtp = socket(AF_INET, SOCK_DGRAM, 0);
171 if (sock_rtp < 0) {
172 perror("socket");
173 exit(1);
174 }
175 rc = bind(sock_rtp, (struct sockaddr *) &sin_rtp,
176 sizeof(struct sockaddr_in));
177 if (rc < 0) {
178 perror("bind");
179 exit(1);
180 }
181 sock_rtcp = socket(AF_INET, SOCK_DGRAM, 0);
182 if (sock_rtcp < 0) {
183 perror("socket");
184 exit(1);
185 }
186 rc = bind(sock_rtcp, (struct sockaddr *) &sin_rtcp,
187 sizeof(struct sockaddr_in));
188 if (rc < 0) {
189 perror("bind");
190 exit(1);
191 }
192 /* read the INVITE packet */
193 read_invite_file();
194 /* open the log file, if we have one */
195 if (log_filename) {
196 logF = fopen(log_filename, "a");
197 if (!logF) {
198 perror(log_filename);
199 exit(1);
200 }
201 }
202 /* now get down to business */
203 max_fd = sock_sip;
204 if (sock_rtp > max_fd)
205 max_fd = sock_rtp;
206 if (sock_rtcp > max_fd)
207 max_fd = sock_rtcp;
208 addrlen = sizeof(struct sockaddr_in);
209 rc = sendto(sock_sip, invite_packet, invite_packet_len, 0,
210 (struct sockaddr *) &sin_remote, addrlen);
211 if (rc < 0) {
212 perror("sendto");
213 exit(1);
214 }
215 gettimeofday(&curtime, 0);
216 log_sip_msg_tx(invite_packet, invite_packet_len, &sin_remote);
217 /* main select loop */
218 for (;;) {
219 FD_ZERO(&fds);
220 FD_SET(sock_sip, &fds);
221 FD_SET(sock_rtp, &fds);
222 FD_SET(sock_rtcp, &fds);
223 rc = select(max_fd+1, &fds, 0, 0, 0);
224 if (rc < 0) {
225 if (errno == EINTR)
226 continue;
227 perror("select");
228 exit(1);
229 }
230 gettimeofday(&curtime, 0);
231 if (FD_ISSET(sock_sip, &fds)) {
232 addrlen = sizeof(struct sockaddr_in);
233 rc = recvfrom(sock_sip, recv_buf, sizeof recv_buf, 0,
234 (struct sockaddr *) &sin_rx, &addrlen);
235 if (rc < 0) {
236 perror("recvfrom");
237 exit(1);
238 }
239 log_sip_msg_rx(recv_buf, rc, &sin_rx);
240 }
241 if (FD_ISSET(sock_rtp, &fds)) {
242 addrlen = sizeof(struct sockaddr_in);
243 rc = recvfrom(sock_rtp, recv_buf, sizeof recv_buf, 0,
244 (struct sockaddr *) &sin_rx, &addrlen);
245 if (rc < 0) {
246 perror("recvfrom");
247 exit(1);
248 }
249 }
250 if (FD_ISSET(sock_rtcp, &fds)) {
251 addrlen = sizeof(struct sockaddr_in);
252 rc = recvfrom(sock_rtp, recv_buf, sizeof recv_buf, 0,
253 (struct sockaddr *) &sin_rx, &addrlen);
254 if (rc < 0) {
255 perror("recvfrom");
256 exit(1);
257 }
258 }
259 }
260 }