📄 sdp_mangler.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 + -