FreeCalypso > hg > themwi-system-sw
changeset 52:ffb563a17f23
wrote sip-out-test program
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 08 Sep 2022 00:27:48 -0800 |
parents | 36a30349b490 |
children | 2423f3aac4ce |
files | .hgignore utils/Makefile utils/sip-out-test.c |
diffstat | 3 files changed, 266 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Wed Sep 07 17:53:10 2022 -0800 +++ b/.hgignore Thu Sep 08 00:27:48 2022 -0800 @@ -10,6 +10,7 @@ ^sip-in/themwi-sip-in$ +^utils/sip-out-test$ ^utils/sip-rx-test$ ^utils/sip-udp-dump$ ^utils/themwi-check-own$
--- a/utils/Makefile Wed Sep 07 17:53:10 2022 -0800 +++ b/utils/Makefile Thu Sep 08 00:27:48 2022 -0800 @@ -1,7 +1,7 @@ CC= gcc CFLAGS= -O2 -PROGS= sip-rx-test sip-udp-dump themwi-check-own themwi-dump-numdb \ - themwi-short-dial themwi-update-numdb +PROGS= sip-out-test sip-rx-test sip-udp-dump themwi-check-own \ + themwi-dump-numdb themwi-short-dial themwi-update-numdb LIBNUMDB=../libnumdb/libnumdb.a LIBSIP= ../libsip/libsip.a LIBUTIL=../libutil/libutil.a @@ -9,6 +9,9 @@ all: ${PROGS} +sip-out-test: sip-out-test.c + ${CC} ${CFLAGS} -o $@ $@.c + sip-rx-test: sip-rx-test.o ${LIBSIP} ${CC} ${CFLAGS} -o $@ $@.o ${LIBSIP}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils/sip-out-test.c Thu Sep 08 00:27:48 2022 -0800 @@ -0,0 +1,260 @@ +/* + * This program is a contraption for testing manually constructed + * outgoing SIP calls to BulkVS. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/errno.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> + +#define MAX_SIP_TX_PACKET 1472 + +static struct in_addr local_ip, remote_ip; +static unsigned local_sip_port, local_rtp_port, remote_port; +static char *invite_filename, *log_filename; +static char invite_packet[MAX_SIP_TX_PACKET]; +static unsigned invite_packet_len; +static FILE *logF; +static struct timeval curtime; + +static void +read_invite_file() +{ + FILE *inf; + char linebuf[128], *cp, *dp; + int lineno; + unsigned size_accum, linelen; + + inf = fopen(invite_filename, "r"); + if (!inf) { + perror(invite_filename); + exit(1); + } + size_accum = 0; + dp = invite_packet; + for (lineno = 1; fgets(linebuf, sizeof(linebuf), inf); lineno++) { + cp = index(linebuf, '\n'); + if (!cp) { + fprintf(stderr, + "%s line %d: too long or missing newline\n", + invite_filename, lineno); + exit(1); + } + *cp = '\0'; + linelen = cp - linebuf; + if (size_accum + linelen + 2 > MAX_SIP_TX_PACKET) { + fprintf(stderr, "%s line %d: packet overflow\n", + invite_filename, lineno); + exit(1); + } + bcopy(linebuf, dp, linelen); + dp += linelen; + *dp++ = '\r'; + *dp++ = '\n'; + size_accum += linelen + 2; + } + fclose(inf); + if (!size_accum) { + fprintf(stderr, "error: %s is empty\n", invite_filename); + exit(1); + } + invite_packet_len = size_accum; +} + +static void +log_common(msg, msglen, sin, dir, outf) + char *msg, *dir; + unsigned msglen; + struct sockaddr_in *sin; + FILE *outf; +{ + unsigned sec, ms; + + sec = curtime.tv_sec % 86400; + ms = curtime.tv_usec / 1000; + fprintf(outf, "Msg %s %s:%u %u bytes %02u:%02u:%02u.%03u\n", dir, + inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), msglen, + sec / 3600, (sec / 60) % 60, sec % 60, ms); + fwrite(msg, 1, msglen, outf); + putc('\n', outf); + fflush(outf); +} + +static void +log_sip_msg_rx(msg, msglen, sin) + char *msg; + unsigned msglen; + struct sockaddr_in *sin; +{ + log_common(msg, msglen, sin, "from", stdout); + if (logF) + log_common(msg, msglen, sin, "from", logF); +} + +static void +log_sip_msg_tx(msg, msglen, sin) + char *msg; + unsigned msglen; + struct sockaddr_in *sin; +{ + log_common(msg, msglen, sin, "to", stdout); + if (logF) + log_common(msg, msglen, sin, "to", logF); +} + +main(argc, argv) + char **argv; +{ + struct sockaddr_in sin_local, sin_rtp, sin_rtcp, sin_remote, sin_rx; + int sock_sip, sock_rtp, sock_rtcp, max_fd; + socklen_t addrlen; + fd_set fds; + char recv_buf[4096]; + int rc; + + /* grok command line arguments */ + if (argc < 7 || argc > 8) { + fprintf(stderr, +"usage: %s local-ip local-sip local-rtp remote-ip remote-sip inv-file [logfile]\n", + argv[0]); + exit(1); + } + local_ip.s_addr = inet_addr(argv[1]); + if (local_ip.s_addr == INADDR_NONE) { + fprintf(stderr, "error: invalid IP address \"%s\"\n", argv[1]); + exit(1); + } + local_sip_port = atoi(argv[2]); + local_rtp_port = atoi(argv[3]); + remote_ip.s_addr = inet_addr(argv[4]); + if (remote_ip.s_addr == INADDR_NONE) { + fprintf(stderr, "error: invalid IP address \"%s\"\n", argv[4]); + exit(1); + } + remote_port = atoi(argv[5]); + invite_filename = argv[6]; + log_filename = argv[7]; + /* fill sin structures */ + sin_local.sin_family = AF_INET; + sin_local.sin_addr = local_ip; + sin_local.sin_port = htons(local_sip_port); + sin_rtp.sin_family = AF_INET; + sin_rtp.sin_addr = local_ip; + sin_rtp.sin_port = htons(local_rtp_port); + sin_rtcp.sin_family = AF_INET; + sin_rtcp.sin_addr = local_ip; + sin_rtcp.sin_port = htons(local_rtp_port+1); + sin_remote.sin_family = AF_INET; + sin_remote.sin_addr = remote_ip; + sin_remote.sin_port = htons(remote_port); + /* create and bind sockets */ + sock_sip = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_sip < 0) { + perror("socket"); + exit(1); + } + rc = bind(sock_sip, (struct sockaddr *) &sin_local, + sizeof(struct sockaddr_in)); + if (rc < 0) { + perror("bind"); + exit(1); + } + sock_rtp = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_rtp < 0) { + perror("socket"); + exit(1); + } + rc = bind(sock_rtp, (struct sockaddr *) &sin_rtp, + sizeof(struct sockaddr_in)); + if (rc < 0) { + perror("bind"); + exit(1); + } + sock_rtcp = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_rtcp < 0) { + perror("socket"); + exit(1); + } + rc = bind(sock_rtcp, (struct sockaddr *) &sin_rtcp, + sizeof(struct sockaddr_in)); + if (rc < 0) { + perror("bind"); + exit(1); + } + /* read the INVITE packet */ + read_invite_file(); + /* open the log file, if we have one */ + if (log_filename) { + logF = fopen(log_filename, "a"); + if (!logF) { + perror(log_filename); + exit(1); + } + } + /* now get down to business */ + max_fd = sock_sip; + if (sock_rtp > max_fd) + max_fd = sock_rtp; + if (sock_rtcp > max_fd) + max_fd = sock_rtcp; + addrlen = sizeof(struct sockaddr_in); + rc = sendto(sock_sip, invite_packet, invite_packet_len, 0, + (struct sockaddr *) &sin_remote, addrlen); + if (rc < 0) { + perror("sendto"); + exit(1); + } + gettimeofday(&curtime, 0); + log_sip_msg_tx(invite_packet, invite_packet_len, &sin_remote); + /* main select loop */ + for (;;) { + FD_ZERO(&fds); + FD_SET(sock_sip, &fds); + FD_SET(sock_rtp, &fds); + FD_SET(sock_rtcp, &fds); + rc = select(max_fd+1, &fds, 0, 0, 0); + if (rc < 0) { + if (errno == EINTR) + continue; + perror("select"); + exit(1); + } + gettimeofday(&curtime, 0); + if (FD_ISSET(sock_sip, &fds)) { + addrlen = sizeof(struct sockaddr_in); + rc = recvfrom(sock_sip, recv_buf, sizeof recv_buf, 0, + (struct sockaddr *) &sin_rx, &addrlen); + if (rc < 0) { + perror("recvfrom"); + exit(1); + } + log_sip_msg_rx(recv_buf, rc, &sin_rx); + } + if (FD_ISSET(sock_rtp, &fds)) { + addrlen = sizeof(struct sockaddr_in); + rc = recvfrom(sock_rtp, recv_buf, sizeof recv_buf, 0, + (struct sockaddr *) &sin_rx, &addrlen); + if (rc < 0) { + perror("recvfrom"); + exit(1); + } + } + if (FD_ISSET(sock_rtcp, &fds)) { + addrlen = sizeof(struct sockaddr_in); + rc = recvfrom(sock_rtp, recv_buf, sizeof recv_buf, 0, + (struct sockaddr *) &sin_rx, &addrlen); + if (rc < 0) { + perror("recvfrom"); + exit(1); + } + } + } +}