rpid.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  * History:
00023  * --------
00024  * 2003-04-28 rpid contributed by Juha Heinanen added (janakj)
00025  * 2005-05-31 general avp specification added for rpid (bogdan)
00026  */
00027 
00035 #include <string.h>
00036 #include <strings.h>
00037 #include "../../str.h"
00038 #include "../../data_lump.h"
00039 #include "../../dprint.h"
00040 #include "../../mem/mem.h"
00041 #include "../../parser/parse_nameaddr.h"
00042 #include "../../parser/parse_uri.h"
00043 #include "../../parser/parser_f.h"
00044 #include "../../ut.h"
00045 #include "../../pvar.h"
00046 #include "rpid.h"
00047 
00048 
00049 #define RPID_HF_NAME "Remote-Party-ID: "
00050 #define RPID_HF_NAME_LEN (sizeof(RPID_HF_NAME) - 1)
00051 
00052 extern str rpid_prefix;       
00053 extern str rpid_suffix;       
00055 /* rpid AVP specs */
00056 static unsigned short rpid_avp_type;
00057 static int_str rpid_avp_name;
00058 
00059 
00065 int init_rpid_avp(char *rpid_avp_param)
00066 {
00067         pv_spec_t avp_spec;
00068         str stmp;
00069         if (rpid_avp_param && *rpid_avp_param) {
00070                 stmp.s = rpid_avp_param; stmp.len = strlen(stmp.s);
00071                 if (pv_parse_spec(&stmp, &avp_spec)==0
00072                                 || avp_spec.type!=PVT_AVP) {
00073                         LM_ERR("malformed or non AVP %s AVP definition\n", rpid_avp_param);
00074                         return -1;
00075                 }
00076 
00077                 if(pv_get_avp_name(0, &(avp_spec.pvp), &rpid_avp_name,
00078                                         &rpid_avp_type)!=0)
00079                 {
00080                         LM_ERR("[%s]- invalid AVP definition\n", rpid_avp_param);
00081                         return -1;
00082                 }
00083         } else {
00084                 rpid_avp_name.n = 0;
00085                 rpid_avp_type = 0;
00086         }
00087 
00088         return 0;
00089 }
00090 
00091 
00097 void get_rpid_avp( int_str *rpid_avp_p, int *rpid_avp_type_p )
00098 {
00099         *rpid_avp_p = rpid_avp_name;
00100         *rpid_avp_type_p = rpid_avp_type;
00101 }
00102 
00103 
00110 static inline int is_e164(str* _user)
00111 {
00112         int i;
00113         char c;
00114         
00115         if ((_user->len > 2) && (_user->len < 17) && ((_user->s)[0] == '+')) {
00116                 for (i = 1; i < _user->len; i++) {
00117                         c = (_user->s)[i];
00118                         if ((c < '0') || (c > '9')) return -1;
00119                 }
00120                 return 1;
00121         } else {
00122             return -1;
00123         }
00124 }
00125 
00126 
00134 static inline int append_rpid_helper(struct sip_msg* _m, str *_s)
00135 {
00136         struct lump* anchor;
00137         
00138         if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
00139                 LM_ERR("failed to parse message\n");
00140                 return -1;
00141         }
00142         
00143         anchor = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0);
00144         if (!anchor) {
00145                 LM_ERR("can't get anchor\n");
00146                 return -2;
00147         }
00148         
00149         if (!insert_new_lump_before(anchor, _s->s, _s->len, 0)) {
00150                 LM_ERR("can't insert lump\n");
00151                 return -3;
00152         }
00153 
00154         return 0;
00155 }
00156 
00157 
00165 int append_rpid_hf(struct sip_msg* _m, char* _s1, char* _s2)
00166 {
00167         struct usr_avp *avp;
00168         str rpid_hf, rpid;
00169         char *at;
00170         int_str val;
00171 
00172         if (rpid_avp_name.n==0) {
00173                 LM_ERR("rpid avp not defined\n");
00174                 return -1;
00175         }
00176 
00177         if ( (avp=search_first_avp( rpid_avp_type , rpid_avp_name, &val, 0))==0 ) {
00178                 LM_DBG("no rpid AVP\n");
00179                 return -1;
00180         }
00181 
00182         if ( !(avp->flags&AVP_VAL_STR) ||  !val.s.s || !val.s.len) {
00183                 LM_DBG("empty or non-string rpid, nothing to append\n");
00184                 return -1;
00185         }
00186 
00187         rpid = val.s;
00188 
00189         rpid_hf.len = RPID_HF_NAME_LEN + rpid_prefix.len + rpid.len
00190                                         + rpid_suffix.len + CRLF_LEN;
00191         rpid_hf.s = pkg_malloc(rpid_hf.len);
00192         if (!rpid_hf.s) {
00193                 LM_ERR("no memory left\n");
00194                 return -1;
00195         }
00196 
00197         at = rpid_hf.s;
00198         memcpy(at, RPID_HF_NAME, RPID_HF_NAME_LEN);
00199         at += RPID_HF_NAME_LEN;
00200 
00201         memcpy(at, rpid_prefix.s, rpid_prefix.len);
00202         at += rpid_prefix.len;
00203 
00204         memcpy(at, rpid.s, rpid.len);
00205         at += rpid.len;
00206 
00207         memcpy(at, rpid_suffix.s, rpid_suffix.len);
00208         at += rpid_suffix.len;
00209 
00210         memcpy(at, CRLF, CRLF_LEN);
00211 
00212         if (append_rpid_helper(_m, &rpid_hf) < 0) {
00213                 pkg_free(rpid_hf.s);
00214                 return -1;
00215         }
00216 
00217         return 1;
00218 }
00219 
00220 
00228 int append_rpid_hf_p(struct sip_msg* _m, char* _prefix, char* _suffix)
00229 {
00230         struct usr_avp *avp;
00231         str rpid_hf, rpid;
00232         char* at;
00233         str* p, *s;
00234         int_str val;
00235 
00236         if (rpid_avp_name.n==0) {
00237                 LM_ERR("rpid avp not defined\n");
00238                 return -1;
00239         }
00240 
00241         if ( (avp=search_first_avp( rpid_avp_type , rpid_avp_name, &val, 0))==0 ) {
00242                 LM_DBG("no rpid AVP\n");
00243                 return -1;
00244         }
00245 
00246         if ( !(avp->flags&AVP_VAL_STR) ||  !val.s.s || !val.s.len) {
00247                 LM_DBG("empty or non-string rpid, nothing to append\n");
00248                 return -1;
00249         }
00250 
00251         rpid = val.s;
00252 
00253         p = (str*)_prefix;
00254         s = (str*)_suffix;
00255 
00256         rpid_hf.len = RPID_HF_NAME_LEN + p->len + rpid.len + s->len + CRLF_LEN;
00257         rpid_hf.s = pkg_malloc(rpid_hf.len);
00258         if (!rpid_hf.s) {
00259                 LM_ERR("no pkg memory left\n");
00260                 return -1;
00261         }
00262 
00263         at = rpid_hf.s;
00264         memcpy(at, RPID_HF_NAME, RPID_HF_NAME_LEN);
00265         at += RPID_HF_NAME_LEN;
00266 
00267         memcpy(at, p->s, p->len);
00268         at += p->len;
00269 
00270         memcpy(at, rpid.s, rpid.len);
00271         at += rpid.len;
00272 
00273         memcpy(at, s->s, s->len);
00274         at += s->len;
00275 
00276         memcpy(at, CRLF, CRLF_LEN);
00277 
00278         if (append_rpid_helper(_m, &rpid_hf) < 0) {
00279                 pkg_free(rpid_hf.s);
00280                 return -1;
00281         }
00282 
00283         return 1;
00284 }
00285 
00286 
00294 int is_rpid_user_e164(struct sip_msg* _m, char* _s1, char* _s2)
00295 {
00296         struct usr_avp *avp;
00297         name_addr_t parsed;
00298         str tmp, rpid;
00299         struct sip_uri uri;
00300         int_str val;
00301 
00302         if (rpid_avp_name.n==0) {
00303                 LM_ERR("rpid avp not defined\n");
00304                 return -1;
00305         }
00306 
00307         if ( (avp=search_first_avp( rpid_avp_type , rpid_avp_name, &val, 0))==0 ) {
00308                 LM_DBG("no rpid AVP\n");
00309                 goto err;
00310         }
00311 
00312         if ( !(avp->flags&AVP_VAL_STR) ||  !val.s.s || !val.s.len) {
00313                 LM_DBG("empty or non-string rpid, nothing to append\n");
00314                 return -1;
00315         }
00316 
00317         rpid = val.s;
00318 
00319         if (find_not_quoted(&rpid, '<')) {
00320                 if (parse_nameaddr(&rpid, &parsed) < 0) {
00321                         LM_ERR("failed to parse RPID\n");
00322                         goto err;
00323                 }
00324                 tmp = parsed.uri;
00325         } else {
00326                 tmp = rpid;
00327         }
00328 
00329         if (parse_uri(tmp.s, tmp.len, &uri) < 0) {
00330             LM_ERR("failed to parse RPID URI\n");
00331             goto err;
00332         }
00333 
00334         return is_e164(&uri.user);
00335 
00336 err:
00337         return -1;
00338 }
00339