encode_via.c

Go to the documentation of this file.
00001 /* $Id: encode_via.c 5192 2008-11-13 10:18:48Z eliasbaixas $
00002  *
00003  * Copyright (C) 2006-2007 VozTelecom Sistemas S.L
00004  *
00005  * This file is part of Kamailio, a free SIP server.
00006  *
00007  * Kamailio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version
00011  *
00012  * Kamailio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License 
00018  * along with this program; if not, write to the Free Software 
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  */
00021 
00022 /*
00023  * =====================================================================================
00024  * 
00025  *        Filename:  encode_via.c
00026  * 
00027  *     Description:  functions to encode VIA headers
00028  * 
00029  *         Version:  1.0
00030  *         Created:  21/11/05 02:30:50 CET
00031  *        Revision:  none
00032  *        Compiler:  gcc
00033  * 
00034  *          Author:  Elias Baixas (EB), elias@conillera.net
00035  *         Company:  VozTele.com
00036  * 
00037  * =====================================================================================
00038  */
00039 
00040 #define _GNU_SOURCE
00041 #include <stdio.h>
00042 
00043 #include "../../parser/parse_via.h"
00044 #include "../../parser/parse_uri.h"
00045 #include "encode_via.h"
00046 #include "encode_uri.h"
00047 #include "xaddress.h"
00048 #include "encode_header.h"
00049 #include "encode_parameters.h"
00050 
00051 #define HAS_PARAMS_F    0x01
00052 #define HAS_BRANCH_F    0x02
00053 #define HAS_RECEIVED_F     0x04
00054 #define HAS_RPORT_F     0x08
00055 #define HAS_I_F         0x10
00056 #define HAS_ALIAS_F     0x20
00057 #define HAS_PORT_F      0x40
00058 
00059 #define REL_PTR(a,b) (unsigned char)((b)-(a))
00060 
00061 /*
00062  * encodes a (maybe aggregated) via header.
00063  * encoding is:
00064  * 1: flags
00065  * 1: number of vias present
00066  * N: fore each via present, the length of the via
00067  * N*M: the via structures concatenated
00068  */
00069 int encode_via_body(char *hdr,int hdrlen,struct via_body *via_parsed,unsigned char *where)
00070 {
00071    int i=0,k,via_offset;
00072    unsigned char flags,tmp[500];
00073    struct via_body *myvia;
00074 
00075    flags=0;
00076    if(via_parsed)
00077       for(via_offset=0,i=0,myvia=via_parsed;myvia;myvia=myvia->next,i++){
00078     if((k=encode_via(hdr,hdrlen,myvia,&tmp[via_offset]))<0){
00079        LM_ERR("failed to parse via number %d\n",i);
00080        return -1;
00081     }
00082     where[2+i]=(unsigned char)k;
00083     via_offset+=k;
00084       }
00085    else
00086       return -1;
00087    where[1]=(unsigned char)i;/*how may vias there are*/
00088    memcpy(&where[2+i],tmp,via_offset);
00089    return 2+i+via_offset;
00090 }
00091 
00092 /* Encoder for vias.
00093  * Returns the length of the encoded structure in bytes
00094  * FORMAT (byte meanings):
00095  * 1: flags
00096  *
00097  */
00098 int encode_via(char *hdrstart,int hdrlen,struct via_body *body,unsigned char *where)
00099 {
00100    int i;/* 1*flags + 1*hostport_len*/
00101    unsigned char flags=0;
00102 
00103    where[1]=REL_PTR(hdrstart,body->name.s);
00104    where[2]=REL_PTR(hdrstart,body->version.s);
00105    where[3]=REL_PTR(hdrstart,body->transport.s);
00106    where[4]=REL_PTR(hdrstart,body->transport.s+body->transport.len+1);
00107    where[5]=REL_PTR(hdrstart,body->host.s);
00108    if(body->port_str.s && body->port_str.len){
00109       flags|=HAS_PORT_F;
00110       where[6]=REL_PTR(hdrstart,body->port_str.s);
00111       where[7]=REL_PTR(hdrstart,body->port_str.s+body->port_str.len+1);
00112       i=8;
00113    }else{
00114       where[6]=REL_PTR(hdrstart,body->host.s+body->host.len+1);
00115       i=7;
00116    }
00117    if(body->params.s && body->params.len){
00118       flags|=HAS_PARAMS_F;
00119       where[i++]=REL_PTR(hdrstart,body->params.s);
00120       where[i++]=(unsigned char)body->params.len;
00121    }
00122    if(body->branch && body->branch->value.s && body->branch->value.len){
00123       flags|=HAS_BRANCH_F;
00124       where[i++]=REL_PTR(hdrstart,body->branch->value.s);
00125       where[i++]=(unsigned char)body->branch->value.len;
00126    }
00127    if(body->received && body->received->value.s && body->received->value.len){
00128       flags|=HAS_RECEIVED_F;
00129       where[i++]=REL_PTR(hdrstart,body->received->value.s);
00130       where[i++]=(unsigned char)body->received->value.len;
00131    }
00132    if(body->rport && body->rport->value.s && body->rport->value.len){
00133       flags|=HAS_RPORT_F;
00134       where[i++]=REL_PTR(hdrstart,body->rport->value.s);
00135       where[i++]=(unsigned char)body->rport->value.len;
00136    }
00137    if(body->i && body->i->value.s && body->i->value.len){
00138       flags|=HAS_I_F;
00139       where[i++]=REL_PTR(hdrstart,body->i->value.s);
00140       where[i++]=(unsigned char)body->i->value.len;
00141    }
00142    if(body->alias && body->alias->value.s && body->alias->value.len){
00143       flags|=HAS_ALIAS_F;
00144       where[i++]=REL_PTR(hdrstart,body->alias->value.s);
00145       where[i++]=(unsigned char)body->alias->value.len;
00146    }
00147 
00148    where[0]=flags;
00149    i+=encode_parameters(&where[i],body->param_lst,hdrstart,(void *)body,'v');
00150    return i;
00151 }
00152 
00153 int print_encoded_via_body(FILE *fd,char *hdr,int hdrlen,unsigned char *payload,int paylen,char *prefix)
00154 {
00155    unsigned char flags, numvias;
00156    int i,offset;
00157 
00158    flags=payload[0];
00159    fprintf(fd,"%s",prefix);
00160    for(i=0;i<paylen;i++)
00161       fprintf(fd,"%s%d%s",i==0?"ENCODED VIA BODY:[":":",payload[i],i==paylen-1?"]\n":"");
00162    numvias=payload[1];
00163    fprintf(fd,"%s%d","NUMBER OF VIAS:",numvias);
00164    if(numvias==0){
00165       LM_ERR("no vias present?\n");
00166       return -1;
00167    }
00168    for(i=0,offset=2+numvias;i<numvias;i++){
00169       print_encoded_via(fd,hdr,hdrlen,&payload[offset],payload[2+i],strcat(prefix,"  "));
00170       offset+=payload[2+i];
00171       prefix[strlen(prefix)-2]=0;
00172    }
00173    return 1;
00174 }
00175 
00176 int print_encoded_via(FILE *fd,char *hdr,int hdrlen,unsigned char* payload,int paylen,char *prefix)
00177 {
00178    int i=2;/* flags + urilength */
00179    unsigned char flags=0;
00180 
00181    flags=payload[0];
00182    fprintf(fd,"%s",prefix);
00183    for(i=0;i<paylen;i++)
00184       fprintf(fd,"%s%d%s",i==0?"ENCODED VIA=[":":",payload[i],i==paylen-1?"]\n":"");
00185 
00186    fprintf(fd,"%sPROT=[%.*s]\n",prefix,payload[2]-payload[1]-1,&hdr[payload[1]]);
00187    fprintf(fd,"%sVER=[%.*s]\n",prefix,payload[3]-payload[2]-1,&hdr[payload[2]]);
00188    fprintf(fd,"%sTRANSP=[%.*s]\n",prefix,payload[4]-payload[3]-1,&hdr[payload[3]]);
00189 
00190    fprintf(fd,"%sHOST=[%.*s]\n",prefix,payload[6]-payload[5]-1,&hdr[payload[5]]);
00191    if(flags & HAS_PORT_F){
00192       fprintf(fd,"%sPORT=[%.*s]\n",prefix,payload[7]-payload[6]-1,&hdr[payload[6]]);
00193       i=8;
00194    }else
00195       i=7;
00196    if(flags & HAS_PARAMS_F){
00197       fprintf(fd,"%sPARAMS=[%.*s]\n",prefix,payload[i+1],&hdr[payload[i]]);
00198       i+=2;
00199    }
00200    if(flags & HAS_BRANCH_F){
00201       fprintf(fd,"%sBRANCH=[%.*s]\n",prefix,payload[i+1],&hdr[payload[i]]);
00202       i+=2;
00203    }
00204    if(flags & HAS_RECEIVED_F){
00205       fprintf(fd,"%sRECEIVED=[%.*s]\n",prefix,payload[i+1],&hdr[payload[i]]);
00206       i+=2;
00207    }
00208    if(flags & HAS_RPORT_F){
00209       fprintf(fd,"%sRPORT=[%.*s]\n",prefix,payload[i+1],&hdr[payload[i]]);
00210       i+=2;
00211    }
00212    if(flags & HAS_I_F){
00213       fprintf(fd,"%sI=[%.*s]\n",prefix,payload[i+1],&hdr[payload[i]]);
00214       i+=2;
00215    }
00216    if(flags & HAS_ALIAS_F){
00217       fprintf(fd,"%sALIAS=[%.*s]\n",prefix,payload[i+1],&hdr[payload[i]]);
00218       i+=2;
00219    }
00220    for(;i<paylen-1;i+=2){
00221       fprintf(fd,"%s[PARAMETER[%.*s]",prefix,payload[i+1]-payload[i]-1,&hdr[payload[i]]);
00222       fprintf(fd,"VALUE[%.*s]]\n",(payload[i+2]-payload[i+1])==0?0:(payload[i+2]-payload[i+1]-1),&hdr[payload[i+1]]);
00223    }
00224    return 0;
00225 }
00226 
00227 int dump_via_body_test(char *hdr,int hdrlen,unsigned char *payload,int paylen,FILE* fd,char segregationLevel)
00228 {
00229    unsigned char flags, numvias;
00230    int i,offset;
00231 
00232    flags=payload[0];
00233 
00234    if(!segregationLevel){
00235       return dump_standard_hdr_test(hdr,hdrlen,payload,paylen,fd);
00236    }
00237 
00238    numvias=payload[1];
00239    if(numvias==0){
00240       LM_ERR("no vias present?\n");
00241       return -1;
00242    }
00243    if(segregationLevel & SEGREGATE)
00244       for(i=0,offset=2+numvias;i<numvias;i++){
00245     dump_standard_hdr_test(hdr,hdrlen,&payload[offset],payload[2+i],fd);
00246     offset+=payload[2+i];
00247       }
00248    return 1;
00249 }

Generated on Wed May 23 06:00:45 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6