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

📄 sdp_mangler.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
字号:
/* * mangler module * * $Id: sdp_mangler.c,v 1.12 2004/08/24 08:58:30 janakj Exp $ * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: *    info@iptel.org * * ser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License  * along with this program; if not, write to the Free Software  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* History: * -------- *  2003-04-07 first version.   */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <regex.h>#include "sdp_mangler.h"#include "ip_helper.h"#include "utils.h"#include "common.h"#include "../../mem/mem.h"#include "../../data_lump.h"#include "../../parser/hf.h"#include "../../parser/parse_content.h"#include "../../parser/parse_uri.h"#include "../../parser/contact/parse_contact.h"#include "../../ut.h"#include "../../parser/msg_parser.h"	/* struct sip_msg *///#define DEBUG 1intsdp_mangle_port (struct sip_msg *msg, char *offset, char *unused){	int oldContentLength, newContentLength, oldlen, err, oldPort, newPort,		diff, offsetValue,len,off,ret,needToDealocate;	struct lump *l;	regmatch_t pmatch;	regex_t *re;	char *s, *pos,*begin,*key;	char buf[6];				key = PORT_REGEX;	/*	 * Checking if msg has a payload	 */	if (msg == NULL)		{		LOG(L_ERR,"ERROR: sdp_mangle_port: Received NULL for msg \n");		return -1;		}                	if ((msg->content_length==0) &&			((parse_headers(msg,HDR_CONTENTLENGTH,0)==-1) ||			 (msg->content_length==0) )){		LOG(L_ERR,"ERROR: sdp_mangle_port: bad or missing "				"Content-Length \n");		return -2;	}        oldContentLength = get_content_length(msg);        	if (oldContentLength <= 0)		{		LOG(L_ERR,"ERROR: sdp_mangle_port: Received <= 0 for Content-Length \n");		return -2;		}		if (offset == NULL)		return -14;	if (sscanf (offset, "%d", &offsetValue) != 1)	{		LOG(L_ERR,"ERROR: sdp_mangle_port: Invalid value for offset \n");		return -13;	}		//offsetValue = (int)offset;#ifdef DEBUG	fprintf (stdout,"---START--------MANGLE PORT-----------------\n");	fprintf(stdout,"===============OFFSET = %d\n",offsetValue);#endif		if ((offsetValue < MIN_OFFSET_VALUE) || (offsetValue > MAX_OFFSET_VALUE))	{		LOG(L_ERR,"ERROR: sdp_mangle_port: Invalid value %d for offset \n",offsetValue);		return -3;	}	begin = get_body(msg); //msg->buf + msg->first_line.len;	// inlocuiesc cu begin = getbody */	ret = -1;	/* try to use pre-compiled expressions */	needToDealocate = 0;	if (portExpression != NULL) 		{		re = portExpression;#ifdef DEBUG		fprintf(stdout,"Using PRECOMPILED expression for port ...\n");#endif		}		else /* we are not using pre-compiled expressions */			{			re = pkg_malloc(sizeof(regex_t));			if (re == NULL)				{				LOG(L_ERR,"ERROR: sdp_mangle_port: Unable to allocate re\n");				return -4;				}			needToDealocate = 1;			if ((regcomp (re, key, REG_EXTENDED)) != 0)				{				LOG(L_ERR,"ERROR: sdp_mangle_port: Unable to compile %s \n",key);				return -5;				}#ifdef DEBUG		fprintf(stdout,"Using ALLOCATED expression for port ...\n");#endif			}		diff = 0;	while ((begin < msg->buf + msg->len) && (regexec (re, begin, 1, &pmatch, 0) == 0))	{		off = begin - msg->buf;		if (pmatch.rm_so == -1)		{			LOG (L_ERR, "ERROR: sdp_mangle_port: offset unknown\n");			return -6;		}	#ifdef STRICT_CHECK		pmatch.rm_eo --; /* return with one space */#endif			/*                 for BSD and Solaris we avoid memrchr                pos = (char *) memrchr (begin + pmatch.rm_so, ' ',pmatch.rm_eo - pmatch.rm_so);                 */                pos = begin+pmatch.rm_eo;#ifdef DEBUG                printf("begin=%c pos=%c rm_so=%d rm_eo=%d\n",*begin,*pos,pmatch.rm_so,pmatch.rm_eo);#endif                do pos--; while (*pos != ' '); /* we should find ' ' because we matched m=audio port */                		pos++;		/* jumping over space */		oldlen = (pmatch.rm_eo - pmatch.rm_so) - (pos - (begin + pmatch.rm_so));	/* port length */		/* convert port to int */		oldPort = str2s (pos, oldlen, &err);#ifdef DEBUG                printf("port to convert [%.*s] to int\n",oldlen,pos);#endif		if (err)			{			LOG(L_ERR,"ERROR: sdp_mangle_port: Error converting [%.*s] to int\n",oldlen,pos);#ifdef STRICT_CHECK			return -7;#else			goto continue1;#endif			}		if ((oldPort < MIN_ORIGINAL_PORT) || (oldPort > MAX_ORIGINAL_PORT))	/* we silently fail,we ignore this match or return -11 */		{#ifdef DEBUG                printf("WARNING: sdp_mangle_port: Silent fail for not matching old port %d\n",oldPort);#endif			LOG(L_WARN,"WARNING: sdp_mangle_port: Silent fail for not matching old port %d\n",oldPort);#ifdef STRICT_CHECK			return -8;#else			goto continue1;#endif		}                if ((offset[0] != '+')&&(offset[0] != '-')) newPort = offsetValue;//fix value		else newPort = oldPort + offsetValue;		/* new port is between 1 and 65536, or so should be */		if ((newPort < MIN_MANGLED_PORT) || (newPort > MAX_MANGLED_PORT))	/* we silently fail,we ignore this match */		{#ifdef DEBUG                printf("WARNING: sdp_mangle_port: Silent fail for not matching new port %d\n",newPort);#endif                			LOG(L_WARN,"WARNING: sdp_mangle_port: Silent fail for not matching new port %d\n",newPort);#ifdef STRICT_CHECK			return -9;#else			goto continue1;#endif		}#ifdef DEBUG		fprintf(stdout,"Extracted port is %d and mangling to %d\n",oldPort,newPort);#endif		/*		len = 1;		while ((newPort = (newPort / 10)) != 0)	len++;		newPort = oldPort + offsetValue;		*/		if (newPort >= 10000) len = 5;			else				if (newPort >= 1000) len = 4;					else						if (newPort >= 100) len = 3;							else								if (newPort >= 10) len = 2;									else len = 1;		/* replaced five div's + 1 add with most probably 1 comparison or 2 */											/* deleting old port */		if ((l = del_lump (msg, pmatch.rm_so + off + 						(pos -(begin + pmatch.rm_so)),oldlen, 0)) == 0)		{			LOG (L_ERR,"ERROR: sdp_mangle_port: del_lump failed\n");			return -10;		}		s = pkg_malloc (len);		if (s == 0)		{			LOG (L_ERR,"ERROR: sdp_mangle_port : memory allocation failure\n");			return -11;		}		snprintf (buf, len + 1, "%u", newPort);	/* converting to string */		memcpy (s, buf, len);		if (insert_new_lump_after (l, s, len, 0) == 0)		{			LOG (L_ERR, "ERROR: sdp_mangle_port: could not insert new lump\n");			pkg_free (s);			return -12;		}		diff = diff + len /*new length */  - oldlen;		/* new cycle */		ret++;#ifndef STRICT_CHECKcontinue1:#endif		begin = begin + pmatch.rm_eo;	}			/* while  */	if (needToDealocate)		{		regfree (re);		pkg_free(re);#ifdef DEBUG		fprintf(stdout,"Deallocating expression for port ...\n");#endif		}		if (diff != 0)	{		newContentLength = oldContentLength + diff;		patch_content_length (msg, newContentLength);	}#ifdef DEBUG	fprintf (stdout,"---END--------MANGLE PORT-----------------\n");#endif	return ret+2;}intsdp_mangle_ip (struct sip_msg *msg, char *oldip, char *newip){	int i, oldContentLength, newContentLength, diff, oldlen,len,off,ret,needToDealocate;	unsigned int mask, address, locatedIp;	struct lump *l;	regmatch_t pmatch;	regex_t *re;	char *s, *pos,*begin,*key;	char buffer[16];	/* 123.456.789.123\0 */#ifdef DEBUG	fprintf (stdout,"---START--------MANGLE IP-----------------\n");#endif		key = IP_REGEX;	/*	 * Checking if msg has a payload	 */	if (msg == NULL)		{		LOG(L_ERR,"ERROR: sdp_mangle_ip: Received NULL for msg\n");		return -1;		}	if ((msg->content_length==0) &&				((parse_headers(msg,HDR_CONTENTLENGTH,0)==-1) ||				 (msg->content_length==0) )){			LOG(L_ERR,"ERROR: sdp_mangle_port: bad or missing "					"Content-Length \n");			return -2;		}        oldContentLength = get_content_length(msg);        	if (oldContentLength <= 0)		{		LOG(L_ERR,"ERROR: sdp_mangle_ip: Received <= for Content-Length\n");		return -2;		}	/* checking oldip */	if (oldip == NULL)		{		LOG(L_ERR,"ERROR: sdp_mangle_ip: Received NULL for oldip\n");		return -3;		}	/* checking newip */	if (newip == NULL)		{		LOG(L_ERR,"ERROR: sdp_mangle_ip: Received NULL for newip\n");		return -4;		}	i = parse_ip_netmask (oldip, &pos, &mask);	if (i == -1)	{		/* invalid value for the netmask specified in oldip */		LOG(L_ERR,"ERROR: sdp_mangle_ip: invalid value for the netmask specified in oldip\n");		return -5;	}	else	{		i = parse_ip_address (pos, &address);		if (pos != NULL) free (pos);		if (i == 0)			{			LOG(L_ERR,"ERROR: sdp_mangle_ip: invalid value for the ip specified in oldip\n");			return -6;	/* parse error in ip */			}	}	/* now we have in address/netmask binary values */	begin = get_body(msg);//msg->buf + msg->first_line.len;	// inlocuiesc cu begin = getbody */	ret = -1;	len = strlen (newip);	/* try to use pre-compiled expressions */	needToDealocate = 0;	if (ipExpression != NULL) 		{		re = ipExpression;#ifdef DEBUG		fprintf(stdout,"Using PRECOMPILED expression for ip ...\n");#endif		}		else /* we are not using pre-compiled expressions */			{			re = pkg_malloc(sizeof(regex_t));			if (re == NULL)				{				LOG(L_ERR,"ERROR: sdp_mangle_ip: Unable to allocate re\n");				return -7;				}			needToDealocate = 1;			if ((regcomp (re, key, REG_EXTENDED)) != 0)				{				LOG(L_ERR,"ERROR: sdp_mangle_ip: Unable to compile %s \n",key);				return -8;				}#ifdef DEBUG		fprintf(stdout,"Using ALLOCATED expression for ip ...\n");#endif			}	diff = 0;	while ((begin < msg->buf + msg->len) && (regexec (re, begin, 1, &pmatch, 0) == 0))	{		off = begin - msg->buf;		if (pmatch.rm_so == -1)		{			LOG (L_ERR,"ERROR: sdp_mangler_ip: offset unknown\n");			return -9;		}	#ifdef STRICT_CHECK		pmatch.rm_eo --; /* return with one space,\n,\r */#endif			/*                 for BSD and Solaris we avoid memrchr                pos = (char *) memrchr (begin + pmatch.rm_so, ' ',pmatch.rm_eo - pmatch.rm_so);                 */                pos = begin+pmatch.rm_eo;                do pos--; while (*pos != ' '); /* we should find ' ' because we matched c=IN IP4 ip */		pos++;		/* jumping over space */		oldlen = (pmatch.rm_eo - pmatch.rm_so) - (pos - (begin + pmatch.rm_so));	/* ip length */		if (oldlen > 15)		{			LOG(L_WARN,"WARNING: sdp_mangle_ip: Silent fail because oldlen > 15\n");#ifdef STRICT_CHECK			return -10;#else 			goto continue2;	/* silent fail return -10; invalid ip format ,probably like 1000.3.12341.2 */#endif					}		buffer[0] = '\0';		strncat ((char *) buffer, pos, oldlen);			buffer[oldlen] = '\0';		i = parse_ip_address (buffer, &locatedIp);		if (i == 0)		{			LOG(L_WARN,"WARNING: sdp_mangle_ip: Silent fail on parsing matched address \n");			#ifdef STRICT_CHECK			return -11;#else 			goto continue2;	#endif		}		if (same_net (locatedIp, address, mask) == 0)		{			LOG(L_WARN,"WARNING: sdp_mangle_ip: Silent fail because matched address is not in network\n");#ifdef DEBUG		fprintf(stdout,"Extracted ip is %s and not mangling \n",buffer);#endif			goto continue2;	/* not in the same net, skipping */		}#ifdef DEBUG		fprintf(stdout,"Extracted ip is %s and mangling to %s\n",buffer,newip);#endif		/* replacing ip */		/* deleting old ip */		if ((l = del_lump (msg,pmatch.rm_so + off + 						(pos - (begin + pmatch.rm_so)),oldlen, 0)) == 0)		{			LOG (L_ERR,"ERROR: sdp_mangle_ip: del_lump failed\n");			return -12;		}		s = pkg_malloc (len);		if (s == 0)		{			LOG (L_ERR,"ERROR: sdp_mangle_ip: mem. allocation failure\n");			return -13;		}		memcpy (s, newip, len);		if (insert_new_lump_after (l, s, len, 0) == 0)		{			LOG (L_ERR, "ERROR: sdp_mangle_ip: could not insert new lump\n");			pkg_free (s);			return -14;		}		diff = diff + len /*new length */  - oldlen;		/* new cycle */		ret++;continue2:		begin = begin + pmatch.rm_eo;	}			/* while */	if (needToDealocate)	{	regfree (re);		/* if I am going to use pre-compiled expressions to be removed */	pkg_free(re);#ifdef DEBUG		fprintf(stdout,"Deallocating expression for ip ...\n");#endif	}		if (diff != 0)	{		newContentLength = oldContentLength + diff;		patch_content_length (msg, newContentLength);	}#ifdef DEBUG	fprintf (stdout,"---END--------MANGLE IP-----------------\n");#endif	return ret+2;}int compile_expresions(char *port,char *ip){	portExpression = NULL;	portExpression = pkg_malloc(sizeof(regex_t));	if (portExpression != NULL)		{		if ((regcomp (portExpression,port, REG_EXTENDED)) != 0)			{			LOG(L_ERR,"ERROR: compile_expresions: Unable to compile portExpression [%s]\n",port);			pkg_free(portExpression);			portExpression = NULL;			}		}	else		{			LOG(L_ERR,"ERROR: compile_expresions: Unable to alloc portExpression \n");		}		ipExpression = NULL;	ipExpression = pkg_malloc(sizeof(regex_t));	if (ipExpression != NULL)		{		if ((regcomp (ipExpression,ip, REG_EXTENDED)) != 0)			{			LOG(L_ERR,"ERROR: compile_expresions: Unable to compile ipExpression [%s]\n",ip);			pkg_free(ipExpression);			ipExpression = NULL;			}		}	else		{			LOG(L_ERR,"ERROR: compile_expresions: Unable to alloc ipExpression \n");		}		return 0;}int free_compiled_expresions(){	if (portExpression != NULL) 		{		regfree(portExpression);		pkg_free(portExpression);		portExpression = NULL;		}	if (ipExpression != NULL) 		{		regfree(ipExpression);		pkg_free(ipExpression);		ipExpression = NULL;		}	return 0;}

⌨️ 快捷键说明

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