changeset 42:891ebfb55e6b

sip-rx-test program written, compiles
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 04 Sep 2022 17:55:40 -0800
parents e57bc4c885a7
children 5995660dcbac
files .hgignore Makefile utils/Makefile utils/sip-rx-test.c
diffstat 4 files changed, 136 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Sep 04 16:35:16 2022 -0800
+++ b/.hgignore	Sun Sep 04 17:55:40 2022 -0800
@@ -8,6 +8,7 @@
 
 ^mtctest/themwi-test-mtc$
 
+^utils/sip-rx-test$
 ^utils/sip-udp-dump$
 ^utils/themwi-check-own$
 ^utils/themwi-dump-numdb$
--- a/Makefile	Sun Sep 04 16:35:16 2022 -0800
+++ b/Makefile	Sun Sep 04 17:55:40 2022 -0800
@@ -10,7 +10,7 @@
 mgw:		libutil
 mncc:		libnumdb libutil
 mtctest:	libnumdb libutil
-utils:		libnumdb libutil
+utils:		libnumdb libsip libutil
 
 ${SUBDIR}: FRC
 	cd $@; ${MAKE} ${MFLAGS} CC=${CC} CFLAGS="${CFLAGS}"
--- a/utils/Makefile	Sun Sep 04 16:35:16 2022 -0800
+++ b/utils/Makefile	Sun Sep 04 17:55:40 2022 -0800
@@ -1,13 +1,17 @@
 CC=	gcc
 CFLAGS=	-O2
-PROGS=	sip-udp-dump themwi-check-own themwi-dump-numdb themwi-short-dial \
-	themwi-update-numdb
+PROGS=	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
 INSTBIN=/usr/local/bin
 
 all:	${PROGS}
 
+sip-rx-test:	sip-rx-test.o ${LIBSIP}
+	${CC} ${CFLAGS} -o $@ $@.o ${LIBSIP}
+
 sip-udp-dump:	sip-udp-dump.c
 	${CC} ${CFLAGS} -o $@ $@.c
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/sip-rx-test.c	Sun Sep 04 17:55:40 2022 -0800
@@ -0,0 +1,128 @@
+/*
+ * This test program is the next level above sip-udp-dump: it binds
+ * to UDP port 5060, waits for a packet to come in, and when a SIP
+ * packet does arrive (call one of the numbers from BulkVS while this
+ * test program is running, to make BulkVS send SIP INVITE), it does
+ * two things with the captured packet:
+ *
+ * 1) The captured packet is written raw into one file named on the
+ *    command line;
+ *
+ * 2) The packet is parsed with parse_incoming_sip_msg(), and the
+ *    parsed structure is written out into the other file named on
+ *    the command line.
+ *
+ * This program is intended to serve as a unit test for the parsing
+ * function.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "../libsip/parse.h"
+
+static int sock;
+static struct sockaddr_in sin;
+static struct sip_pkt_rx pkt;
+
+static void
+save_raw_packet(filename)
+	char *filename;
+{
+	int fd;
+
+	fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+	if (fd < 0) {
+		perror(filename);
+		exit(1);
+	}
+	write(fd, pkt.pkt_buffer, pkt.pkt_length);
+	close(fd);
+}
+
+static void
+write_parse_output(filename)
+	char *filename;
+{
+	FILE *of;
+	unsigned n;
+
+	of = fopen(filename, "w");
+	if (!of) {
+		perror(filename);
+		exit(1);
+	}
+	switch (pkt.parse_msgtype) {
+	case SIP_MSG_TYPE_REQ:
+		fprintf(of, "Message is a request\n");
+		fprintf(of, "Method: %s\n", pkt.req_method);
+		fprintf(of, "Request-URI: %s\n", pkt.req_uri);
+		break;
+	case SIP_MSG_TYPE_RESP:
+		fprintf(of, "Message is a response\n");
+		fprintf(of, "Status code: %u\n", pkt.status_code);
+		fprintf(of, "Status string: %s\n", pkt.status_str);
+		break;
+	default:
+		fprintf(of, "Parsed returned unknown message type %d\n",
+			pkt.parse_msgtype);
+	}
+	fprintf(of, "Number of header fields: %u\n", pkt.num_hdr_fields);
+	for (n = 0; n < pkt.num_hdr_fields; n++) {
+		fprintf(of, "Header field %u:\n", n);
+		fprintf(of, "  Field name: %s\n",
+			pkt.hdr_fields[n].field_name);
+		fprintf(of, "  Field value: %s\n",
+			pkt.hdr_fields[n].field_value);
+	}
+	fprintf(of, "Message body length: %u\n", pkt.msg_body_len);
+	fclose(of);
+}
+
+main(argc, argv)
+	char **argv;
+{
+	int rc;
+	socklen_t addrlen;
+
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s raw-file parsed-file\n", argv[0]);
+		exit(1);
+	}
+	sock = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sock < 0) {
+		perror("socket");
+		exit(1);
+	}
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = INADDR_ANY;
+	sin.sin_port = htons(5060);
+	rc = bind(sock, (struct sockaddr *) &sin, sizeof sin);
+	if (rc < 0)
+		perror("bind");
+	addrlen = sizeof sin;
+	rc = recvfrom(sock, pkt.pkt_buffer, MAX_SIP_RX_PACKET, 0,
+			(struct sockaddr *) &sin, &addrlen);
+	if (rc < 0) {
+		perror("recvfrom");
+		exit(1);
+	}
+	pkt.pkt_length = rc;
+	printf("Rx from %s:%u, %u bytes\n", inet_ntoa(sin.sin_addr),
+		ntohs(sin.sin_port), pkt.pkt_length);
+	save_raw_packet(argv[1]);
+	rc = parse_incoming_sip_msg(&pkt);
+	if (rc < 0) {
+		printf("Parse error: %d\n", rc);
+		exit(0);
+	}
+	write_parse_output(argv[2]);
+	exit(0);
+}