changeset 46:5427b26525cd

libsip: beginning to flesh out
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 06 Sep 2022 20:29:44 -0800
parents f1cf80c7e243
children 62f39c7cee15
files libsip/Makefile libsip/get_header.c libsip/out_msg.c libsip/out_msg.h libsip/uas_basic.c libsip/uas_basic.h libsip/uri_utils.c
diffstat 7 files changed, 258 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libsip/Makefile	Tue Sep 06 15:15:42 2022 -0800
+++ b/libsip/Makefile	Tue Sep 06 20:29:44 2022 -0800
@@ -1,6 +1,6 @@
 CC=	gcc
 CFLAGS=	-O2
-OBJS=	primary_parse.o
+OBJS=	get_header.o out_msg.o primary_parse.o uas_basic.o uri_utils.o
 LIB=	libsip.a
 
 all:	${LIB}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libsip/get_header.c	Tue Sep 06 20:29:44 2022 -0800
@@ -0,0 +1,39 @@
+/*
+ * In this module we implement functions for retrieving individual
+ * header fields from struct sip_pkt_rx.
+ */
+
+#include <string.h>
+#include <strings.h>
+#include "parse.h"
+
+char *
+get_single_header(msg, name, altname, dupp)
+	struct sip_pkt_rx *msg;
+	char *name, *altname;
+	int *dupp;
+{
+	unsigned n;
+	char *ret;
+
+	for (n = 0; n < msg->num_hdr_fields; n++) {
+		if (!strcasecmp(msg->hdr_fields[n].field_name, name))
+			break;
+		if (altname &&
+		    !strcasecmp(msg->hdr_fields[n].field_name, altname))
+			break;
+	}
+	if (n >= msg->num_hdr_fields)
+		return 0;
+	ret = msg->hdr_fields[n].field_value;
+	if (!dupp)
+		return ret;
+	for (n++; n < msg->num_hdr_fields; n++) {
+		if (!strcasecmp(msg->hdr_fields[n].field_name, name))
+			*dupp = 1;
+		if (altname &&
+		    !strcasecmp(msg->hdr_fields[n].field_name, altname))
+			*dupp = 1;
+	}
+	return ret;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libsip/out_msg.c	Tue Sep 06 20:29:44 2022 -0800
@@ -0,0 +1,73 @@
+/*
+ * Functions for constructing outgoing SIP messages.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+
+#include "out_msg.h"
+
+start_request_out_msg(msg, method, uri)
+	struct sip_msg_out *msg;
+	char *method, *uri;
+{
+	unsigned len;
+
+	len = strlen(method) + strlen(uri) + (2 + 7 + 2);
+	if (len + 2 > MAX_SIP_TX_PACKET)
+		return(-1);
+	sprintf(msg->buf, "%s %s SIP/2.0\r\n", method, uri);
+	msg->msg_len = len;
+	return(0);
+}
+
+start_response_out_msg(msg, status)
+	struct sip_msg_out *msg;
+	char *status;
+{
+	unsigned len;
+
+	len = strlen(status) + (8 + 2);
+	if (len + 2 > MAX_SIP_TX_PACKET)
+		return(-1);
+	sprintf(msg->buf, "SIP/2.0 %s\r\n", status);
+	msg->msg_len = len;
+	return(0);
+}
+
+out_msg_add_header(msg, name, value)
+	struct sip_msg_out *msg;
+	char *name, *value;
+{
+	unsigned len;
+
+	len = strlen(name) + strlen(value) + 4;
+	if (msg->msg_len + len + 2 > MAX_SIP_TX_PACKET)
+		return(-1);
+	sprintf(msg->buf + msg->msg_len, "%s: %s\r\n", name, value);
+	msg->msg_len += len;
+	return(0);
+}
+
+out_msg_finish(msg)
+	struct sip_msg_out *msg;
+{
+	msg->buf[msg->msg_len++] = '\r';
+	msg->buf[msg->msg_len++] = '\n';
+	return(0);
+}
+
+out_msg_finish_body(msg, body, bodylen)
+	struct sip_msg_out *msg;
+	char *body;
+	unsigned bodylen;
+{
+	msg->buf[msg->msg_len++] = '\r';
+	msg->buf[msg->msg_len++] = '\n';
+	if (msg->msg_len + bodylen > MAX_SIP_TX_PACKET)
+		return(-1);
+	bcopy(body, msg->buf + msg->msg_len, bodylen);
+	msg->msg_len += bodylen;
+	return(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libsip/out_msg.h	Tue Sep 06 20:29:44 2022 -0800
@@ -0,0 +1,11 @@
+/*
+ * Here we define the structure we are going to use for constructing
+ * outgoing SIP messages (UDP packets).
+ */
+
+#define	MAX_SIP_TX_PACKET	1472
+
+struct sip_msg_out {
+	char		buf[MAX_SIP_TX_PACKET];
+	unsigned	msg_len;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libsip/uas_basic.c	Tue Sep 06 20:29:44 2022 -0800
@@ -0,0 +1,88 @@
+/*
+ * Here we implement some essential UAS functions.
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "parse.h"
+#include "uas_basic.h"
+#include "out_msg.h"
+
+extern char *get_single_header();
+
+uas_get_basic_headers(msg, ess)
+	struct sip_pkt_rx *msg;
+	struct uas_parse_hdrs *ess;
+{
+	char *hval, *cp;
+	int dup_flag = 0;
+
+	hval = get_single_header(msg, "Call-ID", "i", &dup_flag);
+	if (!hval || dup_flag) {
+		ess->error_field = "Call-ID";
+		return(-1);
+	}
+	ess->call_id = hval;
+	hval = get_single_header(msg, "CSeq", (char *) 0, &dup_flag);
+	if (!hval || dup_flag) {
+bad_cseq:	ess->error_field = "CSeq";
+		return(-1);
+	}
+	if (!isdigit(*hval))
+		goto bad_cseq;
+	ess->cseq_num = strtoul(hval, &cp, 10);
+	if (*cp) {
+		if (!isspace(*cp))
+			goto bad_cseq;
+		while (isspace(*cp))
+			cp++;
+		if (strcmp(cp, msg->req_method))
+			goto bad_cseq;
+	}
+	hval = get_single_header(msg, "From", "f", &dup_flag);
+	if (!hval || dup_flag) {
+		ess->error_field = "From";
+		return(-1);
+	}
+	ess->from = hval;
+	hval = get_single_header(msg, "To", "t", &dup_flag);
+	if (!hval || dup_flag) {
+		ess->error_field = "To";
+		return(-1);
+	}
+	ess->to = hval;
+	hval = get_single_header(msg, "Via", "v", &dup_flag);
+	if (!hval || dup_flag) {
+		ess->error_field = "Via";
+		return(-1);
+	}
+	ess->via = hval;
+	return(0);
+}
+
+add_resp_basic_headers(msg, ess, req_method)
+	struct sip_msg_out *msg;
+	struct uas_parse_hdrs *ess;
+	char *req_method;
+{
+	char cseq_str[80];
+	int rc;
+
+	rc = out_msg_add_header(msg, "From", ess->from);
+	if (rc < 0)
+		return rc;
+	rc = out_msg_add_header(msg, "To", ess->to);
+	if (rc < 0)
+		return rc;
+	rc = out_msg_add_header(msg, "Call-ID", ess->call_id);
+	if (rc < 0)
+		return rc;
+	sprintf(cseq_str, "%u %.64s", ess->cseq_num, req_method);
+	rc = out_msg_add_header(msg, "CSeq", cseq_str);
+	if (rc < 0)
+		return rc;
+	return out_msg_add_header(msg, "Via", ess->via);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libsip/uas_basic.h	Tue Sep 06 20:29:44 2022 -0800
@@ -0,0 +1,14 @@
+/*
+ * Here we define struct uas_parse_hdrs, a structure that captures
+ * the 5 essential header fields that must be present in every
+ * received request in order for us to be able to respond to it.
+ */
+
+struct uas_parse_hdrs {
+	char		*from;
+	char		*to;
+	char		*call_id;
+	unsigned	cseq_num;
+	char		*via;
+	char		*error_field;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libsip/uri_utils.c	Tue Sep 06 20:29:44 2022 -0800
@@ -0,0 +1,32 @@
+/*
+ * Some utility functions for working with SIP URIs.
+ */
+
+#include <string.h>
+#include <strings.h>
+
+user_from_sip_uri(uri, outbuf, maxlen)
+	char *uri, *outbuf;
+	unsigned maxlen;
+{
+	char *cp, *dp;
+	unsigned n;
+
+	if (strncasecmp(uri, "sip:", 4))
+		return(-1);
+	cp = uri + 4;
+	dp = outbuf;
+	n = 0;
+	for (;;) {
+		if (!*cp)
+			return(-1);
+		if (*cp == '@')
+			break;
+		if (n >= maxlen)
+			return(-2);
+		*dp++ = *cp++;
+		n++;
+	}
+	*dp = '\0';
+	return(0);
+}