/* $Id: encode_via.c 1819 2007-03-11 19:20:59Z miconda $ * * Copyright (C) 2006-2007 VozTelecom Sistemas S.L * * This file is part of openser, a free SIP server. * * openser 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 * * openser 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 */ /* * ===================================================================================== * * Filename: encode_via.c * * Description: functions to encode VIA headers * * Version: 1.0 * Created: 21/11/05 02:30:50 CET * Revision: none * Compiler: gcc * * Author: Elias Baixas (EB), elias@conillera.net * Company: VozTele.com * * ===================================================================================== */ #define _GNU_SOURCE #include #include "../../parser/parse_via.h" #include "../../parser/parse_uri.h" #include "encode_via.h" #include "encode_uri.h" #include "xaddress.h" #include "encode_header.h" #include "encode_parameters.h" #define HAS_PARAMS_F 0x01 #define HAS_BRANCH_F 0x02 #define HAS_RECEIVED_F 0x04 #define HAS_RPORT_F 0x08 #define HAS_I_F 0x10 #define HAS_ALIAS_F 0x20 #define HAS_PORT_F 0x40 #define REL_PTR(a,b) (unsigned char)((b)-(a)) /* * encodes a (maybe aggregated) via header. * encoding is: * 1: flags * 1: number of vias present * N: fore each via present, the length of the via * N*M: the via structures concatenated */ int encode_via_body(char *hdr,int hdrlen,struct via_body *via_parsed,unsigned char *where) { int i=0,k,via_offset; unsigned char flags,tmp[500]; struct via_body *myvia; flags=0; if(via_parsed) for(via_offset=0,i=0,myvia=via_parsed;myvia;myvia=myvia->next,i++){ if((k=encode_via(hdr,hdrlen,myvia,&tmp[via_offset]))<0){ LOG(L_ERR,"parsing via number %d\n",i); return -1; } where[2+i]=(unsigned char)k; via_offset+=k; } else return -1; where[1]=(unsigned char)i;/*how may vias there are*/ memcpy(&where[2+i],tmp,via_offset); return 2+i+via_offset; } /* Encoder for vias. * Returns the length of the encoded structure in bytes * FORMAT (byte meanings): * 1: flags * */ int encode_via(char *hdrstart,int hdrlen,struct via_body *body,unsigned char *where) { int i;/* 1*flags + 1*hostport_len*/ unsigned char flags=0; where[1]=REL_PTR(hdrstart,body->name.s); where[2]=REL_PTR(hdrstart,body->version.s); where[3]=REL_PTR(hdrstart,body->transport.s); where[4]=REL_PTR(hdrstart,body->transport.s+body->transport.len+1); where[5]=REL_PTR(hdrstart,body->host.s); if(body->port_str.s && body->port_str.len){ flags|=HAS_PORT_F; where[6]=REL_PTR(hdrstart,body->port_str.s); where[7]=REL_PTR(hdrstart,body->port_str.s+body->port_str.len+1); i=8; }else{ where[6]=REL_PTR(hdrstart,body->host.s+body->host.len+1); i=7; } if(body->params.s && body->params.len){ flags|=HAS_PARAMS_F; where[i++]=REL_PTR(hdrstart,body->params.s); where[i++]=(unsigned char)body->params.len; } if(body->branch && body->branch->value.s && body->branch->value.len){ flags|=HAS_BRANCH_F; where[i++]=REL_PTR(hdrstart,body->branch->value.s); where[i++]=(unsigned char)body->branch->value.len; } if(body->received && body->received->value.s && body->received->value.len){ flags|=HAS_RECEIVED_F; where[i++]=REL_PTR(hdrstart,body->received->value.s); where[i++]=(unsigned char)body->received->value.len; } if(body->rport && body->rport->value.s && body->rport->value.len){ flags|=HAS_RPORT_F; where[i++]=REL_PTR(hdrstart,body->rport->value.s); where[i++]=(unsigned char)body->rport->value.len; } if(body->i && body->i->value.s && body->i->value.len){ flags|=HAS_I_F; where[i++]=REL_PTR(hdrstart,body->i->value.s); where[i++]=(unsigned char)body->i->value.len; } if(body->alias && body->alias->value.s && body->alias->value.len){ flags|=HAS_ALIAS_F; where[i++]=REL_PTR(hdrstart,body->alias->value.s); where[i++]=(unsigned char)body->alias->value.len; } where[0]=flags; i+=encode_parameters(&where[i],body->param_lst,hdrstart,(void *)body,'v'); return i; } int print_encoded_via_body(int fd,char *hdr,int hdrlen,unsigned char *payload,int paylen,char *prefix) { unsigned char flags, numvias; int i,offset; flags=payload[0]; dprintf(fd,"%s",prefix); for(i=0;i