aboutsummaryrefslogtreecommitdiff
path: root/sip.c
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2023-07-23 22:52:31 +0000
committerrodri <rgl@antares-labs.eu>2023-07-23 22:52:31 +0000
commit2e99eaaea1aa6776eda10f5ec8bd90adcfe8424a (patch)
treefe2602798fbafacef77d0636c7ef5f717a12bbed /sip.c
downloadcatphone-2e99eaaea1aa6776eda10f5ec8bd90adcfe8424a.tar.gz
catphone-2e99eaaea1aa6776eda10f5ec8bd90adcfe8424a.tar.bz2
catphone-2e99eaaea1aa6776eda10f5ec8bd90adcfe8424a.zip
layed out initial structures. began work on registration procedure.
Diffstat (limited to 'sip.c')
-rw-r--r--sip.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/sip.c b/sip.c
new file mode 100644
index 0000000..267c49a
--- /dev/null
+++ b/sip.c
@@ -0,0 +1,211 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <draw.h>
+#include "dat.h"
+#include "fns.h"
+
+static char sipversion[] = "SIP/2.0";
+static char *methodstrtab[] = {
+ [REGISTER] "REGISTER",
+ [INVITE] "INVITE",
+ [ACK] "ACK",
+ [BYE] "BYE",
+ [CANCEL] "CANCEL",
+ [OPTIONS] "OPTIONS",
+ [NOTIFY] "NOTIFY",
+ [SUBSCRIBE] "SUBSCRIBE",
+ [INFO] "INFO",
+ [MESSAGE] "MESSAGE",
+ [UPDATE] "UPDATE",
+ [REFER] "REFER",
+};
+
+static char registerhdr0[] = "REGISTER sip:%s %s\r\n"
+ "Via: %s/UDP %s:%s;branch=z9hG4bK703d971c0c737b8e;rport\r\n"
+ "Contact: <sip:%s-0x82a66a010@%s:%s>;expires=3849\r\n"
+ "Max-Forwards: 70\r\n"
+ "To: <sip:%s@%s>\r\n"
+ "From: <sip:%s@%s>;tag=4a5a693256d38cbc\r\n"
+ "Call-ID: 2cee372fc4be4e45\r\n"
+ "CSeq: 16021 REGISTER\r\n"
+ "User-Agent: catphone (plan9front)\r\n"
+ "Allow: INVITE,ACK,BYE,CANCEL,OPTIONS,NOTIFY,SUBSCRIBE,INFO,MESSAGE,UPDATE,REFER\r\n"
+ "Content-Length: 0\r\n"
+ "\r\n";
+static char registerhdr[] = "REGISTER sip:10.0.0.104 SIP/2.0\r\n"
+ "Via: SIP/2.0/UDP 10.0.1.9:54022;branch=z9hG4bKdf800c31b9a88ffb;rport\r\n"
+ "Contact: <sip:sam-0x82a66a010@10.0.1.9:54022>;expires=3849\r\n"
+ "Max-Forwards: 70\r\n"
+ "Authorization: Digest username=\"sam\", realm=\"asterisk\", nonce=\"0d39ab10\", uri=\"sip:10.0.0.104\", response=\"a12e05b52604b5226763ce577d5c240b\", algorithm=MD5\r\n"
+ "To: <sip:sam@10.0.0.104>\r\n"
+ "From: <sip:sam@10.0.0.104>;tag=4a5a693256d38cbc\r\n"
+ "Call-ID: 2cee372fc4be4e45\r\n"
+ "CSeq: 16022 REGISTER\r\n"
+ "User-Agent: catphone (plan9front)\r\n"
+ "Allow: INVITE,ACK,BYE,CANCEL,OPTIONS,NOTIFY,SUBSCRIBE,INFO,MESSAGE,UPDATE,REFER\r\n"
+ "Content-Length: 0\r\n"
+ "\r\n";
+
+static char *
+getmethodstr(SipMethod m)
+{
+ return methodstrtab[m];
+}
+
+static uint
+hash(char *s)
+{
+ uint h;
+
+ h = 0x811c9dc5;
+ while(*s != 0)
+ h = (h^(uchar)*s++) * 0x1000193;
+ return h % 13;
+}
+
+void
+addheader(Hdrtab *ht, char *name, char *value)
+{
+ Hdr *h, *newh;
+ uint key;
+
+ key = hash(name);
+ newh = emalloc(sizeof(Hdr));
+ newh->name = strdup(name);
+ newh->value = strdup(value);
+ newh->next = nil;
+
+ h = ht->headers[key];
+ if(h == nil){
+ ht->headers[key] = newh;
+ return;
+ }
+ while(h->next != nil)
+ h = h->next;
+ h->next = newh;
+}
+
+Hdr *
+getheader(Hdrtab *ht, char *name)
+{
+ Hdr *h;
+ uint key;
+
+ key = hash(name);
+ for(h = ht->headers[key]; h != nil; h = h->next)
+ if(cistrcmp(h->name, name) == 0)
+ return h;
+ return nil;
+}
+
+void
+delheader(Hdrtab *ht, char *name)
+{
+ Hdr **h, *nh;
+ uint key;
+
+ key = hash(name);
+ h = &ht->headers[key];
+ while(*h != nil){
+ nh = (*h)->next;
+ if(cistrcmp((*h)->name, name) == 0){
+ free((*h)->name);
+ free((*h)->value);
+ free(*h);
+ }
+ *h = nh;
+ }
+}
+
+void
+delheaders(Hdrtab *ht)
+{
+ Hdr *h, *nh;
+ int i;
+
+ for(i = 0; i < nelem(ht->headers); i++)
+ for(h = ht->headers[i]; h != nil; h = nh){
+ nh = h->next;
+ free(h->name);
+ free(h->value);
+ free(h);
+ }
+}
+
+/* rfc3261 ยง 10 - Registrations */
+static int
+sip_register(Sip *s, char *user, char *pass)
+{
+ Biobuf *bin, *bout;
+ char *line, *p, *kv[2];
+ int n;
+
+ if((bin = Bfdopen(s->fd, OREAD)) == nil)
+ sysfatal("Bfdopen: %r");
+ if((bout = Bfdopen(s->fd, OWRITE)) == nil)
+ sysfatal("Bfdopen: %r");
+
+ /* present yourself */
+ Bprint(bout, registerhdr0, s->nci->rsys, sipversion,
+ sipversion, s->nci->lsys, s->nci->lserv,
+ user, s->nci->lsys, s->nci->lserv,
+ user, s->nci->rsys,
+ user, s->nci->rsys);
+ Bflush(bout);
+
+ /* wait for the challenge */
+ while((line = Brdline(bin, '\n')) != nil){
+ if(strncmp(line, "\r\n", 2) == 0)
+ break;
+
+ p = strchr(line, '\r');
+ *p++ = 0, *p = 0;
+ if(debug)
+ fprint(2, "%s\n", line);
+
+ if(strstr(line, ":") == nil)
+ continue;
+
+ gettokens(line, kv, nelem(kv), ": ");
+ if(debug)
+ fprint(2, "got key=%s value=%s\n", kv[0], kv[1]);
+ }
+
+ /* respond to the challenge */
+
+ /* get the OK */
+
+ Bterm(bin);
+ Bterm(bout);
+
+ return 0;
+}
+
+Sip *
+mksip(int fd)
+{
+ Sip *s;
+
+ s = emalloc(sizeof(Sip));
+ memset(s, 0, sizeof *s);
+ s->version = 2;
+ s->nci = getnetconninfo(nil, fd);
+ if(s->nci == nil){
+ werrstr("couldn't getnetconninfo");
+ free(s);
+ return nil;
+ }
+ s->fd = fd;
+ s->reg = sip_register;
+
+ return s;
+}
+
+void
+rmsip(Sip *s)
+{
+ close(s->fd);
+ freenetconninfo(s->nci);
+ free(s);
+}