Coverage Report

Created: 2025-07-11 06:28

/src/opensips/transformations.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2007 voice-system.ro
3
 *
4
 * This file is part of opensips, a free SIP server.
5
 *
6
 * opensips is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version
10
 *
11
 * opensips is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19
 *
20
 */
21
22
/*! \file
23
 * \brief Support for transformations
24
 */
25
26
/* make strptime available */
27
#define _GNU_SOURCE
28
#include <time.h>
29
30
#include <stdio.h>
31
#include <string.h>
32
#include <stdlib.h>
33
#include <sys/types.h>
34
#include <unistd.h>
35
36
#include "dprint.h"
37
#include "mem/mem.h"
38
#include "ut.h"
39
#include "trim.h"
40
#include "dset.h"
41
#include "usr_avp.h"
42
#include "errinfo.h"
43
#include "resolve.h"
44
#include "ip_addr.h"
45
46
#include "parser/parse_param.h"
47
#include "parser/parse_uri.h"
48
#include "parser/parse_via.h"
49
#include "parser/parse_to.h"
50
#include "parser/sdp/sdp_helpr_funcs.h"
51
#include "parser/sdp/sdp.h"
52
53
#include "lib/csv.h"
54
#include "strcommon.h"
55
#include "transformations.h"
56
#include "re.h"
57
#include "sha1.h"
58
#include "sha256.h"
59
#include "sha512.h"
60
#include "time_rec.h"
61
62
0
#define TR_BUFFER_SIZE 65536
63
64
/* two buffers are enough to allow infinite chaining (R/W <-> W/R) */
65
0
#define TR_CHAIN_BUFS  2
66
67
/* a separate set of chaining buffers for each script function argument */
68
static char __tr_buffers[MAX_ACTION_ELEMS - 1][TR_CHAIN_BUFS][TR_BUFFER_SIZE];
69
static int __crt_tr_bufs, __crt_tr_link;
70
71
#define get_tr_buffer() \
72
0
  __tr_buffers[__crt_tr_bufs] \
73
0
    [__crt_tr_link = (__crt_tr_link + 1) % TR_CHAIN_BUFS]
74
75
trans_extra_t *tr_extra_list;
76
77
static const trans_export_t core_trans[] = {
78
  {str_const_init("s"), tr_parse_string, tr_eval_string},
79
  {str_const_init("uri"), tr_parse_uri, tr_eval_uri},
80
  {str_const_init("via"), tr_parse_via, tr_eval_via},
81
  {str_const_init("param"), tr_parse_paramlist, tr_eval_paramlist},
82
  {str_const_init("nameaddr"), tr_parse_nameaddr, tr_eval_nameaddr},
83
  {str_const_init("ip"), tr_parse_ip, tr_eval_ip},
84
  {str_const_init("csv"), tr_parse_csv, tr_eval_csv},
85
  {str_const_init("sdp"), tr_parse_sdp, tr_eval_sdp},
86
  {str_const_init("re"), tr_parse_re, tr_eval_re},
87
  {{0,0}, 0, 0}
88
};
89
90
int tr_add_extra(const trans_export_t *e)
91
0
{
92
0
  trans_extra_t *tr_extra;
93
0
  int i;
94
95
0
  if(!e || !e->name.s || !e->parse_func || !e->eval_func) {
96
0
    LM_ERR("invalid transformation export parameters\n");
97
0
    return -1;
98
0
  }
99
100
0
  for (i = 0; core_trans[i].name.s; i++)
101
0
    if (e->name.len == core_trans[i].name.len &&
102
0
      !memcmp(e->name.s, core_trans[i].name.s, e->name.len)) {
103
0
      LM_ERR("transformation class <%.*s> already registered by core\n",
104
0
        e->name.len, e->name.s);
105
0
      return -1;
106
0
    }
107
0
  for (tr_extra = tr_extra_list; tr_extra; tr_extra = tr_extra->next)
108
0
    if (e->name.len == tr_extra->tre.name.len &&
109
0
      !memcmp(e->name.s, tr_extra->tre.name.s, e->name.len)) {
110
0
      LM_ERR("transformation class <%.*s> already registered\n",
111
0
        e->name.len, e->name.s);
112
0
      return -1;
113
0
    }
114
115
0
  tr_extra = NULL;
116
0
  tr_extra = pkg_malloc(sizeof *tr_extra);
117
0
  if (!tr_extra) {
118
0
    LM_ERR("No more pkg mem\n");
119
0
    return -1;
120
0
  }
121
0
  memcpy(&tr_extra->tre, e, sizeof(trans_export_t));
122
0
  tr_extra->next = tr_extra_list;
123
0
  tr_extra_list = tr_extra;
124
125
0
  return 0;
126
0
}
127
128
int register_trans_mod(const char *mod_name, const trans_export_t *tr_exports)
129
0
{
130
0
  int i;
131
132
0
  if (!tr_exports)
133
0
    return 0;
134
135
0
  for (i = 0; tr_exports[i].name.s; i++)
136
0
    if (tr_add_extra(&tr_exports[i]) < 0) {
137
0
      LM_ERR("failed to register transformation class <%.*s> for module %s\n",
138
0
          tr_exports[i].name.len, tr_exports[i].name.s, mod_name);
139
0
      return -1;
140
0
    }
141
142
0
  return 0;
143
0
}
144
145
void tr_free_extra_list(void)
146
0
{
147
0
  trans_extra_t *tre, *tre_aux;
148
149
0
  tre = tr_extra_list;
150
0
  while (tre) {
151
0
    tre_aux = tre;
152
0
    tre = tre->next;
153
0
    pkg_free(tre_aux);
154
0
  }
155
0
}
156
157
int run_transformations(struct sip_msg *msg, trans_t *tr, pv_value_t *val)
158
0
{
159
0
  trans_t *it;
160
0
  int ret = 0;
161
162
0
  if (tr==NULL || val==NULL) {
163
0
    LM_DBG("null pointer\n");
164
0
    ret = -1;
165
0
    goto out;
166
0
  }
167
168
0
  it = tr;
169
0
  while (it) {
170
0
    ret = (*it->trf)(msg, it->params, it->subtype, val);
171
0
    if(ret!=0)
172
0
      goto out;
173
0
    it = it->next;
174
0
  }
175
176
0
out:
177
  /* advancing the current set of buffers avoids buffer overruns when passing
178
   * multiple transformation-enabled vars as cfg function parameters */
179
0
  __crt_tr_bufs = (__crt_tr_bufs + 1) % (MAX_ACTION_ELEMS - 1);
180
181
0
  return ret;
182
0
}
183
184
static void trans_fill_left(pv_value_t *val, str pad, int len, char *_tr_buffer)
185
0
{
186
0
  char *p;
187
0
  int r;
188
189
  /* fill with a single char */
190
0
  if (pad.len == 1) {
191
0
    memset(_tr_buffer, pad.s[0], len);
192
0
    memcpy(_tr_buffer + len, val->rs.s, val->rs.len);
193
194
0
    val->flags = PV_VAL_STR;
195
0
    val->rs.s = _tr_buffer;
196
0
    val->rs.len += len;
197
198
  /* fill with a string */
199
0
  } else {
200
0
    p = _tr_buffer;
201
0
    r = len % pad.len;
202
    /* handle the first non-even pad */
203
0
    if (r != 0) {
204
0
      memcpy(p, pad.s + (pad.len - r), r);
205
0
      p += r;
206
0
      len -= r;
207
0
      val->rs.len += r;
208
0
    }
209
210
    /* save initial string len */
211
0
    r = val->rs.len;
212
213
0
    while (len > 0) {
214
0
      memcpy(p, pad.s, pad.len);
215
0
      p += pad.len;
216
0
      val->rs.len += pad.len;
217
0
      len -= pad.len;
218
0
    }
219
220
0
    memcpy(p + len, val->rs.s, r);
221
222
0
    val->flags = PV_VAL_STR;
223
0
    val->rs.s = _tr_buffer;
224
0
  }
225
0
}
226
227
static void trans_fill_right(pv_value_t *val, str pad, int len, char *_tr_buffer)
228
0
{
229
0
  char *p;
230
0
  int r;
231
232
0
  memcpy(_tr_buffer, val->rs.s, val->rs.len);
233
234
  /* fill with a single char */
235
0
  if (pad.len == 1) {
236
0
    memset(_tr_buffer + val->rs.len, pad.s[0], len);
237
238
0
    val->flags = PV_VAL_STR;
239
0
    val->rs.s = _tr_buffer;
240
0
    val->rs.len += len;
241
242
  /* fill with a string */
243
0
  } else {
244
0
    p = _tr_buffer + val->rs.len;
245
246
0
    while (len > 0) {
247
0
      r = len < pad.len ? len : pad.len;
248
0
      memcpy(p, pad.s, r);
249
0
      p += r;
250
0
      val->rs.len += r;
251
0
      len -= pad.len;
252
0
    }
253
254
0
    val->flags = PV_VAL_STR;
255
0
    val->rs.s = _tr_buffer;
256
0
  }
257
0
}
258
259
int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
260
    pv_value_t *val)
261
0
{
262
0
  int i, j;
263
0
  char *p, *s, *_tr_buffer = get_tr_buffer();
264
0
  str st;
265
0
  pv_value_t v;
266
0
  pv_elem_p el=NULL;
267
268
0
  if (!val)
269
0
    return -1;
270
271
0
  if (val->flags & PV_VAL_NULL)
272
0
    return 0;
273
274
0
  switch(subtype)
275
0
  {
276
0
    case TR_S_LEN:
277
0
      if(!(val->flags&PV_VAL_STR))
278
0
        val->rs.s = int2str(val->ri, &val->rs.len);
279
280
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
281
0
      val->ri = val->rs.len;
282
0
      val->rs.s = int2str(val->ri, &val->rs.len);
283
0
      break;
284
0
    case TR_S_INT:
285
0
      if(!(val->flags&PV_VAL_INT))
286
0
      {
287
        //Default conversion to 0
288
0
        val->ri = 0;
289
        /*Ignore the return value of str2sint.
290
          str2sint will convert the string up until it finds a non-number char
291
          which is the desired behavior for the script level transformation*/
292
0
        str2sint(&val->rs, &val->ri);
293
0
      } else {
294
0
        if(!(val->flags&PV_VAL_STR))
295
0
          val->rs.s = int2str(val->ri, &val->rs.len);
296
0
      }
297
298
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
299
0
      break;
300
0
    case TR_S_MD5:
301
0
      if(!(val->flags&PV_VAL_STR))
302
0
        val->rs.s = int2str(val->ri, &val->rs.len);
303
304
0
      compute_md5(_tr_buffer, val->rs.s, val->rs.len);
305
0
      _tr_buffer[MD5_LEN] = '\0';
306
0
      val->flags = PV_VAL_STR;
307
0
      val->ri = 0;
308
0
      val->rs.s = _tr_buffer;
309
0
      val->rs.len = MD5_LEN;
310
0
      break;
311
0
    case TR_S_SHA1:
312
0
    case TR_S_SHA1_HMAC:
313
0
    case TR_S_SHA224:
314
0
    case TR_S_SHA224_HMAC:
315
0
    case TR_S_SHA256:
316
0
    case TR_S_SHA256_HMAC:
317
0
    case TR_S_SHA384:
318
0
    case TR_S_SHA384_HMAC:
319
0
    case TR_S_SHA512:
320
0
    case TR_S_SHA512_HMAC:
321
0
      if(!(val->flags&PV_VAL_STR))
322
0
        val->rs.s = int2str(val->ri, &val->rs.len);
323
324
0
      unsigned char sha_buf[64];
325
0
      int sha_hash_len = 0;
326
327
0
      if (tp != 0) { // We have parameter (hmac function)
328
0
        if(tp->type==TR_PARAM_STRING)
329
0
        {
330
0
          st = tp->v.s;
331
0
        } else {
332
0
          if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
333
0
            || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
334
0
          {
335
0
            LM_ERR("sha hmac transformation cannot get p1\n");
336
0
            goto error;
337
0
          }
338
0
          st = v.rs;
339
0
        }
340
0
      }
341
342
0
      if (subtype == TR_S_SHA1) {
343
0
        sha1((unsigned char *)val->rs.s, val->rs.len, sha_buf);
344
0
        sha_hash_len = 20;
345
0
      } else if (subtype == TR_S_SHA224) {
346
0
        sha256((unsigned char *)val->rs.s, val->rs.len, sha_buf, 1);
347
0
        sha_hash_len = 28;
348
0
      } else if (subtype == TR_S_SHA256) {
349
0
        sha256((unsigned char *)val->rs.s, val->rs.len, sha_buf, 0);
350
0
        sha_hash_len = 32;
351
0
      } else if (subtype == TR_S_SHA384) {
352
0
        sha512((unsigned char *)val->rs.s, val->rs.len, sha_buf, 1);
353
0
        sha_hash_len = 48;
354
0
      } else if (subtype == TR_S_SHA512) {
355
0
        sha512((unsigned char *)val->rs.s, val->rs.len, sha_buf, 0);
356
0
        sha_hash_len = 64;
357
0
      } else if (subtype == TR_S_SHA1_HMAC) {
358
0
        sha1_hmac((unsigned char *)st.s, st.len,
359
0
          (unsigned char *)val->rs.s, val->rs.len, sha_buf);
360
0
        sha_hash_len = 20;
361
0
      } else if (subtype == TR_S_SHA224_HMAC) {
362
0
        sha256_hmac((unsigned char *)st.s, st.len,
363
0
          (unsigned char *)val->rs.s, val->rs.len, sha_buf, 1);
364
0
        sha_hash_len = 28;
365
0
      } else if (subtype == TR_S_SHA256_HMAC) {
366
0
        sha256_hmac((unsigned char *)st.s, st.len,
367
0
          (unsigned char *)val->rs.s, val->rs.len, sha_buf, 0);
368
0
        sha_hash_len = 32;
369
0
      } else if (subtype == TR_S_SHA384_HMAC) {
370
0
        sha512_hmac((unsigned char *)st.s, st.len,
371
0
          (unsigned char *)val->rs.s, val->rs.len, sha_buf, 1);
372
0
        sha_hash_len = 48;
373
0
      } else if (subtype == TR_S_SHA512_HMAC) {
374
0
        sha512_hmac((unsigned char *)st.s, st.len,
375
0
          (unsigned char *)val->rs.s, val->rs.len, sha_buf, 0);
376
0
        sha_hash_len = 64;
377
0
      }
378
379
0
      val->flags = PV_VAL_STR;
380
0
      val->ri = 0;
381
0
      val->rs.s = _tr_buffer;
382
0
      val->rs.len = string2hex((char *)sha_buf, sha_hash_len, _tr_buffer);
383
0
      _tr_buffer[sha_hash_len*2] = '\0';
384
0
      break;
385
0
    case TR_S_CRC32:
386
0
      if(!(val->flags&PV_VAL_STR))
387
0
        val->rs.s = int2str(val->ri, &val->rs.len);
388
0
      unsigned int crc_val;
389
0
      int length = 10;
390
0
      crc32_uint(&val->rs,&crc_val);
391
0
      val->rs.len = length;
392
0
      val->rs.s = int2str(crc_val,&length);
393
0
      val->flags = PV_VAL_STR;
394
0
      break;
395
0
    case TR_S_ENCODEHEXA:
396
0
      if(!(val->flags&PV_VAL_STR))
397
0
        val->rs.s = int2str(val->ri, &val->rs.len);
398
0
      if(val->rs.len>TR_BUFFER_SIZE/2-1)
399
0
        goto error;
400
0
      j = 0;
401
0
      for(i=0; i<val->rs.len; i++)
402
0
      {
403
0
        _tr_buffer[j++] = fourbits2char[(unsigned char)val->rs.s[i] >> 4];
404
0
        _tr_buffer[j++] = fourbits2char[(unsigned char)val->rs.s[i] & 0xf];
405
0
      }
406
0
      _tr_buffer[j] = '\0';
407
0
      memset(val, 0, sizeof(pv_value_t));
408
0
      val->flags = PV_VAL_STR;
409
0
      val->rs.s = _tr_buffer;
410
0
      val->rs.len = j;
411
0
      break;
412
0
    case TR_S_DECODEHEXA:
413
0
      if(!(val->flags&PV_VAL_STR))
414
0
        val->rs.s = int2str(val->ri, &val->rs.len);
415
0
      if(val->rs.len>TR_BUFFER_SIZE*2-1)
416
0
        goto error;
417
0
      for(i=0; i<val->rs.len/2; i++)
418
0
      {
419
0
        if(val->rs.s[2*i]>='0'&&val->rs.s[2*i]<='9')
420
0
          _tr_buffer[i] = (val->rs.s[2*i]-'0') << 4;
421
0
        else if(val->rs.s[2*i]>='a'&&val->rs.s[2*i]<='f')
422
0
          _tr_buffer[i] = (val->rs.s[2*i]-'a'+10) << 4;
423
0
        else if(val->rs.s[2*i]>='A'&&val->rs.s[2*i]<='F')
424
0
          _tr_buffer[i] = (val->rs.s[2*i]-'A'+10) << 4;
425
0
        else goto error;
426
427
0
        if(val->rs.s[2*i+1]>='0'&&val->rs.s[2*i+1]<='9')
428
0
          _tr_buffer[i] += val->rs.s[2*i+1]-'0';
429
0
        else if(val->rs.s[2*i+1]>='a'&&val->rs.s[2*i+1]<='f')
430
0
          _tr_buffer[i] += val->rs.s[2*i+1]-'a'+10;
431
0
        else if(val->rs.s[2*i+1]>='A'&&val->rs.s[2*i+1]<='F')
432
0
          _tr_buffer[i] += val->rs.s[2*i+1]-'A'+10;
433
0
        else goto error;
434
0
      }
435
0
      _tr_buffer[i] = '\0';
436
0
      memset(val, 0, sizeof(pv_value_t));
437
0
      val->flags = PV_VAL_STR;
438
0
      val->rs.s = _tr_buffer;
439
0
      val->rs.len = i;
440
0
      break;
441
0
    case TR_S_HEX2DEC:
442
0
      if(val->flags&PV_VAL_INT)
443
0
        break; /* already converted */
444
0
      s = NULL;
445
0
      if (hexstr2int(val->rs.s, val->rs.len, (unsigned int *)&i) < 0)
446
0
        goto error;
447
0
      val->rs.s = int2str(i, &val->rs.len);
448
0
      val->ri = i;
449
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
450
0
      break;
451
0
    case TR_S_DEC2HEX:
452
0
      if(!(val->flags&PV_VAL_INT))
453
0
      {
454
0
        if(str2sint(&val->rs, &val->ri)!=0)
455
0
          goto error;
456
0
      }
457
0
      val->rs.len = snprintf(_tr_buffer, TR_BUFFER_SIZE, "%x", val->ri);
458
0
      if (val->rs.len < 0 || val->rs.len > TR_BUFFER_SIZE)
459
0
        goto error;
460
0
      val->ri = 0;
461
0
      val->rs.s = _tr_buffer;
462
0
      val->flags = PV_VAL_STR;
463
0
      break;
464
0
    case TR_S_DATE2UNIX:
465
0
      if(!(val->flags&PV_VAL_STR))
466
0
        goto error;
467
468
0
      struct tm date_tm;
469
470
0
      memcpy(_tr_buffer, val->rs.s, val->rs.len);
471
0
      _tr_buffer[val->rs.len] = 0;
472
473
0
      memset(&date_tm, 0, sizeof date_tm);
474
475
0
      if (!strptime(_tr_buffer, "%a, %d %b %Y %H:%M:%S GMT", &date_tm)) {
476
0
        LM_ERR("Failed to parse Date header field\n");
477
0
        goto error;
478
0
      }
479
480
0
      _tz_set("");
481
0
      snprintf(_tr_buffer, TR_BUFFER_SIZE, "%lld", (long long)mktime(&date_tm));
482
0
      tz_reset();
483
484
0
      if (strncmp(_tr_buffer, "-1", strlen("-1")) == 0) {
485
0
        LM_ERR("Failed convert to UNIX time\n");
486
0
        goto error;
487
0
      }
488
489
0
      val->rs.len = strlen(_tr_buffer);
490
0
      if (val->rs.len < 0 || val->rs.len > TR_BUFFER_SIZE)
491
0
        goto error;
492
0
      val->ri = 0;
493
0
      val->rs.s = _tr_buffer;
494
0
      val->flags = PV_VAL_STR;
495
0
      break;
496
0
    case TR_S_ESCAPECOMMON:
497
0
      if(!(val->flags&PV_VAL_STR))
498
0
        val->rs.s = int2str(val->ri, &val->rs.len);
499
0
      if(val->rs.len>TR_BUFFER_SIZE/2-1)
500
0
        goto error;
501
0
      i = escape_common(_tr_buffer, val->rs.s, val->rs.len);
502
0
      _tr_buffer[i] = '\0';
503
0
      memset(val, 0, sizeof(pv_value_t));
504
0
      val->flags = PV_VAL_STR;
505
0
      val->rs.s = _tr_buffer;
506
0
      val->rs.len = i;
507
0
      break;
508
0
    case TR_S_UNESCAPECOMMON:
509
0
      if(!(val->flags&PV_VAL_STR))
510
0
        val->rs.s = int2str(val->ri, &val->rs.len);
511
0
      if(val->rs.len>TR_BUFFER_SIZE-1)
512
0
        goto error;
513
0
      i = unescape_common(_tr_buffer, val->rs.s, val->rs.len);
514
0
      _tr_buffer[i] = '\0';
515
0
      memset(val, 0, sizeof(pv_value_t));
516
0
      val->flags = PV_VAL_STR;
517
0
      val->rs.s = _tr_buffer;
518
0
      val->rs.len = i;
519
0
      break;
520
0
    case TR_S_ESCAPEUSER:
521
0
      if(!(val->flags&PV_VAL_STR))
522
0
        val->rs.s = int2str(val->ri, &val->rs.len);
523
0
      if(val->rs.len>TR_BUFFER_SIZE/2-1)
524
0
        goto error;
525
0
      st.s = _tr_buffer;
526
0
      st.len = TR_BUFFER_SIZE;
527
0
      if (escape_user(&val->rs, &st))
528
0
        goto error;
529
0
      memset(val, 0, sizeof(pv_value_t));
530
0
      val->flags = PV_VAL_STR;
531
0
      val->rs = st;
532
0
      break;
533
0
    case TR_S_UNESCAPEUSER:
534
0
      if(!(val->flags&PV_VAL_STR))
535
0
        val->rs.s = int2str(val->ri, &val->rs.len);
536
0
      if(val->rs.len>TR_BUFFER_SIZE-1)
537
0
        goto error;
538
0
      st.s = _tr_buffer;
539
0
      st.len = TR_BUFFER_SIZE;
540
0
      if (unescape_user(&val->rs, &st))
541
0
        goto error;
542
0
      memset(val, 0, sizeof(pv_value_t));
543
0
      val->flags = PV_VAL_STR;
544
0
      val->rs = st;
545
0
      break;
546
0
    case TR_S_ESCAPEPARAM:
547
0
      if(!(val->flags&PV_VAL_STR))
548
0
        val->rs.s = int2str(val->ri, &val->rs.len);
549
0
      if(val->rs.len>TR_BUFFER_SIZE/2-1)
550
0
        goto error;
551
0
      st.s = _tr_buffer;
552
0
      st.len = TR_BUFFER_SIZE;
553
0
      if (escape_param(&val->rs, &st) < 0)
554
0
        goto error;
555
0
      memset(val, 0, sizeof(pv_value_t));
556
0
      val->flags = PV_VAL_STR;
557
0
      val->rs = st;
558
0
      break;
559
0
    case TR_S_UNESCAPEPARAM:
560
0
      if(!(val->flags&PV_VAL_STR))
561
0
        val->rs.s = int2str(val->ri, &val->rs.len);
562
0
      if(val->rs.len>TR_BUFFER_SIZE-1)
563
0
        goto error;
564
0
      st.s = _tr_buffer;
565
0
      st.len = TR_BUFFER_SIZE;
566
0
      if (unescape_param(&val->rs, &st) < 0)
567
0
        goto error;
568
0
      memset(val, 0, sizeof(pv_value_t));
569
0
      val->flags = PV_VAL_STR;
570
0
      val->rs = st;
571
0
      break;
572
0
    case TR_S_SUBSTR:
573
0
      if(tp==NULL || tp->next==NULL)
574
0
      {
575
0
        LM_ERR("substr invalid parameters\n");
576
0
        goto error;
577
0
      }
578
0
      if(!(val->flags&PV_VAL_STR))
579
0
        val->rs.s = int2str(val->ri, &val->rs.len);
580
0
      if(tp->type==TR_PARAM_NUMBER)
581
0
      {
582
0
        i = tp->v.n;
583
0
      } else {
584
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
585
0
            || (!(v.flags&PV_VAL_INT)))
586
0
        {
587
0
          LM_ERR("substr cannot get p1\n");
588
0
          goto error;
589
0
        }
590
0
        i = v.ri;
591
0
      }
592
0
      if(tp->next->type==TR_PARAM_NUMBER)
593
0
      {
594
0
        j = tp->next->v.n;
595
0
      } else {
596
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->next->v.data, &v)!=0
597
0
            || (!(v.flags&PV_VAL_INT)))
598
0
        {
599
0
          LM_ERR("substr cannot get p2\n");
600
0
          goto error;
601
0
        }
602
0
        j = v.ri;
603
0
      }
604
0
      LM_DBG("i=%d j=%d\n", i, j);
605
606
      /* adjust negative offset */
607
0
      if (i < 0)
608
0
      {
609
0
        if (-i > val->rs.len)
610
0
        {
611
          /* negative start out of range */
612
0
          goto error;
613
0
        } else {
614
0
          i = val->rs.len + i;
615
0
        }
616
0
      }
617
      /* start position out of range ? */
618
0
      if (i >= val->rs.len)
619
0
      {
620
        /* return NULL output */
621
0
        goto error;
622
0
      }
623
624
      /* adjust negative index */
625
0
      if (j < 1)
626
0
        j = val->rs.len + j - i;
627
628
      /* cut if length > string */
629
0
      if (i+j > val->rs.len)
630
0
        j = val->rs.len - i;
631
632
0
      val->flags = PV_VAL_STR;
633
0
      val->ri = 0;
634
635
0
      val->rs.s += i;
636
0
      val->rs.len = j;
637
0
      break;
638
639
0
    case TR_S_SELECT:
640
0
      if(tp==NULL || tp->next==NULL)
641
0
      {
642
0
        LM_ERR("select invalid parameters\n");
643
0
        goto error;
644
0
      }
645
0
      if(!(val->flags&PV_VAL_STR))
646
0
        val->rs.s = int2str(val->ri, &val->rs.len);
647
0
      if(tp->type==TR_PARAM_NUMBER)
648
0
      {
649
0
        i = tp->v.n;
650
0
      } else {
651
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
652
0
            || (!(v.flags&PV_VAL_INT)))
653
0
        {
654
0
          LM_ERR("select cannot get p1\n");
655
0
          goto error;
656
0
        }
657
0
        i = v.ri;
658
0
      }
659
0
      val->flags = PV_VAL_STR;
660
0
      val->ri = 0;
661
0
      if(i<0)
662
0
      {
663
0
        s = val->rs.s+val->rs.len-1;
664
0
        p = s;
665
0
        i = -i;
666
0
        i--;
667
0
        while(p>=val->rs.s)
668
0
        {
669
0
          if(*p==tp->next->v.s.s[0])
670
0
          {
671
0
            if(i==0)
672
0
              break;
673
0
            s = p-1;
674
0
            i--;
675
0
          }
676
0
          p--;
677
0
        }
678
0
        if(i==0)
679
0
        {
680
0
          val->rs.s = p+1;
681
0
          val->rs.len = s-p;
682
0
        } else {
683
0
          val->flags = PV_VAL_NULL;
684
0
        }
685
0
      } else {
686
0
        s = val->rs.s;
687
0
        p = s;
688
0
        while(p<val->rs.s+val->rs.len)
689
0
        {
690
0
          if(*p==tp->next->v.s.s[0])
691
0
          {
692
0
            if(i==0)
693
0
              break;
694
0
            s = p + 1;
695
0
            i--;
696
0
          }
697
0
          p++;
698
0
        }
699
0
        if(i==0)
700
0
        {
701
0
          val->rs.s = s;
702
0
          val->rs.len = p-s;
703
0
        } else {
704
0
          val->flags = PV_VAL_NULL;
705
0
        }
706
0
      }
707
0
      break;
708
709
0
    case TR_S_TOLOWER:
710
0
      if(!(val->flags&PV_VAL_STR))
711
0
      {
712
0
        val->rs.s = int2str(val->ri, &val->rs.len);
713
0
        val->flags |= PV_VAL_STR;
714
0
        break;
715
0
      }
716
0
      if(val->rs.len>TR_BUFFER_SIZE-1)
717
0
        goto error;
718
0
      st.s = _tr_buffer;
719
0
      st.len = val->rs.len;
720
0
      for (i=0; i<st.len; i++)
721
0
        st.s[i]=(val->rs.s[i]>='A' && val->rs.s[i]<='Z')
722
0
              ?('a' + val->rs.s[i] -'A'):val->rs.s[i];
723
0
      memset(val, 0, sizeof(pv_value_t));
724
0
      val->flags = PV_VAL_STR;
725
0
      val->rs = st;
726
0
      break;
727
728
0
    case TR_S_TOUPPER:
729
0
      if(!(val->flags&PV_VAL_STR))
730
0
      {
731
0
        val->rs.s = int2str(val->ri, &val->rs.len);
732
0
        val->flags |= PV_VAL_STR;
733
0
        break;
734
0
      }
735
0
      if(val->rs.len>TR_BUFFER_SIZE-1)
736
0
        goto error;
737
0
      st.s = _tr_buffer;
738
0
      st.len = val->rs.len;
739
0
      for (i=0; i<st.len; i++)
740
0
        st.s[i]=(val->rs.s[i]>='a' && val->rs.s[i]<='z')
741
0
              ?('A' + val->rs.s[i] -'a'):val->rs.s[i];
742
0
      memset(val, 0, sizeof(pv_value_t));
743
0
      val->flags = PV_VAL_STR;
744
0
      val->rs = st;
745
0
      break;
746
0
    case TR_S_INDEX:
747
0
    case TR_S_RINDEX:
748
      /* Ensure it is in string format */
749
0
      if(!(val->flags&PV_VAL_STR))
750
0
      {
751
0
        val->rs.s = int2str(val->ri, &val->rs.len);
752
0
        val->flags |= PV_VAL_STR;
753
0
      }
754
755
      /* Needle to look for in haystack */
756
0
      if(tp->type==TR_PARAM_STRING)
757
0
      {
758
0
        st = tp->v.s;
759
0
      } else {
760
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
761
0
                                                || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
762
0
        {
763
0
          LM_ERR("index/rindex cannot get p1\n");
764
0
          goto error;
765
0
        }
766
767
0
        st = v.rs;
768
0
      }
769
770
      /* User supplied starting position */
771
0
      if (tp->next != NULL) {
772
0
        if(tp->next->type==TR_PARAM_NUMBER)
773
0
        {
774
0
          i = tp->next->v.n;
775
0
        } else {
776
0
          if(pv_get_spec_value(msg, (pv_spec_p)tp->next->v.data, &v)!=0
777
0
              || (!(v.flags&PV_VAL_INT)))
778
0
          {
779
0
            LM_ERR("index/rindex cannot get p2\n");
780
0
            goto error;
781
0
          }
782
0
          i = v.ri;
783
0
        }
784
0
      } else {
785
        /* Default start positions: 0 for index, end of str for rindex */
786
0
        i = (subtype == TR_S_INDEX ? 0 : (val->rs.len - 1));
787
0
      }
788
789
      /* If start is negative base it off end of string
790
         e.g -2 on 10 char str start of 8. */
791
0
      if (i < 0 ){
792
0
        if ( val->rs.len > 0 ) {
793
          /* Support wrapping on negative index
794
             e.g -2 and -12 index are same on strlen of 10 */
795
0
          i = ( (i * -1) % val->rs.len );
796
          /* No remainder means we start at 0
797
             otherwise take remainder off the end */
798
0
          if ( i > 0) {
799
0
            i = (val->rs.len - i);
800
0
          }
801
0
        } else {
802
          /* Case of searching through an empty string is caught later */
803
0
          i = 0;
804
0
        }
805
0
      }
806
807
      /* Index */
808
0
      if (subtype == TR_S_INDEX) {
809
        /* If start index is beyond end of string or
810
           Needle is bigger than haystack return NULL */
811
0
        if ( i >= val->rs.len || st.len > (val->rs.len - i)) {
812
0
          memset(val, 0, sizeof(pv_value_t));
813
0
          val->flags = PV_VAL_NULL;
814
0
          break;
815
0
        }
816
817
        /* Iterate through string starting at index
818
           After j there are no longer enough characters left to match the needle */
819
0
        j = (val->rs.len - st.len);
820
0
        while (i <= j) {
821
0
          if (val->rs.s[i] == st.s[0]) {
822
            /* First character matches, do a full comparison
823
               shortcut for single character lookups */
824
0
            if (st.len == 1 || strncmp(val->rs.s + i, st.s, st.len) == 0) {
825
              /* Bingo, found it */
826
0
              memset(val, 0, sizeof(pv_value_t));
827
0
              val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
828
0
              val->ri = i;
829
0
              val->rs.s = int2str(val->ri, &val->rs.len);
830
0
              return 0;
831
0
            }
832
0
          }
833
0
          i++;
834
0
        }
835
      /* Rindex */
836
0
      } else {
837
        /* Needle bigger than haystack */
838
0
        if ( st.len > val->rs.len ) {
839
0
          memset(val, 0, sizeof(pv_value_t));
840
0
          val->flags = PV_VAL_NULL;
841
0
          break;
842
0
        }
843
844
        /* Incase of RINDEX clamp index to end of string */
845
0
        if (i >= val->rs.len) {
846
0
          i = (val->rs.len - 1);
847
0
        }
848
849
        /* Start position does not leave enough characters to match needle, jump ahead */
850
0
        if ( st.len > (val->rs.len - i) ) {
851
          /* Minimum start position allowing for matches */
852
0
          i = (val->rs.len - st.len);
853
0
        }
854
855
        /* Iterate through string starting at index and going backwards */
856
0
        while (i >= 0) {
857
0
          if (val->rs.s[i] == st.s[0]) {
858
            /* First character matches, do a full comparison
859
               shortcut for single character lookups */
860
0
            if (st.len == 1 || strncmp(val->rs.s + i, st.s, st.len) == 0) {
861
              /* Bingo, found it */
862
0
              memset(val, 0, sizeof(pv_value_t));
863
0
              val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
864
0
              val->ri = i;
865
0
              val->rs.s = int2str(val->ri, &val->rs.len);
866
0
              return 0;
867
0
            }
868
0
          }
869
0
          i--;
870
0
        }
871
872
0
      }
873
874
      /* Not found */
875
0
      memset(val, 0, sizeof(pv_value_t));
876
0
      val->flags = PV_VAL_NULL;
877
0
      break;
878
0
    case TR_S_FILL_LEFT:
879
0
    case TR_S_FILL_RIGHT:
880
881
      /* padding string parameter */
882
0
      st = tp->v.s;
883
884
      /* padded final length parameter */
885
0
      i = tp->next->v.n;
886
887
0
      if (val->flags & PV_VAL_STR)
888
0
      {
889
0
        i -= val->rs.len;
890
0
      } else if (val->flags & PV_VAL_INT)
891
0
      {
892
0
        val->rs.s = int2str(val->ri, &val->rs.len);
893
0
        i -= val->rs.len;
894
0
      }
895
896
      /* no need for padding */
897
0
      if (i < 0)
898
0
        return 0;
899
900
0
      if (subtype == TR_S_FILL_LEFT)
901
0
        trans_fill_left(val, st, i, _tr_buffer);
902
0
      else
903
0
        trans_fill_right(val, st, i, _tr_buffer);
904
905
0
      break;
906
0
    case TR_S_WIDTH:
907
0
      if(tp==NULL || tp->next!=NULL)
908
0
      {
909
0
        LM_ERR("width invalid parameters\n");
910
0
        goto error;
911
0
      }
912
0
      if(!(val->flags&PV_VAL_STR))
913
0
        val->rs.s = int2str(val->ri, &val->rs.len);
914
0
      if(tp->type==TR_PARAM_NUMBER)
915
0
      {
916
0
        i = tp->v.n;
917
0
      } else {
918
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
919
0
            || (!(v.flags&PV_VAL_INT)))
920
0
        {
921
0
          LM_ERR("substr cannot get p1\n");
922
0
          goto error;
923
0
        }
924
0
        i = v.ri;
925
0
      }
926
0
      if (i <= 0) {
927
0
        LM_ERR("width invalid (must be >= 1)\n");
928
0
        goto error;
929
0
      }
930
0
      if (i <= val->rs.len) {
931
        /* since the requested width is less than
932
           the value length, just update the length */
933
0
        val->rs.len = i;
934
0
        break;
935
0
      }
936
937
0
      if(i>TR_BUFFER_SIZE-1)
938
        /* width cant be greater than buffer */
939
0
        goto error;
940
941
0
      j = i - val->rs.len; /* calc extra length */
942
0
      p = _tr_buffer;
943
944
      /* copy existing string to buffer and append j spaces */
945
0
      memcpy(p, val->rs.s, val->rs.len);
946
0
      memset(p+val->rs.len, ' ', j);
947
0
      memset(val, 0, sizeof(pv_value_t));
948
949
0
      val->flags = PV_VAL_STR;
950
0
      val->rs.s = _tr_buffer;
951
0
      val->rs.len = i;
952
0
      break;
953
0
    case TR_S_B64ENCODE:
954
0
      if(!(val->flags&PV_VAL_STR))
955
0
      {
956
0
        val->rs.s = int2str(val->ri, &val->rs.len);
957
0
        val->flags |= PV_VAL_STR;
958
0
        break;
959
0
      }
960
0
      if(val->rs.len>TR_BUFFER_SIZE-1) {
961
0
        LM_ERR("b64encode value larger than buffer\n");
962
0
        goto error;
963
0
      }
964
0
      st.s = _tr_buffer;
965
0
      st.len = calc_base64_encode_len(val->rs.len);
966
967
0
      base64encode((unsigned char *)st.s,
968
0
             (unsigned char *)val->rs.s,
969
0
             val->rs.len);
970
971
0
      memset(val, 0, sizeof(pv_value_t));
972
0
      val->flags = PV_VAL_STR;
973
0
      val->rs = st;
974
0
      break;
975
0
    case TR_S_B64DECODE:
976
0
      if(!(val->flags&PV_VAL_STR))
977
0
      {
978
0
        val->rs.s = int2str(val->ri, &val->rs.len);
979
0
        val->flags |= PV_VAL_STR;
980
0
        break;
981
0
      }
982
0
      if(val->rs.len>TR_BUFFER_SIZE-1) {
983
0
        LM_ERR("b64decode value larger than buffer\n");
984
0
        return -1;
985
0
      }
986
0
                        st.s = _tr_buffer;
987
0
                        st.len = base64decode((unsigned char *)st.s, 
988
0
                                              (unsigned char *)val->rs.s,
989
0
                                              val->rs.len);
990
0
                        memset(val, 0, sizeof(pv_value_t));
991
0
                        val->flags = PV_VAL_STR;
992
0
                        val->rs = st;
993
0
                        break;
994
0
    case TR_S_XOR:
995
      /* ensure string format */
996
0
      if(!(val->flags&PV_VAL_STR))
997
0
      {
998
0
        val->rs.s = int2str(val->ri, &val->rs.len);
999
0
        val->flags |= PV_VAL_STR;
1000
0
      }
1001
0
      if(val->rs.len>TR_BUFFER_SIZE-1) {
1002
0
        LM_ERR("xor value larger than buffer\n");
1003
0
        goto error;
1004
0
      }
1005
      /* secret to use */
1006
0
      if(tp->type==TR_PARAM_STRING)
1007
0
      {
1008
0
        st = tp->v.s;
1009
0
      } else {
1010
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1011
0
                                                || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
1012
0
        {
1013
0
          LM_ERR("xor cannot get p1\n");
1014
0
          return -1;
1015
0
        }
1016
0
        st = v.rs;
1017
0
      }
1018
      
1019
0
      p = _tr_buffer;
1020
0
      for (i=0; i<val->rs.len; i++) {
1021
0
        *p = val->rs.s[i] ^ st.s[i % st.len];
1022
0
        p++;
1023
0
      }
1024
      /* leave val flags and length in tact and update with result */
1025
0
                        val->rs.s = _tr_buffer;
1026
0
      break;
1027
0
    case TR_S_TRIM:
1028
0
      if (!(val->flags & PV_VAL_STR))
1029
0
      {
1030
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1031
0
        val->flags |= PV_VAL_STR;
1032
0
      }
1033
1034
0
      trim(&val->rs);
1035
0
      break;
1036
0
    case TR_S_TRIMR:
1037
0
      if (!(val->flags & PV_VAL_STR))
1038
0
      {
1039
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1040
0
        val->flags |= PV_VAL_STR;
1041
0
      }
1042
1043
0
      trim_trailing(&val->rs);
1044
0
      break;
1045
0
    case TR_S_TRIML:
1046
0
      if (!(val->flags & PV_VAL_STR))
1047
0
      {
1048
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1049
0
        val->flags |= PV_VAL_STR;
1050
0
      }
1051
1052
0
      trim_leading(&val->rs);
1053
0
      break;
1054
0
    case TR_S_REVERSE:
1055
0
      if (!(val->flags & PV_VAL_STR))
1056
0
      {
1057
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1058
0
        val->flags |= PV_VAL_STR;
1059
0
      }
1060
1061
      /*To big for buffer*/
1062
0
      if(val->rs.len>TR_BUFFER_SIZE-1)
1063
0
        goto error;
1064
1065
0
      p = _tr_buffer;
1066
1067
      /*Reverse Order*/
1068
0
      for (i=0; i < val->rs.len; i++) {
1069
0
        p[val->rs.len - 1 - i] = val->rs.s[i];
1070
0
      }
1071
1072
      /*Save Result*/
1073
0
      val->rs.s = _tr_buffer;
1074
0
      val->flags = PV_VAL_STR;
1075
0
      break;
1076
0
    case TR_S_EVAL:
1077
0
      if(!(val->flags&PV_VAL_STR))
1078
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1079
1080
0
      if (pv_parse_format(&val->rs,&el) != 0) {
1081
0
        LM_ERR("Failed to parse input \n");
1082
0
        goto error;
1083
0
      }
1084
1085
0
      if (pv_printf_s(msg,el,&st) != 0) {
1086
0
        LM_ERR("Failed to print input \n");
1087
0
        pv_elem_free_all(el);
1088
0
        goto error;
1089
0
      }
1090
1091
0
      memcpy(_tr_buffer,st.s,st.len);
1092
0
      _tr_buffer[st.len] = '\0';
1093
1094
0
      val->flags = PV_VAL_STR;
1095
0
      val->ri = 0;
1096
0
      val->rs.s = _tr_buffer;
1097
0
      val->rs.len = st.len;
1098
1099
0
      pv_elem_free_all(el);
1100
0
      break;
1101
0
    default:
1102
0
      LM_ERR("unknown subtype %d\n",
1103
0
          subtype);
1104
0
      goto error;
1105
0
  }
1106
1107
0
  return 0;
1108
0
error:
1109
0
  val->flags = PV_VAL_NULL;
1110
0
  return -1;
1111
0
}
1112
1113
static str _tr_empty = { "", 0 };
1114
static str _tr_uri = {0, 0};
1115
static struct sip_uri _tr_parsed_uri;
1116
static param_t* _tr_uri_params = NULL;
1117
1118
int tr_eval_uri(struct sip_msg *msg, tr_param_t *tp, int subtype,
1119
    pv_value_t *val)
1120
0
{
1121
0
  pv_value_t v;
1122
0
  str sv;
1123
0
  param_hooks_t phooks;
1124
0
  param_t *pit=NULL;
1125
1126
0
  if (!val)
1127
0
    return -1;
1128
1129
0
  if (val->flags & PV_VAL_NULL)
1130
0
    return 0;
1131
1132
0
  if((!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
1133
0
    goto error;
1134
1135
0
  if(_tr_uri.len==0 || _tr_uri.len!=val->rs.len ||
1136
0
      strncmp(_tr_uri.s, val->rs.s, val->rs.len)!=0)
1137
0
  {
1138
0
    if(val->rs.len>_tr_uri.len)
1139
0
    {
1140
0
      if(_tr_uri.s) pkg_free(_tr_uri.s);
1141
0
      _tr_uri.s = (char*)pkg_malloc((val->rs.len+1)*sizeof(char));
1142
0
      if(_tr_uri.s==NULL)
1143
0
      {
1144
0
        LM_ERR("no more private memory\n");
1145
0
        if(_tr_uri_params != NULL)
1146
0
        {
1147
0
          free_params(_tr_uri_params);
1148
0
          _tr_uri_params = 0;
1149
0
        }
1150
0
        memset(&_tr_uri, 0, sizeof(str));
1151
0
        memset(&_tr_parsed_uri, 0, sizeof(struct sip_uri));
1152
0
        goto error;
1153
0
      }
1154
0
    }
1155
0
    _tr_uri.len = val->rs.len;
1156
0
    memcpy(_tr_uri.s, val->rs.s, val->rs.len);
1157
0
    _tr_uri.s[_tr_uri.len] = '\0';
1158
    /* reset old values */
1159
0
    memset(&_tr_parsed_uri, 0, sizeof(struct sip_uri));
1160
0
    if(_tr_uri_params != NULL)
1161
0
    {
1162
0
      free_params(_tr_uri_params);
1163
0
      _tr_uri_params = 0;
1164
0
    }
1165
    /* parse uri -- params only when requested */
1166
0
    if(parse_uri(_tr_uri.s, _tr_uri.len, &_tr_parsed_uri)!=0)
1167
0
    {
1168
0
      LM_ERR("invalid uri [%.*s]\n", val->rs.len,
1169
0
          val->rs.s);
1170
0
      if(_tr_uri_params != NULL)
1171
0
      {
1172
0
        free_params(_tr_uri_params);
1173
0
        _tr_uri_params = 0;
1174
0
      }
1175
0
      pkg_free(_tr_uri.s);
1176
0
      memset(&_tr_uri, 0, sizeof(str));
1177
0
      memset(&_tr_parsed_uri, 0, sizeof(struct sip_uri));
1178
0
      goto error;
1179
0
    }
1180
0
  }
1181
0
  memset(val, 0, sizeof(pv_value_t));
1182
0
  val->flags = PV_VAL_STR;
1183
1184
0
  switch(subtype)
1185
0
  {
1186
0
    case TR_URI_USER:
1187
0
      val->rs = (_tr_parsed_uri.user.s)?_tr_parsed_uri.user:_tr_empty;
1188
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1189
0
      break;
1190
0
    case TR_URI_HOST:
1191
0
      val->rs = (_tr_parsed_uri.host.s)?_tr_parsed_uri.host:_tr_empty;
1192
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1193
0
      break;
1194
0
    case TR_URI_PASSWD:
1195
0
      val->rs = (_tr_parsed_uri.passwd.s)?_tr_parsed_uri.passwd:_tr_empty;
1196
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1197
0
      break;
1198
0
    case TR_URI_PORT:
1199
0
      val->flags |= PV_TYPE_INT|PV_VAL_INT;
1200
0
      val->rs = (_tr_parsed_uri.port.s)?_tr_parsed_uri.port:_tr_empty;
1201
0
      val->ri = _tr_parsed_uri.port_no;
1202
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1203
0
      break;
1204
0
    case TR_URI_PARAMS:
1205
0
      val->rs = (_tr_parsed_uri.params.s)?_tr_parsed_uri.params:_tr_empty;
1206
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1207
0
      break;
1208
0
    case TR_URI_PARAM:
1209
0
      if(tp==NULL)
1210
0
      {
1211
0
        LM_ERR("param invalid parameters\n");
1212
0
        goto error;
1213
0
      }
1214
0
      if(_tr_parsed_uri.params.len<=0)
1215
0
      {
1216
0
        val->flags = PV_VAL_NULL;
1217
0
        break;
1218
0
      }
1219
1220
0
      if(_tr_uri_params == NULL)
1221
0
      {
1222
0
        sv = _tr_parsed_uri.params;
1223
0
        if (parse_params(&sv, CLASS_ANY, &phooks, &_tr_uri_params)<0)
1224
0
          goto error;
1225
0
      }
1226
0
      if(tp->type==TR_PARAM_STRING)
1227
0
      {
1228
0
        sv = tp->v.s;
1229
0
      } else {
1230
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1231
0
            || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
1232
0
        {
1233
0
          LM_ERR("param cannot get p1\n");
1234
0
          goto error;
1235
0
        }
1236
0
        sv = v.rs;
1237
0
      }
1238
0
      for (pit = _tr_uri_params; pit; pit=pit->next)
1239
0
      {
1240
0
        if (pit->name.len==sv.len
1241
0
            && strncasecmp(pit->name.s, sv.s, sv.len)==0)
1242
0
        {
1243
0
          if (ZSTR(pit->body))
1244
0
            val->rs = STR_EMPTY;
1245
0
          else
1246
0
            val->rs = pit->body;
1247
0
          goto done;
1248
0
        }
1249
0
      }
1250
0
      val->flags = PV_VAL_NULL;
1251
0
      break;
1252
0
    case TR_URI_HEADERS:
1253
0
      val->rs = (_tr_parsed_uri.headers.s)?_tr_parsed_uri.headers:
1254
0
            _tr_empty;
1255
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1256
0
      break;
1257
0
    case TR_URI_TRANSPORT:
1258
0
      val->rs = (_tr_parsed_uri.transport_val.s)?
1259
0
        _tr_parsed_uri.transport_val:_tr_empty;
1260
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1261
0
      break;
1262
0
    case TR_URI_TTL:
1263
0
      val->rs = (_tr_parsed_uri.ttl_val.s)?
1264
0
        _tr_parsed_uri.ttl_val:_tr_empty;
1265
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1266
0
      break;
1267
0
    case TR_URI_UPARAM:
1268
0
      val->rs = (_tr_parsed_uri.user_param_val.s)?
1269
0
        _tr_parsed_uri.user_param_val:_tr_empty;
1270
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1271
0
      break;
1272
0
    case TR_URI_MADDR:
1273
0
      val->rs = (_tr_parsed_uri.maddr_val.s)?
1274
0
        _tr_parsed_uri.maddr_val:_tr_empty;
1275
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1276
0
      break;
1277
0
    case TR_URI_METHOD:
1278
0
      val->rs = (_tr_parsed_uri.method_val.s)?
1279
0
        _tr_parsed_uri.method_val:_tr_empty;
1280
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1281
0
      break;
1282
0
    case TR_URI_LR:
1283
0
      val->rs = (_tr_parsed_uri.lr_val.s)?
1284
0
        _tr_parsed_uri.lr_val:_tr_empty;
1285
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1286
0
      break;
1287
0
    case TR_URI_R2:
1288
0
      val->rs = (_tr_parsed_uri.r2_val.s)?
1289
0
        _tr_parsed_uri.r2_val:_tr_empty;
1290
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1291
0
      break;
1292
0
    case TR_URI_SCHEMA:
1293
0
      val->rs.s = _tr_uri.s;
1294
      /* maximum size of schema can be 4 so the ':' shall be found after
1295
       * five chars */
1296
0
      val->rs.len = q_memchr(val->rs.s, ':', 5) - val->rs.s;
1297
0
      break;
1298
0
    default:
1299
0
      LM_ERR("unknown subtype %d\n",
1300
0
          subtype);
1301
0
      goto error;
1302
0
  }
1303
0
done:
1304
0
  return 0;
1305
0
error:
1306
0
  val->flags = PV_VAL_NULL;
1307
0
  return -1;
1308
0
}
1309
1310
1311
/* last via string */
1312
static str _tr_via = {0, 0};
1313
/* the actual len of the allocated buffer (to hold the via) */
1314
static int _tr_via_buf_len = 0;
1315
/* holder for the parsed via */
1316
static struct via_body *_tr_parsed_via = 0;
1317
1318
int tr_eval_via(struct sip_msg *msg, tr_param_t *tp, int subtype,
1319
    pv_value_t *val)
1320
0
{
1321
0
  pv_value_t v;
1322
0
  str sv;
1323
0
  struct via_param *pit;
1324
1325
0
  if (!val)
1326
0
    return -1;
1327
1328
0
  if (val->flags & PV_VAL_NULL)
1329
0
    return 0;
1330
1331
  // WATCHOUT: need at least 2 chars so \r\n check wont segfault
1332
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=2) {
1333
0
    val->flags = PV_VAL_NULL;
1334
0
    return -1;
1335
0
  }
1336
1337
0
  if(_tr_via_buf_len==0 || _tr_via.len!=val->rs.len ||
1338
0
      strncmp(_tr_via.s, val->rs.s, val->rs.len)!=0
1339
0
      || _tr_parsed_via==0)
1340
0
  {
1341
0
    if (val->rs.len+4 > _tr_via_buf_len)
1342
0
    {
1343
0
      if(_tr_via.s) pkg_free(_tr_via.s);
1344
0
      _tr_via.s = (char*)pkg_malloc((val->rs.len+4)*sizeof(char));
1345
0
      if(_tr_via.s==NULL)
1346
0
      {
1347
0
        _tr_via_buf_len = 0;
1348
0
        LM_ERR("no more private memory\n");
1349
0
        goto error;
1350
0
      }
1351
0
      _tr_via_buf_len = val->rs.len+4;
1352
0
    }
1353
0
    _tr_via.len = val->rs.len;
1354
0
    memcpy(_tr_via.s, val->rs.s, val->rs.len);
1355
    // $hdr PV strips off the terminating CRLR
1356
    // parse_via wants to parse a full message (including
1357
    // multiple vias), not just a header line.  Fake this
1358
0
    _tr_via.s[_tr_via.len+0] = '\r';
1359
0
    _tr_via.s[_tr_via.len+1] = '\n';
1360
0
    _tr_via.s[_tr_via.len+2] = 'A'; // anything other than V
1361
0
    _tr_via.s[_tr_via.len+3] = '\0';
1362
    /* reset old values */
1363
0
    free_via_list(_tr_parsed_via);
1364
0
    if ( (_tr_parsed_via=pkg_malloc(sizeof(struct via_body))) == NULL ) {
1365
0
      LM_ERR("no more private memory\n");
1366
0
      goto error;
1367
0
    }
1368
0
    memset(_tr_parsed_via, 0, sizeof(struct via_body));
1369
0
    parse_via(_tr_via.s, _tr_via.s+_tr_via.len+4, _tr_parsed_via);
1370
0
    if(_tr_parsed_via->error != PARSE_OK) {
1371
0
      LM_ERR("invalid via [%.*s]\n", val->rs.len,
1372
0
          val->rs.s);
1373
0
      goto error;
1374
0
    }
1375
0
  }
1376
0
  memset(val, 0, sizeof(pv_value_t));
1377
0
  val->flags = PV_VAL_STR;
1378
1379
0
  switch(subtype)
1380
0
  {
1381
0
    case TR_VIA_NAME:
1382
0
      val->rs = (_tr_parsed_via->name.s)?_tr_parsed_via->name:_tr_empty;
1383
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1384
0
      break;
1385
0
    case TR_VIA_VERSION:
1386
0
      val->rs = (_tr_parsed_via->version.s)?_tr_parsed_via->version:_tr_empty;
1387
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1388
0
      break;
1389
0
    case TR_VIA_TRANSPORT:
1390
0
      val->rs = (_tr_parsed_via->transport.s)?_tr_parsed_via->transport:_tr_empty;
1391
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1392
0
      break;
1393
0
    case TR_VIA_HOST:
1394
0
      val->rs = (_tr_parsed_via->host.s)?_tr_parsed_via->host:_tr_empty;
1395
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1396
0
      break;
1397
0
    case TR_VIA_PORT:
1398
0
      val->flags |= PV_TYPE_INT|PV_VAL_INT;
1399
0
      val->rs = (_tr_parsed_via->port_str.s)?_tr_parsed_via->port_str:_tr_empty;
1400
0
      val->ri = _tr_parsed_via->port;
1401
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1402
0
      break;
1403
0
    case TR_VIA_PARAMS:
1404
0
      val->rs = (_tr_parsed_via->params.s)?_tr_parsed_via->params:_tr_empty;
1405
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1406
0
      break;
1407
0
    case TR_VIA_COMMENT:
1408
0
      val->rs = (_tr_parsed_via->comment.s)?_tr_parsed_via->comment:_tr_empty;
1409
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1410
0
      break;
1411
0
    case TR_VIA_PARAM:  // param by name
1412
0
      if(tp==NULL)
1413
0
      {
1414
0
        LM_ERR("param invalid parameters\n");
1415
0
        val->flags = PV_VAL_NULL;
1416
0
        return -1;
1417
0
      }
1418
0
      if(_tr_parsed_via->params.len<=0)
1419
0
      {
1420
0
        val->flags = PV_VAL_NULL;
1421
0
        break;
1422
0
      }
1423
1424
0
      if(tp->type==TR_PARAM_STRING)
1425
0
      {
1426
0
        sv = tp->v.s;
1427
0
      } else {
1428
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1429
0
            || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
1430
0
        {
1431
0
          LM_ERR("param cannot get p1\n");
1432
0
          val->flags = PV_VAL_NULL;
1433
0
          return -1;
1434
0
        }
1435
0
        sv = v.rs;
1436
0
      }
1437
0
      for (pit = _tr_parsed_via->param_lst; pit; pit=pit->next)
1438
0
      {
1439
0
        if (pit->name.len==sv.len
1440
0
            && strncasecmp(pit->name.s, sv.s, sv.len)==0)
1441
0
        {
1442
0
          val->rs = pit->value;
1443
0
          goto done;
1444
0
        }
1445
0
      }
1446
0
      val->flags = PV_VAL_NULL;
1447
0
      break;
1448
0
    case TR_VIA_BRANCH:
1449
0
      val->rs = (_tr_parsed_via->branch&&_tr_parsed_via->branch->value.s)?_tr_parsed_via->branch->value: _tr_empty;
1450
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1451
0
      break;
1452
0
    case TR_VIA_RECEIVED:
1453
0
      val->rs = (_tr_parsed_via->received&&_tr_parsed_via->received->value.s)?_tr_parsed_via->received->value: _tr_empty;
1454
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1455
0
      break;
1456
0
    case TR_VIA_RPORT:
1457
0
      val->rs = (_tr_parsed_via->rport&&_tr_parsed_via->rport->value.s)?_tr_parsed_via->rport->value: _tr_empty;
1458
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1459
0
      break;
1460
0
    default:
1461
0
      LM_ERR("unknown subtype %d\n",
1462
0
          subtype);
1463
0
      val->flags = PV_VAL_NULL;
1464
0
      return -1;
1465
0
  }
1466
1467
0
done:
1468
0
  return 0;
1469
1470
0
error:
1471
0
  if ( _tr_via.s ) {
1472
0
    pkg_free(_tr_via.s);
1473
0
  }
1474
0
  memset(&_tr_via, 0, sizeof(str));
1475
0
  if ( _tr_parsed_via ) {
1476
0
        free_via_list(_tr_parsed_via);
1477
0
    _tr_parsed_via = 0;
1478
0
  }
1479
0
  val->flags = PV_VAL_NULL;
1480
0
  return -1;
1481
0
}
1482
1483
static str _tr_csv_str = {0,0};
1484
static csv_record* _tr_csv_list = NULL;
1485
1486
int tr_eval_csv(struct sip_msg *msg, tr_param_t *tp,int subtype,
1487
    pv_value_t *val)
1488
0
{
1489
0
  csv_record *cit=NULL;
1490
0
  int n,i,list_size=0;
1491
0
  pv_value_t v;
1492
1493
0
  if (!val)
1494
0
    return -1;
1495
1496
0
  if (val->flags & PV_VAL_NULL)
1497
0
    return 0;
1498
1499
0
  if (!(val->flags&PV_VAL_STR) || val->rs.len<=0)
1500
0
    goto error;
1501
1502
0
  if(_tr_csv_str.len==0 || _tr_csv_str.len!=val->rs.len ||
1503
0
      strncmp(_tr_csv_str.s, val->rs.s, val->rs.len)!=0)
1504
0
  {
1505
0
    if(val->rs.len>_tr_csv_str.len)
1506
0
    {
1507
0
      if(_tr_csv_str.s) pkg_free(_tr_csv_str.s);
1508
0
        _tr_csv_str.s = (char*)pkg_malloc((val->rs.len+1));
1509
0
      if(_tr_csv_str.s==NULL)
1510
0
      {
1511
0
        LM_ERR("no more private memory\n");
1512
0
        memset(&_tr_csv_str, 0, sizeof(str));
1513
0
        if(_tr_csv_list != NULL)
1514
0
        {
1515
0
          free_csv_record(_tr_csv_list);
1516
0
          _tr_csv_list = NULL;
1517
0
        }
1518
0
        goto error;
1519
0
      }
1520
0
    }
1521
0
    _tr_csv_str.len = val->rs.len;
1522
0
    memcpy(_tr_csv_str.s, val->rs.s, val->rs.len);
1523
0
    _tr_csv_str.s[_tr_csv_str.len] = '\0';
1524
1525
    /* reset old values */
1526
0
    if(_tr_csv_list != NULL)
1527
0
    {
1528
0
      free_csv_record(_tr_csv_list);
1529
0
      _tr_csv_list = NULL;
1530
0
    }
1531
1532
    /* parse csv */
1533
0
    _tr_csv_list = _parse_csv_record(&_tr_csv_str, CSV_RFC_4180);
1534
0
    if (!_tr_csv_list)
1535
0
      goto error;
1536
0
  }
1537
1538
0
  if (_tr_csv_list == NULL)
1539
0
    goto error;
1540
1541
0
  switch(subtype)
1542
0
  {
1543
0
    case TR_CSV_COUNT:
1544
0
      val->ri = 0;
1545
0
      for (cit=_tr_csv_list;cit;cit=cit->next)
1546
0
        val->ri++;
1547
1548
0
      val->rs.s = int2str(val->ri, &val->rs.len);
1549
0
      val->flags = PV_VAL_INT | PV_VAL_STR | PV_TYPE_INT;
1550
0
      break;
1551
0
    case TR_CSV_VALUEAT:
1552
0
      if(tp==NULL)
1553
0
      {
1554
0
        LM_ERR("csv invalid parameters\n");
1555
0
        goto error;
1556
0
      }
1557
0
      if(tp->type==TR_PARAM_NUMBER)
1558
0
      {
1559
0
        n = tp->v.n;
1560
0
      } else {
1561
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1562
0
            || (!(v.flags&PV_VAL_INT)))
1563
0
        {
1564
0
          LM_ERR("cannot get parameter\n");
1565
0
          goto error;
1566
0
        }
1567
0
        n = v.ri;
1568
0
      }
1569
1570
0
      if (n<0)
1571
0
      {
1572
0
        for (cit=_tr_csv_list;cit;cit=cit->next)
1573
0
          list_size++;
1574
0
        n = list_size + n;
1575
0
        if (n<0)
1576
0
        {
1577
0
          LM_ERR("Too large negative index\n");
1578
0
          goto error;
1579
0
        }
1580
0
      }
1581
1582
0
      cit = _tr_csv_list;
1583
0
      for (i=0;i<n;i++)
1584
0
      {
1585
0
        cit=cit->next;
1586
0
        if (!cit)
1587
0
        {
1588
0
          LM_ERR("Index out of bounds\n");
1589
0
          goto error;
1590
0
        }
1591
0
      }
1592
1593
0
      val->rs = cit->s;
1594
0
      val->flags =  PV_VAL_STR;
1595
0
      break;
1596
1597
0
    default:
1598
0
      LM_ERR("unknown subtype %d\n",subtype);
1599
0
      goto error;
1600
0
  }
1601
1602
0
  return 0;
1603
1604
0
error:
1605
0
  val->flags = PV_VAL_NULL;
1606
0
  return -1;
1607
0
}
1608
1609
static str _tr_sdp_str;
1610
1611
int tr_eval_sdp(struct sip_msg *msg, tr_param_t *tp,int subtype,
1612
    pv_value_t *val)
1613
0
{
1614
0
  str media;
1615
0
  char *bodylimit;
1616
0
  char *answer;
1617
0
  char *answerEnd;
1618
0
  char searchLine;
1619
0
  int entryNo,i,lenoff;
1620
1621
0
  pv_value_t v;
1622
0
  sdp_info_t sdp;
1623
0
  sdp_session_cell_t *session;
1624
0
  sdp_stream_cell_t *stream;
1625
1626
0
  if (!val)
1627
0
    return -1;
1628
1629
0
  if (val->flags & PV_VAL_NULL)
1630
0
    return 0;
1631
1632
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
1633
0
    goto error;
1634
1635
0
  if (!tp)
1636
0
    goto error;
1637
1638
0
  if(_tr_sdp_str.len==0 || _tr_sdp_str.len!=val->rs.len ||
1639
0
      strncmp(_tr_sdp_str.s, val->rs.s, val->rs.len)!=0)
1640
0
  {
1641
0
    if (pkg_str_extend(&_tr_sdp_str, val->rs.len + 3 /* \r\n\0 */) != 0)
1642
0
    {
1643
0
      LM_ERR("no more private memory\n");
1644
0
      goto error;
1645
0
    }
1646
1647
0
    _tr_sdp_str.len = val->rs.len + 2;
1648
0
    _tr_sdp_str.s[0] = '\r';
1649
0
    _tr_sdp_str.s[1] = '\n';
1650
0
    memcpy(_tr_sdp_str.s + 2, val->rs.s, val->rs.len);
1651
0
    _tr_sdp_str.s[_tr_sdp_str.len] = '\0';
1652
1653
0
  }
1654
1655
0
  switch (subtype)
1656
0
  {
1657
0
    case TR_SDP_LINEAT:
1658
1659
      /* line index is mandatory */
1660
0
      if (!tp->next)
1661
0
        goto error;
1662
0
      bodylimit = _tr_sdp_str.s + _tr_sdp_str.len;
1663
0
      searchLine = *(tp->v.s.s);
1664
0
      if(tp->next->type==TR_PARAM_NUMBER)
1665
0
        entryNo = tp->next->v.n;
1666
0
      else
1667
0
      {
1668
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->next->v.data, &v)!=0
1669
0
            || (!(v.flags&PV_VAL_INT)))
1670
0
        {
1671
0
          LM_ERR("cannot get parameter\n");
1672
0
          goto error;
1673
0
        }
1674
0
        entryNo = v.ri;
1675
0
      }
1676
0
      if (entryNo < 0)
1677
0
      {
1678
0
        LM_ERR("negative index provided for sdp.lineat\n");
1679
0
        goto error;
1680
0
      }
1681
1682
0
      answer = find_sdp_line(_tr_sdp_str.s, bodylimit, searchLine);
1683
0
      if (!answer) {
1684
0
        LM_DBG("No such line [%c=]\n", searchLine);
1685
0
        return pv_get_null(NULL, NULL, val);
1686
0
      }
1687
1688
0
      for (i=1;i<=entryNo;i++)
1689
0
      {
1690
0
        answer = find_next_sdp_line(answer,bodylimit,searchLine,bodylimit);
1691
0
        if (!answer || answer == bodylimit)
1692
0
        {
1693
0
          val->flags = PV_VAL_NULL;
1694
0
          LM_DBG("No such line [%c] nr %d in SDP body. Max fields = %d\n",
1695
0
              searchLine,entryNo,i);
1696
0
          return 0;
1697
0
        }
1698
0
      }
1699
1700
      /* find CR */
1701
0
      answerEnd = strchr(answer,13);
1702
0
      if (answerEnd == NULL)
1703
0
      {
1704
0
        LM_ERR("malformed SDP body\n");
1705
0
        goto error;
1706
0
      }
1707
1708
0
      val->flags = PV_VAL_STR;
1709
0
      val->rs.s = answer;
1710
0
      val->rs.len = answerEnd - answer;
1711
1712
0
      break;
1713
1714
0
    case TR_SDP_STREAM:
1715
0
    case TR_SDP_STREAM_DEL:
1716
      /* determine the media type we are talking about
1717
       * either by index or by name */
1718
0
      media = STR_NULL;
1719
0
      entryNo = 0;
1720
0
      switch (tp->type) {
1721
0
        case TR_PARAM_NUMBER:
1722
0
          entryNo = tp->v.n;
1723
0
          break;
1724
0
        case TR_PARAM_STRING:
1725
0
          media = tp->v.s;
1726
0
          break;
1727
0
        case TR_PARAM_SPEC:
1728
0
          media.s = NULL;
1729
0
          if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0)
1730
0
          {
1731
0
            LM_ERR("cannot get parameter\n");
1732
0
            goto error;
1733
0
          }
1734
0
          if (v.flags & PV_VAL_INT)
1735
0
            entryNo = v.ri;
1736
0
          else if (str2sint(&v.rs, &entryNo) < 0)
1737
0
            media = v.rs;
1738
          /* else entryNo has the media index */
1739
0
          break;
1740
0
      }
1741
1742
0
      memset(&sdp, 0, sizeof(sdp));
1743
0
      if (parse_sdp_session(&_tr_sdp_str, 0, NULL, &sdp) < 0)
1744
0
        goto error;
1745
1746
0
      if (media.s == NULL) {
1747
0
        if (entryNo < 0) {
1748
0
          if (entryNo + sdp.streams_num < 0)
1749
            /* out of bounds index */
1750
0
            goto parse_sdp_free;
1751
0
          entryNo += sdp.streams_num;
1752
0
        } else if (entryNo >= sdp.streams_num)
1753
0
          goto parse_sdp_free;
1754
0
        LM_DBG("stream index %d\n", entryNo);
1755
0
      } else
1756
0
        LM_DBG("stream type %.*s\n", media.len, media.s);
1757
0
      lenoff = 0;
1758
0
      if (subtype == TR_SDP_STREAM_DEL) {
1759
0
        for (session = sdp.sessions; session; session = session->next) {
1760
0
          for (stream = session->streams; stream; stream = stream->next) {
1761
0
            if ((media.s != NULL && stream->media.len == media.len &&
1762
                /* hack to update the offset */
1763
0
                strncasecmp(stream->media.s, media.s, media.len) == 0) ||
1764
0
              (media.s == NULL && entryNo == stream->stream_num)) {
1765
1766
0
              memmove(stream->body.s - lenoff, stream->body.s - lenoff + stream->body.len,
1767
0
                  _tr_sdp_str.s + _tr_sdp_str.len - stream->body.s);
1768
0
              _tr_sdp_str.len -= stream->body.len;
1769
1770
0
              if (media.s == NULL)
1771
0
                goto success;
1772
1773
0
              lenoff += stream->body.len;
1774
0
            }
1775
0
          }
1776
0
          if (media.s == NULL)
1777
0
            entryNo -= session->streams_num;
1778
0
        }
1779
0
      } else {
1780
0
        for (session = sdp.sessions; session; session = session->next) {
1781
0
          for (stream = session->streams; stream; stream = stream->next) {
1782
0
            if ((media.s != NULL && stream->media.len == media.len &&
1783
0
                strncasecmp(stream->media.s, media.s, media.len) == 0) ||
1784
0
              (media.s == NULL && entryNo == stream->stream_num)) {
1785
1786
0
              val->rs.len = stream->body.len;
1787
0
              val->rs.s = stream->body.s;
1788
0
              goto ret;
1789
0
            }
1790
0
          }
1791
0
        }
1792
0
      }
1793
0
      if (!lenoff) /* no stream found */
1794
0
        goto parse_sdp_free;
1795
0
success:
1796
0
      val->rs.len = _tr_sdp_str.len - 2;
1797
0
      val->rs.s = _tr_sdp_str.s + 2;
1798
0
ret:
1799
0
      val->flags = PV_VAL_STR;
1800
0
      free_sdp_content(&sdp);
1801
0
      break;
1802
0
    default:
1803
0
      LM_ERR("unknown subtype %d\n",subtype);
1804
0
      goto error;
1805
0
  }
1806
1807
0
  return 0;
1808
1809
0
parse_sdp_free:
1810
0
  free_sdp_content(&sdp);
1811
1812
0
error:
1813
0
  val->flags = PV_VAL_NULL;
1814
0
  return -1;
1815
0
}
1816
1817
int tr_eval_ip(struct sip_msg *msg, tr_param_t *tp,int subtype,
1818
    pv_value_t *val)
1819
0
{
1820
0
  char *buffer, *_tr_buffer = get_tr_buffer();
1821
0
  struct ip_addr *p_ip;
1822
0
  str inet = str_init("INET");
1823
0
  str inet6 = str_init("INET6");
1824
0
  struct hostent *server;
1825
0
  struct ip_addr ip;
1826
0
  unsigned int len, rc;
1827
0
  struct net *mask;
1828
0
  pv_value_t v;
1829
0
  str sv;
1830
0
  char *p;
1831
1832
0
  if (!val)
1833
0
    return -1;
1834
1835
0
  if (val->flags & PV_VAL_NULL)
1836
0
    return 0;
1837
1838
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
1839
0
    goto error;
1840
1841
0
  switch (subtype)
1842
0
  {
1843
0
    case TR_IP_FAMILY:
1844
0
      if (val->rs.len == 4)
1845
0
      {
1846
0
        memcpy(val->rs.s,inet.s,inet.len);
1847
0
        val->rs.len = inet.len;
1848
0
      }
1849
0
      else if (val->rs.len == 16)
1850
0
      {
1851
0
        memcpy(val->rs.s,inet6.s,inet6.len);
1852
0
        val->rs.len = inet6.len;
1853
0
      }
1854
0
      else
1855
0
      {
1856
0
        LM_ERR("Invalid ip address provided for ip.family. "
1857
0
          "Binary format expected !\n");
1858
0
        goto error;
1859
0
      }
1860
1861
0
      val->flags = PV_VAL_STR;
1862
0
      break;
1863
0
    case TR_IP_NTOP:
1864
0
      if (val->rs.len == 4)
1865
0
        ip.af = AF_INET;
1866
0
      else if (val->rs.len == 16)
1867
0
        ip.af = AF_INET6;
1868
0
      else
1869
0
      {
1870
0
        LM_ERR("Invalid ip address provided for ip.ntop. "
1871
0
          "Binary format expected !\n");
1872
0
        goto error;
1873
0
      }
1874
1875
0
      memcpy(ip.u.addr,val->rs.s,val->rs.len);
1876
0
      ip.len = val->rs.len;
1877
0
      buffer = ip_addr2a(&ip);
1878
1879
0
      val->rs.len = strlen(buffer);
1880
0
      memcpy(_tr_buffer, buffer, val->rs.len);
1881
0
      val->rs.s = _tr_buffer;
1882
1883
0
      val->flags = PV_VAL_STR;
1884
0
      break;
1885
0
    case TR_IP_ISIP:
1886
0
      if(!(val->flags&PV_VAL_STR))
1887
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1888
1889
0
      if ( str2ip(&(val->rs)) || str2ip6(&(val->rs)) )
1890
0
        val->ri = 1;
1891
0
      else
1892
0
        val->ri = 0;
1893
1894
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
1895
0
      val->rs.s = int2str(val->ri, &val->rs.len);
1896
0
      break;
1897
0
    case TR_IP_ISIP4:
1898
0
      if(!(val->flags&PV_VAL_STR))
1899
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1900
1901
0
      if (str2ip(&(val->rs)))
1902
0
        val->ri = 1;
1903
0
      else
1904
0
        val->ri = 0;
1905
1906
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
1907
0
      val->rs.s = int2str(val->ri, &val->rs.len);
1908
0
      break;
1909
0
    case TR_IP_ISIP6:
1910
0
      if(!(val->flags&PV_VAL_STR))
1911
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1912
1913
0
      if (str2ip6(&(val->rs)))
1914
0
        val->ri = 1;
1915
0
      else
1916
0
        val->ri = 0;
1917
1918
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
1919
0
      val->rs.s = int2str(val->ri, &val->rs.len);
1920
0
      break;
1921
0
    case TR_IP_PTON:
1922
0
      p_ip = str2ip(&(val->rs));
1923
0
      if (!p_ip)
1924
0
      {
1925
0
        p_ip = str2ip6(&(val->rs));
1926
0
        if (!p_ip)
1927
0
        {
1928
0
          LM_ERR("pton transformation applied to invalid IP\n");
1929
0
          goto error;
1930
0
        }
1931
0
      }
1932
1933
0
      memcpy(_tr_buffer, (char *)p_ip->u.addr, p_ip->len);
1934
0
      val->rs.s = _tr_buffer;
1935
0
      val->rs.len = p_ip->len;
1936
1937
0
      val->flags = PV_VAL_STR;
1938
0
      break;
1939
0
    case TR_IP_RESOLVE:
1940
0
      val->flags = PV_VAL_STR;
1941
0
      if (val->rs.len + 1 > TR_BUFFER_SIZE) {
1942
0
        LM_ERR("failed to resolve host, length too large (%d)\n",
1943
0
               val->rs.len);
1944
0
        goto error;
1945
0
      }
1946
0
      memcpy(_tr_buffer, val->rs.s, val->rs.len);
1947
0
      _tr_buffer[val->rs.len] = '\0';
1948
1949
0
      server = resolvehost(_tr_buffer, 0);
1950
0
      if (!server || !server->h_addr)
1951
0
      {
1952
0
        val->flags = PV_VAL_NULL;
1953
0
        return 0;
1954
0
      }
1955
1956
0
      if (server->h_addrtype == AF_INET)
1957
0
      {
1958
0
        memcpy(ip.u.addr,server->h_addr,4);
1959
0
        ip.len = 4;
1960
0
        ip.af = AF_INET;
1961
0
      }
1962
0
      else if (server->h_addrtype == AF_INET6)
1963
0
      {
1964
0
        memcpy(ip.u.addr,server->h_addr,16);
1965
0
        ip.len = 16;
1966
0
        ip.af = AF_INET6;
1967
0
      }
1968
0
      else
1969
0
      {
1970
0
        LM_ERR("Unexpected IP address type \n");
1971
0
        goto error;
1972
0
      }
1973
1974
0
      buffer = ip_addr2a(&ip);
1975
1976
0
      val->rs.len = strlen(buffer);
1977
0
      memcpy(_tr_buffer, buffer, val->rs.len);
1978
0
      val->rs.s = _tr_buffer;
1979
1980
0
      break;
1981
0
    case TR_IP_MATCHES:
1982
      /* get the input which must be an IP addr as string */
1983
0
      if ( (p_ip=str2ip(&val->rs))==NULL &&
1984
0
      (p_ip=str2ip6(&val->rs))==NULL ) {
1985
0
        LM_ERR("Invalid input IP address <%.*s>\n",
1986
0
          val->rs.len,val->rs.s);
1987
0
        goto error;
1988
0
      }
1989
0
      ip = *p_ip;
1990
      /* get the parameter which must be IP/netlen */
1991
0
      if (tp->type == TR_PARAM_STRING) {
1992
0
        sv = tp->v.s;
1993
0
      } else {
1994
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1995
0
            || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0) {
1996
0
          LM_ERR("cannot get value from spec\n");
1997
0
          goto error;
1998
0
        }
1999
0
        sv = v.rs;
2000
0
      }
2001
      /* the value must be in "ip/marsklen" format */
2002
0
      if ( (p=q_memchr(sv.s, '/', sv.len))==NULL) {
2003
0
        LM_ERR("value not in ip/len format, separator not found\n");
2004
0
        goto error;
2005
0
      }
2006
0
      val->rs.s = sv.s;
2007
0
      val->rs.len = p-sv.s;
2008
0
      if ( (p_ip=str2ip(&val->rs))==NULL &&
2009
0
      (p_ip=str2ip6(&val->rs))==NULL ) {
2010
0
        LM_ERR("Invalid parameter IP address <%.*s>\n",
2011
0
          val->rs.len,val->rs.s);
2012
0
        goto error;
2013
0
      }
2014
0
      val->rs.s = p+1;
2015
0
      val->rs.len = sv.s+sv.len-p-1;
2016
0
      if (str2int(&val->rs, &len)!=0 || len>p_ip->len*8) {
2017
0
        LM_ERR("Invalid mask len in parameter <%.*s>\n",
2018
0
          val->rs.len,val->rs.s);
2019
0
        goto error;
2020
0
      }
2021
2022
0
      mask = mk_net_bitlen(p_ip, len);
2023
0
      rc = matchnet(&ip, mask);
2024
0
      pkg_free(mask);
2025
2026
0
      switch (rc) {
2027
0
        case 1: /* matches */
2028
0
          val->ri = 1; break;
2029
0
        case 0: /* does not matches */
2030
0
          val->ri = 0; break;
2031
0
        default:
2032
0
          LM_ERR("cannot compare, different AF?\n");
2033
0
          goto error;
2034
0
      }
2035
2036
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
2037
0
      val->rs.s = int2str(val->ri, &val->rs.len);
2038
0
      break;
2039
0
    case TR_IP_ISPRIVATE:
2040
0
      if(!(val->flags&PV_VAL_STR))
2041
0
        val->rs.s = int2str(val->ri, &val->rs.len);
2042
2043
0
      val->ri = ip_addr_is_1918(&(val->rs), 0);
2044
2045
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
2046
0
      val->rs.s = int2str(val->ri, &val->rs.len);
2047
0
      break;
2048
2049
0
    default:
2050
0
      LM_ERR("unknown subtype %d\n",subtype);
2051
0
      goto error;
2052
0
  }
2053
2054
0
  return 0;
2055
0
error:
2056
0
  val->flags = PV_VAL_NULL;
2057
0
  return -1;
2058
0
}
2059
2060
static char *reg_input_buf = NULL;
2061
static struct subst_expr *subst_re = NULL;
2062
static str buf_re = { 0, 0 };
2063
int tr_eval_re(struct sip_msg *msg, tr_param_t *tp, int subtype,
2064
    pv_value_t *val)
2065
0
{
2066
0
  int match_no=0;
2067
0
  pv_value_t v;
2068
0
  str *result;
2069
0
  str sv;
2070
0
  char *s, *e, *p;
2071
0
  char *buf;
2072
2073
0
  if (!val)
2074
0
    return -1;
2075
2076
0
  if (val->flags & PV_VAL_NULL)
2077
0
    return 0;
2078
2079
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
2080
0
    goto error;
2081
2082
0
  switch (subtype) {
2083
0
    case TR_RE_SUBST:
2084
0
        if (tp->type == TR_PARAM_STRING) {
2085
0
          sv = tp->v.s;
2086
0
        } else {
2087
0
          if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2088
0
              || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0) {
2089
0
            LM_ERR("cannot get value from spec\n");
2090
0
            goto error;
2091
0
          }
2092
0
          sv = v.rs;
2093
0
        }
2094
        /* temporary use the regex input buffer to check the subst */
2095
0
        buf = pkg_realloc(reg_input_buf, sv.len);
2096
0
        if (!buf) {
2097
0
          LM_ERR("not enough memory for regex buffer %d [%.*s]\n",
2098
0
              sv.len, sv.len, sv.s);
2099
0
          goto error;
2100
0
        }
2101
0
        reg_input_buf = buf;
2102
        /* copy un-escaped str to buf */
2103
0
        for (s = sv.s, e = sv.s + sv.len, p = buf; s < e; s++, p++) {
2104
0
          if (*s=='\\') {
2105
0
            if (s + 1 >= e)
2106
0
              break;
2107
0
            if (*(s + 1) == TR_RBRACKET || *(s + 1) == TR_LBRACKET) {
2108
0
              s++;
2109
0
              sv.len--;
2110
0
            }
2111
0
          }
2112
0
          *p = *s;
2113
0
        }
2114
0
        sv.s = buf;
2115
2116
0
        LM_DBG("Trying to apply regexp [%.*s] on : [%.*s]\n",
2117
0
            sv.len,sv.s,val->rs.len, val->rs.s);
2118
0
        if (subst_re==NULL || !buf_re.s || buf_re.len != sv.len ||
2119
0
        memcmp(buf_re.s, sv.s, sv.len) != 0) {
2120
0
          LM_DBG("we must compile the regexp\n");
2121
0
          if (subst_re != NULL) {
2122
0
            LM_DBG("freeing prev regexp\n");
2123
0
            subst_expr_free(subst_re);
2124
0
          }
2125
0
          subst_re=subst_parser(&sv);
2126
0
          if (subst_re==0) {
2127
0
            LM_ERR("Can't compile regexp\n");
2128
0
            goto error;
2129
0
          }
2130
          /* swap buffers */
2131
0
          reg_input_buf = buf_re.s;
2132
0
          buf_re.s = buf;
2133
0
          buf_re.len = sv.len;
2134
0
        } else
2135
0
          LM_DBG("yay, we can use the pre-compile regexp\n");
2136
2137
0
        buf = pkg_realloc(reg_input_buf, val->rs.len + 1);
2138
0
        if (!buf) {
2139
0
          LM_ERR("not enough memory for input buffer %d [%.*s]\n",
2140
0
              val->rs.len + 1, val->rs.len, val->rs.s);
2141
0
          goto error;
2142
0
        }
2143
0
        reg_input_buf = buf;
2144
0
        memcpy(reg_input_buf,val->rs.s,val->rs.len);
2145
0
        reg_input_buf[val->rs.len]=0;
2146
2147
0
        result=subst_str(reg_input_buf, msg, subst_re, &match_no);
2148
0
        if (result == NULL) {
2149
0
          if (match_no == 0) {
2150
0
            LM_DBG("no match for subst expression\n");
2151
0
            break;
2152
0
          } else if (match_no < 0) {
2153
0
            LM_ERR("subst failed\n");
2154
0
            goto error;
2155
0
          }
2156
0
        }
2157
        /* release the input buffer */
2158
0
        pkg_free(reg_input_buf);
2159
0
        reg_input_buf = result->s;
2160
0
        val->flags = PV_VAL_STR;
2161
0
        val->rs.s = result->s;
2162
0
        val->rs.len = result->len;
2163
0
        pkg_free(result);
2164
0
        return 0;
2165
0
    default:
2166
0
      LM_ERR("Unexpected subtype for RE : %d\n",subtype);
2167
0
      goto error;
2168
0
  }
2169
0
  return 0;
2170
2171
0
error:
2172
0
  val->flags = PV_VAL_NULL;
2173
0
  return -1;
2174
0
}
2175
2176
static str _tr_params_str = {0, 0};
2177
static param_t* _tr_params_list = NULL;
2178
2179
int tr_eval_paramlist(struct sip_msg *msg, tr_param_t *tp, int subtype,
2180
    pv_value_t *val)
2181
0
{
2182
0
  pv_value_t v;
2183
0
  str sv;
2184
0
  int n, i;
2185
0
  param_hooks_t phooks;
2186
0
  param_t *pit=NULL;
2187
2188
0
  if (!val)
2189
0
    return -1;
2190
2191
0
  if (val->flags & PV_VAL_NULL)
2192
0
    return 0;
2193
2194
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
2195
0
    goto error;
2196
2197
0
  if(_tr_params_str.len==0 || _tr_params_str.len!=val->rs.len ||
2198
0
      strncmp(_tr_params_str.s, val->rs.s, val->rs.len)!=0)
2199
0
  {
2200
2201
0
    if(val->rs.len>_tr_params_str.len)
2202
0
    {
2203
0
      if(_tr_params_str.s) pkg_free(_tr_params_str.s);
2204
0
      _tr_params_str.s = (char*)pkg_malloc((val->rs.len+1)*sizeof(char));
2205
0
      if(_tr_params_str.s==NULL)
2206
0
      {
2207
0
        LM_ERR("no more private memory\n");
2208
0
        memset(&_tr_params_str, 0, sizeof(str));
2209
0
        if(_tr_params_list != NULL)
2210
0
        {
2211
0
          free_params(_tr_params_list);
2212
0
          _tr_params_list = 0;
2213
0
        }
2214
0
        goto error;
2215
0
      }
2216
0
    }
2217
0
    _tr_params_str.len = val->rs.len;
2218
0
    memcpy(_tr_params_str.s, val->rs.s, val->rs.len);
2219
0
    _tr_params_str.s[_tr_params_str.len] = '\0';
2220
2221
    /* reset old values */
2222
0
    if(_tr_params_list != NULL)
2223
0
    {
2224
0
      free_params(_tr_params_list);
2225
0
      _tr_params_list = 0;
2226
0
    }
2227
2228
    /* parse params */
2229
0
    sv = _tr_params_str;
2230
0
    if (parse_params(&sv, CLASS_ANY, &phooks, &_tr_params_list)<0)
2231
0
      goto error;
2232
2233
0
  }
2234
2235
0
  if(_tr_params_list==NULL)
2236
0
    goto error;
2237
2238
0
  memset(val, 0, sizeof(pv_value_t));
2239
0
  val->flags = PV_VAL_STR;
2240
2241
0
  switch(subtype)
2242
0
  {
2243
0
    case TR_PL_VALUE:
2244
0
      if(tp==NULL)
2245
0
      {
2246
0
        LM_ERR("value invalid parameters\n");
2247
0
        goto error;
2248
0
      }
2249
2250
0
      if(tp->type==TR_PARAM_STRING)
2251
0
      {
2252
0
        sv = tp->v.s;
2253
0
      } else {
2254
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2255
0
            || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
2256
0
        {
2257
0
          LM_ERR("value cannot get p1\n");
2258
0
          goto error;
2259
0
        }
2260
0
        sv = v.rs;
2261
0
      }
2262
2263
0
      for (pit = _tr_params_list; pit; pit=pit->next)
2264
0
      {
2265
0
        if (pit->name.len==sv.len
2266
0
            && strncasecmp(pit->name.s, sv.s, sv.len)==0)
2267
0
        {
2268
0
          if (ZSTR(pit->body))
2269
0
            val->rs = STR_EMPTY;
2270
0
          else
2271
0
            val->rs = pit->body;
2272
0
          goto done;
2273
0
        }
2274
0
      }
2275
0
      val->flags = PV_VAL_NULL;
2276
0
      break;
2277
2278
0
    case TR_PL_VALUEAT:
2279
0
      if(tp==NULL)
2280
0
      {
2281
0
        LM_ERR("name invalid parameters\n");
2282
0
        goto error;
2283
0
      }
2284
2285
0
      if(tp->type==TR_PARAM_NUMBER)
2286
0
      {
2287
0
        n = tp->v.n;
2288
0
      } else {
2289
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2290
0
            || (!(v.flags&PV_VAL_INT)))
2291
0
        {
2292
0
          LM_ERR("name cannot get p1\n");
2293
0
          goto error;
2294
0
        }
2295
0
        n = v.ri;
2296
0
      }
2297
0
      if(n>=0)
2298
0
      {
2299
0
        for (pit = _tr_params_list; pit; pit=pit->next)
2300
0
        {
2301
0
          if(n==0)
2302
0
          {
2303
0
            val->rs = pit->body;
2304
0
            goto done;
2305
0
          }
2306
0
          n--;
2307
0
        }
2308
0
      } else {
2309
        /* ugly hack -- params are in reverse order
2310
         * - first count then find */
2311
0
        n = -n;
2312
0
        n--;
2313
2314
0
        i = 0;
2315
0
        for (pit = _tr_params_list; pit; pit=pit->next)
2316
0
          i++;
2317
0
        if(n<i)
2318
0
        {
2319
0
          n = i - n - 1;
2320
0
          for (pit = _tr_params_list; pit; pit=pit->next)
2321
0
          {
2322
0
            if(n==0)
2323
0
            {
2324
0
              val->rs = pit->body;
2325
0
              goto done;
2326
0
            }
2327
0
            n--;
2328
0
          }
2329
0
        }
2330
0
      }
2331
0
      val->flags = PV_VAL_NULL;
2332
0
      break;
2333
2334
0
    case TR_PL_NAME:
2335
0
      if(tp==NULL)
2336
0
      {
2337
0
        LM_ERR("name invalid parameters\n");
2338
0
        goto error;
2339
0
      }
2340
2341
0
      if(tp->type==TR_PARAM_NUMBER)
2342
0
      {
2343
0
        n = tp->v.n;
2344
0
      } else {
2345
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2346
0
            || (!(v.flags&PV_VAL_INT)))
2347
0
        {
2348
0
          LM_ERR("name cannot get p1\n");
2349
0
          goto error;
2350
0
        }
2351
0
        n = v.ri;
2352
0
      }
2353
0
      if(n>=0)
2354
0
      {
2355
0
        for (pit = _tr_params_list; pit; pit=pit->next)
2356
0
        {
2357
0
          if(n==0)
2358
0
          {
2359
0
            val->rs = pit->name;
2360
0
            goto done;
2361
0
          }
2362
0
          n--;
2363
0
        }
2364
0
      } else {
2365
        /* ugly hack -- params are in sorted order
2366
         * - first count then find */
2367
0
        n = -n;
2368
0
        n--;
2369
2370
0
        i = 0;
2371
0
        for (pit = _tr_params_list; pit; pit=pit->next)
2372
0
          i++;
2373
0
        if(n<i)
2374
0
        {
2375
0
          n = i - n - 1;
2376
0
          for (pit = _tr_params_list; pit; pit=pit->next)
2377
0
          {
2378
0
            if(n==0)
2379
0
            {
2380
0
              val->rs = pit->name;
2381
0
              goto done;
2382
0
            }
2383
0
            n--;
2384
0
          }
2385
0
        }
2386
0
      }
2387
0
      val->flags = PV_VAL_NULL;
2388
0
      break;
2389
2390
0
    case TR_PL_COUNT:
2391
0
      val->ri = 0;
2392
0
      for (pit = _tr_params_list; pit; pit=pit->next) {
2393
0
        val->ri++;
2394
0
      }
2395
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
2396
0
      val->rs.s = int2str(val->ri, &val->rs.len);
2397
0
      break;
2398
2399
2400
0
    case TR_PL_EXIST:
2401
0
      if(tp==NULL)
2402
0
      {
2403
0
        LM_ERR("value invalid parameters\n");
2404
0
        goto error;
2405
0
      }
2406
2407
0
      if(tp->type==TR_PARAM_STRING)
2408
0
      {
2409
0
        sv = tp->v.s;
2410
0
      } else {
2411
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2412
0
            || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
2413
0
        {
2414
0
          LM_ERR("value cannot get p1\n");
2415
0
          goto error;
2416
0
        }
2417
0
        sv = v.rs;
2418
0
      }
2419
2420
0
      val->ri = 0;
2421
0
      for (pit = _tr_params_list; pit; pit=pit->next)
2422
0
      {
2423
0
        if (pit->name.len==sv.len
2424
0
            && strncasecmp(pit->name.s, sv.s, sv.len)==0)
2425
0
        {
2426
0
          val->ri = 1;
2427
0
          break;
2428
0
        }
2429
0
      }
2430
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
2431
0
      val->rs.s = int2str(val->ri, &val->rs.len);
2432
0
      goto done;
2433
2434
0
    default:
2435
0
      LM_ERR("unknown subtype %d\n",
2436
0
          subtype);
2437
0
      goto error;
2438
0
  }
2439
2440
0
done:
2441
0
  return 0;
2442
0
error:
2443
0
  val->flags = PV_VAL_NULL;
2444
0
  return -1;
2445
0
}
2446
2447
static str nameaddr_str = {0, 0};
2448
static struct to_body *nameaddr_to_body = NULL;
2449
2450
int tr_eval_nameaddr(struct sip_msg *msg, tr_param_t *tp, int subtype,
2451
    pv_value_t *val)
2452
0
{
2453
0
  struct to_param* topar;
2454
0
  pv_value_t v;
2455
0
  int index, total;
2456
0
  struct to_body *nameaddr = NULL;
2457
2458
0
  if (!val)
2459
0
    return -1;
2460
2461
0
  if (val->flags & PV_VAL_NULL)
2462
0
    return 0;
2463
2464
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
2465
0
    goto error;
2466
2467
0
  LM_DBG("String to transform %.*s\n", val->rs.len, val->rs.s);
2468
2469
0
  if(nameaddr_str.len==0 || nameaddr_str.len!=val->rs.len ||
2470
0
      strncmp(nameaddr_str.s, val->rs.s, val->rs.len)!=0)
2471
0
  {
2472
    /* copy the value in the global variable */
2473
0
    if(val->rs.len+CRLF_LEN > nameaddr_str.len)
2474
0
    {
2475
0
      if(nameaddr_str.s) pkg_free(nameaddr_str.s);
2476
0
      nameaddr_str.s =
2477
0
          (char*)pkg_malloc((val->rs.len+CRLF_LEN+1)*sizeof(char));
2478
0
      if(nameaddr_str.s==NULL)
2479
0
      {
2480
0
        LM_ERR("no more private memory\n");
2481
0
        memset(&nameaddr_str, 0, sizeof(str));
2482
0
        goto error;
2483
0
      }
2484
0
    }
2485
0
    nameaddr_str.len = val->rs.len + CRLF_LEN;
2486
0
    memcpy(nameaddr_str.s, val->rs.s, val->rs.len);
2487
0
    memcpy(nameaddr_str.s + val->rs.len, CRLF, CRLF_LEN);
2488
0
    nameaddr_str.s[nameaddr_str.len] = '\0';
2489
2490
    /* reset old values */
2491
0
    if (nameaddr_to_body) {
2492
0
      free_to(nameaddr_to_body);
2493
0
      nameaddr_to_body = NULL;
2494
0
    }
2495
2496
    /* parse TO hdr + params */
2497
0
    nameaddr_to_body = (struct to_body*)pkg_malloc(sizeof(struct to_body));
2498
0
    if(nameaddr_to_body==NULL)
2499
0
    {
2500
0
      LM_ERR("no more private memory\n");
2501
      /* keep the buffer, but flush the content to force the realloc
2502
         next time */
2503
0
      nameaddr_str.s[0] = 0;
2504
0
      goto error;
2505
0
    }
2506
0
    parse_multi_to(nameaddr_str.s, nameaddr_str.s + nameaddr_str.len,
2507
0
      nameaddr_to_body);
2508
0
  }
2509
2510
0
  if (nameaddr_to_body->error == PARSE_ERROR)
2511
0
  {
2512
0
    LM_ERR("Wrong syntax. It must have the To header format\n");
2513
0
    goto error;
2514
0
  }
2515
2516
  /* check if there is an index set */
2517
0
  if (tp && (subtype != TR_NA_PARAM || tp->next)) {
2518
    /* we do have an index */
2519
0
    switch (tp->type) {
2520
0
      case TR_PARAM_NUMBER:
2521
0
        index = tp->v.n;
2522
0
        break;
2523
0
      case TR_PARAM_SPEC:
2524
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2525
0
            || (!(v.flags&PV_VAL_INT)))
2526
0
        {
2527
0
          LM_ERR("invalid index type: %d; integer expected\n",
2528
0
              v.flags);
2529
0
          goto error;
2530
0
        }
2531
0
        index = v.ri;
2532
0
        break;
2533
0
      default:
2534
0
        LM_ERR("unsupported index type: %d\n", tp->type);
2535
0
        goto error;
2536
0
    }
2537
0
    tp = tp->next;
2538
0
    if (index < 0) {
2539
0
      total = 0;
2540
0
      for (nameaddr = nameaddr_to_body; nameaddr; nameaddr = nameaddr->next)
2541
0
        total++;
2542
0
      if (index + total < 0) {
2543
0
        LM_DBG("index %d out of bounds %d\n", index, total);
2544
0
        goto out_of_bounds;
2545
0
      }
2546
0
      index = total + index;
2547
0
    }
2548
0
    for (nameaddr = nameaddr_to_body;
2549
0
        nameaddr && index != 0;
2550
0
        nameaddr = nameaddr->next, index--);
2551
0
    if (index > 0 || !nameaddr) {
2552
0
      LM_DBG("index out of bounds\n");
2553
0
      goto out_of_bounds;
2554
0
    }
2555
2556
0
  } else {
2557
    /* otherwise we default to first body */
2558
0
    nameaddr = nameaddr_to_body;
2559
0
  }
2560
2561
0
  memset(val, 0, sizeof(pv_value_t));
2562
0
  val->flags = PV_VAL_STR;
2563
2564
0
  switch(subtype)
2565
0
  {
2566
0
    case TR_NA_URI:
2567
0
      val->rs =(nameaddr->uri.s)?nameaddr->uri:_tr_empty;
2568
0
      val->flags |= (val->rs.len) ? 0 : PV_VAL_NULL;
2569
0
      break;
2570
0
    case TR_NA_LEN:
2571
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
2572
0
      val->ri = nameaddr->body.len;
2573
0
      val->rs.s = int2str(val->ri, &val->rs.len);
2574
0
      break;
2575
0
    case TR_NA_NAME:
2576
0
      val->rs = (nameaddr->display.s)?
2577
0
        nameaddr->display:_tr_empty;
2578
0
      val->flags |= (val->rs.len) ? 0 : PV_VAL_NULL;
2579
0
      break;
2580
0
    case TR_NA_PARAM:
2581
0
      if(tp->type != TR_PARAM_STRING)
2582
0
      {
2583
0
        LM_ERR("Wrong type for parameter, it must string\n");
2584
0
        goto error;
2585
0
      }
2586
0
      topar = nameaddr->param_lst;
2587
      /* search the parameter */
2588
0
      while(topar)
2589
0
      {
2590
0
        if(topar->name.len == tp->v.s.len &&
2591
0
            strncmp(topar->name.s, tp->v.s.s, topar->name.len)== 0)
2592
0
          break;
2593
0
        topar = topar->next;
2594
0
      }
2595
0
      val->rs = (topar)?topar->value:_tr_empty;
2596
0
      val->flags |= (val->rs.len) ? 0 : PV_VAL_NULL;
2597
0
      break;
2598
0
    case TR_NA_PARAMS:
2599
0
      topar = nameaddr->param_lst;
2600
0
      if (!topar) {
2601
0
        LM_DBG("no params\n");
2602
0
        val->flags = PV_VAL_NULL;
2603
0
      }
2604
0
      else {
2605
0
        LM_DBG("We have params\n");
2606
0
        val->rs.s = topar->name.s;
2607
0
        if (nameaddr->last_param->value.s==NULL) {
2608
0
          val->rs.len = nameaddr->last_param->name.s +
2609
0
            nameaddr->last_param->name.len - val->rs.s;
2610
0
        } else {
2611
0
          val->rs.len = nameaddr->last_param->value.s +
2612
0
            nameaddr->last_param->value.len - val->rs.s;
2613
          /* compensate the len if the value of the last param is
2614
           * a quoted value (include the closing quote in the len) */
2615
0
          if ( (val->rs.s+val->rs.len<nameaddr_str.len+nameaddr_str.s) &&
2616
0
          (val->rs.s[val->rs.len]=='"' || val->rs.s[val->rs.len]=='\'' ) )
2617
0
            val->rs.len++;
2618
0
        }
2619
0
      }
2620
0
      break;
2621
2622
0
    default:
2623
0
      LM_ERR("unknown subtype %d\n", subtype);
2624
0
      goto error;
2625
0
  }
2626
2627
0
  return 0;
2628
2629
0
error:
2630
0
  val->flags = PV_VAL_NULL;
2631
0
  return -1;
2632
0
out_of_bounds:
2633
0
  val->flags = PV_VAL_NULL;
2634
0
  return 0;
2635
0
}
2636
2637
2638
0
#define is_in_str(p, in) (p<in->s+in->len && *p)
2639
2640
char* parse_transformation(str *in, trans_t **tr)
2641
0
{
2642
0
  char *p;
2643
0
  str tclass;
2644
0
  trans_t *t = NULL;
2645
0
  trans_t *t0 = NULL;
2646
0
  str s;
2647
0
  const trans_export_t *tr_export;
2648
0
  trans_extra_t *tr_extra;
2649
0
  int i, nesting_level = 0;
2650
2651
0
  if(in==NULL || in->s==NULL || tr==NULL)
2652
0
    return NULL;
2653
2654
0
  p = in->s;
2655
0
  do {
2656
0
    while(is_in_str(p, in) && is_ws(*p)) p++;
2657
0
    if(*p != TR_LBRACKET)
2658
0
      break;
2659
0
    p++;
2660
2661
0
    t = (trans_t*)pkg_malloc(sizeof(trans_t));
2662
0
    if(t == NULL)
2663
0
    {
2664
0
      LM_ERR("no more private memory\n");
2665
0
      return NULL;
2666
0
    }
2667
0
    memset(t, 0, sizeof(trans_t));
2668
0
    if(t0==NULL)
2669
0
      *tr = t;
2670
0
    else
2671
0
      t0->next = t;
2672
0
    t0 = t;
2673
2674
    /* find transformation class */
2675
0
    tclass.s = p;
2676
0
    while(is_in_str(p, in) && *p!=TR_CLASS_MARKER) p++;
2677
0
    if(*p!=TR_CLASS_MARKER || tclass.s == p)
2678
0
    {
2679
0
      LM_ERR("invalid transformation: %.*s (%c)!\n", in->len, in->s, *p);
2680
0
      goto error;
2681
0
    }
2682
0
    tclass.len = p - tclass.s;
2683
0
    p++;
2684
2685
0
    tr_export = NULL;
2686
2687
    /* search through core transformations */
2688
0
    for (i = 0; core_trans[i].name.s; i++)
2689
0
      if (core_trans[i].name.len == tclass.len &&
2690
0
        !strncasecmp(core_trans[i].name.s, tclass.s, tclass.len)) {
2691
0
        tr_export = &core_trans[i];
2692
0
        break;
2693
0
      }
2694
2695
0
    if (!tr_export)
2696
      /* search through module exported transformations */
2697
0
      for (tr_extra = tr_extra_list; tr_extra; tr_extra = tr_extra->next)
2698
0
        if (tr_extra->tre.name.len == tclass.len &&
2699
0
          !strncasecmp(tr_extra->tre.name.s, tclass.s, tclass.len)) {
2700
0
          tr_export = &tr_extra->tre;
2701
0
          break;
2702
0
        }
2703
2704
0
    if (!tr_export) {
2705
0
      LM_ERR("unknown transformation: [%.*s] in [%.*s]\n",
2706
0
        tclass.len, tclass.s, in->len, in->s);
2707
0
      goto error;
2708
0
    }
2709
2710
0
    t->trf = tr_export->eval_func;
2711
2712
0
    s.s = p;
2713
    /* allow nested transformations! */
2714
0
    while(is_in_str(p, in) && (nesting_level > 0 || *p != TR_RBRACKET)) {
2715
0
      if (*p == TR_LBRACKET)
2716
0
        nesting_level++;
2717
2718
0
      if (*p == TR_RBRACKET)
2719
0
        nesting_level--;
2720
0
      p++;
2721
0
    }
2722
2723
0
    if(*p == '\0') {
2724
0
      LM_ERR("invalid transformation: %.*s\n", in->len, in->s);
2725
0
      goto error;
2726
0
    }
2727
0
    s.len = p - s.s;
2728
2729
0
    if (tr_export->parse_func(&s, t) < 0)
2730
0
      goto error;
2731
2732
0
    p++;
2733
0
    if(!is_in_str(p, in))
2734
0
      break;
2735
0
  } while(1);
2736
2737
0
  return p;
2738
0
error:
2739
0
  LM_ERR("error parsing [%.*s]\n", in->len, in->s);
2740
0
  t = *tr;
2741
0
  while(t)
2742
0
  {
2743
0
    t0 = t;
2744
0
    t = t->next;
2745
0
    free_tr_param(t0->params);
2746
0
    pkg_free(t0);
2747
0
  }
2748
0
  return NULL;
2749
0
}
2750
2751
char *tr_parse_nparam(char *p, str *in, tr_param_t **tp)
2752
0
{
2753
0
  char *p0;
2754
0
  pv_spec_t *spec = NULL;
2755
0
  int n, sign;
2756
0
  str s;
2757
2758
0
  while (is_in_str(p, in) && is_ws(*p)) p++;
2759
2760
0
  if(*p == PV_MARKER) { /* pseudo-variable */
2761
0
    spec = pkg_malloc(sizeof(pv_spec_t));
2762
0
    if (spec == NULL) {
2763
0
      LM_ERR("no more private memory!\n");
2764
0
      goto error;
2765
0
    }
2766
0
    s.s = p;
2767
0
    s.len = in->s + in->len - p;
2768
0
    p0 = pv_parse_spec(&s, spec);
2769
0
    if(p0 == NULL) {
2770
0
      LM_ERR("invalid spec in substr transformation: %.*s!\n",
2771
0
        in->len, in->s);
2772
0
      goto error;
2773
0
    }
2774
0
    p = p0;
2775
0
    *tp = pkg_malloc(sizeof(tr_param_t));
2776
0
    if(*tp == NULL) {
2777
0
      LM_ERR("no more private memory!\n");
2778
0
      goto error;
2779
0
    }
2780
0
    memset(*tp, 0, sizeof(tr_param_t));
2781
0
    (*tp)->type = TR_PARAM_SPEC;
2782
0
    (*tp)->v.data = (void*)spec;
2783
2784
0
    return p;
2785
0
  } else {
2786
0
    if (*p == '+' || *p == '-' || (*p >= '0' && *p <= '9')) { /* number */
2787
0
      sign = 1;
2788
0
      if (*p == '-') {
2789
0
        p++;
2790
0
        sign = -1;
2791
0
      } else if (*p == '+') p++;
2792
0
      n = 0;
2793
0
      while (is_in_str(p, in) && is_ws(*p))
2794
0
        p++;
2795
0
      while (is_in_str(p, in) && *p >= '0' && *p <= '9') {
2796
0
        n = n*10 + *p - '0';
2797
0
        p++;
2798
0
      }
2799
0
      *tp = pkg_malloc(sizeof(tr_param_t));
2800
0
      if (*tp == NULL) {
2801
0
        LM_ERR("no more private memory!\n");
2802
0
        goto error;
2803
0
      }
2804
0
      memset(*tp, 0, sizeof(tr_param_t));
2805
0
      (*tp)->type = TR_PARAM_NUMBER;
2806
0
      (*tp)->v.n = sign*n;
2807
0
    } else {
2808
0
      LM_ERR("invalid param in transformation: %.*s!!\n",
2809
0
        in->len, in->s);
2810
0
      goto error;
2811
0
    }
2812
2813
0
    return p;
2814
0
  }
2815
2816
0
error:
2817
0
  if (spec)
2818
0
    pv_spec_free(spec);
2819
0
  return NULL;
2820
0
}
2821
2822
/*
2823
 * Not all transformation string parameters have the same meaning
2824
 * Some of them are SIP headers, thus they cannot contain whitespace,
2825
 * while others may just be strings with no additional restrictions.
2826
 * Set "skip_param_ws" to 1 if your param may contain inside whitespace
2827
 *    -> e.g. ' ', "foo bar", "foob\tar" ...
2828
 */
2829
2830
char *tr_parse_sparam(char *p, str *in, tr_param_t **tp, int skip_param_ws)
2831
0
{
2832
0
  char *p0, *ps;
2833
0
  pv_spec_t *spec = NULL;
2834
0
  str s;
2835
2836
0
  while (is_in_str(p, in) && is_ws(*p)) p++;
2837
2838
0
  if (*p == PV_MARKER) { /* pseudo-variable */
2839
0
    spec = pkg_malloc(sizeof(pv_spec_t));
2840
0
    if (spec == NULL) {
2841
0
      LM_ERR("no more private memory!\n");
2842
0
      goto error;
2843
0
    }
2844
0
    s.s = p;
2845
0
    s.len = in->s + in->len - p;
2846
0
    p0 = pv_parse_spec(&s, spec);
2847
0
    if (p0 == NULL) {
2848
0
      LM_ERR("invalid spec in substr transformation: %.*s!\n",
2849
0
        in->len, in->s);
2850
0
      goto error;
2851
0
    }
2852
0
    p = p0;
2853
0
    *tp = pkg_malloc(sizeof(tr_param_t));
2854
0
    if (*tp == NULL) {
2855
0
      LM_ERR("no more private memory!\n");
2856
0
      goto error;
2857
0
    }
2858
0
    memset(*tp, 0, sizeof(tr_param_t));
2859
0
    (*tp)->type = TR_PARAM_SPEC;
2860
0
    (*tp)->v.data = (void*)spec;
2861
2862
0
    return p;
2863
0
  } else { /* string */
2864
0
    ps = p;
2865
0
    while (is_in_str(p, in) && (skip_param_ws || !is_ws(*p))) {
2866
0
      if ((*p == TR_PARAM_MARKER || *p == TR_RBRACKET) &&
2867
0
          (p - 1 < ps || *(p - 1) != '\\'))
2868
0
        break;
2869
0
      p++;
2870
0
    }
2871
2872
0
    if (*p == '\0') {
2873
0
      LM_ERR("invalid param in transformation: %.*s!!\n",
2874
0
        in->len, in->s);
2875
0
      goto error;
2876
0
    }
2877
0
    *tp = pkg_malloc(sizeof(tr_param_t));
2878
0
    if (*tp == NULL) {
2879
0
      LM_ERR("no more private memory!\n");
2880
0
      goto error;
2881
0
    }
2882
0
    memset(*tp, 0, sizeof(tr_param_t));
2883
0
    (*tp)->type = TR_PARAM_STRING;
2884
0
    (*tp)->v.s.s = ps;
2885
0
    (*tp)->v.s.len = p - ps;
2886
2887
0
    return p;
2888
0
  }
2889
2890
0
error:
2891
0
  if (spec)
2892
0
    pv_spec_free(spec);
2893
0
  return NULL;
2894
0
}
2895
2896
int tr_parse_string(str* in, trans_t *t)
2897
0
{
2898
0
  char *p, *cp;
2899
0
  str name;
2900
0
  tr_param_t *tp = NULL;
2901
2902
0
  if(in==NULL || t==NULL)
2903
0
    return -1;
2904
2905
0
  p = in->s;
2906
0
  name.s = in->s;
2907
2908
  /* find next token */
2909
0
  while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
2910
0
  if(*p=='\0')
2911
0
  {
2912
0
    LM_ERR("invalid transformation: %.*s\n",
2913
0
        in->len, in->s);
2914
0
    goto error;
2915
0
  }
2916
0
  name.len = p - name.s;
2917
0
  trim(&name);
2918
2919
0
  if(name.len==3 && strncasecmp(name.s, "len", 3)==0)
2920
0
  {
2921
0
    t->subtype = TR_S_LEN;
2922
0
    return 0;
2923
0
  } else if(name.len==3 && strncasecmp(name.s, "int", 3)==0) {
2924
0
    t->subtype = TR_S_INT;
2925
0
    return 0;
2926
0
  } else if(name.len==3 && strncasecmp(name.s, "md5", 3)==0) {
2927
0
    t->subtype = TR_S_MD5;
2928
0
    return 0;
2929
0
  } else if(name.len==5 && strncasecmp(name.s, "crc32", 5)==0) {
2930
0
    t->subtype = TR_S_CRC32;
2931
0
    return 0;
2932
0
  } else if(name.len==7 && strncasecmp(name.s, "tolower", 7)==0) {
2933
0
    t->subtype = TR_S_TOLOWER;
2934
0
    return 0;
2935
0
  } else if(name.len==7 && strncasecmp(name.s, "toupper", 7)==0) {
2936
0
    t->subtype = TR_S_TOUPPER;
2937
0
    return 0;
2938
0
  } else if(name.len==11 && strncasecmp(name.s, "encode.hexa", 11)==0) {
2939
0
    t->subtype = TR_S_ENCODEHEXA;
2940
0
    return 0;
2941
0
  } else if(name.len==11 && strncasecmp(name.s, "decode.hexa", 11)==0) {
2942
0
    t->subtype = TR_S_DECODEHEXA;
2943
0
    return 0;
2944
0
  } else if(name.len==7 && strncasecmp(name.s, "hex2dec", 7)==0) {
2945
0
    t->subtype = TR_S_HEX2DEC;
2946
0
    return 0;
2947
0
  } else if(name.len==7 && strncasecmp(name.s, "dec2hex", 7)==0) {
2948
0
    t->subtype = TR_S_DEC2HEX;
2949
0
    return 0;
2950
0
  } else if(name.len==9 && strncasecmp(name.s, "date2unix", 9)==0) {
2951
0
    t->subtype = TR_S_DATE2UNIX;
2952
0
    return 0;
2953
0
  } else if(name.len==13 && strncasecmp(name.s, "escape.common", 13)==0) {
2954
0
    t->subtype = TR_S_ESCAPECOMMON;
2955
0
    return 0;
2956
0
  } else if(name.len==15 && strncasecmp(name.s, "unescape.common", 15)==0) {
2957
0
    t->subtype = TR_S_UNESCAPECOMMON;
2958
0
    return 0;
2959
0
  } else if(name.len==11 && strncasecmp(name.s, "escape.user", 11)==0) {
2960
0
    t->subtype = TR_S_ESCAPEUSER;
2961
0
    return 0;
2962
0
  } else if(name.len==13 && strncasecmp(name.s, "unescape.user", 13)==0) {
2963
0
    t->subtype = TR_S_UNESCAPEUSER;
2964
0
    return 0;
2965
0
  } else if(name.len==12 && strncasecmp(name.s, "escape.param", 12)==0) {
2966
0
    t->subtype = TR_S_ESCAPEPARAM;
2967
0
    return 0;
2968
0
  } else if(name.len==14 && strncasecmp(name.s, "unescape.param", 14)==0) {
2969
0
    t->subtype = TR_S_UNESCAPEPARAM;
2970
0
    return 0;
2971
0
  } else if(name.len==5 && strncasecmp(name.s, "index", 5)==0) {
2972
0
    t->subtype = TR_S_INDEX;
2973
0
    if(*p!=TR_PARAM_MARKER)
2974
0
    {
2975
0
      LM_ERR("invalid index transformation: %.*s!\n", in->len, in->s);
2976
0
      goto error;
2977
0
    }
2978
0
    p++;
2979
0
    if ((p = tr_parse_sparam(p, in, &tp, 0)) == NULL)
2980
0
      goto error;
2981
0
    t->params = tp;
2982
0
    tp = 0;
2983
0
    trim_ws(p);
2984
0
    if(*p!=TR_PARAM_MARKER && *p!=TR_RBRACKET)
2985
0
    {
2986
0
      LM_ERR("invalid index transformation: %.*s!\n",
2987
0
        in->len, in->s);
2988
0
      goto error;
2989
0
    }
2990
0
    if (*p!=TR_RBRACKET) {
2991
0
      p++;
2992
0
      if (tr_parse_nparam(p, in, &tp) == NULL)
2993
0
        goto error;
2994
0
      t->params->next = tp;
2995
0
    } else {
2996
0
      t->params->next = NULL;
2997
0
    }
2998
2999
0
    tp = 0;
3000
3001
0
    return 0;
3002
0
  } else if(name.len==6 && strncasecmp(name.s, "rindex", 6)==0) {
3003
0
    t->subtype = TR_S_RINDEX;
3004
0
    if(*p!=TR_PARAM_MARKER)
3005
0
    {
3006
0
      LM_ERR("invalid rindex transformation: %.*s!\n", in->len, in->s);
3007
0
      goto error;
3008
0
    }
3009
0
    p++;
3010
0
    if ((p = tr_parse_sparam(p, in, &tp, 0)) == NULL)
3011
0
      goto error;
3012
0
    t->params = tp;
3013
0
    tp = 0;
3014
0
    trim_ws(p);
3015
0
    if(*p!=TR_PARAM_MARKER && *p!=TR_RBRACKET)
3016
0
    {
3017
0
      LM_ERR("invalid rindex transformation: %.*s!\n",
3018
0
        in->len, in->s);
3019
0
      goto error;
3020
0
    }
3021
0
    if (*p!=TR_RBRACKET) {
3022
0
      p++;
3023
0
      if (tr_parse_nparam(p, in, &tp) == NULL)
3024
0
        goto error;
3025
0
      t->params->next = tp;
3026
0
    } else {
3027
0
      t->params->next = NULL;
3028
0
    }
3029
3030
0
    tp = 0;
3031
3032
0
    return 0;
3033
0
  } else if(name.len==6 && strncasecmp(name.s, "substr", 6)==0) {
3034
0
    t->subtype = TR_S_SUBSTR;
3035
0
    if(*p!=TR_PARAM_MARKER)
3036
0
    {
3037
0
      LM_ERR("invalid substr transformation: %.*s!\n", in->len, in->s);
3038
0
      goto error;
3039
0
    }
3040
0
    p++;
3041
0
    if ((p = tr_parse_nparam(p, in, &tp)) == NULL)
3042
0
      goto error;
3043
0
    t->params = tp;
3044
0
    tp = 0;
3045
0
    trim_ws(p);
3046
0
    if(*p!=TR_PARAM_MARKER)
3047
0
    {
3048
0
      LM_ERR("invalid substr transformation: %.*s!\n",
3049
0
        in->len, in->s);
3050
0
      goto error;
3051
0
    }
3052
0
    p++;
3053
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3054
0
      goto error;
3055
0
    t->params->next = tp;
3056
0
    tp = 0;
3057
3058
0
    return 0;
3059
0
  } else if(name.len==6 && strncasecmp(name.s, "select", 6)==0) {
3060
0
    t->subtype = TR_S_SELECT;
3061
0
    if(*p!=TR_PARAM_MARKER)
3062
0
    {
3063
0
      LM_ERR("invalid select transformation: %.*s!\n",
3064
0
          in->len, in->s);
3065
0
      goto error;
3066
0
    }
3067
0
    p++;
3068
0
    if ((p = tr_parse_nparam(p, in, &tp)) == NULL)
3069
0
      goto error;
3070
0
    t->params = tp;
3071
0
    tp = 0;
3072
0
    trim_ws(p);
3073
0
    if(*p!=TR_PARAM_MARKER || *(p+1)=='\0')
3074
0
    {
3075
0
      LM_ERR("invalid select transformation: %.*s!\n", in->len, in->s);
3076
0
      goto error;
3077
0
    }
3078
0
    p++;
3079
0
    tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t));
3080
0
    if(tp==NULL)
3081
0
    {
3082
0
      LM_ERR("no more private memory!\n");
3083
0
      goto error;
3084
0
    }
3085
0
    memset(tp, 0, sizeof(tr_param_t));
3086
0
    tp->type = TR_PARAM_STRING;
3087
0
    tp->v.s.s = p;
3088
0
    tp->v.s.len = 1;
3089
0
    t->params->next = tp;
3090
0
    tp = 0;
3091
3092
0
    return 0;
3093
0
  } else if ((name.len==9 && strncasecmp(name.s, "fill.left", 9)==0) ||
3094
0
        (name.len==10 && strncasecmp(name.s, "fill.right", 10)==0)) {
3095
3096
0
    t->subtype = (name.len == 9 ? TR_S_FILL_LEFT : TR_S_FILL_RIGHT);
3097
0
    if (*p != TR_PARAM_MARKER)
3098
0
    {
3099
0
      LM_ERR("invalid fill transformation: %.*s!\n", in->len, in->s);
3100
0
      goto error;
3101
0
    }
3102
0
    p++;
3103
0
    if ((p = tr_parse_sparam(p, in, &tp, 1)) == NULL)
3104
0
      goto error;
3105
0
    if (tp->type == TR_PARAM_SPEC)
3106
0
    {
3107
0
      LM_ERR("fill transformation does not allow PVs: %.*s!\n", in->len, in->s);
3108
0
      goto error;
3109
0
    }
3110
0
    if (tp->v.s.len == 0)
3111
0
    {
3112
0
      LM_ERR("fill transformation is a NOP, maybe use quotes? %.*s\n",
3113
0
          in->len, in->s);
3114
0
      goto error;
3115
0
    }
3116
3117
0
    if (tp->v.s.len > 1) {
3118
      /* we allowed all whitespace, so manually skip trailing ws */
3119
0
      cp = &tp->v.s.s[tp->v.s.len - 1];
3120
0
      trim_trail_ws(cp);
3121
0
      tp->v.s.len -= &tp->v.s.s[tp->v.s.len - 1] - cp;
3122
3123
      /* support for quoted chars/strings */
3124
0
      if (tp->v.s.len > 1 &&
3125
0
        ((tp->v.s.s[0] == '\'' && tp->v.s.s[tp->v.s.len - 1] == '\'') ||
3126
0
        (tp->v.s.s[0] == '\"' && tp->v.s.s[tp->v.s.len - 1] == '\"'))) {
3127
3128
0
        if (tp->v.s.len == 2)
3129
0
        {
3130
0
          LM_ERR("fill transformation is a NOP, maybe use quotes? %.*s\n",
3131
0
              in->len, in->s);
3132
0
          goto error;
3133
0
        }
3134
3135
0
        tp->v.s.len -= 2;
3136
0
        tp->v.s.s++;
3137
0
      }
3138
0
    }
3139
0
    t->params = tp;
3140
0
    tp = 0;
3141
0
    trim_ws(p);
3142
0
    if (*p != TR_PARAM_MARKER || *(p+1) == '\0')
3143
0
    {
3144
0
      LM_ERR("invalid fill transformation: %.*s!\n", in->len, in->s);
3145
0
      goto error;
3146
0
    }
3147
0
    p++;
3148
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3149
0
      goto error;
3150
0
    if (tp->type == TR_PARAM_SPEC)
3151
0
    {
3152
0
      LM_ERR("fill transformation does not allow PVs: %.*s!\n", in->len, in->s);
3153
0
      goto error;
3154
0
    }
3155
0
    t->params->next = tp;
3156
3157
0
    tp = 0;
3158
3159
0
    return 0;
3160
0
  } else if(name.len==5 && strncasecmp(name.s, "width", 5)==0) {
3161
0
    t->subtype = TR_S_WIDTH;
3162
0
    if(*p!=TR_PARAM_MARKER)
3163
0
    {
3164
0
      LM_ERR("invalid substr transformation: %.*s!\n", in->len, in->s);
3165
0
      goto error;
3166
0
    }
3167
0
    p++;
3168
0
    if ((p = tr_parse_nparam(p, in, &tp)) == NULL)
3169
0
      goto error;
3170
0
    if(tp->type==TR_PARAM_NUMBER && tp->v.n<0)
3171
0
    {
3172
0
      LM_ERR("width negative\n");
3173
0
      goto error;
3174
0
    }
3175
0
    t->params = tp;
3176
0
    tp = 0;
3177
0
    while(is_in_str(p, in) && (*p==' ' || *p=='\t' || *p=='\n')) p++;
3178
0
    if(*p!=TR_RBRACKET)
3179
0
    {
3180
0
      LM_ERR("invalid width transformation: %.*s!!\n",
3181
0
        in->len, in->s);
3182
0
      goto error;
3183
0
    }
3184
0
    return 0;
3185
0
  } else if(name.len==9 && strncasecmp(name.s, "b64encode", 9)==0) {
3186
0
    t->subtype = TR_S_B64ENCODE;
3187
0
    return 0;
3188
0
  } else if(name.len==9 && strncasecmp(name.s, "b64decode", 9)==0) {
3189
0
    t->subtype = TR_S_B64DECODE;
3190
0
    return 0;
3191
0
  } else if(name.len==3 && strncasecmp(name.s, "xor", 3)==0) {
3192
0
    t->subtype = TR_S_XOR;
3193
0
    if(*p!=TR_PARAM_MARKER)
3194
0
    {
3195
0
      LM_ERR("invalid xor transformation: %.*s!\n", in->len, in->s);
3196
0
      goto error;
3197
0
    }
3198
0
    p++;
3199
0
    if (tr_parse_sparam(p, in, &tp, 0) == NULL)
3200
0
      goto error;
3201
0
    t->params = tp;
3202
0
    tp = 0;
3203
3204
0
    return 0;
3205
0
  } else if (strncasecmp(name.s, "trim", 4) == 0) {
3206
0
    if (name.len == 4)
3207
0
      t->subtype = TR_S_TRIM;
3208
0
    else if (name.len > 4 && strncasecmp(name.s, "trimr", 5) == 0)
3209
0
      t->subtype = TR_S_TRIMR;
3210
0
    else if (name.len > 4 && strncasecmp(name.s, "triml", 5) == 0)
3211
0
      t->subtype = TR_S_TRIML;
3212
0
    else {
3213
0
      LM_ERR("bad trim transformation!\n");
3214
0
      goto error;
3215
0
    }
3216
3217
0
    return 0;
3218
0
  } else if(name.len==7 && strncasecmp(name.s, "reverse", 7)==0) {
3219
0
    t->subtype = TR_S_REVERSE;
3220
0
    return 0;
3221
0
  } else if(name.len==4 && strncasecmp(name.s, "eval", 4)==0) {
3222
0
    t->subtype = TR_S_EVAL;
3223
0
    return 0;
3224
0
    return 0;
3225
0
  } else if(name.len==4 && strncasecmp(name.s, "sha1", 4)==0) {
3226
0
    t->subtype = TR_S_SHA1;
3227
0
    return 0;
3228
0
  } else if(name.len==6 && strncasecmp(name.s, "sha224", 6)==0) {
3229
0
    t->subtype = TR_S_SHA224;
3230
0
    return 0;
3231
0
  } else if(name.len==6 && strncasecmp(name.s, "sha256", 6)==0) {
3232
0
    t->subtype = TR_S_SHA256;
3233
0
    return 0;
3234
0
  } else if(name.len==6 && strncasecmp(name.s, "sha384", 6)==0) {
3235
0
    t->subtype = TR_S_SHA384;
3236
0
    return 0;
3237
0
  } else if(name.len==6 && strncasecmp(name.s, "sha512", 6)==0) {
3238
0
    t->subtype = TR_S_SHA512;
3239
0
    return 0;
3240
0
  } else if ( (name.len==9 || name.len==11) && strncasecmp(name.s, "sha", 3)==0 &&
3241
0
      strncasecmp(name.s+(name.len-5), "_hmac", 5)==0 ) {
3242
3243
0
    if (strncasecmp(name.s+3, "1", 1) == 0) { // SHA1
3244
0
      t->subtype = TR_S_SHA1_HMAC;
3245
0
    } else if (strncasecmp(name.s+3, "224", 3) == 0) { // SHA224
3246
0
      t->subtype = TR_S_SHA224_HMAC;
3247
0
    } else if (strncasecmp(name.s+3, "256", 3) == 0) { // SHA256
3248
0
      t->subtype = TR_S_SHA256_HMAC;
3249
0
    } else if (strncasecmp(name.s+3, "384", 3) == 0) { // SHA384
3250
0
      t->subtype = TR_S_SHA384_HMAC;
3251
0
    } else if (strncasecmp(name.s+3, "512", 3) == 0) { // SHA512
3252
0
      t->subtype = TR_S_SHA512_HMAC;
3253
0
    } else {
3254
0
      goto unknown;
3255
0
    }
3256
3257
0
    if(*p!=TR_PARAM_MARKER)
3258
0
    {
3259
0
      LM_ERR("invalid sha hmac transformation: %.*s!\n", in->len, in->s);
3260
0
      goto error;
3261
0
    }
3262
0
    p++;
3263
0
    if (tr_parse_sparam(p, in, &tp, 0) == NULL)
3264
0
      goto error;
3265
0
    t->params = tp;
3266
0
    tp = 0;
3267
3268
0
    return 0;
3269
0
  }
3270
3271
0
unknown:
3272
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3273
0
      name.len, name.s, name.len);
3274
0
error:
3275
0
  if(tp)
3276
0
    free_tr_param(tp);
3277
0
  return -1;
3278
0
}
3279
3280
int tr_parse_uri(str* in, trans_t *t)
3281
0
{
3282
0
  char *p;
3283
0
  str name;
3284
0
  tr_param_t *tp = NULL;
3285
3286
0
  if(in==NULL || in->s==NULL || t==NULL)
3287
0
    return -1;
3288
0
  p = in->s;
3289
0
  name.s = in->s;
3290
3291
  /* find next token */
3292
0
  while(*p && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3293
0
  if(*p=='\0')
3294
0
  {
3295
0
    LM_ERR("invalid transformation: %.*s\n", in->len, in->s);
3296
0
    goto error;
3297
0
  }
3298
0
  name.len = p - name.s;
3299
0
  trim(&name);
3300
3301
0
  if(name.len==4 && strncasecmp(name.s, "user", 4)==0)
3302
0
  {
3303
0
    t->subtype = TR_URI_USER;
3304
0
    return 0;
3305
0
  } else if((name.len==4 && strncasecmp(name.s, "host", 4)==0)
3306
0
      || (name.len==6 && strncasecmp(name.s, "domain", 6)==0)) {
3307
0
    t->subtype = TR_URI_HOST;
3308
0
    return 0;
3309
0
  } else if(name.len==6 && strncasecmp(name.s, "passwd", 6)==0) {
3310
0
    t->subtype = TR_URI_PASSWD;
3311
0
    return 0;
3312
0
  } else if(name.len==4 && strncasecmp(name.s, "port", 4)==0) {
3313
0
    t->subtype = TR_URI_PORT;
3314
0
    return 0;
3315
0
  } else if(name.len==6 && strncasecmp(name.s, "params", 6)==0) {
3316
0
    t->subtype = TR_URI_PARAMS;
3317
0
    return 0;
3318
0
  } else if(name.len==5 && strncasecmp(name.s, "param", 5)==0) {
3319
0
    t->subtype = TR_URI_PARAM;
3320
0
    if(*p!=TR_PARAM_MARKER)
3321
0
    {
3322
0
      LM_ERR("invalid param transformation: %.*s\n", in->len, in->s);
3323
0
      goto error;
3324
0
    }
3325
0
    p++;
3326
0
    if (tr_parse_sparam(p, in, &tp, 0) == NULL)
3327
0
      goto error;
3328
0
    t->params = tp;
3329
0
    return 0;
3330
0
  } else if(name.len==9 && strncasecmp(name.s, "transport", 9)==0) {
3331
0
    t->subtype = TR_URI_TRANSPORT;
3332
0
    return 0;
3333
0
  } else if(name.len==7 && strncasecmp(name.s, "headers", 7)==0) {
3334
0
    t->subtype = TR_URI_HEADERS;
3335
0
    return 0;
3336
0
  } else if(name.len==3 && strncasecmp(name.s, "ttl", 3)==0) {
3337
0
    t->subtype = TR_URI_TTL;
3338
0
    return 0;
3339
0
  } else if(name.len==6 && strncasecmp(name.s, "uparam", 6)==0) {
3340
0
    t->subtype = TR_URI_UPARAM;
3341
0
    return 0;
3342
0
  } else if(name.len==5 && strncasecmp(name.s, "maddr", 5)==0) {
3343
0
    t->subtype = TR_URI_MADDR;
3344
0
    return 0;
3345
0
  } else if(name.len==6 && strncasecmp(name.s, "method", 6)==0) {
3346
0
    t->subtype = TR_URI_METHOD;
3347
0
    return 0;
3348
0
  } else if(name.len==2 && strncasecmp(name.s, "lr", 2)==0) {
3349
0
    t->subtype = TR_URI_LR;
3350
0
    return 0;
3351
0
  } else if(name.len==2 && strncasecmp(name.s, "r2", 2)==0) {
3352
0
    t->subtype = TR_URI_R2;
3353
0
    return 0;
3354
0
  } else if (name.len==6 && strncasecmp(name.s, "schema", 6)==0) {
3355
0
    t->subtype = TR_URI_SCHEMA;
3356
0
    return 0;
3357
0
  }
3358
3359
0
  LM_ERR("unknown transformation: %.*s/%.*s!\n", in->len,
3360
0
      in->s, name.len, name.s);
3361
0
error:
3362
0
  return -1;
3363
0
}
3364
3365
3366
int tr_parse_via(str* in, trans_t *t)
3367
0
{
3368
0
  char *p;
3369
0
  str name;
3370
0
  tr_param_t *tp = NULL;
3371
3372
0
  if(in==NULL || in->s==NULL || t==NULL)
3373
0
    return -1;
3374
0
  p = in->s;
3375
0
  name.s = in->s;
3376
3377
  /* find next token */
3378
0
  while(*p && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3379
0
  if(*p=='\0')
3380
0
  {
3381
0
    LM_ERR("invalid transformation: %.*s\n", in->len, in->s);
3382
0
    goto error;
3383
0
  }
3384
0
  name.len = p - name.s;
3385
0
  trim(&name);
3386
3387
0
  if(name.len==4 && strncasecmp(name.s, "name", 4)==0)
3388
0
  {
3389
0
    t->subtype = TR_VIA_NAME;
3390
0
    return 0;
3391
0
  } else if(name.len==7 && strncasecmp(name.s, "version", 7)==0)
3392
0
  {
3393
0
    t->subtype = TR_VIA_VERSION;
3394
0
    return 0;
3395
0
  } else if(name.len==9 && strncasecmp(name.s, "transport", 9)==0) {
3396
0
    t->subtype = TR_VIA_TRANSPORT;
3397
0
    return 0;
3398
0
  } else if((name.len==4 && strncasecmp(name.s, "host", 4)==0)
3399
0
      || (name.len==6 && strncasecmp(name.s, "domain", 6)==0)) {
3400
0
    t->subtype = TR_VIA_HOST;
3401
0
    return 0;
3402
0
  } else if(name.len==4 && strncasecmp(name.s, "port", 4)==0) {
3403
0
    t->subtype = TR_VIA_PORT;
3404
0
    return 0;
3405
0
  } else if(name.len==6 && strncasecmp(name.s, "params", 6)==0) {
3406
0
    t->subtype = TR_VIA_PARAMS;
3407
0
    return 0;
3408
0
  } else if(name.len==5 && strncasecmp(name.s, "param", 5)==0) {
3409
0
    t->subtype = TR_VIA_PARAM;
3410
0
    if(*p!=TR_PARAM_MARKER)
3411
0
    {
3412
0
      LM_ERR("invalid param transformation: %.*s\n", in->len, in->s);
3413
0
      goto error;
3414
0
    }
3415
0
    p++;
3416
0
    if (tr_parse_sparam(p, in, &tp, 0) == NULL)
3417
0
      goto error;
3418
0
    t->params = tp;
3419
3420
0
    return 0;
3421
0
  } else if(name.len==7 && strncasecmp(name.s, "comment", 7)==0) {
3422
0
    t->subtype = TR_VIA_COMMENT;
3423
0
    return 0;
3424
0
  } else if(name.len==6 && strncasecmp(name.s, "branch", 6)==0) {
3425
0
    t->subtype = TR_VIA_BRANCH;
3426
0
    return 0;
3427
0
  } else if(name.len==8 && strncasecmp(name.s, "received", 8)==0) {
3428
0
    t->subtype = TR_VIA_RECEIVED;
3429
0
    return 0;
3430
0
  } else if(name.len==5 && strncasecmp(name.s, "rport", 5)==0) {
3431
0
    t->subtype = TR_VIA_RPORT;
3432
0
    return 0;
3433
0
  }
3434
3435
3436
0
  LM_ERR("unknown transformation: %.*s/%.*s!\n", in->len,
3437
0
      in->s, name.len, name.s);
3438
0
error:
3439
0
  return -1;
3440
0
}
3441
3442
int tr_parse_paramlist(str* in, trans_t *t)
3443
0
{
3444
0
  char *p;
3445
0
  str name;
3446
0
  tr_param_t *tp = NULL;
3447
3448
0
  if(in==NULL || in->s==NULL || t==NULL)
3449
0
    return -1;
3450
3451
0
  p = in->s;
3452
0
  name.s = in->s;
3453
3454
  /* find next token */
3455
0
  while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3456
0
  if(*p=='\0')
3457
0
  {
3458
0
    LM_ERR("invalid transformation: %.*s\n",
3459
0
        in->len, in->s);
3460
0
    goto error;
3461
0
  }
3462
0
  name.len = p - name.s;
3463
0
  trim(&name);
3464
3465
0
  if(name.len==5 && strncasecmp(name.s, "value", 5)==0)
3466
0
  {
3467
0
    t->subtype = TR_PL_VALUE;
3468
0
    if(*p!=TR_PARAM_MARKER)
3469
0
    {
3470
0
      LM_ERR("invalid value transformation: %.*s\n",
3471
0
          in->len, in->s);
3472
0
      goto error;
3473
0
    }
3474
0
    p++;
3475
0
    if (tr_parse_sparam(p, in, &tp, 0) == NULL)
3476
0
      goto error;
3477
0
    t->params = tp;
3478
3479
0
    return 0;
3480
3481
0
  } else if(str_match(&name, &(str_const_init("exist")))
3482
0
            || str_match(&name, &(str_const_init("exists")))) {
3483
0
    t->subtype = TR_PL_EXIST;
3484
0
    if(*p!=TR_PARAM_MARKER)
3485
0
    {
3486
0
      LM_ERR("invalid value transformation: %.*s\n",
3487
0
          in->len, in->s);
3488
0
      goto error;
3489
0
    }
3490
0
    p++;
3491
0
    if (tr_parse_sparam(p, in, &tp, 0) == NULL)
3492
0
      goto error;
3493
0
    t->params = tp;
3494
3495
0
    return 0;
3496
0
  } else if(name.len==7 && strncasecmp(name.s, "valueat", 7)==0) {
3497
0
    t->subtype = TR_PL_VALUEAT;
3498
0
    if(*p!=TR_PARAM_MARKER)
3499
0
    {
3500
0
      LM_ERR("invalid name transformation: %.*s\n",
3501
0
          in->len, in->s);
3502
0
      goto error;
3503
0
    }
3504
0
    p++;
3505
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3506
0
      goto error;
3507
0
    t->params = tp;
3508
3509
0
    return 0;
3510
0
  } else if(name.len==4 && strncasecmp(name.s, "name", 4)==0) {
3511
0
    t->subtype = TR_PL_NAME;
3512
0
    if(*p!=TR_PARAM_MARKER)
3513
0
    {
3514
0
      LM_ERR("invalid name transformation: %.*s\n",
3515
0
          in->len, in->s);
3516
0
      goto error;
3517
0
    }
3518
0
    p++;
3519
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3520
0
      goto error;
3521
0
    t->params = tp;
3522
3523
0
    return 0;
3524
0
  } else if(name.len==5 && strncasecmp(name.s, "count", 5)==0) {
3525
0
    t->subtype = TR_PL_COUNT;
3526
0
    return 0;
3527
0
  }
3528
3529
0
  LM_ERR("unknown transformation: %.*s/%.*s!\n",
3530
0
      in->len, in->s, name.len, name.s);
3531
0
error:
3532
0
  return -1;
3533
0
}
3534
3535
int tr_parse_nameaddr(str* in, trans_t *t)
3536
0
{
3537
0
  char *p;
3538
0
  str name;
3539
0
  tr_param_t *tp = NULL;
3540
3541
3542
0
  if(in==NULL || t==NULL)
3543
0
    return -1;
3544
3545
0
  p = in->s;
3546
0
parse_name:
3547
0
  name.s = p;
3548
3549
  /* find next token */
3550
0
  while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET && *p!=TR_CLASS_MARKER) p++;
3551
0
  if(*p=='\0')
3552
0
  {
3553
0
    LM_ERR("invalid transformation: %.*s\n",
3554
0
        in->len, in->s);
3555
0
    goto error;
3556
0
  }
3557
0
  name.len = p - name.s;
3558
0
  trim(&name);
3559
0
  if (*p == TR_CLASS_MARKER) {
3560
0
    if (t->params) {
3561
0
      LM_ERR("transformation [%.*s] already has an index!\n",
3562
0
          in->len, in->s);
3563
0
      goto error;
3564
0
    }
3565
    /* we either have a pvar, or an index */
3566
0
    if (tr_parse_nparam(name.s, &name, &tp) == NULL) {
3567
0
      LM_ERR("invalid index: %.*s\n", name.len, name.s);
3568
0
      goto error;
3569
0
    }
3570
0
    t->params = tp;
3571
0
    tp = 0;
3572
0
    p++;
3573
0
    goto parse_name;
3574
0
  }
3575
3576
0
  if(name.len==3 && strncasecmp(name.s, "uri", 3)==0)
3577
0
  {
3578
0
    t->subtype = TR_NA_URI;
3579
0
    return 0;
3580
0
  } else if(name.len==3 && strncasecmp(name.s, "len", 3)==0)
3581
0
  {
3582
0
    t->subtype = TR_NA_LEN;
3583
0
    return 0;
3584
0
  } else if(name.len==4 && strncasecmp(name.s, "name", 4)==0) {
3585
0
    t->subtype = TR_NA_NAME;
3586
0
    return 0;
3587
0
  } else if(name.len==5 && strncasecmp(name.s, "param", 5)==0) {
3588
0
    t->subtype = TR_NA_PARAM;
3589
0
    if(*p!=TR_PARAM_MARKER)
3590
0
    {
3591
0
      LM_ERR("invalid value transformation: %.*s\n",
3592
0
          in->len, in->s);
3593
0
      goto error;
3594
0
    }
3595
0
    p++;
3596
0
    if (tr_parse_sparam(p, in, &tp, 0) == NULL)
3597
0
      goto error;
3598
0
    if (t->params)
3599
0
      t->params->next = tp;
3600
0
    else
3601
0
      t->params = tp;
3602
0
    tp = 0;
3603
3604
0
    return 0;
3605
0
  } else if(name.len==6 && strncasecmp(name.s, "params", 6)==0) {
3606
0
    t->subtype = TR_NA_PARAMS;
3607
0
    return 0;
3608
0
  }
3609
3610
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3611
0
      name.len, name.s, name.len);
3612
0
error:
3613
0
  return -1;
3614
0
}
3615
3616
int tr_parse_csv(str *in, trans_t *t)
3617
0
{
3618
0
  char *p;
3619
0
  str name;
3620
0
  tr_param_t *tp = NULL;
3621
3622
0
  if (in == NULL || t == NULL)
3623
0
    return -1;
3624
3625
0
  p = in->s;
3626
0
  name.s = in->s;
3627
3628
  /* find next token */
3629
0
  while (is_in_str(p,in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3630
0
  if (*p == '\0')
3631
0
  {
3632
0
    LM_ERR("invalid transformation: %.*s\n",in->len,in->s);
3633
0
    return -1;
3634
0
  }
3635
3636
0
  name.len = p - name.s;
3637
0
  trim(&name);
3638
3639
0
  if (name.len==5 && strncasecmp(name.s,"count",5)==0)
3640
0
  {
3641
0
    t->subtype = TR_CSV_COUNT;
3642
0
    return 0;
3643
0
  }
3644
0
  else if (name.len==5 && strncasecmp(name.s,"value",5)==0)
3645
0
  {
3646
0
    t->subtype = TR_CSV_VALUEAT;
3647
0
    if(*p!=TR_PARAM_MARKER)
3648
0
    {
3649
0
      LM_ERR("invalid name transformation: %.*s\n",
3650
0
          in->len, in->s);
3651
0
      goto error;
3652
0
    }
3653
0
    p++;
3654
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3655
0
      goto error;
3656
0
    t->params = tp;
3657
0
    tp = 0;
3658
3659
0
    return 0;
3660
0
  }
3661
3662
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3663
0
      name.len, name.s, name.len);
3664
0
error:
3665
0
  return -1;
3666
3667
0
}
3668
3669
int tr_parse_sdp(str *in, trans_t *t)
3670
0
{
3671
0
  int tmp;
3672
0
  char *p;
3673
0
  str name;
3674
0
  tr_param_t *tp = NULL;
3675
3676
0
  if (in == NULL || t == NULL)
3677
0
    return -1;
3678
3679
0
  p = in->s;
3680
0
  name.s = in->s;
3681
3682
  /* find next token */
3683
0
  while (is_in_str(p,in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3684
0
  if (*p == '\0')
3685
0
  {
3686
0
    LM_ERR("invalid transformation: %.*s\n",in->len,in->s);
3687
0
    return -1;
3688
0
  }
3689
3690
0
  name.len = p - name.s;
3691
0
  trim(&name);
3692
3693
0
  if (name.len==4 && strncasecmp(name.s,"line",4)==0)
3694
0
  {
3695
0
    t->subtype = TR_SDP_LINEAT;
3696
0
    if(*p!=TR_PARAM_MARKER)
3697
0
    {
3698
0
      LM_ERR("invalid lineat transformation: %.*s!\n", in->len, in->s);
3699
0
      goto error;
3700
0
    }
3701
0
    p++;
3702
0
    if ((p = tr_parse_sparam(p, in, &tp, 0)) == NULL)
3703
0
      goto error;
3704
0
    t->params = tp;
3705
0
    tp = 0;
3706
0
    trim_ws(p);
3707
0
    if(*p!=TR_PARAM_MARKER)
3708
0
    {
3709
      /* lineat has only one parameter */
3710
0
      tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t));
3711
0
      if (!tp)
3712
0
      {
3713
0
        LM_ERR("no more pkg memory\n");
3714
0
        goto error;
3715
0
      }
3716
0
      memset(tp, 0, sizeof(tr_param_t));
3717
0
      tp->type = TR_PARAM_NUMBER;
3718
0
      tp->v.n = 0;
3719
0
      t->params->next = tp;
3720
0
      LM_DBG("sdp.lineat with only one parameter. default = 1\n");
3721
0
      return 0;
3722
0
    }
3723
0
    p++;
3724
3725
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3726
0
      goto error;
3727
0
    if(tp->type==TR_PARAM_NUMBER && tp->v.n<0)
3728
0
    {
3729
0
      LM_ERR("lineat negative argument\n");
3730
0
      goto error;
3731
0
    }
3732
0
    t->params->next = tp;
3733
0
    tp = 0;
3734
3735
0
    return 0;
3736
0
  } else if ((name.len==13 && strncasecmp(name.s,"stream-delete",13)==0) ||
3737
0
        (name.len==6 && strncasecmp(name.s,"stream",6)==0)) {
3738
0
    if (name.len == 6)
3739
0
      t->subtype = TR_SDP_STREAM;
3740
0
    else
3741
0
      t->subtype = TR_SDP_STREAM_DEL;
3742
0
    if(*p!=TR_PARAM_MARKER)
3743
0
    {
3744
0
      LM_ERR("media delete without type or index: %.*s!\n", in->len, in->s);
3745
0
      goto error;
3746
0
    }
3747
0
    p++;
3748
0
    if ((p = tr_parse_sparam(p, in, &tp, 0)) == NULL)
3749
0
      goto error;
3750
    /* if it is a static numeric, convert it now */
3751
0
    if (tp->type == TR_PARAM_STRING) {
3752
      /* try to convert it now to an int, if possible */
3753
0
      if (str2sint(&tp->v.s, &tmp) >= 0) {
3754
0
        tp->v.n = tmp;
3755
0
        tp->type = TR_PARAM_NUMBER;
3756
0
      }
3757
0
    }
3758
0
    t->params = tp;
3759
0
    tp = 0;
3760
3761
0
    return 0;
3762
0
  }
3763
3764
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3765
0
      name.len, name.s, name.len);
3766
0
error:
3767
0
  return -1;
3768
0
}
3769
3770
int tr_parse_ip(str *in, trans_t *t)
3771
0
{
3772
0
  char *p;
3773
0
  str name;
3774
3775
0
  if (in == NULL || t == NULL)
3776
0
    return -1;
3777
3778
0
  p = in->s;
3779
0
  name.s = in->s;
3780
3781
  /* find next token */
3782
0
  while (is_in_str(p,in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3783
0
  if (*p == '\0')
3784
0
  {
3785
0
    LM_ERR("invalid transformation: %.*s\n",in->len,in->s);
3786
0
    goto error;
3787
0
  }
3788
3789
0
  name.len = p - name.s;
3790
0
  trim(&name);
3791
3792
0
  if (name.len==6 && strncasecmp(name.s,"family",6)==0) {
3793
0
    t->subtype = TR_IP_FAMILY;
3794
0
    return 0;
3795
0
  } else if (name.len==4 && strncasecmp(name.s,"ntop",4)==0) {
3796
0
    t->subtype = TR_IP_NTOP;
3797
0
    return 0;
3798
0
  } else if (name.len == 4 && strncasecmp(name.s,"isip",4) == 0) {
3799
0
    t->subtype = TR_IP_ISIP;
3800
0
    return 0;
3801
0
        } else if (name.len == 5 && strncasecmp(name.s,"isip4",5) == 0) {
3802
0
                t->subtype = TR_IP_ISIP4;
3803
0
                return 0;
3804
0
        } else if (name.len == 5 && strncasecmp(name.s,"isip6",5) == 0) {
3805
0
                t->subtype = TR_IP_ISIP6;
3806
0
                return 0;
3807
0
  } else if (name.len == 4 && strncasecmp(name.s,"pton",4) == 0) {
3808
0
    t->subtype = TR_IP_PTON;
3809
0
    return 0;
3810
0
  } else if (name.len == 7 && strncasecmp(name.s,"resolve",7) == 0) {
3811
0
    t->subtype = TR_IP_RESOLVE;
3812
0
    return 0;
3813
0
  } else if (name.len == 7 && strncasecmp(name.s,"matches",5) == 0) {
3814
0
    t->subtype = TR_IP_MATCHES;
3815
0
    if(*p!=TR_PARAM_MARKER)
3816
0
    {
3817
0
      LM_ERR("invalid value transformation: %.*s\n",
3818
0
          in->len, in->s);
3819
0
      goto error;
3820
0
    }
3821
0
    p++;
3822
0
    LM_DBG("preparing to parse param\n");
3823
0
    if (tr_parse_sparam(p, in, &t->params, 0) == NULL)
3824
0
      goto error;
3825
0
    return 0;
3826
0
  } else if (name.len == 9 && strncasecmp(name.s,"isprivate",9) == 0) {
3827
0
    t->subtype = TR_IP_ISPRIVATE;
3828
0
    return 0;
3829
0
  }
3830
3831
3832
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3833
0
      name.len, name.s, name.len);
3834
0
error:
3835
0
  return -1;
3836
3837
0
}
3838
3839
int tr_parse_re(str *in,trans_t *t)
3840
0
{
3841
0
  char *p;
3842
0
  str name;
3843
0
  tr_param_t *tp = NULL;
3844
3845
0
  if (in == NULL || t == NULL)
3846
0
    return -1;
3847
3848
0
  p = in->s;
3849
0
  name.s = in->s;
3850
3851
  /* find next token */
3852
0
  while (is_in_str(p,in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3853
0
  if (*p == '\0')
3854
0
  {
3855
0
    LM_ERR("invalid transformation: %.*s\n",in->len,in->s);
3856
0
    goto error;
3857
0
  }
3858
3859
0
  name.len = p - name.s;
3860
0
  trim(&name);
3861
3862
0
  if (name.len==5 && strncasecmp(name.s,"subst",5)==0)
3863
0
  {
3864
0
    t->subtype = TR_RE_SUBST;
3865
0
    if(*p!=TR_PARAM_MARKER)
3866
0
    {
3867
0
      LM_ERR("invalid value transformation: %.*s\n",
3868
0
          in->len, in->s);
3869
0
      goto error;
3870
0
    }
3871
0
    p++;
3872
0
    LM_DBG("preparing to parse param\n");
3873
0
    if (tr_parse_sparam(p, in, &tp, 0) == NULL)
3874
0
      goto error;
3875
0
    t->params = tp;
3876
0
    tp = 0;
3877
3878
0
    return 0;
3879
0
  }
3880
3881
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3882
0
      name.len, name.s, name.len);
3883
0
error:
3884
0
  return -1;
3885
0
}
3886
3887
void free_transformation(trans_t *t)
3888
0
{
3889
0
  trans_t *t0;
3890
3891
0
  while(t)
3892
0
  {
3893
0
    t0 = t;
3894
0
    t = t->next;
3895
0
    free_tr_param(t0->params);
3896
0
    pkg_free(t0);
3897
0
  }
3898
0
}
3899
3900
void free_tr_param(tr_param_t *tp)
3901
0
{
3902
0
  tr_param_t *tp0;
3903
3904
0
  if(tp==NULL) return;
3905
0
  while(tp)
3906
0
  {
3907
0
    tp0 = tp;
3908
0
    tp = tp->next;
3909
0
    if(tp0->type==TR_PARAM_SPEC)
3910
0
      pv_spec_free((pv_spec_t*)tp0->v.data);
3911
0
    pkg_free(tp0);
3912
0
  }
3913
0
}