Răsfoiți Sursa

- added cseq_body and prototype cseq parser
- fixed some missing #ifdef STATS

Andrei Pelinescu-Onciul 24 ani în urmă
părinte
comite
e4067ffbbf
6 a modificat fișierele cu 99 adăugiri și 5 ștergeri
  1. 1 1
      Makefile
  2. 1 0
      TODO
  3. 5 1
      cfg.y
  4. 4 0
      main.c
  5. 73 3
      msg_parser.c
  6. 15 0
      msg_parser.h

+ 1 - 1
Makefile

@@ -28,7 +28,7 @@ NAME=ser
 # DEBUG compiles in some extra debugging code
 # DEBUG compiles in some extra debugging code
 # OLD_PARSER uses the old and stable parser (from ser 8.3.2)
 # OLD_PARSER uses the old and stable parser (from ser 8.3.2)
 # DNS_IP_HACK faster ip address resolver for ip strings (e.g "127.0.0.1")
 # DNS_IP_HACK faster ip address resolver for ip strings (e.g "127.0.0.1")
-DEFS=-DNOCR -DMACROEATER -DSTATS -DDNS_IP_HACK #-DNO_DEBUG 
+DEFS=-DNOCR -DMACROEATER -DDNS_IP_HACK #-DSTATS -DNO_DEBUG 
 #-DNO_LOG
 #-DNO_LOG
 
 
 PROFILE=  # -pg #set this if you want profiling
 PROFILE=  # -pg #set this if you want profiling

+ 1 - 0
TODO

@@ -2,6 +2,7 @@ $Id$
 
 
 ( - todo, x - done)
 ( - todo, x - done)
 
 
+- fix parse_cseq!!! (it doesnt parse 1234\n INVITE a.s.o)
 - better Via parsing (handle ' ' in uri, eg: foo.bar : 1234 ; received=) and
 - better Via parsing (handle ' ' in uri, eg: foo.bar : 1234 ; received=) and
  ipv6 addresses ([fec0:aa::01]).
  ipv6 addresses ([fec0:aa::01]).
 - fix format string vulnerability in log()
 - fix format string vulnerability in log()

+ 5 - 1
cfg.y

@@ -149,7 +149,11 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
 		| REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
 		| REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
 		| REV_DNS EQUAL error { yyerror("boolean value expected"); }
 		| REV_DNS EQUAL error { yyerror("boolean value expected"); }
 		| PORT EQUAL NUMBER   { port_no=$3; }
 		| PORT EQUAL NUMBER   { port_no=$3; }
-		| STAT EQUAL STRING { stat_file=$3; }
+		| STAT EQUAL STRING {
+					#ifdef STATS
+							stat_file=$3;
+					#endif
+							}
 		| MAXBUFFER EQUAL NUMBER { maxbuffer=$3; }
 		| MAXBUFFER EQUAL NUMBER { maxbuffer=$3; }
 		| MAXBUFFER EQUAL error { yyerror("number expected"); }
 		| MAXBUFFER EQUAL error { yyerror("number expected"); }
 		| PORT EQUAL error    { yyerror("number expected"); } 
 		| PORT EQUAL error    { yyerror("number expected"); } 

+ 4 - 0
main.c

@@ -288,7 +288,9 @@ static void sig_usr(int signo)
 		DPrint("Thank you for flying ser\n");
 		DPrint("Thank you for flying ser\n");
 		exit(0);
 		exit(0);
 	} else if (signo==SIGUSR1) { /* statistic */
 	} else if (signo==SIGUSR1) { /* statistic */
+#ifdef STATS
 		dump_all_statistic();
 		dump_all_statistic();
+#endif
 	}
 	}
 }
 }
 	
 	
@@ -329,7 +331,9 @@ int main(int argc, char** argv)
 					cfg_file=optarg;
 					cfg_file=optarg;
 					break;
 					break;
 			case 's':
 			case 's':
+				#ifdef STATS
 					stat_file=optarg;
 					stat_file=optarg;
+				#endif
 					break;
 					break;
 			case 'p':
 			case 'p':
 					port_no=strtol(optarg, &tmp, 10);
 					port_no=strtol(optarg, &tmp, 10);

+ 73 - 3
msg_parser.c

@@ -209,6 +209,7 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 	char* tmp;
 	char* tmp;
 	char *match;
 	char *match;
 	struct via_body *vb;
 	struct via_body *vb;
+	struct cseq_body* cseq_b;
 
 
 	if ((*buf)=='\n' || (*buf)=='\r'){
 	if ((*buf)=='\n' || (*buf)=='\r'){
 		/* double crlf or lflf or crcr */
 		/* double crlf or lflf or crcr */
@@ -241,12 +242,29 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 			hdr->parsed=vb;
 			hdr->parsed=vb;
 			vb->hdr.s=hdr->name.s;
 			vb->hdr.s=hdr->name.s;
 			vb->hdr.len=hdr->name.len;
 			vb->hdr.len=hdr->name.len;
-			/*vb->size=tmp-hdr->name.s;*/
 			hdr->body.len=tmp-hdr->body.s;
 			hdr->body.len=tmp-hdr->body.s;
 			break;
 			break;
+		case HDR_CSEQ:
+			cseq_b=malloc(sizeof(struct cseq_body));
+			if (cseq_b==0){
+				LOG(L_ERR, "get_hdr_field: out of memory\n");
+				goto error;
+			}
+			memset(cseq_b, 0, sizeof(struct cseq_body));
+			hdr->body.s=tmp;
+			tmp=parse_cseq(tmp, end, cseq_b);
+			if (cseq_b->error==PARSE_ERROR){
+				LOG(L_ERR, "ERROR: get_hdr_field: bad cseq\n");
+				free(cseq_b);
+				goto error;
+			}
+			hdr->parsed=cseq_b;
+			hdr->body.len=tmp-hdr->body.s;
+			DBG("get_hdr_field: cseq <%s>: <%s> <%s>\n",
+					hdr->name.s, cseq_b->number.s, cseq_b->method.s);
+			break;
 		case HDR_TO:
 		case HDR_TO:
 		case HDR_FROM:
 		case HDR_FROM:
-		case HDR_CSEQ:
 		case HDR_CALLID:
 		case HDR_CALLID:
 		case HDR_CONTACT:
 		case HDR_CONTACT:
 		case HDR_OTHER:
 		case HDR_OTHER:
@@ -268,7 +286,8 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 				#endif
 				#endif
 				}else {
 				}else {
 					tmp=end;
 					tmp=end;
-					LOG(L_ERR, "ERROR: get_hdr_field: bad body for <%s>(%d)\n",
+					LOG(L_ERR,
+							"ERROR: get_hdr_field: bad body for <%s>(%d)\n",
 							hdr->name.s, hdr->type);
 							hdr->name.s, hdr->type);
 					goto error;
 					goto error;
 				}
 				}
@@ -402,6 +421,54 @@ char* parse_hostport(char* buf, str* host, short int* port)
 
 
 
 
 
 
+/*BUGGY*/
+char * parse_cseq(char *buf, char* end, struct cseq_body* cb)
+{
+	char *t;
+	char c;
+
+	cb->error=PARSE_ERROR;
+	t=eat_space_end(buf, end);
+	if (t>=end) goto error;
+	
+	cb->number.s=t;
+	t=eat_token_end(t, end);
+	if (t>=end) goto error;
+	*t=0; /*null terminate it*/
+	cb->number.len=t-cb->number.s;
+	t++;
+	t=eat_space_end(t, end);
+	if (t>=end) goto error;
+	cb->method.s=t;
+	t=eat_token_end(t, end);
+	if (t>=end) goto error;
+	c=*t;
+	*t=0; /*null terminate it*/
+	cb->method.len=t-cb->method.s;
+	t++;
+	/*check if the header ends here*/
+	if (c=='\n') goto check_continue;
+	do{
+		for (;(t<end)&&((*t==' ')||(*t=='\t')||(*t=='\r'));t++);
+		if (t>=end) goto error;
+		if (*t!='\n'){
+			LOG(L_ERR, "ERROR:parse_cseq: unexpected char <%c> at end of"
+					" cseq\n", *t);
+			goto error;
+		}
+		t++;
+check_continue:
+	}while( (t<end) && ((*t==' ')||(*t=='\t')) );
+
+	cb->error=PARSE_OK;
+	return t;
+error:
+	LOG(L_ERR, "ERROR: parse_cseq: bad cseq\n");
+	return t;
+}
+
+
+
 /* buf= pointer to begining of uri (sip:[email protected]:5060;a=b?h=i)
 /* buf= pointer to begining of uri (sip:[email protected]:5060;a=b?h=i)
    len= len of uri
    len= len of uri
 returns: fills uri & returns <0 on error or 0 if ok */
 returns: fills uri & returns <0 on error or 0 if ok */
@@ -957,6 +1024,9 @@ void clean_hdr_field(struct hdr_field* hf)
 			case HDR_VIA:
 			case HDR_VIA:
 				free_via_list(hf->parsed);
 				free_via_list(hf->parsed);
 				break;
 				break;
+			case HDR_CSEQ:
+				free(hf->parsed);
+				break;
 			default:
 			default:
 				LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
 				LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
 						hf->type);
 						hf->type);

+ 15 - 0
msg_parser.h

@@ -48,6 +48,8 @@ if (  (*tmp==(firstchar) || *tmp==((firstchar) | 32)) &&                  \
 
 
 #define VIA_PARSE_OK	1
 #define VIA_PARSE_OK	1
 #define VIA_PARSE_ERROR -1
 #define VIA_PARSE_ERROR -1
+#define PARSE_ERROR -1
+#define PARSE_OK 1
 
 
 #define SIP_VERSION	"SIP/2.0"
 #define SIP_VERSION	"SIP/2.0"
 #define SIP_VERSION_LEN 7
 #define SIP_VERSION_LEN 7
@@ -95,6 +97,16 @@ struct via_body{  /* format: name/version/transport host:port;params comment */
 							  compact via or null */
 							  compact via or null */
 };
 };
 
 
+
+
+struct cseq_body{
+	int error;
+	str number;
+	str method;
+};
+
+
+
 struct sip_msg{
 struct sip_msg{
 	unsigned int id; /* message id, unique/process*/
 	unsigned int id; /* message id, unique/process*/
 	struct msg_start first_line;
 	struct msg_start first_line;
@@ -155,12 +167,15 @@ char* parse_via_body(char* buffer,unsigned int len, struct via_body * vb);
 #endif
 #endif
 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg);
 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg);
 int parse_uri(char *buf, int len, struct sip_uri* uri);
 int parse_uri(char *buf, int len, struct sip_uri* uri);
+int parse_headers(struct sip_msg* msg, int flags);
+
 void free_uri(struct sip_uri* u);
 void free_uri(struct sip_uri* u);
 
 
 
 
 #ifndef OLD_PARSER
 #ifndef OLD_PARSER
 char* parse_hname(char* buf, char* end, struct hdr_field* hdr);
 char* parse_hname(char* buf, char* end, struct hdr_field* hdr);
 char* parse_via(char* buffer, char* end, struct via_body *vb);
 char* parse_via(char* buffer, char* end, struct via_body *vb);
+char* parse_cseq(char* buffer, char* end, struct cseq_body *cb);
 #endif
 #endif
 
 
 void free_via_list(struct via_body *vb);
 void free_via_list(struct via_body *vb);