parser seems to work
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 4 Sep 2001 01:41:39 +0000 (01:41 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 4 Sep 2001 01:41:39 +0000 (01:41 +0000)
18 files changed:
.cfg_parser.c.swp [deleted file]
.cfg_parser.h.swp [deleted file]
.main.c.swp [deleted file]
.msg_parser.c.swp [deleted file]
.msg_parser.h.swp [deleted file]
.parser_f.c.swp [deleted file]
.parser_f.h.swp [deleted file]
.route.c.swp [deleted file]
.route.h.swp [deleted file]
.sip_router.cfg.swp [deleted file]
.test.c.swp [deleted file]
forward.c [new file with mode: 0644]
forward.h [new file with mode: 0644]
main.c
msg_parser.c
msg_parser.h
receive.c [new file with mode: 0644]
receive.h [new file with mode: 0644]

diff --git a/.cfg_parser.c.swp b/.cfg_parser.c.swp
deleted file mode 100644 (file)
index 8301019..0000000
Binary files a/.cfg_parser.c.swp and /dev/null differ
diff --git a/.cfg_parser.h.swp b/.cfg_parser.h.swp
deleted file mode 100644 (file)
index 08e7493..0000000
Binary files a/.cfg_parser.h.swp and /dev/null differ
diff --git a/.main.c.swp b/.main.c.swp
deleted file mode 100644 (file)
index 8891072..0000000
Binary files a/.main.c.swp and /dev/null differ
diff --git a/.msg_parser.c.swp b/.msg_parser.c.swp
deleted file mode 100644 (file)
index 25438c7..0000000
Binary files a/.msg_parser.c.swp and /dev/null differ
diff --git a/.msg_parser.h.swp b/.msg_parser.h.swp
deleted file mode 100644 (file)
index 285ef5a..0000000
Binary files a/.msg_parser.h.swp and /dev/null differ
diff --git a/.parser_f.c.swp b/.parser_f.c.swp
deleted file mode 100644 (file)
index 5375d2f..0000000
Binary files a/.parser_f.c.swp and /dev/null differ
diff --git a/.parser_f.h.swp b/.parser_f.h.swp
deleted file mode 100644 (file)
index 5724bcf..0000000
Binary files a/.parser_f.h.swp and /dev/null differ
diff --git a/.route.c.swp b/.route.c.swp
deleted file mode 100644 (file)
index bcca88c..0000000
Binary files a/.route.c.swp and /dev/null differ
diff --git a/.route.h.swp b/.route.h.swp
deleted file mode 100644 (file)
index e3452d2..0000000
Binary files a/.route.h.swp and /dev/null differ
diff --git a/.sip_router.cfg.swp b/.sip_router.cfg.swp
deleted file mode 100644 (file)
index ea4adaa..0000000
Binary files a/.sip_router.cfg.swp and /dev/null differ
diff --git a/.test.c.swp b/.test.c.swp
deleted file mode 100644 (file)
index 85711a8..0000000
Binary files a/.test.c.swp and /dev/null differ
diff --git a/forward.c b/forward.c
new file mode 100644 (file)
index 0000000..4f9c6b9
--- /dev/null
+++ b/forward.c
@@ -0,0 +1,137 @@
+/*
+ * $Id$
+ */
+
+
+#include <string.h>
+
+#include "forward.h"
+#include "msg_parser.h"
+#include "route.h"
+#include "dprint.h"
+
+#define MAX_VIA_LINE_SIZE      240
+#define MAX_RECEIVED_SIZE  57
+
+#define our_address "dorian.fokus.gmd.de"
+#define our_port 1234
+
+
+int forward_request(char * orig, char* buf, 
+                                        unsigned int len,
+                                        struct sip_msg* msg,
+                                        struct route_elem* re)
+{
+       unsigned int new_len, via_len, received_len;
+       char line_buf[MAX_VIA_LINE_SIZE];
+       char received_buf[MAX_RECEIVED_SIZE];
+       char* new_buf;
+       int offset, s_offset, size;
+
+       received_len=0;
+       printf("0\n");
+
+       via_len=snprintf(line_buf, MAX_VIA_LINE_SIZE, "Via: SIP/2.0/UDP %s:%d\r\n",
+                                               our_address, our_port);
+       /* check if received needs to be added */
+       /* if check_address(source_ip, msg->via1.host) */
+       received_len=snprintf(received_buf, MAX_RECEIVED_SIZE, ";received=%s",
+                                                       "10.11.12.13");
+       
+       new_len=len+via_len+received_len;
+       new_buf=(char*)malloc(new_len+1);
+       if (new_buf==0){
+               DPrint("ERROR: forward_request: out of memory\n");
+               goto error;
+       }
+       printf("1\n");
+ /* copy msg till first via */
+       offset=s_offset=0;
+       size=msg->via1.hdr-buf;
+       memcpy(new_buf, orig, size);
+       offset+=size;
+       s_offset+=size;
+       printf("2\n");
+ /* add our via */
+       memcpy(new_buf+offset, line_buf, via_len);
+       offset+=via_len;
+       printf("3\n");
+ /* modify original via if neccesarry (received=...)*/
+       if (received_len){
+               if (msg->via1.params){
+                               size= msg->via1.params-msg->via1.hdr-1; /*compensate for ';' */
+               }else{
+                               size= msg->via1.host-msg->via1.hdr+strlen(msg->via1.host);
+                               if (msg->via1.port!=0){
+                                       size+=strlen(msg->via1.hdr+size+1);
+                               }
+               }
+               memcpy(new_buf+offset, orig+s_offset, 
+                                                               size);
+               offset+=size;
+               s_offset+=size;
+               printf("4\n");
+               memcpy(new_buf+offset, received_buf, received_len);
+               printf("5\n");
+               offset+=received_len;
+       }
+       /* copy the rest of the msg */
+       memcpy(new_buf+offset, orig+s_offset, len-s_offset);
+       printf("6\n");
+       new_buf[new_len]=0;
+
+        /* send it! */
+        printf("Sending:\n%s.\n", new_buf);
+        
+       return 0;
+error:
+       return -1;
+
+}
+
+
+
+/* removes first via & sends msg to the second */
+int forward_reply(char * orig, char* buf, 
+                                        unsigned int len,
+                                        struct sip_msg* msg)
+{
+
+
+       unsigned int new_len, via_len;
+       char* new_buf;
+       int offset, s_offset, size;
+
+
+       /* we must remove first via */
+       via_len=msg->via1.size;
+       size=msg->via1.hdr-buf;
+       if (msg->via1.next){
+               via_len-=strlen(msg->via1.hdr)+1; /* +1 from ':' */
+               size+=strlen(msg->via1.hdr)+1;
+       }
+       new_len=len-size;
+       printf("r1\n");
+       new_buf=(char*)malloc(new_len);
+       if (new_buf==0){
+               DPrint("ERROR: forward_reply: out of memory\n");
+               goto error;
+       }
+       printf("r2\n");
+       memcpy(new_buf, orig, size);
+       offset=size;
+       s_offset=size+via_len;
+       printf("r3\n");
+       memcpy(new_buf+offset,orig+s_offset, len-s_offset);
+       printf("r4\n");
+        /* send it! */
+       printf("Sending: to %s:%d, \n%s.\n",
+                       msg->via2.host, 
+                       (unsigned short)msg->via2.port,
+                       new_buf);
+       
+       return 0;
+
+error:
+       return -1;
+}
diff --git a/forward.h b/forward.h
new file mode 100644 (file)
index 0000000..b0bc9f6
--- /dev/null
+++ b/forward.h
@@ -0,0 +1,18 @@
+/*
+ *  $Id$
+ */
+
+
+#ifndef forward_h
+#define forward_h
+
+#include "msg_parser.h"
+#include "route.h"
+
+int forward_request(char * orig, char* buf, unsigned int len,
+                                        struct sip_msg* msg,  struct route_elem* re);
+
+int forward_reply(char * orig, char* buf, unsigned int len, 
+                                       struct sip_msg* msg);
+
+#endif
diff --git a/main.c b/main.c
index d07bd80..564dfd5 100644 (file)
--- a/main.c
+++ b/main.c
 #define CFG_FILE "./sip_router.cfg"
 
 
+/* debuging function */
+
+void receive_stdin_loop()
+{
+       #define BSIZE 1024
+       char buf[BSIZE+1];
+       int len;
+       
+       while(1){
+               len=fread(buf,1,BSIZE,stdin);
+               buf[len+1]=0;
+               receive_msg(buf, len);
+               printf("-------------------------\n");
+       }
+}
+
+
+
 int main(int argc, char** argv)
 {
 
@@ -40,10 +58,12 @@ int main(int argc, char** argv)
 
 
 
-       /* start other processes/threads ? */
+       /* start/init other processes/threads ? */
 
        /* receive loop */
 
+       receive_stdin_loop();
+
 
 error:
        return -1;
index b800142..f276061 100644 (file)
@@ -5,14 +5,18 @@
  *
  */
 
-#include "msg_parser.h"
-#include "string.h"
+#include <string.h>
 
+#include "msg_parser.h"
 #include "parser_f.h"
 #include "dprint.h"
 
 
 
+#define DEBUG
+
+
+
 /* parses the first line, returns pointer to  next line  & fills fl;
    also  modifies buffer (to avoid extra copy ops) */
 char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl)
@@ -313,3 +317,145 @@ error:
        return tmp;
 }
 
+
+
+/* returns 0 if ok, -1 for errors */
+int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
+{
+
+       char *tmp, *bar;
+       char* rest;
+       char* first_via;
+       char* second_via;
+       struct msg_start fl;
+       struct hdr_field hf;
+       struct via_body vb1, vb2;
+       int offset;
+       int r;
+
+       
+       /* eat crlf from the beginning */
+       for (tmp=buf; (*tmp=='\n' || *tmp=='\r')&&
+                       tmp-buf < len ; tmp++);
+       offset=tmp-buf;
+       rest=parse_first_line(tmp, len-offset, &fl);
+       offset+=rest-tmp;
+       tmp=rest;
+       switch(fl.type){
+               case SIP_INVALID:
+                       DPrint("invalid message\n");
+                       goto error;
+                       break;
+               case SIP_REQUEST:
+                       DPrint("SIP Request:\n");
+                       DPrint(" method:  <%s>\n",fl.u.request.method);
+                       DPrint(" uri:     <%s>\n",fl.u.request.uri);
+                       DPrint(" version: <%s>\n",fl.u.request.version);
+                       break;
+               case SIP_REPLY:
+                       DPrint("SIP Reply  (status):\n");
+                       DPrint(" version: <%s>\n",fl.u.reply.version);
+                       DPrint(" status:  <%s>\n",fl.u.reply.status);
+                       DPrint(" reason:  <%s>\n",fl.u.reply.reason);
+                       break;
+               default:
+                       DPrint("unknown type %d\n",fl.type);
+       }
+       
+       /*find first Via: */
+       hf.type=HDR_ERROR;
+       first_via=0;
+       second_via=0;
+       do{
+               rest=get_hdr_field(tmp, len-offset, &hf);
+               offset+=rest-tmp;
+               switch (hf.type){
+                       case HDR_ERROR:
+                               DPrint("ERROR: bad header  field\n");
+                               goto  error;
+                       case HDR_EOH: 
+                               goto skip;
+                       case HDR_VIA:
+                               if (first_via==0){
+                                               first_via=hf.body;
+                                               vb1.hdr=hf.name;
+                                               /* replace cr/lf with space in first via */
+                                               for (bar=first_via;(first_via) && (*bar);bar++)
+                                                       if ((*bar=='\r')||(*bar=='\n')) *bar=' ';
+                               #ifdef DEBUG
+                                               printf("first via: <%s>\n", first_via);
+                               #endif
+                                               bar=parse_via_body(first_via, strlen(first_via), &vb1);
+                                               if (vb1.error!=VIA_PARSE_OK){
+                                                       DPrint("ERROR: parsing via body: %s\n", first_via);
+                                                       goto error;
+                                               }
+                                               vb1.size=bar-first_via+first_via-vb1.hdr;
+                                               
+                                               /* compact via */
+                                               if (vb1.next) {
+                                                       second_via=vb1.next;
+                                                       /* not interested in the rest of the header */
+                                                       goto skip;
+                                               }
+                               }else if (second_via==0){
+                                                       second_via=hf.body;
+                                                       vb2.hdr=hf.name;
+                                                       goto skip;
+                               }
+                               break;
+               }
+       #ifdef DEBUG
+               printf("header field type %d, name=<%s>, body=<%s>\n",
+                       hf.type, hf.name, hf.body);
+       #endif
+               tmp=rest;
+       }while(hf.type!=HDR_EOH && rest-buf < len);
+
+skip:
+       /* replace cr/lf with space in the second via */
+       for (tmp=second_via;(second_via) && (*tmp);tmp++)
+               if ((*tmp=='\r')||(*tmp=='\n')) *tmp=' ';
+
+       if (second_via) {
+               tmp=parse_via_body(second_via, strlen(second_via), &vb2);
+               if (vb2.error!=VIA_PARSE_OK){
+                       DPrint("ERROR: parsing via body: %s\n", second_via);
+                       goto error;
+               }
+               vb2.size=tmp-second_via;
+               if (vb2.hdr) vb2.size+=second_via-vb2.hdr;
+       }
+       
+
+#ifdef DEBUG
+       /* dump parsed data */
+       printf(" first  via: <%s/%s/%s> <%s:%d>",
+                       vb1.name, vb1.version, vb1.transport, vb1.host, vb1.port);
+       if (vb1.params) printf(";<%s>", vb1.params);
+       if (vb1.comment) printf(" <%s>", vb1.comment);
+       printf ("\n");
+       if (second_via){
+               printf(" second via: <%s/%s/%s> <%s:%d>",
+                               vb2.name, vb2.version, vb2.transport, vb2.host, vb2.port);
+               if (vb2.params) printf(";<%s>", vb2.params);
+               if (vb2.comment) printf(" <%s>", vb2.comment);
+               printf ("\n");
+       }
+#endif
+       
+       /* copy data into msg */
+       memcpy(&(msg->first_line), &fl, sizeof(struct msg_start));
+       memcpy(&(msg->via1), &vb1, sizeof(struct via_body));
+       memcpy(&(msg->via2), &vb2, sizeof(struct via_body));
+
+#ifdef DEBUG
+       printf ("exiting parse_msg\n");
+#endif
+
+       return 0;
+       
+error:
+       return -1;
+}
+
index 7a243a0..340c057 100644 (file)
@@ -48,6 +48,7 @@ struct hdr_field{   /* format: name':' body */
 
 struct via_body{  /* format: name/version/transport host:port;params comment */
        int error;
+       char *hdr;   /* contains "Via" or "v" */
        char* name;
        char* version;
        char* transport;
@@ -55,9 +56,16 @@ struct via_body{  /* format: name/version/transport host:port;params comment */
        int port;
        char* params;
        char* comment;
+       int size;    /* full size, including hdr */
        char* next; /* pointer to next via body string if compact via or null */
 };
 
+struct sip_msg{
+       struct msg_start first_line;
+       struct via_body via1;
+       struct via_body via2;
+};
+
 
 
 char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl);
@@ -65,11 +73,8 @@ char* get_hdr_field(char *buffer, unsigned int len, struct hdr_field*  hdr_f);
 int field_name(char *s);
 char* parse_hostport(char* buf, char** host, short int* port);
 char* parse_via_body(char* buffer,unsigned int len, struct via_body * vb);
-
-
+int parse_msg(char* buf, unsigned int len, struct sip_msg* msg);
 
 
 
 #endif
-
diff --git a/receive.c b/receive.c
new file mode 100644 (file)
index 0000000..51fc621
--- /dev/null
+++ b/receive.c
@@ -0,0 +1,80 @@
+/* 
+ *$Id$
+ */
+
+#include <string.h>
+
+#include "receive.h"
+#include "dprint.h"
+#include "route.h"
+#include "msg_parser.h"
+#include "forward.h"
+
+
+int receive_msg(char* buf, unsigned int len)
+{
+       struct sip_msg msg;
+       struct route_elem *re;
+       char * orig;
+
+       /* make a copy of the message */
+       orig=(char*) malloc(len);
+       if (orig==0){
+               DPrint("ERROR: memory allocation failure\n");
+               goto error;
+       }
+       memcpy(orig, buf, len);
+       
+       if (parse_msg(buf,len, &msg)!=0){
+               goto error;
+       }
+       
+       if (msg.first_line.type==SIP_REQUEST){
+               /* sanity checks */
+               if (msg.via1.error!=VIA_PARSE_OK){
+                       /* no via, send back error ? */
+                       goto skip;
+               }
+               /* check if neccesarry to add receive? */
+               
+               /* find route */
+               re=route_match(  msg.first_line.u.request.method,
+                                                msg.first_line.u.request.uri,
+                                                &rlist
+                                         );
+               if (re==0){
+                       /* no route found, send back error msg? */
+                       DPrint("WARNING: no route found!\n");
+                       goto skip;
+               }
+               re->tx++;
+               /* send msg */
+               forward_request(orig, buf, len, &msg, re);
+               DPrint(" found route to: %s\n", re->host.h_name);
+       }else if (msg.first_line.type==SIP_REPLY){
+               /* sanity checks */
+               if (msg.via1.error!=VIA_PARSE_OK){
+                       /* no via, send back error ? */
+                       goto skip;
+               }
+               if (msg.via2.error!=VIA_PARSE_OK){
+                       /* no second via => error? */
+                       goto skip;
+               }
+               /* check if via1 == us */
+               
+               /* send the msg */
+               forward_reply(orig, buf, len, &msg);
+               DPrint(" reply forwarded to %s:%d\n", 
+                                       msg.via2.host,
+                                       (unsigned short) msg.via2.port
+                               );
+       }
+skip:
+       free(orig);
+       return 0;
+error:
+       return -1;
+
+}
+
diff --git a/receive.h b/receive.h
new file mode 100644 (file)
index 0000000..d600f9d
--- /dev/null
+++ b/receive.h
@@ -0,0 +1,12 @@
+/*
+ * $Id$
+ */
+
+
+#ifndef receive_h
+#define receive_h
+
+int receive_msg(char* buf, unsigned int len);
+
+
+#endif