⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.c

📁 sip代理服务器源码
💻 C
字号:
/***********************************************************************\	SIP Server		Date		Ver		Author		MemoRandom	Jul 3,2002	1.0		Hiroaki Hata	Created	(C) 2002 All Copyrights reserved. *************************************************************************/#include <sys/types.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <string.h>#include <netdb.h>#include <time.h>#include "udp.h"#include "sipd.h"#include "parser.h"extern int	dump_flag;typedef struct {	char	token[64];	int	type;	int	format;}HTYPE;static HTYPE mtype[]={	{"INVITE",M_INVITE,0},	{"ACK",M_ACK,0},	{"OPTIONS",M_OPTIONS,0},	{"BYE",M_BYE,0},	{"CANCEL",M_CANCEL,0},	{"REGISTER",M_REGISTER,0},	{"SUBSCRIBE",M_SUBSCRIBE,0},	{"MESSAGE",M_MESSAGE,0},	{"INFO",M_INFO,0},	{"",ELSE_H,0}};static HTYPE htype[]={	{"Via",VIA_H,0},	{"Expires",EXPIRES_H,0},	{"Call-ID",CALLID_H,0},	{"Content-Type",CONTENTTYPE_H,0},	{"Content-Length",CONTENTLEN_H,0},	{"User-Agent",USERAGENT_H,0},	{"To",TO_H,0},	{"T",TO_H,0},	{"From",FROM_H,0},	{"Cseq",CSEQ_H,0},	{"CSeq",CSEQ_H,0},	{"Contact",CONTACT_H,0},	{"Max-Forwards",MAXFORWARDS_H,0},	{"Record-Route",RECORDROUTE_H,0},	{"Route",ROUTE_H,0},	{"Proxy-Authenticate",PROXY_AUTHTC_H,0},	{"Proxy-Authorization",PROXY_AUTHRZ_H,0},	{"",ELSE_H,0}};static char *get_line(char *buff,char *line);static int analyze_header_type(char *buff,HTYPE *ptr);static int analyze_header(char *buff,MESSAGE *mes);static int first_line(char *buff,MESSAGE *mes);/***************************************************************/static char *get_line(char *buff,char *line)// buffで绩された疤弥から1乖きりだしてlineに呈羌する//渴めたポインタ疤弥を手す{#define D	0x0d#define	A	0x0a	char	*ptr;	char	*eol;	int	n=0;	*line='\0';	if(*buff=='\0') return NULL;//EOT	for(ptr=buff;;ptr++){		if(n>(CLEN-10)){			logging(2,"String too long (AnalyzeHeader 349)");			logging(2,buff);			return NULL;		}		switch(*ptr){		case D:			eol=ptr++;			if(*ptr==A){				ptr++;			}			*eol='\0';			strcpy(line,buff);			return ptr;		case A:			eol=ptr++;			*eol='\0';			strcpy(line,buff);			return ptr;		case '\0':			strcpy(line,buff);			return NULL;		default:			n++;			break;		}	}	return NULL;}static void LowerCase(char *p){	for(;*p;p++){		if(*p>='A' && *p<='Z') *p=*p+'a'-'A';	}}static int analyze_header_type(char *buff,HTYPE *ptr){	int i;	char	tmp1[CLEN];	char	tmp2[CLEN];	if(*buff=='\0'||*buff==0x0a||*buff==0x0d) return Blank;	strncpy(tmp1,buff,CLEN);	LowerCase(tmp1);		for(i=0;ptr[i].token[0];i++){		strncpy(tmp2,ptr[i].token,CLEN);		LowerCase(tmp2);		if(strcmp(tmp1,tmp2)==0){			return ptr[i].type;		}	}	return ELSE_H;}static int first_line(char *buff,MESSAGE *mes){	int 	i,ret=OK;	char	tmp[3][1024];	char	*ptr[3];	for(i=0;i<3;i++){		ptr[i]=tmp[i];	}	if(strncmp(buff,"SIP",3)==0){		//Response		mes->start.type=RESPONSE;		if(strlen(buff)>SCLEN-1){			logging(2,"Firstline Size too long(Respose)");			logging(2,buff);			return NG;		}		strcpy(mes->start.response,buff);		SeparateLex(buff,' ',ptr,3);		mes->start.code=atoi(tmp[1]);		ret=OK;	}else{		mes->start.type=REQUEST;		SeparateLex(buff,' ',ptr,3);		if(strlen(tmp[0]) >SCLEN-1) {			logging(2,"Firstline Size too long");			logging(2,tmp[0]);			return NG;		}		strncpy(mes->start.method,tmp[0],SCLEN-1);		if(strlen(tmp[1]) >SCLEN-1 ){			logging(2,"Firstline Size too long");			logging(2,tmp[1]);			return NG;		}		/*		 *		strncpy(mes->start.sipuri,tmp[1],SCLEN-1);		if(strlen(tmp[2]) >SCLEN-1) {			logging(2,"Firstline Size too long");			logging(2,tmp[2]);			return NG;		}		*/		AnalyzeURI(tmp[1],&mes->start.requri);		strncpy(mes->start.proto,tmp[2],SCLEN-1);		mes->start.message=analyze_header_type(tmp[0],mtype);		if(mes->start.message==ELSE_H){			ret=NG;		}	}	return ret;}static int analyze_header(char *buff,MESSAGE *mes){	int type;	char	*p;	VIA	*via;	VIA	*v;	URI	*uri;	URI	*c;	int	ret;	GENERAL *g;	GENERAL	*ptr;	char	header[CLEN];	char	rr[CLEN];	PAUTH	*pauth;	//Check Params	if( buff==NULL||mes==NULL) {		logging(3,"Param Error (Analyze Header:110)");		return NG;	}	if(*buff=='\0'||*buff==0x0a||*buff==0x0d) return Blank;	if(strlen(buff)>CLEN-1){		logging(3,"Parameter too long(Analyze Header:115)");		return NG;	}	//ヘッダ叹を藐叫	strcpy(header,buff);	p=strchr(header,':');	if(p==NULL){		logging(3,"No header Name (118)");		return NG;	}	*p='\0';	type=analyze_header_type(header,htype);	if(type == ELSE_H){		//润涩寇ヘッダ		//RR From Here -----------------------------		sprintf(rr,"Record-Route: <sip:%s",HOSTID);		if(strncmp(rr,buff,strlen(rr))==0){			return ELSE_H;		}		//-------------------------------------------		g=(GENERAL *)malloc(sizeof(GENERAL));		if(g==NULL){			logging(3,"malloc error(Analyze Header:210)");			return NG;		}		strncpy(g->body,buff,CLEN);		g->next=NULL;		if(mes->header.general==NULL){			mes->header.general=g;		}else{			for(ptr=mes->header.general;ptr->next!=NULL;					ptr=ptr->next){}			ptr->next=g;		}	}else{ 		//ヘッダ叹を磊り皖とし		p=strchr(buff,':');		p++;	}DEBUG	//printf("%d:%s\n",type,buff);DEND	switch(type){	case VIA_H:		via=(VIA *)malloc(sizeof(VIA));		if(via ==NULL){			logging(3,"malloc error(Analyze Header:212)");			return NG;		}		memset(via,0,sizeof(VIA));		ret=AnalyzeVia(p,via);		if(ret!=OK){			free(via);			logging(2,"Via Analyze failed");			logging(2,buff);			return NG;		}		via->next=NULL;		if(mes->header.via==NULL){			mes->header.via=via;		}else{			for(v=mes->header.via;v->next!=NULL;v=v->next){}			v->next=via;		}		break;	case EXPIRES_H:		ret=AnalyzeIntHeader(p,&mes->header.expires);		if(ret!=OK){			logging(2,"Expires Analyze failed");			logging(2,buff);			return NG;		}		break;	case CALLID_H:		ret=AnalyzeCharHeader(p,mes->header.callid);		if(ret!=OK){			logging(2,"Call-ID Analyze failed");			logging(2,buff);			return NG;		}		break;	case USERAGENT_H:		ret=AnalyzeCharHeader(p,mes->header.userAgent);		if(ret!=OK){			logging(2,"UserAgent Analyze failed");			logging(2,buff);			return NG;		}		break;	case CONTENTTYPE_H:		ret=AnalyzeCharHeader(p,mes->header.contentType);		if(ret!=OK){			logging(2,"Content-type Analyze failed");			logging(2,buff);			return NG;		}		break;	case CONTENTLEN_H:		ret=AnalyzeIntHeader(p,&mes->header.contentLength);		if(ret!=OK){			logging(2,"Content-len Analyze failed");			logging(2,buff);			return NG;		}		break;	case MAXFORWARDS_H:		ret=AnalyzeIntHeader(p,&mes->header.maxforwards);		if(ret!=OK){			logging(2,"Maxforwards Analyze failed");			logging(2,buff);			return NG;		}		break;	case CSEQ_H:		ret=AnalyzeCSeq(p,&mes->header.cseq);		if(ret!=OK){			logging(2,"CSEQ Analyze failed");			logging(2,buff);			return NG;		}		break;	case TO_H:		ret=AnalyzeURI(p,&mes->header.to);		if(ret!=OK){			logging(2,"To Analyze failed");			logging(2,buff);			return NG;		}		break;	case FROM_H:		ret=AnalyzeURI(p,&mes->header.from);		if(ret!=OK){			logging(2,"From Analyze failed");			logging(2,buff);			return NG;		}		break;	case PROXY_AUTHRZ_H:		if(mes->header.authrz != NULL){			logging(2,"Duplicate Authorization Header");			return NG;		}		pauth=(PAUTH *)malloc(sizeof(PAUTH));		if(pauth==NULL){			logging(2,"Memory short(Authorization)");			return NG;		}		memset(pauth,0,sizeof(PAUTH));		ret=AnalyzePAUTH(p,pauth);		if(ret!=OK){			free(pauth);			logging(2,"Proxy-Authorization  Analyze failed");			logging(2,buff);			return NG;		}		mes->header.authrz=pauth;		break;	case PROXY_AUTHTC_H:		if(mes->header.authtc != NULL){			logging(2,"Duplicate Authenticate Header");			return NG;		}		pauth=(PAUTH *)malloc(sizeof(PAUTH));		if(pauth==NULL){			logging(2,"Memory short(Authenticate)");			return NG;		}		memset(pauth,0,sizeof(PAUTH));		ret=AnalyzePAUTH(p,pauth);		if(ret!=OK){			free(pauth);			logging(2,"Proxy-Authenticate  Analyze failed");			logging(2,buff);			return NG;		}		mes->header.authtc=pauth;		break;	case CONTACT_H:		uri=(URI *)malloc(sizeof(URI));		if(uri ==NULL){			logging(2,"malloc error(Anlyze Header:215)");			return NG;		}		memset(uri,0,sizeof(URI));		ret=AnalyzeURI(p,uri);		if(ret!=OK){			free(uri);			logging(2,"Contact Analyze failed");			logging(2,buff);			return NG;		}		uri->next=NULL;		if(mes->header.contact==NULL){			mes->header.contact=uri;		}else{			for(c=mes->header.contact;c->next!=NULL;c=c->next){}			c->next=uri;		}		break;	case RECORDROUTE_H:		uri=(URI *)malloc(sizeof(URI));		if(uri ==NULL){			logging(2,"malloc error(Anlyze Header:345:R-R)");			return NG;		}		memset(uri,0,sizeof(URI));		ret=AnalyzeURI(p,uri);		if(ret!=OK){			free(uri);			logging(2,"RouteRecord Analyze failed");			logging(2,buff);			return NG;		}		uri->next=NULL;		if(mes->header.recordroute==NULL){			mes->header.recordroute=uri;		}else{			for(c=mes->header.recordroute;c->next!=NULL;c=c->next){}			c->next=uri;		}		break;	case ROUTE_H:		uri=(URI *)malloc(sizeof(URI));		if(uri ==NULL){			logging(2,"malloc error(Anlyze Header:348:R)");			return NG;		}		memset(uri,0,sizeof(URI));		ret=AnalyzeURI(p,uri);		if(ret!=OK){			free(uri);			logging(2,"Route Analyze failed");			logging(2,buff);			return NG;		}		uri->next=NULL;		if(mes->header.route==NULL){			mes->header.route=uri;		}else{			for(c=mes->header.route;c->next!=NULL;c=c->next){}			c->next=uri;		}		break;	default:		break;	}	return type;}int AnalyzePDU(char *rbuff,int rlen,MESSAGE *mes){	char	line[CLEN];	char	tmp[CLEN];	char	*ptr;	char	*ptr1;	int	i,l=1;	time_t	tick;	int	type;	int	checksheet[VIA_H+1];	for(type=0;type<=VIA_H;type++){		checksheet[type]=0;	}	ptr=rbuff;	ptr=get_line(ptr,line);	if(ptr==NULL) {		logging(3,"Parameter Error(AnalyzePDU)");		return NG-1;	}DEBUG	printf("--------------------------------------------------\n");	time(&tick);	printf("%sReceived(%s)\n",ctime(&tick),mes->ip);	printf("%s",mes->buff);	printf("--------------------------------------------------\n");DEND	type=first_line(line,mes);	if(type==NG){		logging(2,"Packet Format Error(First Line)");		logging(2,line);		return NG-10;	}	for(;ptr!=NULL;){		*line='\0';		//getLine		//乖黎片が鄂球矢机は、涟の乖の鲁き		for(*tmp='\0';;){			ptr1=get_line(ptr,tmp);			l++;			if(ptr1==NULL){				type=NG;				logging(3,"Line ends without CRLF");				logging(3,tmp);				goto label1;			}			ptr=ptr1;			strcat(line,tmp);			if(*ptr==' '||*ptr=='\t') continue;			else break;		}		//HeaderType		type=analyze_header(line,mes);		if(type==Blank||type==NG){			break;		}else if(type<=VIA_H){			checksheet[type]=1;		}	}label1:	if(type==NG){		return NG-30;	}else{		//retreave contents;		if(mes->header.contentLength>0){DEBUG//			printf("%s\n",ptr);DEND			mes->contents=(void *)malloc(mes->header.contentLength);			if(mes->contents==NULL){				logging(3,"Malloc Error(AnalyzePDU)");				return NG-40;			}else{				memcpy(mes->contents,ptr,					mes->header.contentLength);			}		}	}	l=0;	//Check Mandatory Header in REQUEST	if(mes->start.type==REQUEST){		for(type=1;type<=VIA_H;type++){			if(checksheet[type]==0){				l=1;				logging(2,"Header short");				for(i=0;htype[i].token[0]!='\0';i++){					if(htype[i].type==type){						sprintf(line,"-Not Found (%s)",							htype[i].token);						logging(2,line);					}				}			}		}	}	if(l==1){return NG-50;}	else return OK;}#ifdef TESTmain(){		MESSAGE	mes;	static void dump_packet(unsigned char *ptr,int len);	char	rbuff[128];	memset(&mes,0,sizeof(MESSAGE));	sprintf(rbuff,"SIP/2.0 %d %s\r\nVia:SIP\r\n\r\n",200,"OK");			dump_packet(rbuff,strlen(rbuff));//	AnalyzePDU(rbuff,strlen(rbuff),&mes);}#endif/************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -