Coverage Report

Created: 2026-09-01 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensips/transformations.c
Line
Count
Source
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
        calc_base64_encode_len(val->rs.len)>TR_BUFFER_SIZE) {
962
0
        LM_ERR("b64encode value larger than buffer\n");
963
0
        goto error;
964
0
      }
965
0
      st.s = _tr_buffer;
966
0
      st.len = calc_base64_encode_len(val->rs.len);
967
968
0
      base64encode((unsigned char *)st.s,
969
0
             (unsigned char *)val->rs.s,
970
0
             val->rs.len);
971
972
0
      memset(val, 0, sizeof(pv_value_t));
973
0
      val->flags = PV_VAL_STR;
974
0
      val->rs = st;
975
0
      break;
976
0
    case TR_S_B64DECODE:
977
0
      if(!(val->flags&PV_VAL_STR))
978
0
      {
979
0
        val->rs.s = int2str(val->ri, &val->rs.len);
980
0
        val->flags |= PV_VAL_STR;
981
0
        break;
982
0
      }
983
0
      if(val->rs.len>TR_BUFFER_SIZE-1) {
984
0
        LM_ERR("b64decode value larger than buffer\n");
985
0
        return -1;
986
0
      }
987
0
                        st.s = _tr_buffer;
988
0
                        st.len = base64decode((unsigned char *)st.s, 
989
0
                                              (unsigned char *)val->rs.s,
990
0
                                              val->rs.len);
991
0
                        memset(val, 0, sizeof(pv_value_t));
992
0
                        val->flags = PV_VAL_STR;
993
0
                        val->rs = st;
994
0
                        break;
995
0
    case TR_S_XOR:
996
      /* ensure string format */
997
0
      if(!(val->flags&PV_VAL_STR))
998
0
      {
999
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1000
0
        val->flags |= PV_VAL_STR;
1001
0
      }
1002
0
      if(val->rs.len>TR_BUFFER_SIZE-1) {
1003
0
        LM_ERR("xor value larger than buffer\n");
1004
0
        goto error;
1005
0
      }
1006
      /* secret to use */
1007
0
      if(tp->type==TR_PARAM_STRING)
1008
0
      {
1009
0
        st = tp->v.s;
1010
0
      } else {
1011
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1012
0
                                                || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
1013
0
        {
1014
0
          LM_ERR("xor cannot get p1\n");
1015
0
          return -1;
1016
0
        }
1017
0
        st = v.rs;
1018
0
      }
1019
      
1020
0
      p = _tr_buffer;
1021
0
      for (i=0; i<val->rs.len; i++) {
1022
0
        *p = val->rs.s[i] ^ st.s[i % st.len];
1023
0
        p++;
1024
0
      }
1025
      /* leave val flags and length in tact and update with result */
1026
0
                        val->rs.s = _tr_buffer;
1027
0
      break;
1028
0
    case TR_S_TRIM:
1029
0
      if (!(val->flags & PV_VAL_STR))
1030
0
      {
1031
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1032
0
        val->flags |= PV_VAL_STR;
1033
0
      }
1034
1035
0
      trim(&val->rs);
1036
0
      break;
1037
0
    case TR_S_TRIMR:
1038
0
      if (!(val->flags & PV_VAL_STR))
1039
0
      {
1040
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1041
0
        val->flags |= PV_VAL_STR;
1042
0
      }
1043
1044
0
      trim_trailing(&val->rs);
1045
0
      break;
1046
0
    case TR_S_TRIML:
1047
0
      if (!(val->flags & PV_VAL_STR))
1048
0
      {
1049
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1050
0
        val->flags |= PV_VAL_STR;
1051
0
      }
1052
1053
0
      trim_leading(&val->rs);
1054
0
      break;
1055
0
    case TR_S_REVERSE:
1056
0
      if (!(val->flags & PV_VAL_STR))
1057
0
      {
1058
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1059
0
        val->flags |= PV_VAL_STR;
1060
0
      }
1061
1062
      /*To big for buffer*/
1063
0
      if(val->rs.len>TR_BUFFER_SIZE-1)
1064
0
        goto error;
1065
1066
0
      p = _tr_buffer;
1067
1068
      /*Reverse Order*/
1069
0
      for (i=0; i < val->rs.len; i++) {
1070
0
        p[val->rs.len - 1 - i] = val->rs.s[i];
1071
0
      }
1072
1073
      /*Save Result*/
1074
0
      val->rs.s = _tr_buffer;
1075
0
      val->flags = PV_VAL_STR;
1076
0
      break;
1077
0
    case TR_S_EVAL:
1078
0
      if(!(val->flags&PV_VAL_STR))
1079
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1080
1081
0
      if (pv_parse_format(&val->rs,&el) != 0) {
1082
0
        LM_ERR("Failed to parse input \n");
1083
0
        goto error;
1084
0
      }
1085
1086
0
      if (pv_printf_s(msg,el,&st) != 0) {
1087
0
        LM_ERR("Failed to print input \n");
1088
0
        pv_elem_free_all(el);
1089
0
        goto error;
1090
0
      }
1091
1092
0
      memcpy(_tr_buffer,st.s,st.len);
1093
0
      _tr_buffer[st.len] = '\0';
1094
1095
0
      val->flags = PV_VAL_STR;
1096
0
      val->ri = 0;
1097
0
      val->rs.s = _tr_buffer;
1098
0
      val->rs.len = st.len;
1099
1100
0
      pv_elem_free_all(el);
1101
0
      break;
1102
0
    default:
1103
0
      LM_ERR("unknown subtype %d\n",
1104
0
          subtype);
1105
0
      goto error;
1106
0
  }
1107
1108
0
  return 0;
1109
0
error:
1110
0
  val->flags = PV_VAL_NULL;
1111
0
  return -1;
1112
0
}
1113
1114
static str _tr_empty = { "", 0 };
1115
static str _tr_uri = {0, 0};
1116
static struct sip_uri _tr_parsed_uri;
1117
static param_t* _tr_uri_params = NULL;
1118
1119
int tr_eval_uri(struct sip_msg *msg, tr_param_t *tp, int subtype,
1120
    pv_value_t *val)
1121
0
{
1122
0
  pv_value_t v;
1123
0
  str sv;
1124
0
  param_hooks_t phooks;
1125
0
  param_t *pit=NULL;
1126
1127
0
  if (!val)
1128
0
    return -1;
1129
1130
0
  if (val->flags & PV_VAL_NULL)
1131
0
    return 0;
1132
1133
0
  if((!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
1134
0
    goto error;
1135
1136
0
  if(_tr_uri.len==0 || _tr_uri.len!=val->rs.len ||
1137
0
      strncmp(_tr_uri.s, val->rs.s, val->rs.len)!=0)
1138
0
  {
1139
0
    if(val->rs.len>_tr_uri.len)
1140
0
    {
1141
0
      if(_tr_uri.s) pkg_free(_tr_uri.s);
1142
0
      _tr_uri.s = (char*)pkg_malloc((val->rs.len+1)*sizeof(char));
1143
0
      if(_tr_uri.s==NULL)
1144
0
      {
1145
0
        LM_ERR("no more private memory\n");
1146
0
        if(_tr_uri_params != NULL)
1147
0
        {
1148
0
          free_params(_tr_uri_params);
1149
0
          _tr_uri_params = 0;
1150
0
        }
1151
0
        memset(&_tr_uri, 0, sizeof(str));
1152
0
        memset(&_tr_parsed_uri, 0, sizeof(struct sip_uri));
1153
0
        goto error;
1154
0
      }
1155
0
    }
1156
0
    _tr_uri.len = val->rs.len;
1157
0
    memcpy(_tr_uri.s, val->rs.s, val->rs.len);
1158
0
    _tr_uri.s[_tr_uri.len] = '\0';
1159
    /* reset old values */
1160
0
    memset(&_tr_parsed_uri, 0, sizeof(struct sip_uri));
1161
0
    if(_tr_uri_params != NULL)
1162
0
    {
1163
0
      free_params(_tr_uri_params);
1164
0
      _tr_uri_params = 0;
1165
0
    }
1166
    /* parse uri -- params only when requested */
1167
0
    if(parse_uri(_tr_uri.s, _tr_uri.len, &_tr_parsed_uri)!=0)
1168
0
    {
1169
0
      LM_ERR("invalid uri [%.*s]\n", val->rs.len,
1170
0
          val->rs.s);
1171
0
      if(_tr_uri_params != NULL)
1172
0
      {
1173
0
        free_params(_tr_uri_params);
1174
0
        _tr_uri_params = 0;
1175
0
      }
1176
0
      pkg_free(_tr_uri.s);
1177
0
      memset(&_tr_uri, 0, sizeof(str));
1178
0
      memset(&_tr_parsed_uri, 0, sizeof(struct sip_uri));
1179
0
      goto error;
1180
0
    }
1181
0
  }
1182
0
  memset(val, 0, sizeof(pv_value_t));
1183
0
  val->flags = PV_VAL_STR;
1184
1185
0
  switch(subtype)
1186
0
  {
1187
0
    case TR_URI_USER:
1188
0
      val->rs = (_tr_parsed_uri.user.s)?_tr_parsed_uri.user:_tr_empty;
1189
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1190
0
      break;
1191
0
    case TR_URI_HOST:
1192
0
      val->rs = (_tr_parsed_uri.host.s)?_tr_parsed_uri.host:_tr_empty;
1193
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1194
0
      break;
1195
0
    case TR_URI_PASSWD:
1196
0
      val->rs = (_tr_parsed_uri.passwd.s)?_tr_parsed_uri.passwd:_tr_empty;
1197
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1198
0
      break;
1199
0
    case TR_URI_PORT:
1200
0
      val->flags |= PV_TYPE_INT|PV_VAL_INT;
1201
0
      val->rs = (_tr_parsed_uri.port.s)?_tr_parsed_uri.port:_tr_empty;
1202
0
      val->ri = _tr_parsed_uri.port_no;
1203
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1204
0
      break;
1205
0
    case TR_URI_PARAMS:
1206
0
      val->rs = (_tr_parsed_uri.params.s)?_tr_parsed_uri.params:_tr_empty;
1207
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1208
0
      break;
1209
0
    case TR_URI_PARAM:
1210
0
      if(tp==NULL)
1211
0
      {
1212
0
        LM_ERR("param invalid parameters\n");
1213
0
        goto error;
1214
0
      }
1215
0
      if(_tr_parsed_uri.params.len<=0)
1216
0
      {
1217
0
        val->flags = PV_VAL_NULL;
1218
0
        break;
1219
0
      }
1220
1221
0
      if(_tr_uri_params == NULL)
1222
0
      {
1223
0
        sv = _tr_parsed_uri.params;
1224
0
        if (parse_params(&sv, CLASS_ANY, &phooks, &_tr_uri_params)<0)
1225
0
          goto error;
1226
0
      }
1227
0
      if(tp->type==TR_PARAM_STRING)
1228
0
      {
1229
0
        sv = tp->v.s;
1230
0
      } else {
1231
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1232
0
            || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
1233
0
        {
1234
0
          LM_ERR("param cannot get p1\n");
1235
0
          goto error;
1236
0
        }
1237
0
        sv = v.rs;
1238
0
      }
1239
0
      for (pit = _tr_uri_params; pit; pit=pit->next)
1240
0
      {
1241
0
        if (pit->name.len==sv.len
1242
0
            && strncasecmp(pit->name.s, sv.s, sv.len)==0)
1243
0
        {
1244
0
          if (ZSTR(pit->body))
1245
0
            val->rs = STR_EMPTY;
1246
0
          else
1247
0
            val->rs = pit->body;
1248
0
          goto done;
1249
0
        }
1250
0
      }
1251
0
      val->flags = PV_VAL_NULL;
1252
0
      break;
1253
0
    case TR_URI_HEADERS:
1254
0
      val->rs = (_tr_parsed_uri.headers.s)?_tr_parsed_uri.headers:
1255
0
            _tr_empty;
1256
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1257
0
      break;
1258
0
    case TR_URI_TRANSPORT:
1259
0
      val->rs = (_tr_parsed_uri.transport_val.s)?
1260
0
        _tr_parsed_uri.transport_val:_tr_empty;
1261
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1262
0
      break;
1263
0
    case TR_URI_TTL:
1264
0
      val->rs = (_tr_parsed_uri.ttl_val.s)?
1265
0
        _tr_parsed_uri.ttl_val:_tr_empty;
1266
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1267
0
      break;
1268
0
    case TR_URI_UPARAM:
1269
0
      val->rs = (_tr_parsed_uri.user_param_val.s)?
1270
0
        _tr_parsed_uri.user_param_val:_tr_empty;
1271
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1272
0
      break;
1273
0
    case TR_URI_MADDR:
1274
0
      val->rs = (_tr_parsed_uri.maddr_val.s)?
1275
0
        _tr_parsed_uri.maddr_val:_tr_empty;
1276
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1277
0
      break;
1278
0
    case TR_URI_METHOD:
1279
0
      val->rs = (_tr_parsed_uri.method_val.s)?
1280
0
        _tr_parsed_uri.method_val:_tr_empty;
1281
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1282
0
      break;
1283
0
    case TR_URI_LR:
1284
0
      val->rs = (_tr_parsed_uri.lr_val.s)?
1285
0
        _tr_parsed_uri.lr_val:_tr_empty;
1286
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1287
0
      break;
1288
0
    case TR_URI_R2:
1289
0
      val->rs = (_tr_parsed_uri.r2_val.s)?
1290
0
        _tr_parsed_uri.r2_val:_tr_empty;
1291
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1292
0
      break;
1293
0
    case TR_URI_SCHEMA:
1294
0
      val->rs.s = _tr_uri.s;
1295
      /* maximum size of schema can be 4 so the ':' shall be found after
1296
       * five chars */
1297
0
      val->rs.len = q_memchr(val->rs.s, ':', 5) - val->rs.s;
1298
0
      break;
1299
0
    default:
1300
0
      LM_ERR("unknown subtype %d\n",
1301
0
          subtype);
1302
0
      goto error;
1303
0
  }
1304
0
done:
1305
0
  return 0;
1306
0
error:
1307
0
  val->flags = PV_VAL_NULL;
1308
0
  return -1;
1309
0
}
1310
1311
1312
/* last via string */
1313
static str _tr_via = {0, 0};
1314
/* the actual len of the allocated buffer (to hold the via) */
1315
static int _tr_via_buf_len = 0;
1316
/* holder for the parsed via */
1317
static struct via_body *_tr_parsed_via = 0;
1318
1319
int tr_eval_via(struct sip_msg *msg, tr_param_t *tp, int subtype,
1320
    pv_value_t *val)
1321
0
{
1322
0
  pv_value_t v;
1323
0
  str sv;
1324
0
  struct via_param *pit;
1325
1326
0
  if (!val)
1327
0
    return -1;
1328
1329
0
  if (val->flags & PV_VAL_NULL)
1330
0
    return 0;
1331
1332
  // WATCHOUT: need at least 2 chars so \r\n check wont segfault
1333
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=2) {
1334
0
    val->flags = PV_VAL_NULL;
1335
0
    return -1;
1336
0
  }
1337
1338
0
  if(_tr_via_buf_len==0 || _tr_via.len!=val->rs.len ||
1339
0
      strncmp(_tr_via.s, val->rs.s, val->rs.len)!=0
1340
0
      || _tr_parsed_via==0)
1341
0
  {
1342
0
    if (val->rs.len+4 > _tr_via_buf_len)
1343
0
    {
1344
0
      if(_tr_via.s) pkg_free(_tr_via.s);
1345
0
      _tr_via.s = (char*)pkg_malloc((val->rs.len+4)*sizeof(char));
1346
0
      if(_tr_via.s==NULL)
1347
0
      {
1348
0
        _tr_via_buf_len = 0;
1349
0
        LM_ERR("no more private memory\n");
1350
0
        goto error;
1351
0
      }
1352
0
      _tr_via_buf_len = val->rs.len+4;
1353
0
    }
1354
0
    _tr_via.len = val->rs.len;
1355
0
    memcpy(_tr_via.s, val->rs.s, val->rs.len);
1356
    // $hdr PV strips off the terminating CRLR
1357
    // parse_via wants to parse a full message (including
1358
    // multiple vias), not just a header line.  Fake this
1359
0
    _tr_via.s[_tr_via.len+0] = '\r';
1360
0
    _tr_via.s[_tr_via.len+1] = '\n';
1361
0
    _tr_via.s[_tr_via.len+2] = 'A'; // anything other than V
1362
0
    _tr_via.s[_tr_via.len+3] = '\0';
1363
    /* reset old values */
1364
0
    free_via_list(_tr_parsed_via);
1365
0
    if ( (_tr_parsed_via=pkg_malloc(sizeof(struct via_body))) == NULL ) {
1366
0
      LM_ERR("no more private memory\n");
1367
0
      goto error;
1368
0
    }
1369
0
    memset(_tr_parsed_via, 0, sizeof(struct via_body));
1370
0
    parse_via(_tr_via.s, _tr_via.s+_tr_via.len+4, _tr_parsed_via);
1371
0
    if(_tr_parsed_via->error != PARSE_OK) {
1372
0
      LM_ERR("invalid via [%.*s]\n", val->rs.len,
1373
0
          val->rs.s);
1374
0
      goto error;
1375
0
    }
1376
0
  }
1377
0
  memset(val, 0, sizeof(pv_value_t));
1378
0
  val->flags = PV_VAL_STR;
1379
1380
0
  switch(subtype)
1381
0
  {
1382
0
    case TR_VIA_NAME:
1383
0
      val->rs = (_tr_parsed_via->name.s)?_tr_parsed_via->name:_tr_empty;
1384
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1385
0
      break;
1386
0
    case TR_VIA_VERSION:
1387
0
      val->rs = (_tr_parsed_via->version.s)?_tr_parsed_via->version:_tr_empty;
1388
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1389
0
      break;
1390
0
    case TR_VIA_TRANSPORT:
1391
0
      val->rs = (_tr_parsed_via->transport.s)?_tr_parsed_via->transport:_tr_empty;
1392
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1393
0
      break;
1394
0
    case TR_VIA_HOST:
1395
0
      val->rs = (_tr_parsed_via->host.s)?_tr_parsed_via->host:_tr_empty;
1396
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1397
0
      break;
1398
0
    case TR_VIA_PORT:
1399
0
      val->flags |= PV_TYPE_INT|PV_VAL_INT;
1400
0
      val->rs = (_tr_parsed_via->port_str.s)?_tr_parsed_via->port_str:_tr_empty;
1401
0
      val->ri = _tr_parsed_via->port;
1402
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1403
0
      break;
1404
0
    case TR_VIA_PARAMS:
1405
0
      val->rs = (_tr_parsed_via->params.s)?_tr_parsed_via->params:_tr_empty;
1406
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1407
0
      break;
1408
0
    case TR_VIA_COMMENT:
1409
0
      val->rs = (_tr_parsed_via->comment.s)?_tr_parsed_via->comment:_tr_empty;
1410
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1411
0
      break;
1412
0
    case TR_VIA_PARAM:  // param by name
1413
0
      if(tp==NULL)
1414
0
      {
1415
0
        LM_ERR("param invalid parameters\n");
1416
0
        val->flags = PV_VAL_NULL;
1417
0
        return -1;
1418
0
      }
1419
0
      if(_tr_parsed_via->params.len<=0)
1420
0
      {
1421
0
        val->flags = PV_VAL_NULL;
1422
0
        break;
1423
0
      }
1424
1425
0
      if(tp->type==TR_PARAM_STRING)
1426
0
      {
1427
0
        sv = tp->v.s;
1428
0
      } else {
1429
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1430
0
            || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
1431
0
        {
1432
0
          LM_ERR("param cannot get p1\n");
1433
0
          val->flags = PV_VAL_NULL;
1434
0
          return -1;
1435
0
        }
1436
0
        sv = v.rs;
1437
0
      }
1438
0
      for (pit = _tr_parsed_via->param_lst; pit; pit=pit->next)
1439
0
      {
1440
0
        if (pit->name.len==sv.len
1441
0
            && strncasecmp(pit->name.s, sv.s, sv.len)==0)
1442
0
        {
1443
0
          val->rs = pit->value;
1444
0
          goto done;
1445
0
        }
1446
0
      }
1447
0
      val->flags = PV_VAL_NULL;
1448
0
      break;
1449
0
    case TR_VIA_BRANCH:
1450
0
      val->rs = (_tr_parsed_via->branch&&_tr_parsed_via->branch->value.s)?_tr_parsed_via->branch->value: _tr_empty;
1451
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1452
0
      break;
1453
0
    case TR_VIA_RECEIVED:
1454
0
      val->rs = (_tr_parsed_via->received&&_tr_parsed_via->received->value.s)?_tr_parsed_via->received->value: _tr_empty;
1455
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1456
0
      break;
1457
0
    case TR_VIA_RPORT:
1458
0
      val->rs = (_tr_parsed_via->rport&&_tr_parsed_via->rport->value.s)?_tr_parsed_via->rport->value: _tr_empty;
1459
0
      val->flags |=  (val->rs.len) ? 0 : PV_VAL_NULL;
1460
0
      break;
1461
0
    default:
1462
0
      LM_ERR("unknown subtype %d\n",
1463
0
          subtype);
1464
0
      val->flags = PV_VAL_NULL;
1465
0
      return -1;
1466
0
  }
1467
1468
0
done:
1469
0
  return 0;
1470
1471
0
error:
1472
0
  if ( _tr_via.s ) {
1473
0
    pkg_free(_tr_via.s);
1474
0
  }
1475
0
  memset(&_tr_via, 0, sizeof(str));
1476
0
  if ( _tr_parsed_via ) {
1477
0
        free_via_list(_tr_parsed_via);
1478
0
    _tr_parsed_via = 0;
1479
0
  }
1480
0
  val->flags = PV_VAL_NULL;
1481
0
  return -1;
1482
0
}
1483
1484
static str _tr_csv_str = {0,0};
1485
static csv_record* _tr_csv_list = NULL;
1486
1487
int tr_eval_csv(struct sip_msg *msg, tr_param_t *tp,int subtype,
1488
    pv_value_t *val)
1489
0
{
1490
0
  csv_record *cit=NULL;
1491
0
  int n,i,list_size=0;
1492
0
  pv_value_t v;
1493
1494
0
  if (!val)
1495
0
    return -1;
1496
1497
0
  if (val->flags & PV_VAL_NULL)
1498
0
    return 0;
1499
1500
0
  if (!(val->flags&PV_VAL_STR) || val->rs.len<=0)
1501
0
    goto error;
1502
1503
0
  if(_tr_csv_str.len==0 || _tr_csv_str.len!=val->rs.len ||
1504
0
      strncmp(_tr_csv_str.s, val->rs.s, val->rs.len)!=0)
1505
0
  {
1506
0
    if(val->rs.len>_tr_csv_str.len)
1507
0
    {
1508
0
      if(_tr_csv_str.s) pkg_free(_tr_csv_str.s);
1509
0
        _tr_csv_str.s = (char*)pkg_malloc((val->rs.len+1));
1510
0
      if(_tr_csv_str.s==NULL)
1511
0
      {
1512
0
        LM_ERR("no more private memory\n");
1513
0
        memset(&_tr_csv_str, 0, sizeof(str));
1514
0
        if(_tr_csv_list != NULL)
1515
0
        {
1516
0
          free_csv_record(_tr_csv_list);
1517
0
          _tr_csv_list = NULL;
1518
0
        }
1519
0
        goto error;
1520
0
      }
1521
0
    }
1522
0
    _tr_csv_str.len = val->rs.len;
1523
0
    memcpy(_tr_csv_str.s, val->rs.s, val->rs.len);
1524
0
    _tr_csv_str.s[_tr_csv_str.len] = '\0';
1525
1526
    /* reset old values */
1527
0
    if(_tr_csv_list != NULL)
1528
0
    {
1529
0
      free_csv_record(_tr_csv_list);
1530
0
      _tr_csv_list = NULL;
1531
0
    }
1532
1533
    /* parse csv */
1534
0
    _tr_csv_list = _parse_csv_record(&_tr_csv_str, CSV_RFC_4180);
1535
0
    if (!_tr_csv_list)
1536
0
      goto error;
1537
0
  }
1538
1539
0
  if (_tr_csv_list == NULL)
1540
0
    goto error;
1541
1542
0
  switch(subtype)
1543
0
  {
1544
0
    case TR_CSV_COUNT:
1545
0
      val->ri = 0;
1546
0
      for (cit=_tr_csv_list;cit;cit=cit->next)
1547
0
        val->ri++;
1548
1549
0
      val->rs.s = int2str(val->ri, &val->rs.len);
1550
0
      val->flags = PV_VAL_INT | PV_VAL_STR | PV_TYPE_INT;
1551
0
      break;
1552
0
    case TR_CSV_VALUEAT:
1553
0
      if(tp==NULL)
1554
0
      {
1555
0
        LM_ERR("csv invalid parameters\n");
1556
0
        goto error;
1557
0
      }
1558
0
      if(tp->type==TR_PARAM_NUMBER)
1559
0
      {
1560
0
        n = tp->v.n;
1561
0
      } else {
1562
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1563
0
            || (!(v.flags&PV_VAL_INT)))
1564
0
        {
1565
0
          LM_ERR("cannot get parameter\n");
1566
0
          goto error;
1567
0
        }
1568
0
        n = v.ri;
1569
0
      }
1570
1571
0
      if (n<0)
1572
0
      {
1573
0
        for (cit=_tr_csv_list;cit;cit=cit->next)
1574
0
          list_size++;
1575
0
        n = list_size + n;
1576
0
        if (n<0)
1577
0
        {
1578
0
          LM_ERR("Too large negative index\n");
1579
0
          goto error;
1580
0
        }
1581
0
      }
1582
1583
0
      cit = _tr_csv_list;
1584
0
      for (i=0;i<n;i++)
1585
0
      {
1586
0
        cit=cit->next;
1587
0
        if (!cit)
1588
0
        {
1589
0
          LM_ERR("Index out of bounds\n");
1590
0
          goto error;
1591
0
        }
1592
0
      }
1593
1594
0
      val->rs = cit->s;
1595
0
      val->flags =  PV_VAL_STR;
1596
0
      break;
1597
1598
0
    default:
1599
0
      LM_ERR("unknown subtype %d\n",subtype);
1600
0
      goto error;
1601
0
  }
1602
1603
0
  return 0;
1604
1605
0
error:
1606
0
  val->flags = PV_VAL_NULL;
1607
0
  return -1;
1608
0
}
1609
1610
static str _tr_sdp_str;
1611
1612
int tr_eval_sdp(struct sip_msg *msg, tr_param_t *tp,int subtype,
1613
    pv_value_t *val)
1614
0
{
1615
0
  str media;
1616
0
  char *bodylimit;
1617
0
  char *answer;
1618
0
  char *answerEnd;
1619
0
  char searchLine;
1620
0
  int entryNo,i,lenoff;
1621
1622
0
  pv_value_t v;
1623
0
  sdp_info_t sdp;
1624
0
  sdp_session_cell_t *session;
1625
0
  sdp_stream_cell_t *stream;
1626
1627
0
  if (!val)
1628
0
    return -1;
1629
1630
0
  if (val->flags & PV_VAL_NULL)
1631
0
    return 0;
1632
1633
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
1634
0
    goto error;
1635
1636
0
  if (!tp)
1637
0
    goto error;
1638
1639
0
  if(_tr_sdp_str.len==0 || _tr_sdp_str.len!=val->rs.len ||
1640
0
      strncmp(_tr_sdp_str.s, val->rs.s, val->rs.len)!=0)
1641
0
  {
1642
0
    if (pkg_str_extend(&_tr_sdp_str, val->rs.len + 3 /* \r\n\0 */) != 0)
1643
0
    {
1644
0
      LM_ERR("no more private memory\n");
1645
0
      goto error;
1646
0
    }
1647
1648
0
    _tr_sdp_str.len = val->rs.len + 2;
1649
0
    _tr_sdp_str.s[0] = '\r';
1650
0
    _tr_sdp_str.s[1] = '\n';
1651
0
    memcpy(_tr_sdp_str.s + 2, val->rs.s, val->rs.len);
1652
0
    _tr_sdp_str.s[_tr_sdp_str.len] = '\0';
1653
1654
0
  }
1655
1656
0
  switch (subtype)
1657
0
  {
1658
0
    case TR_SDP_LINEAT:
1659
1660
      /* line index is mandatory */
1661
0
      if (!tp->next)
1662
0
        goto error;
1663
0
      bodylimit = _tr_sdp_str.s + _tr_sdp_str.len;
1664
0
      searchLine = *(tp->v.s.s);
1665
0
      if(tp->next->type==TR_PARAM_NUMBER)
1666
0
        entryNo = tp->next->v.n;
1667
0
      else
1668
0
      {
1669
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->next->v.data, &v)!=0
1670
0
            || (!(v.flags&PV_VAL_INT)))
1671
0
        {
1672
0
          LM_ERR("cannot get parameter\n");
1673
0
          goto error;
1674
0
        }
1675
0
        entryNo = v.ri;
1676
0
      }
1677
0
      if (entryNo < 0)
1678
0
      {
1679
0
        LM_ERR("negative index provided for sdp.lineat\n");
1680
0
        goto error;
1681
0
      }
1682
1683
0
      answer = find_sdp_line(_tr_sdp_str.s, bodylimit, searchLine);
1684
0
      if (!answer) {
1685
0
        LM_DBG("No such line [%c=]\n", searchLine);
1686
0
        return pv_get_null(NULL, NULL, val);
1687
0
      }
1688
1689
0
      for (i=1;i<=entryNo;i++)
1690
0
      {
1691
0
        answer = find_next_sdp_line(answer,bodylimit,searchLine,bodylimit);
1692
0
        if (!answer || answer == bodylimit)
1693
0
        {
1694
0
          val->flags = PV_VAL_NULL;
1695
0
          LM_DBG("No such line [%c] nr %d in SDP body. Max fields = %d\n",
1696
0
              searchLine,entryNo,i);
1697
0
          return 0;
1698
0
        }
1699
0
      }
1700
1701
      /* find CR */
1702
0
      answerEnd = strchr(answer,13);
1703
0
      if (answerEnd == NULL)
1704
0
      {
1705
0
        LM_ERR("malformed SDP body\n");
1706
0
        goto error;
1707
0
      }
1708
1709
0
      val->flags = PV_VAL_STR;
1710
0
      val->rs.s = answer;
1711
0
      val->rs.len = answerEnd - answer;
1712
1713
0
      break;
1714
1715
0
    case TR_SDP_STREAM:
1716
0
    case TR_SDP_STREAM_DEL:
1717
      /* determine the media type we are talking about
1718
       * either by index or by name */
1719
0
      media = STR_NULL;
1720
0
      entryNo = 0;
1721
0
      switch (tp->type) {
1722
0
        case TR_PARAM_NUMBER:
1723
0
          entryNo = tp->v.n;
1724
0
          break;
1725
0
        case TR_PARAM_STRING:
1726
0
          media = tp->v.s;
1727
0
          break;
1728
0
        case TR_PARAM_SPEC:
1729
0
          media.s = NULL;
1730
0
          if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0)
1731
0
          {
1732
0
            LM_ERR("cannot get parameter\n");
1733
0
            goto error;
1734
0
          }
1735
0
          if (v.flags & PV_VAL_INT)
1736
0
            entryNo = v.ri;
1737
0
          else if (str2sint(&v.rs, &entryNo) < 0)
1738
0
            media = v.rs;
1739
          /* else entryNo has the media index */
1740
0
          break;
1741
0
      }
1742
1743
0
      memset(&sdp, 0, sizeof(sdp));
1744
0
      if (parse_sdp_session(&_tr_sdp_str, 0, NULL, &sdp) < 0)
1745
0
        goto error;
1746
1747
0
      if (media.s == NULL) {
1748
0
        if (entryNo < 0) {
1749
0
          if (entryNo + sdp.streams_num < 0)
1750
            /* out of bounds index */
1751
0
            goto parse_sdp_free;
1752
0
          entryNo += sdp.streams_num;
1753
0
        } else if (entryNo >= sdp.streams_num)
1754
0
          goto parse_sdp_free;
1755
0
        LM_DBG("stream index %d\n", entryNo);
1756
0
      } else
1757
0
        LM_DBG("stream type %.*s\n", media.len, media.s);
1758
0
      lenoff = 0;
1759
0
      if (subtype == TR_SDP_STREAM_DEL) {
1760
0
        for (session = sdp.sessions; session; session = session->next) {
1761
0
          for (stream = session->streams; stream; stream = stream->next) {
1762
0
            if ((media.s != NULL && stream->media.len == media.len &&
1763
                /* hack to update the offset */
1764
0
                strncasecmp(stream->media.s, media.s, media.len) == 0) ||
1765
0
              (media.s == NULL && entryNo == stream->stream_num)) {
1766
1767
0
              memmove(stream->body.s - lenoff, stream->body.s - lenoff + stream->body.len,
1768
0
                  _tr_sdp_str.s + _tr_sdp_str.len - stream->body.s);
1769
0
              _tr_sdp_str.len -= stream->body.len;
1770
1771
0
              if (media.s == NULL)
1772
0
                goto success;
1773
1774
0
              lenoff += stream->body.len;
1775
0
            }
1776
0
          }
1777
0
          if (media.s == NULL)
1778
0
            entryNo -= session->streams_num;
1779
0
        }
1780
0
      } else {
1781
0
        for (session = sdp.sessions; session; session = session->next) {
1782
0
          for (stream = session->streams; stream; stream = stream->next) {
1783
0
            if ((media.s != NULL && stream->media.len == media.len &&
1784
0
                strncasecmp(stream->media.s, media.s, media.len) == 0) ||
1785
0
              (media.s == NULL && entryNo == stream->stream_num)) {
1786
1787
0
              val->rs.len = stream->body.len;
1788
0
              val->rs.s = stream->body.s;
1789
0
              goto ret;
1790
0
            }
1791
0
          }
1792
0
        }
1793
0
      }
1794
0
      if (!lenoff) /* no stream found */
1795
0
        goto parse_sdp_free;
1796
0
success:
1797
0
      val->rs.len = _tr_sdp_str.len - 2;
1798
0
      val->rs.s = _tr_sdp_str.s + 2;
1799
0
ret:
1800
0
      val->flags = PV_VAL_STR;
1801
0
      free_sdp_content(&sdp);
1802
0
      break;
1803
0
    default:
1804
0
      LM_ERR("unknown subtype %d\n",subtype);
1805
0
      goto error;
1806
0
  }
1807
1808
0
  return 0;
1809
1810
0
parse_sdp_free:
1811
0
  free_sdp_content(&sdp);
1812
1813
0
error:
1814
0
  val->flags = PV_VAL_NULL;
1815
0
  return -1;
1816
0
}
1817
1818
int tr_eval_ip(struct sip_msg *msg, tr_param_t *tp,int subtype,
1819
    pv_value_t *val)
1820
0
{
1821
0
  char *buffer, *_tr_buffer = get_tr_buffer();
1822
0
  struct ip_addr *p_ip;
1823
0
  str inet = str_init("INET");
1824
0
  str inet6 = str_init("INET6");
1825
0
  struct hostent *server;
1826
0
  struct ip_addr ip;
1827
0
  unsigned int len, rc;
1828
0
  struct net *mask;
1829
0
  pv_value_t v;
1830
0
  str sv;
1831
0
  char *p;
1832
1833
0
  if (!val)
1834
0
    return -1;
1835
1836
0
  if (val->flags & PV_VAL_NULL)
1837
0
    return 0;
1838
1839
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
1840
0
    goto error;
1841
1842
0
  switch (subtype)
1843
0
  {
1844
0
    case TR_IP_FAMILY:
1845
0
      if (val->rs.len == 4)
1846
0
      {
1847
0
        memcpy(val->rs.s,inet.s,inet.len);
1848
0
        val->rs.len = inet.len;
1849
0
      }
1850
0
      else if (val->rs.len == 16)
1851
0
      {
1852
0
        memcpy(val->rs.s,inet6.s,inet6.len);
1853
0
        val->rs.len = inet6.len;
1854
0
      }
1855
0
      else
1856
0
      {
1857
0
        LM_ERR("Invalid ip address provided for ip.family. "
1858
0
          "Binary format expected !\n");
1859
0
        goto error;
1860
0
      }
1861
1862
0
      val->flags = PV_VAL_STR;
1863
0
      break;
1864
0
    case TR_IP_NTOP:
1865
0
      if (val->rs.len == 4)
1866
0
        ip.af = AF_INET;
1867
0
      else if (val->rs.len == 16)
1868
0
        ip.af = AF_INET6;
1869
0
      else
1870
0
      {
1871
0
        LM_ERR("Invalid ip address provided for ip.ntop. "
1872
0
          "Binary format expected !\n");
1873
0
        goto error;
1874
0
      }
1875
1876
0
      memcpy(ip.u.addr,val->rs.s,val->rs.len);
1877
0
      ip.len = val->rs.len;
1878
0
      buffer = ip_addr2a(&ip);
1879
1880
0
      val->rs.len = strlen(buffer);
1881
0
      memcpy(_tr_buffer, buffer, val->rs.len);
1882
0
      val->rs.s = _tr_buffer;
1883
1884
0
      val->flags = PV_VAL_STR;
1885
0
      break;
1886
0
    case TR_IP_ISIP:
1887
0
      if(!(val->flags&PV_VAL_STR))
1888
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1889
1890
0
      if ( str2ip(&(val->rs)) || str2ip6(&(val->rs)) )
1891
0
        val->ri = 1;
1892
0
      else
1893
0
        val->ri = 0;
1894
1895
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
1896
0
      val->rs.s = int2str(val->ri, &val->rs.len);
1897
0
      break;
1898
0
    case TR_IP_ISIP4:
1899
0
      if(!(val->flags&PV_VAL_STR))
1900
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1901
1902
0
      if (str2ip(&(val->rs)))
1903
0
        val->ri = 1;
1904
0
      else
1905
0
        val->ri = 0;
1906
1907
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
1908
0
      val->rs.s = int2str(val->ri, &val->rs.len);
1909
0
      break;
1910
0
    case TR_IP_ISIP6:
1911
0
      if(!(val->flags&PV_VAL_STR))
1912
0
        val->rs.s = int2str(val->ri, &val->rs.len);
1913
1914
0
      if (str2ip6(&(val->rs)))
1915
0
        val->ri = 1;
1916
0
      else
1917
0
        val->ri = 0;
1918
1919
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
1920
0
      val->rs.s = int2str(val->ri, &val->rs.len);
1921
0
      break;
1922
0
    case TR_IP_PTON:
1923
0
      p_ip = str2ip(&(val->rs));
1924
0
      if (!p_ip)
1925
0
      {
1926
0
        p_ip = str2ip6(&(val->rs));
1927
0
        if (!p_ip)
1928
0
        {
1929
0
          LM_ERR("pton transformation applied to invalid IP\n");
1930
0
          goto error;
1931
0
        }
1932
0
      }
1933
1934
0
      memcpy(_tr_buffer, (char *)p_ip->u.addr, p_ip->len);
1935
0
      val->rs.s = _tr_buffer;
1936
0
      val->rs.len = p_ip->len;
1937
1938
0
      val->flags = PV_VAL_STR;
1939
0
      break;
1940
0
    case TR_IP_RESOLVE:
1941
0
    case TR_IP_RESOLVE_V4:
1942
0
    case TR_IP_RESOLVE_V6:
1943
0
      val->flags = PV_VAL_STR;
1944
0
      if (val->rs.len + 1 > TR_BUFFER_SIZE) {
1945
0
        LM_ERR("failed to resolve host, length too large (%d)\n",
1946
0
               val->rs.len);
1947
0
        goto error;
1948
0
      }
1949
0
      memcpy(_tr_buffer, val->rs.s, val->rs.len);
1950
0
      _tr_buffer[val->rs.len] = '\0';
1951
1952
0
      if (subtype == TR_IP_RESOLVE_V4)
1953
0
        server = resolvehost_af(_tr_buffer, 0, AF_INET);
1954
0
      else if (subtype == TR_IP_RESOLVE_V6)
1955
0
        server = resolvehost_af(_tr_buffer, 0, AF_INET6);
1956
0
      else
1957
0
        server = resolvehost(_tr_buffer, 0);
1958
0
      if (!server || !server->h_addr)
1959
0
      {
1960
0
        val->flags = PV_VAL_NULL;
1961
0
        return 0;
1962
0
      }
1963
1964
0
      if (server->h_addrtype == AF_INET)
1965
0
      {
1966
0
        memcpy(ip.u.addr,server->h_addr,4);
1967
0
        ip.len = 4;
1968
0
        ip.af = AF_INET;
1969
0
      }
1970
0
      else if (server->h_addrtype == AF_INET6)
1971
0
      {
1972
0
        memcpy(ip.u.addr,server->h_addr,16);
1973
0
        ip.len = 16;
1974
0
        ip.af = AF_INET6;
1975
0
      }
1976
0
      else
1977
0
      {
1978
0
        LM_ERR("Unexpected IP address type \n");
1979
0
        goto error;
1980
0
      }
1981
1982
0
      buffer = ip_addr2a(&ip);
1983
1984
0
      val->rs.len = strlen(buffer);
1985
0
      memcpy(_tr_buffer, buffer, val->rs.len);
1986
0
      val->rs.s = _tr_buffer;
1987
1988
0
      break;
1989
0
    case TR_IP_MATCHES:
1990
      /* get the input which must be an IP addr as string */
1991
0
      if ( (p_ip=str2ip(&val->rs))==NULL &&
1992
0
      (p_ip=str2ip6(&val->rs))==NULL ) {
1993
0
        LM_ERR("Invalid input IP address <%.*s>\n",
1994
0
          val->rs.len,val->rs.s);
1995
0
        goto error;
1996
0
      }
1997
0
      ip = *p_ip;
1998
      /* get the parameter which must be IP/netlen */
1999
0
      if (tp->type == TR_PARAM_STRING) {
2000
0
        sv = tp->v.s;
2001
0
      } else {
2002
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2003
0
            || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0) {
2004
0
          LM_ERR("cannot get value from spec\n");
2005
0
          goto error;
2006
0
        }
2007
0
        sv = v.rs;
2008
0
      }
2009
      /* the value must be in "ip/marsklen" format */
2010
0
      if ( (p=q_memchr(sv.s, '/', sv.len))==NULL) {
2011
0
        LM_ERR("value not in ip/len format, separator not found\n");
2012
0
        goto error;
2013
0
      }
2014
0
      val->rs.s = sv.s;
2015
0
      val->rs.len = p-sv.s;
2016
0
      if ( (p_ip=str2ip(&val->rs))==NULL &&
2017
0
      (p_ip=str2ip6(&val->rs))==NULL ) {
2018
0
        LM_ERR("Invalid parameter IP address <%.*s>\n",
2019
0
          val->rs.len,val->rs.s);
2020
0
        goto error;
2021
0
      }
2022
0
      val->rs.s = p+1;
2023
0
      val->rs.len = sv.s+sv.len-p-1;
2024
0
      if (str2int(&val->rs, &len)!=0 || len>p_ip->len*8) {
2025
0
        LM_ERR("Invalid mask len in parameter <%.*s>\n",
2026
0
          val->rs.len,val->rs.s);
2027
0
        goto error;
2028
0
      }
2029
2030
0
      mask = mk_net_bitlen(p_ip, len);
2031
0
      rc = matchnet(&ip, mask);
2032
0
      pkg_free(mask);
2033
2034
0
      switch (rc) {
2035
0
        case 1: /* matches */
2036
0
          val->ri = 1; break;
2037
0
        case 0: /* does not matches */
2038
0
          val->ri = 0; break;
2039
0
        default:
2040
0
          LM_ERR("cannot compare, different AF?\n");
2041
0
          goto error;
2042
0
      }
2043
2044
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
2045
0
      val->rs.s = int2str(val->ri, &val->rs.len);
2046
0
      break;
2047
0
    case TR_IP_ISPRIVATE:
2048
0
      if(!(val->flags&PV_VAL_STR))
2049
0
        val->rs.s = int2str(val->ri, &val->rs.len);
2050
2051
0
      val->ri = ip_addr_is_1918(&(val->rs), 0);
2052
2053
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
2054
0
      val->rs.s = int2str(val->ri, &val->rs.len);
2055
0
      break;
2056
2057
0
    default:
2058
0
      LM_ERR("unknown subtype %d\n",subtype);
2059
0
      goto error;
2060
0
  }
2061
2062
0
  return 0;
2063
0
error:
2064
0
  val->flags = PV_VAL_NULL;
2065
0
  return -1;
2066
0
}
2067
2068
static char *reg_input_buf = NULL;
2069
static struct subst_expr *subst_re = NULL;
2070
static str buf_re = { 0, 0 };
2071
int tr_eval_re(struct sip_msg *msg, tr_param_t *tp, int subtype,
2072
    pv_value_t *val)
2073
0
{
2074
0
  int match_no=0;
2075
0
  pv_value_t v;
2076
0
  str *result;
2077
0
  str sv;
2078
0
  char *s, *e, *p;
2079
0
  char *buf;
2080
2081
0
  if (!val)
2082
0
    return -1;
2083
2084
0
  if (val->flags & PV_VAL_NULL)
2085
0
    return 0;
2086
2087
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
2088
0
    goto error;
2089
2090
0
  switch (subtype) {
2091
0
    case TR_RE_SUBST:
2092
0
        if (tp->type == TR_PARAM_STRING) {
2093
0
          sv = tp->v.s;
2094
0
        } else {
2095
0
          if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2096
0
              || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0) {
2097
0
            LM_ERR("cannot get value from spec\n");
2098
0
            goto error;
2099
0
          }
2100
0
          sv = v.rs;
2101
0
        }
2102
        /* temporary use the regex input buffer to check the subst */
2103
0
        buf = pkg_realloc(reg_input_buf, sv.len);
2104
0
        if (!buf) {
2105
0
          LM_ERR("not enough memory for regex buffer %d [%.*s]\n",
2106
0
              sv.len, sv.len, sv.s);
2107
0
          goto error;
2108
0
        }
2109
0
        reg_input_buf = buf;
2110
        /* copy un-escaped str to buf */
2111
0
        for (s = sv.s, e = sv.s + sv.len, p = buf; s < e; s++, p++) {
2112
0
          if (*s=='\\') {
2113
0
            if (s + 1 >= e)
2114
0
              break;
2115
0
            if (*(s + 1) == TR_RBRACKET || *(s + 1) == TR_LBRACKET) {
2116
0
              s++;
2117
0
              sv.len--;
2118
0
            }
2119
0
          }
2120
0
          *p = *s;
2121
0
        }
2122
0
        sv.s = buf;
2123
2124
0
        LM_DBG("Trying to apply regexp [%.*s] on : [%.*s]\n",
2125
0
            sv.len,sv.s,val->rs.len, val->rs.s);
2126
0
        if (subst_re==NULL || !buf_re.s || buf_re.len != sv.len ||
2127
0
        memcmp(buf_re.s, sv.s, sv.len) != 0) {
2128
0
          LM_DBG("we must compile the regexp\n");
2129
0
          if (subst_re != NULL) {
2130
0
            LM_DBG("freeing prev regexp\n");
2131
0
            subst_expr_free(subst_re);
2132
0
          }
2133
0
          subst_re=subst_parser(&sv);
2134
0
          if (subst_re==0) {
2135
0
            LM_ERR("Can't compile regexp\n");
2136
0
            goto error;
2137
0
          }
2138
          /* swap buffers */
2139
0
          reg_input_buf = buf_re.s;
2140
0
          buf_re.s = buf;
2141
0
          buf_re.len = sv.len;
2142
0
        } else
2143
0
          LM_DBG("yay, we can use the pre-compile regexp\n");
2144
2145
0
        buf = pkg_realloc(reg_input_buf, val->rs.len + 1);
2146
0
        if (!buf) {
2147
0
          LM_ERR("not enough memory for input buffer %d [%.*s]\n",
2148
0
              val->rs.len + 1, val->rs.len, val->rs.s);
2149
0
          goto error;
2150
0
        }
2151
0
        reg_input_buf = buf;
2152
0
        memcpy(reg_input_buf,val->rs.s,val->rs.len);
2153
0
        reg_input_buf[val->rs.len]=0;
2154
2155
0
        result=subst_str(reg_input_buf, msg, subst_re, &match_no);
2156
0
        if (result == NULL) {
2157
0
          if (match_no == 0) {
2158
0
            LM_DBG("no match for subst expression\n");
2159
0
            break;
2160
0
          } else if (match_no < 0) {
2161
0
            LM_ERR("subst failed\n");
2162
0
            goto error;
2163
0
          }
2164
0
        }
2165
        /* release the input buffer */
2166
0
        pkg_free(reg_input_buf);
2167
0
        reg_input_buf = result->s;
2168
0
        val->flags = PV_VAL_STR;
2169
0
        val->rs.s = result->s;
2170
0
        val->rs.len = result->len;
2171
0
        pkg_free(result);
2172
0
        return 0;
2173
0
    default:
2174
0
      LM_ERR("Unexpected subtype for RE : %d\n",subtype);
2175
0
      goto error;
2176
0
  }
2177
0
  return 0;
2178
2179
0
error:
2180
0
  val->flags = PV_VAL_NULL;
2181
0
  return -1;
2182
0
}
2183
2184
static str _tr_params_str = {0, 0};
2185
static param_t* _tr_params_list = NULL;
2186
2187
int tr_eval_paramlist(struct sip_msg *msg, tr_param_t *tp, int subtype,
2188
    pv_value_t *val)
2189
0
{
2190
0
  pv_value_t v;
2191
0
  str sv;
2192
0
  int n, i;
2193
0
  param_hooks_t phooks;
2194
0
  param_t *pit=NULL;
2195
2196
0
  if (!val)
2197
0
    return -1;
2198
2199
0
  if (val->flags & PV_VAL_NULL)
2200
0
    return 0;
2201
2202
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
2203
0
    goto error;
2204
2205
0
  if(_tr_params_str.len==0 || _tr_params_str.len!=val->rs.len ||
2206
0
      strncmp(_tr_params_str.s, val->rs.s, val->rs.len)!=0)
2207
0
  {
2208
2209
0
    if(val->rs.len>_tr_params_str.len)
2210
0
    {
2211
0
      if(_tr_params_str.s) pkg_free(_tr_params_str.s);
2212
0
      _tr_params_str.s = (char*)pkg_malloc((val->rs.len+1)*sizeof(char));
2213
0
      if(_tr_params_str.s==NULL)
2214
0
      {
2215
0
        LM_ERR("no more private memory\n");
2216
0
        memset(&_tr_params_str, 0, sizeof(str));
2217
0
        if(_tr_params_list != NULL)
2218
0
        {
2219
0
          free_params(_tr_params_list);
2220
0
          _tr_params_list = 0;
2221
0
        }
2222
0
        goto error;
2223
0
      }
2224
0
    }
2225
0
    _tr_params_str.len = val->rs.len;
2226
0
    memcpy(_tr_params_str.s, val->rs.s, val->rs.len);
2227
0
    _tr_params_str.s[_tr_params_str.len] = '\0';
2228
2229
    /* reset old values */
2230
0
    if(_tr_params_list != NULL)
2231
0
    {
2232
0
      free_params(_tr_params_list);
2233
0
      _tr_params_list = 0;
2234
0
    }
2235
2236
    /* parse params */
2237
0
    sv = _tr_params_str;
2238
0
    if (parse_params(&sv, CLASS_ANY, &phooks, &_tr_params_list)<0)
2239
0
      goto error;
2240
2241
0
  }
2242
2243
0
  if(_tr_params_list==NULL)
2244
0
    goto error;
2245
2246
0
  memset(val, 0, sizeof(pv_value_t));
2247
0
  val->flags = PV_VAL_STR;
2248
2249
0
  switch(subtype)
2250
0
  {
2251
0
    case TR_PL_VALUE:
2252
0
      if(tp==NULL)
2253
0
      {
2254
0
        LM_ERR("value invalid parameters\n");
2255
0
        goto error;
2256
0
      }
2257
2258
0
      if(tp->type==TR_PARAM_STRING)
2259
0
      {
2260
0
        sv = tp->v.s;
2261
0
      } else {
2262
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2263
0
            || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
2264
0
        {
2265
0
          LM_ERR("value cannot get p1\n");
2266
0
          goto error;
2267
0
        }
2268
0
        sv = v.rs;
2269
0
      }
2270
2271
0
      for (pit = _tr_params_list; pit; pit=pit->next)
2272
0
      {
2273
0
        if (pit->name.len==sv.len
2274
0
            && strncasecmp(pit->name.s, sv.s, sv.len)==0)
2275
0
        {
2276
0
          if (ZSTR(pit->body))
2277
0
            val->rs = STR_EMPTY;
2278
0
          else
2279
0
            val->rs = pit->body;
2280
0
          goto done;
2281
0
        }
2282
0
      }
2283
0
      val->flags = PV_VAL_NULL;
2284
0
      break;
2285
2286
0
    case TR_PL_VALUEAT:
2287
0
      if(tp==NULL)
2288
0
      {
2289
0
        LM_ERR("name invalid parameters\n");
2290
0
        goto error;
2291
0
      }
2292
2293
0
      if(tp->type==TR_PARAM_NUMBER)
2294
0
      {
2295
0
        n = tp->v.n;
2296
0
      } else {
2297
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2298
0
            || (!(v.flags&PV_VAL_INT)))
2299
0
        {
2300
0
          LM_ERR("name cannot get p1\n");
2301
0
          goto error;
2302
0
        }
2303
0
        n = v.ri;
2304
0
      }
2305
0
      if(n>=0)
2306
0
      {
2307
0
        for (pit = _tr_params_list; pit; pit=pit->next)
2308
0
        {
2309
0
          if(n==0)
2310
0
          {
2311
0
            val->rs = pit->body;
2312
0
            goto done;
2313
0
          }
2314
0
          n--;
2315
0
        }
2316
0
      } else {
2317
        /* ugly hack -- params are in reverse order
2318
         * - first count then find */
2319
0
        n = -n;
2320
0
        n--;
2321
2322
0
        i = 0;
2323
0
        for (pit = _tr_params_list; pit; pit=pit->next)
2324
0
          i++;
2325
0
        if(n<i)
2326
0
        {
2327
0
          n = i - n - 1;
2328
0
          for (pit = _tr_params_list; pit; pit=pit->next)
2329
0
          {
2330
0
            if(n==0)
2331
0
            {
2332
0
              val->rs = pit->body;
2333
0
              goto done;
2334
0
            }
2335
0
            n--;
2336
0
          }
2337
0
        }
2338
0
      }
2339
0
      val->flags = PV_VAL_NULL;
2340
0
      break;
2341
2342
0
    case TR_PL_NAME:
2343
0
      if(tp==NULL)
2344
0
      {
2345
0
        LM_ERR("name invalid parameters\n");
2346
0
        goto error;
2347
0
      }
2348
2349
0
      if(tp->type==TR_PARAM_NUMBER)
2350
0
      {
2351
0
        n = tp->v.n;
2352
0
      } else {
2353
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2354
0
            || (!(v.flags&PV_VAL_INT)))
2355
0
        {
2356
0
          LM_ERR("name cannot get p1\n");
2357
0
          goto error;
2358
0
        }
2359
0
        n = v.ri;
2360
0
      }
2361
0
      if(n>=0)
2362
0
      {
2363
0
        for (pit = _tr_params_list; pit; pit=pit->next)
2364
0
        {
2365
0
          if(n==0)
2366
0
          {
2367
0
            val->rs = pit->name;
2368
0
            goto done;
2369
0
          }
2370
0
          n--;
2371
0
        }
2372
0
      } else {
2373
        /* ugly hack -- params are in sorted order
2374
         * - first count then find */
2375
0
        n = -n;
2376
0
        n--;
2377
2378
0
        i = 0;
2379
0
        for (pit = _tr_params_list; pit; pit=pit->next)
2380
0
          i++;
2381
0
        if(n<i)
2382
0
        {
2383
0
          n = i - n - 1;
2384
0
          for (pit = _tr_params_list; pit; pit=pit->next)
2385
0
          {
2386
0
            if(n==0)
2387
0
            {
2388
0
              val->rs = pit->name;
2389
0
              goto done;
2390
0
            }
2391
0
            n--;
2392
0
          }
2393
0
        }
2394
0
      }
2395
0
      val->flags = PV_VAL_NULL;
2396
0
      break;
2397
2398
0
    case TR_PL_COUNT:
2399
0
      val->ri = 0;
2400
0
      for (pit = _tr_params_list; pit; pit=pit->next) {
2401
0
        val->ri++;
2402
0
      }
2403
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
2404
0
      val->rs.s = int2str(val->ri, &val->rs.len);
2405
0
      break;
2406
2407
2408
0
    case TR_PL_EXIST:
2409
0
      if(tp==NULL)
2410
0
      {
2411
0
        LM_ERR("value invalid parameters\n");
2412
0
        goto error;
2413
0
      }
2414
2415
0
      if(tp->type==TR_PARAM_STRING)
2416
0
      {
2417
0
        sv = tp->v.s;
2418
0
      } else {
2419
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2420
0
            || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
2421
0
        {
2422
0
          LM_ERR("value cannot get p1\n");
2423
0
          goto error;
2424
0
        }
2425
0
        sv = v.rs;
2426
0
      }
2427
2428
0
      val->ri = 0;
2429
0
      for (pit = _tr_params_list; pit; pit=pit->next)
2430
0
      {
2431
0
        if (pit->name.len==sv.len
2432
0
            && strncasecmp(pit->name.s, sv.s, sv.len)==0)
2433
0
        {
2434
0
          val->ri = 1;
2435
0
          break;
2436
0
        }
2437
0
      }
2438
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
2439
0
      val->rs.s = int2str(val->ri, &val->rs.len);
2440
0
      goto done;
2441
2442
0
    default:
2443
0
      LM_ERR("unknown subtype %d\n",
2444
0
          subtype);
2445
0
      goto error;
2446
0
  }
2447
2448
0
done:
2449
0
  return 0;
2450
0
error:
2451
0
  val->flags = PV_VAL_NULL;
2452
0
  return -1;
2453
0
}
2454
2455
static str nameaddr_str = {0, 0};
2456
static struct to_body *nameaddr_to_body = NULL;
2457
2458
int tr_eval_nameaddr(struct sip_msg *msg, tr_param_t *tp, int subtype,
2459
    pv_value_t *val)
2460
0
{
2461
0
  struct to_param* topar;
2462
0
  pv_value_t v;
2463
0
  int index, total;
2464
0
  struct to_body *nameaddr = NULL;
2465
2466
0
  if (!val)
2467
0
    return -1;
2468
2469
0
  if (val->flags & PV_VAL_NULL)
2470
0
    return 0;
2471
2472
0
  if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
2473
0
    goto error;
2474
2475
0
  LM_DBG("String to transform %.*s\n", val->rs.len, val->rs.s);
2476
2477
0
  if(nameaddr_str.len==0 || nameaddr_str.len!=val->rs.len ||
2478
0
      strncmp(nameaddr_str.s, val->rs.s, val->rs.len)!=0)
2479
0
  {
2480
    /* copy the value in the global variable */
2481
0
    if(val->rs.len+CRLF_LEN > nameaddr_str.len)
2482
0
    {
2483
0
      if(nameaddr_str.s) pkg_free(nameaddr_str.s);
2484
0
      nameaddr_str.s =
2485
0
          (char*)pkg_malloc((val->rs.len+CRLF_LEN+1)*sizeof(char));
2486
0
      if(nameaddr_str.s==NULL)
2487
0
      {
2488
0
        LM_ERR("no more private memory\n");
2489
0
        memset(&nameaddr_str, 0, sizeof(str));
2490
0
        goto error;
2491
0
      }
2492
0
    }
2493
0
    nameaddr_str.len = val->rs.len + CRLF_LEN;
2494
0
    memcpy(nameaddr_str.s, val->rs.s, val->rs.len);
2495
0
    memcpy(nameaddr_str.s + val->rs.len, CRLF, CRLF_LEN);
2496
0
    nameaddr_str.s[nameaddr_str.len] = '\0';
2497
2498
    /* reset old values */
2499
0
    if (nameaddr_to_body) {
2500
0
      free_to(nameaddr_to_body);
2501
0
      nameaddr_to_body = NULL;
2502
0
    }
2503
2504
    /* parse TO hdr + params */
2505
0
    nameaddr_to_body = (struct to_body*)pkg_malloc(sizeof(struct to_body));
2506
0
    if(nameaddr_to_body==NULL)
2507
0
    {
2508
0
      LM_ERR("no more private memory\n");
2509
      /* keep the buffer, but flush the content to force the realloc
2510
         next time */
2511
0
      nameaddr_str.s[0] = 0;
2512
0
      goto error;
2513
0
    }
2514
0
    parse_multi_to(nameaddr_str.s, nameaddr_str.s + nameaddr_str.len,
2515
0
      nameaddr_to_body);
2516
0
  }
2517
2518
0
  if (nameaddr_to_body->error == PARSE_ERROR)
2519
0
  {
2520
0
    LM_ERR("Wrong syntax. It must have the To header format\n");
2521
0
    goto error;
2522
0
  }
2523
2524
  /* check if there is an index set */
2525
0
  if (tp && (subtype != TR_NA_PARAM || tp->next)) {
2526
    /* we do have an index */
2527
0
    switch (tp->type) {
2528
0
      case TR_PARAM_NUMBER:
2529
0
        index = tp->v.n;
2530
0
        break;
2531
0
      case TR_PARAM_SPEC:
2532
0
        if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
2533
0
            || (!(v.flags&PV_VAL_INT)))
2534
0
        {
2535
0
          LM_ERR("invalid index type: %d; integer expected\n",
2536
0
              v.flags);
2537
0
          goto error;
2538
0
        }
2539
0
        index = v.ri;
2540
0
        break;
2541
0
      default:
2542
0
        LM_ERR("unsupported index type: %d\n", tp->type);
2543
0
        goto error;
2544
0
    }
2545
0
    tp = tp->next;
2546
0
    if (index < 0) {
2547
0
      total = 0;
2548
0
      for (nameaddr = nameaddr_to_body; nameaddr; nameaddr = nameaddr->next)
2549
0
        total++;
2550
0
      if (index + total < 0) {
2551
0
        LM_DBG("index %d out of bounds %d\n", index, total);
2552
0
        goto out_of_bounds;
2553
0
      }
2554
0
      index = total + index;
2555
0
    }
2556
0
    for (nameaddr = nameaddr_to_body;
2557
0
        nameaddr && index != 0;
2558
0
        nameaddr = nameaddr->next, index--);
2559
0
    if (index > 0 || !nameaddr) {
2560
0
      LM_DBG("index out of bounds\n");
2561
0
      goto out_of_bounds;
2562
0
    }
2563
2564
0
  } else {
2565
    /* otherwise we default to first body */
2566
0
    nameaddr = nameaddr_to_body;
2567
0
  }
2568
2569
0
  memset(val, 0, sizeof(pv_value_t));
2570
0
  val->flags = PV_VAL_STR;
2571
2572
0
  switch(subtype)
2573
0
  {
2574
0
    case TR_NA_URI:
2575
0
      val->rs =(nameaddr->uri.s)?nameaddr->uri:_tr_empty;
2576
0
      val->flags |= (val->rs.len) ? 0 : PV_VAL_NULL;
2577
0
      break;
2578
0
    case TR_NA_LEN:
2579
0
      val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
2580
0
      val->ri = nameaddr->body.len;
2581
0
      val->rs.s = int2str(val->ri, &val->rs.len);
2582
0
      break;
2583
0
    case TR_NA_NAME:
2584
0
      val->rs = (nameaddr->display.s)?
2585
0
        nameaddr->display:_tr_empty;
2586
0
      val->flags |= (val->rs.len) ? 0 : PV_VAL_NULL;
2587
0
      break;
2588
0
    case TR_NA_PARAM:
2589
0
      if (!tp)
2590
0
        goto error;
2591
0
      if(tp->type != TR_PARAM_STRING)
2592
0
      {
2593
0
        LM_ERR("Wrong type for parameter, it must string\n");
2594
0
        goto error;
2595
0
      }
2596
0
      topar = nameaddr->param_lst;
2597
      /* search the parameter */
2598
0
      while(topar)
2599
0
      {
2600
0
        if(topar->name.len == tp->v.s.len &&
2601
0
            strncmp(topar->name.s, tp->v.s.s, topar->name.len)== 0)
2602
0
          break;
2603
0
        topar = topar->next;
2604
0
      }
2605
0
      val->rs = (topar)?topar->value:_tr_empty;
2606
0
      val->flags |= (val->rs.len) ? 0 : PV_VAL_NULL;
2607
0
      break;
2608
0
    case TR_NA_PARAMS:
2609
0
      topar = nameaddr->param_lst;
2610
0
      if (!topar) {
2611
0
        LM_DBG("no params\n");
2612
0
        val->flags = PV_VAL_NULL;
2613
0
      }
2614
0
      else {
2615
0
        LM_DBG("We have params\n");
2616
0
        val->rs.s = topar->name.s;
2617
0
        if (nameaddr->last_param->value.s==NULL) {
2618
0
          val->rs.len = nameaddr->last_param->name.s +
2619
0
            nameaddr->last_param->name.len - val->rs.s;
2620
0
        } else {
2621
0
          val->rs.len = nameaddr->last_param->value.s +
2622
0
            nameaddr->last_param->value.len - val->rs.s;
2623
          /* compensate the len if the value of the last param is
2624
           * a quoted value (include the closing quote in the len) */
2625
0
          if ( (val->rs.s+val->rs.len<nameaddr_str.len+nameaddr_str.s) &&
2626
0
          (val->rs.s[val->rs.len]=='"' || val->rs.s[val->rs.len]=='\'' ) )
2627
0
            val->rs.len++;
2628
0
        }
2629
0
      }
2630
0
      break;
2631
2632
0
    default:
2633
0
      LM_ERR("unknown subtype %d\n", subtype);
2634
0
      goto error;
2635
0
  }
2636
2637
0
  return 0;
2638
2639
0
error:
2640
0
  val->flags = PV_VAL_NULL;
2641
0
  return -1;
2642
0
out_of_bounds:
2643
0
  val->flags = PV_VAL_NULL;
2644
0
  return 0;
2645
0
}
2646
2647
2648
0
#define is_in_str(p, in) (p<in->s+in->len && *p)
2649
2650
char* parse_transformation(str *in, trans_t **tr)
2651
0
{
2652
0
  char *p;
2653
0
  str tclass;
2654
0
  trans_t *t = NULL;
2655
0
  trans_t *t0 = NULL;
2656
0
  str s;
2657
0
  const trans_export_t *tr_export;
2658
0
  trans_extra_t *tr_extra;
2659
0
  int i, nesting_level = 0;
2660
2661
0
  if(in==NULL || in->s==NULL || tr==NULL)
2662
0
    return NULL;
2663
2664
0
  p = in->s;
2665
0
  do {
2666
0
    while(is_in_str(p, in) && is_ws(*p)) p++;
2667
0
    if(*p != TR_LBRACKET)
2668
0
      break;
2669
0
    p++;
2670
2671
0
    t = (trans_t*)pkg_malloc(sizeof(trans_t));
2672
0
    if(t == NULL)
2673
0
    {
2674
0
      LM_ERR("no more private memory\n");
2675
0
      return NULL;
2676
0
    }
2677
0
    memset(t, 0, sizeof(trans_t));
2678
0
    if(t0==NULL)
2679
0
      *tr = t;
2680
0
    else
2681
0
      t0->next = t;
2682
0
    t0 = t;
2683
2684
    /* find transformation class */
2685
0
    tclass.s = p;
2686
0
    while(is_in_str(p, in) && *p!=TR_CLASS_MARKER) p++;
2687
0
    if(*p!=TR_CLASS_MARKER || tclass.s == p)
2688
0
    {
2689
0
      LM_ERR("invalid transformation: %.*s (%c)!\n", in->len, in->s, *p);
2690
0
      goto error;
2691
0
    }
2692
0
    tclass.len = p - tclass.s;
2693
0
    p++;
2694
2695
0
    tr_export = NULL;
2696
2697
    /* search through core transformations */
2698
0
    for (i = 0; core_trans[i].name.s; i++)
2699
0
      if (core_trans[i].name.len == tclass.len &&
2700
0
        !strncasecmp(core_trans[i].name.s, tclass.s, tclass.len)) {
2701
0
        tr_export = &core_trans[i];
2702
0
        break;
2703
0
      }
2704
2705
0
    if (!tr_export)
2706
      /* search through module exported transformations */
2707
0
      for (tr_extra = tr_extra_list; tr_extra; tr_extra = tr_extra->next)
2708
0
        if (tr_extra->tre.name.len == tclass.len &&
2709
0
          !strncasecmp(tr_extra->tre.name.s, tclass.s, tclass.len)) {
2710
0
          tr_export = &tr_extra->tre;
2711
0
          break;
2712
0
        }
2713
2714
0
    if (!tr_export) {
2715
0
      LM_ERR("unknown transformation: [%.*s] in [%.*s]\n",
2716
0
        tclass.len, tclass.s, in->len, in->s);
2717
0
      goto error;
2718
0
    }
2719
2720
0
    t->trf = tr_export->eval_func;
2721
2722
0
    s.s = p;
2723
    /* allow nested transformations! */
2724
0
    while(is_in_str(p, in) && (nesting_level > 0 || *p != TR_RBRACKET)) {
2725
0
      if (*p == TR_LBRACKET)
2726
0
        nesting_level++;
2727
2728
0
      if (*p == TR_RBRACKET)
2729
0
        nesting_level--;
2730
0
      p++;
2731
0
    }
2732
2733
0
    if(*p == '\0') {
2734
0
      LM_ERR("invalid transformation: %.*s\n", in->len, in->s);
2735
0
      goto error;
2736
0
    }
2737
0
    s.len = p - s.s;
2738
2739
0
    if (tr_export->parse_func(&s, t) < 0)
2740
0
      goto error;
2741
2742
0
    p++;
2743
0
    if(!is_in_str(p, in))
2744
0
      break;
2745
0
  } while(1);
2746
2747
0
  return p;
2748
0
error:
2749
0
  LM_ERR("error parsing [%.*s]\n", in->len, in->s);
2750
0
  t = *tr;
2751
0
  while(t)
2752
0
  {
2753
0
    t0 = t;
2754
0
    t = t->next;
2755
0
    free_tr_param(t0->params);
2756
0
    pkg_free(t0);
2757
0
  }
2758
0
  return NULL;
2759
0
}
2760
2761
char *tr_parse_nparam(char *p, str *in, tr_param_t **tp)
2762
0
{
2763
0
  char *p0;
2764
0
  pv_spec_t *spec = NULL;
2765
0
  int n, sign;
2766
0
  str s;
2767
2768
0
  while (is_in_str(p, in) && is_ws(*p)) p++;
2769
2770
0
  if(*p == PV_MARKER) { /* pseudo-variable */
2771
0
    spec = pkg_malloc(sizeof(pv_spec_t));
2772
0
    if (spec == NULL) {
2773
0
      LM_ERR("no more private memory!\n");
2774
0
      goto error;
2775
0
    }
2776
0
    s.s = p;
2777
0
    s.len = in->s + in->len - p;
2778
0
    p0 = pv_parse_spec(&s, spec);
2779
0
    if(p0 == NULL) {
2780
0
      LM_ERR("invalid spec in substr transformation: %.*s!\n",
2781
0
        in->len, in->s);
2782
0
      goto error;
2783
0
    }
2784
0
    p = p0;
2785
0
    *tp = pkg_malloc(sizeof(tr_param_t));
2786
0
    if(*tp == NULL) {
2787
0
      LM_ERR("no more private memory!\n");
2788
0
      goto error;
2789
0
    }
2790
0
    memset(*tp, 0, sizeof(tr_param_t));
2791
0
    (*tp)->type = TR_PARAM_SPEC;
2792
0
    (*tp)->v.data = (void*)spec;
2793
2794
0
    return p;
2795
0
  } else {
2796
0
    if (*p == '+' || *p == '-' || (*p >= '0' && *p <= '9')) { /* number */
2797
0
      sign = 1;
2798
0
      if (*p == '-') {
2799
0
        p++;
2800
0
        sign = -1;
2801
0
      } else if (*p == '+') p++;
2802
0
      n = 0;
2803
0
      while (is_in_str(p, in) && is_ws(*p))
2804
0
        p++;
2805
0
      while (is_in_str(p, in) && *p >= '0' && *p <= '9') {
2806
0
        n = n*10 + *p - '0';
2807
0
        p++;
2808
0
      }
2809
0
      *tp = pkg_malloc(sizeof(tr_param_t));
2810
0
      if (*tp == NULL) {
2811
0
        LM_ERR("no more private memory!\n");
2812
0
        goto error;
2813
0
      }
2814
0
      memset(*tp, 0, sizeof(tr_param_t));
2815
0
      (*tp)->type = TR_PARAM_NUMBER;
2816
0
      (*tp)->v.n = sign*n;
2817
0
    } else {
2818
0
      LM_ERR("invalid param in transformation: %.*s!!\n",
2819
0
        in->len, in->s);
2820
0
      goto error;
2821
0
    }
2822
2823
0
    return p;
2824
0
  }
2825
2826
0
error:
2827
0
  if (spec)
2828
0
    pv_spec_free(spec);
2829
0
  return NULL;
2830
0
}
2831
2832
/*
2833
 * Not all transformation string parameters have the same meaning
2834
 * Some of them are SIP headers, thus they cannot contain whitespace,
2835
 * while others may just be strings with no additional restrictions.
2836
 * Set the mode to TR_PARSE_SPARAM_WS if your param may contain
2837
 * whitespace
2838
 *    -> e.g. ' ', "foo bar", "foob\tar" ...
2839
 */
2840
2841
char *tr_parse_sparam(char *p, str *in, tr_param_t **tp,
2842
    enum tr_parse_sparam_mode mode)
2843
0
{
2844
0
  char *p0, *ps;
2845
0
  pv_spec_t *spec = NULL;
2846
0
  str s;
2847
2848
0
  while (is_in_str(p, in) && is_ws(*p)) p++;
2849
2850
0
  if (*p == PV_MARKER) { /* pseudo-variable */
2851
0
    spec = pkg_malloc(sizeof(pv_spec_t));
2852
0
    if (spec == NULL) {
2853
0
      LM_ERR("no more private memory!\n");
2854
0
      goto error;
2855
0
    }
2856
0
    s.s = p;
2857
0
    s.len = in->s + in->len - p;
2858
0
    p0 = pv_parse_spec(&s, spec);
2859
0
    if (p0 == NULL) {
2860
0
      LM_ERR("invalid spec in substr transformation: %.*s!\n",
2861
0
        in->len, in->s);
2862
0
      goto error;
2863
0
    }
2864
0
    p = p0;
2865
0
    *tp = pkg_malloc(sizeof(tr_param_t));
2866
0
    if (*tp == NULL) {
2867
0
      LM_ERR("no more private memory!\n");
2868
0
      goto error;
2869
0
    }
2870
0
    memset(*tp, 0, sizeof(tr_param_t));
2871
0
    (*tp)->type = TR_PARAM_SPEC;
2872
0
    (*tp)->v.data = (void*)spec;
2873
2874
0
    return p;
2875
0
  } else { /* string */
2876
0
    ps = p;
2877
0
    while (is_in_str(p, in) &&
2878
0
        (mode != TR_PARSE_SPARAM_NO_WS || !is_ws(*p))) {
2879
0
      if ((*p == TR_PARAM_MARKER ||
2880
0
          (*p == TR_RBRACKET &&
2881
0
              mode != TR_PARSE_SPARAM_WS_RBRACKET)) &&
2882
0
          (p - 1 < ps || *(p - 1) != '\\'))
2883
0
        break;
2884
0
      p++;
2885
0
    }
2886
2887
0
    if (*p == '\0') {
2888
0
      LM_ERR("invalid param in transformation: %.*s!!\n",
2889
0
        in->len, in->s);
2890
0
      goto error;
2891
0
    }
2892
0
    *tp = pkg_malloc(sizeof(tr_param_t));
2893
0
    if (*tp == NULL) {
2894
0
      LM_ERR("no more private memory!\n");
2895
0
      goto error;
2896
0
    }
2897
0
    memset(*tp, 0, sizeof(tr_param_t));
2898
0
    (*tp)->type = TR_PARAM_STRING;
2899
0
    (*tp)->v.s.s = ps;
2900
0
    (*tp)->v.s.len = p - ps;
2901
2902
0
    return p;
2903
0
  }
2904
2905
0
error:
2906
0
  if (spec)
2907
0
    pv_spec_free(spec);
2908
0
  return NULL;
2909
0
}
2910
2911
int tr_parse_string(str* in, trans_t *t)
2912
0
{
2913
0
  char *p, *cp;
2914
0
  str name;
2915
0
  tr_param_t *tp = NULL;
2916
2917
0
  if(in==NULL || t==NULL)
2918
0
    return -1;
2919
2920
0
  p = in->s;
2921
0
  name.s = in->s;
2922
2923
  /* find next token */
2924
0
  while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
2925
0
  if(*p=='\0')
2926
0
  {
2927
0
    LM_ERR("invalid transformation: %.*s\n",
2928
0
        in->len, in->s);
2929
0
    goto error;
2930
0
  }
2931
0
  name.len = p - name.s;
2932
0
  trim(&name);
2933
2934
0
  if(name.len==3 && strncasecmp(name.s, "len", 3)==0)
2935
0
  {
2936
0
    t->subtype = TR_S_LEN;
2937
0
    return 0;
2938
0
  } else if(name.len==3 && strncasecmp(name.s, "int", 3)==0) {
2939
0
    t->subtype = TR_S_INT;
2940
0
    return 0;
2941
0
  } else if(name.len==3 && strncasecmp(name.s, "md5", 3)==0) {
2942
0
    t->subtype = TR_S_MD5;
2943
0
    return 0;
2944
0
  } else if(name.len==5 && strncasecmp(name.s, "crc32", 5)==0) {
2945
0
    t->subtype = TR_S_CRC32;
2946
0
    return 0;
2947
0
  } else if(name.len==7 && strncasecmp(name.s, "tolower", 7)==0) {
2948
0
    t->subtype = TR_S_TOLOWER;
2949
0
    return 0;
2950
0
  } else if(name.len==7 && strncasecmp(name.s, "toupper", 7)==0) {
2951
0
    t->subtype = TR_S_TOUPPER;
2952
0
    return 0;
2953
0
  } else if(name.len==11 && strncasecmp(name.s, "encode.hexa", 11)==0) {
2954
0
    t->subtype = TR_S_ENCODEHEXA;
2955
0
    return 0;
2956
0
  } else if(name.len==11 && strncasecmp(name.s, "decode.hexa", 11)==0) {
2957
0
    t->subtype = TR_S_DECODEHEXA;
2958
0
    return 0;
2959
0
  } else if(name.len==7 && strncasecmp(name.s, "hex2dec", 7)==0) {
2960
0
    t->subtype = TR_S_HEX2DEC;
2961
0
    return 0;
2962
0
  } else if(name.len==7 && strncasecmp(name.s, "dec2hex", 7)==0) {
2963
0
    t->subtype = TR_S_DEC2HEX;
2964
0
    return 0;
2965
0
  } else if(name.len==9 && strncasecmp(name.s, "date2unix", 9)==0) {
2966
0
    t->subtype = TR_S_DATE2UNIX;
2967
0
    return 0;
2968
0
  } else if(name.len==13 && strncasecmp(name.s, "escape.common", 13)==0) {
2969
0
    t->subtype = TR_S_ESCAPECOMMON;
2970
0
    return 0;
2971
0
  } else if(name.len==15 && strncasecmp(name.s, "unescape.common", 15)==0) {
2972
0
    t->subtype = TR_S_UNESCAPECOMMON;
2973
0
    return 0;
2974
0
  } else if(name.len==11 && strncasecmp(name.s, "escape.user", 11)==0) {
2975
0
    t->subtype = TR_S_ESCAPEUSER;
2976
0
    return 0;
2977
0
  } else if(name.len==13 && strncasecmp(name.s, "unescape.user", 13)==0) {
2978
0
    t->subtype = TR_S_UNESCAPEUSER;
2979
0
    return 0;
2980
0
  } else if(name.len==12 && strncasecmp(name.s, "escape.param", 12)==0) {
2981
0
    t->subtype = TR_S_ESCAPEPARAM;
2982
0
    return 0;
2983
0
  } else if(name.len==14 && strncasecmp(name.s, "unescape.param", 14)==0) {
2984
0
    t->subtype = TR_S_UNESCAPEPARAM;
2985
0
    return 0;
2986
0
  } else if(name.len==5 && strncasecmp(name.s, "index", 5)==0) {
2987
0
    t->subtype = TR_S_INDEX;
2988
0
    if(*p!=TR_PARAM_MARKER)
2989
0
    {
2990
0
      LM_ERR("invalid index transformation: %.*s!\n", in->len, in->s);
2991
0
      goto error;
2992
0
    }
2993
0
    p++;
2994
0
    if ((p = tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_NO_WS)) == NULL)
2995
0
      goto error;
2996
0
    t->params = tp;
2997
0
    tp = 0;
2998
0
    trim_ws(p);
2999
0
    if(*p!=TR_PARAM_MARKER && *p!=TR_RBRACKET)
3000
0
    {
3001
0
      LM_ERR("invalid index transformation: %.*s!\n",
3002
0
        in->len, in->s);
3003
0
      goto error;
3004
0
    }
3005
0
    if (*p!=TR_RBRACKET) {
3006
0
      p++;
3007
0
      if (tr_parse_nparam(p, in, &tp) == NULL)
3008
0
        goto error;
3009
0
      t->params->next = tp;
3010
0
    } else {
3011
0
      t->params->next = NULL;
3012
0
    }
3013
3014
0
    tp = 0;
3015
3016
0
    return 0;
3017
0
  } else if(name.len==6 && strncasecmp(name.s, "rindex", 6)==0) {
3018
0
    t->subtype = TR_S_RINDEX;
3019
0
    if(*p!=TR_PARAM_MARKER)
3020
0
    {
3021
0
      LM_ERR("invalid rindex transformation: %.*s!\n", in->len, in->s);
3022
0
      goto error;
3023
0
    }
3024
0
    p++;
3025
0
    if ((p = tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_NO_WS)) == NULL)
3026
0
      goto error;
3027
0
    t->params = tp;
3028
0
    tp = 0;
3029
0
    trim_ws(p);
3030
0
    if(*p!=TR_PARAM_MARKER && *p!=TR_RBRACKET)
3031
0
    {
3032
0
      LM_ERR("invalid rindex transformation: %.*s!\n",
3033
0
        in->len, in->s);
3034
0
      goto error;
3035
0
    }
3036
0
    if (*p!=TR_RBRACKET) {
3037
0
      p++;
3038
0
      if (tr_parse_nparam(p, in, &tp) == NULL)
3039
0
        goto error;
3040
0
      t->params->next = tp;
3041
0
    } else {
3042
0
      t->params->next = NULL;
3043
0
    }
3044
3045
0
    tp = 0;
3046
3047
0
    return 0;
3048
0
  } else if(name.len==6 && strncasecmp(name.s, "substr", 6)==0) {
3049
0
    t->subtype = TR_S_SUBSTR;
3050
0
    if(*p!=TR_PARAM_MARKER)
3051
0
    {
3052
0
      LM_ERR("invalid substr transformation: %.*s!\n", in->len, in->s);
3053
0
      goto error;
3054
0
    }
3055
0
    p++;
3056
0
    if ((p = tr_parse_nparam(p, in, &tp)) == NULL)
3057
0
      goto error;
3058
0
    t->params = tp;
3059
0
    tp = 0;
3060
0
    trim_ws(p);
3061
0
    if(*p!=TR_PARAM_MARKER)
3062
0
    {
3063
0
      LM_ERR("invalid substr transformation: %.*s!\n",
3064
0
        in->len, in->s);
3065
0
      goto error;
3066
0
    }
3067
0
    p++;
3068
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3069
0
      goto error;
3070
0
    t->params->next = tp;
3071
0
    tp = 0;
3072
3073
0
    return 0;
3074
0
  } else if(name.len==6 && strncasecmp(name.s, "select", 6)==0) {
3075
0
    t->subtype = TR_S_SELECT;
3076
0
    if(*p!=TR_PARAM_MARKER)
3077
0
    {
3078
0
      LM_ERR("invalid select transformation: %.*s!\n",
3079
0
          in->len, in->s);
3080
0
      goto error;
3081
0
    }
3082
0
    p++;
3083
0
    if ((p = tr_parse_nparam(p, in, &tp)) == NULL)
3084
0
      goto error;
3085
0
    t->params = tp;
3086
0
    tp = 0;
3087
0
    trim_ws(p);
3088
0
    if(*p!=TR_PARAM_MARKER || *(p+1)=='\0')
3089
0
    {
3090
0
      LM_ERR("invalid select transformation: %.*s!\n", in->len, in->s);
3091
0
      goto error;
3092
0
    }
3093
0
    p++;
3094
0
    tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t));
3095
0
    if(tp==NULL)
3096
0
    {
3097
0
      LM_ERR("no more private memory!\n");
3098
0
      goto error;
3099
0
    }
3100
0
    memset(tp, 0, sizeof(tr_param_t));
3101
0
    tp->type = TR_PARAM_STRING;
3102
0
    tp->v.s.s = p;
3103
0
    tp->v.s.len = 1;
3104
0
    t->params->next = tp;
3105
0
    tp = 0;
3106
3107
0
    return 0;
3108
0
  } else if ((name.len==9 && strncasecmp(name.s, "fill.left", 9)==0) ||
3109
0
        (name.len==10 && strncasecmp(name.s, "fill.right", 10)==0)) {
3110
3111
0
    t->subtype = (name.len == 9 ? TR_S_FILL_LEFT : TR_S_FILL_RIGHT);
3112
0
    if (*p != TR_PARAM_MARKER)
3113
0
    {
3114
0
      LM_ERR("invalid fill transformation: %.*s!\n", in->len, in->s);
3115
0
      goto error;
3116
0
    }
3117
0
    p++;
3118
0
    if ((p = tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_WS)) == NULL)
3119
0
      goto error;
3120
0
    if (tp->type == TR_PARAM_SPEC)
3121
0
    {
3122
0
      LM_ERR("fill transformation does not allow PVs: %.*s!\n", in->len, in->s);
3123
0
      goto error;
3124
0
    }
3125
0
    if (tp->v.s.len == 0)
3126
0
    {
3127
0
      LM_ERR("fill transformation is a NOP, maybe use quotes? %.*s\n",
3128
0
          in->len, in->s);
3129
0
      goto error;
3130
0
    }
3131
3132
0
    if (tp->v.s.len > 1) {
3133
      /* we allowed all whitespace, so manually skip trailing ws */
3134
0
      cp = &tp->v.s.s[tp->v.s.len - 1];
3135
0
      trim_trail_ws(cp);
3136
0
      tp->v.s.len -= &tp->v.s.s[tp->v.s.len - 1] - cp;
3137
3138
      /* support for quoted chars/strings */
3139
0
      if (tp->v.s.len > 1 &&
3140
0
        ((tp->v.s.s[0] == '\'' && tp->v.s.s[tp->v.s.len - 1] == '\'') ||
3141
0
        (tp->v.s.s[0] == '\"' && tp->v.s.s[tp->v.s.len - 1] == '\"'))) {
3142
3143
0
        if (tp->v.s.len == 2)
3144
0
        {
3145
0
          LM_ERR("fill transformation is a NOP, maybe use quotes? %.*s\n",
3146
0
              in->len, in->s);
3147
0
          goto error;
3148
0
        }
3149
3150
0
        tp->v.s.len -= 2;
3151
0
        tp->v.s.s++;
3152
0
      }
3153
0
    }
3154
0
    t->params = tp;
3155
0
    tp = 0;
3156
0
    trim_ws(p);
3157
0
    if (*p != TR_PARAM_MARKER || *(p+1) == '\0')
3158
0
    {
3159
0
      LM_ERR("invalid fill transformation: %.*s!\n", in->len, in->s);
3160
0
      goto error;
3161
0
    }
3162
0
    p++;
3163
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3164
0
      goto error;
3165
0
    if (tp->type == TR_PARAM_SPEC)
3166
0
    {
3167
0
      LM_ERR("fill transformation does not allow PVs: %.*s!\n", in->len, in->s);
3168
0
      goto error;
3169
0
    }
3170
0
    t->params->next = tp;
3171
3172
0
    tp = 0;
3173
3174
0
    return 0;
3175
0
  } else if(name.len==5 && strncasecmp(name.s, "width", 5)==0) {
3176
0
    t->subtype = TR_S_WIDTH;
3177
0
    if(*p!=TR_PARAM_MARKER)
3178
0
    {
3179
0
      LM_ERR("invalid substr transformation: %.*s!\n", in->len, in->s);
3180
0
      goto error;
3181
0
    }
3182
0
    p++;
3183
0
    if ((p = tr_parse_nparam(p, in, &tp)) == NULL)
3184
0
      goto error;
3185
0
    if(tp->type==TR_PARAM_NUMBER && tp->v.n<0)
3186
0
    {
3187
0
      LM_ERR("width negative\n");
3188
0
      goto error;
3189
0
    }
3190
0
    t->params = tp;
3191
0
    tp = 0;
3192
0
    while(is_in_str(p, in) && (*p==' ' || *p=='\t' || *p=='\n')) p++;
3193
0
    if(*p!=TR_RBRACKET)
3194
0
    {
3195
0
      LM_ERR("invalid width transformation: %.*s!!\n",
3196
0
        in->len, in->s);
3197
0
      goto error;
3198
0
    }
3199
0
    return 0;
3200
0
  } else if(name.len==9 && strncasecmp(name.s, "b64encode", 9)==0) {
3201
0
    t->subtype = TR_S_B64ENCODE;
3202
0
    return 0;
3203
0
  } else if(name.len==9 && strncasecmp(name.s, "b64decode", 9)==0) {
3204
0
    t->subtype = TR_S_B64DECODE;
3205
0
    return 0;
3206
0
  } else if(name.len==3 && strncasecmp(name.s, "xor", 3)==0) {
3207
0
    t->subtype = TR_S_XOR;
3208
0
    if(*p!=TR_PARAM_MARKER)
3209
0
    {
3210
0
      LM_ERR("invalid xor transformation: %.*s!\n", in->len, in->s);
3211
0
      goto error;
3212
0
    }
3213
0
    p++;
3214
0
    if (tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_NO_WS) == NULL)
3215
0
      goto error;
3216
0
    t->params = tp;
3217
0
    tp = 0;
3218
3219
0
    return 0;
3220
0
  } else if (strncasecmp(name.s, "trim", 4) == 0) {
3221
0
    if (name.len == 4)
3222
0
      t->subtype = TR_S_TRIM;
3223
0
    else if (name.len > 4 && strncasecmp(name.s, "trimr", 5) == 0)
3224
0
      t->subtype = TR_S_TRIMR;
3225
0
    else if (name.len > 4 && strncasecmp(name.s, "triml", 5) == 0)
3226
0
      t->subtype = TR_S_TRIML;
3227
0
    else {
3228
0
      LM_ERR("bad trim transformation!\n");
3229
0
      goto error;
3230
0
    }
3231
3232
0
    return 0;
3233
0
  } else if(name.len==7 && strncasecmp(name.s, "reverse", 7)==0) {
3234
0
    t->subtype = TR_S_REVERSE;
3235
0
    return 0;
3236
0
  } else if(name.len==4 && strncasecmp(name.s, "eval", 4)==0) {
3237
0
    t->subtype = TR_S_EVAL;
3238
0
    return 0;
3239
0
    return 0;
3240
0
  } else if(name.len==4 && strncasecmp(name.s, "sha1", 4)==0) {
3241
0
    t->subtype = TR_S_SHA1;
3242
0
    return 0;
3243
0
  } else if(name.len==6 && strncasecmp(name.s, "sha224", 6)==0) {
3244
0
    t->subtype = TR_S_SHA224;
3245
0
    return 0;
3246
0
  } else if(name.len==6 && strncasecmp(name.s, "sha256", 6)==0) {
3247
0
    t->subtype = TR_S_SHA256;
3248
0
    return 0;
3249
0
  } else if(name.len==6 && strncasecmp(name.s, "sha384", 6)==0) {
3250
0
    t->subtype = TR_S_SHA384;
3251
0
    return 0;
3252
0
  } else if(name.len==6 && strncasecmp(name.s, "sha512", 6)==0) {
3253
0
    t->subtype = TR_S_SHA512;
3254
0
    return 0;
3255
0
  } else if ( (name.len==9 || name.len==11) && strncasecmp(name.s, "sha", 3)==0 &&
3256
0
      strncasecmp(name.s+(name.len-5), "_hmac", 5)==0 ) {
3257
3258
0
    if (strncasecmp(name.s+3, "1", 1) == 0) { // SHA1
3259
0
      t->subtype = TR_S_SHA1_HMAC;
3260
0
    } else if (strncasecmp(name.s+3, "224", 3) == 0) { // SHA224
3261
0
      t->subtype = TR_S_SHA224_HMAC;
3262
0
    } else if (strncasecmp(name.s+3, "256", 3) == 0) { // SHA256
3263
0
      t->subtype = TR_S_SHA256_HMAC;
3264
0
    } else if (strncasecmp(name.s+3, "384", 3) == 0) { // SHA384
3265
0
      t->subtype = TR_S_SHA384_HMAC;
3266
0
    } else if (strncasecmp(name.s+3, "512", 3) == 0) { // SHA512
3267
0
      t->subtype = TR_S_SHA512_HMAC;
3268
0
    } else {
3269
0
      goto unknown;
3270
0
    }
3271
3272
0
    if(*p!=TR_PARAM_MARKER)
3273
0
    {
3274
0
      LM_ERR("invalid sha hmac transformation: %.*s!\n", in->len, in->s);
3275
0
      goto error;
3276
0
    }
3277
0
    p++;
3278
0
    if (tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_NO_WS) == NULL)
3279
0
      goto error;
3280
0
    t->params = tp;
3281
0
    tp = 0;
3282
3283
0
    return 0;
3284
0
  }
3285
3286
0
unknown:
3287
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3288
0
      name.len, name.s, name.len);
3289
0
error:
3290
0
  if(tp)
3291
0
    free_tr_param(tp);
3292
0
  return -1;
3293
0
}
3294
3295
int tr_parse_uri(str* in, trans_t *t)
3296
0
{
3297
0
  char *p;
3298
0
  str name;
3299
0
  tr_param_t *tp = NULL;
3300
3301
0
  if(in==NULL || in->s==NULL || t==NULL)
3302
0
    return -1;
3303
0
  p = in->s;
3304
0
  name.s = in->s;
3305
3306
  /* find next token */
3307
0
  while(*p && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3308
0
  if(*p=='\0')
3309
0
  {
3310
0
    LM_ERR("invalid transformation: %.*s\n", in->len, in->s);
3311
0
    goto error;
3312
0
  }
3313
0
  name.len = p - name.s;
3314
0
  trim(&name);
3315
3316
0
  if(name.len==4 && strncasecmp(name.s, "user", 4)==0)
3317
0
  {
3318
0
    t->subtype = TR_URI_USER;
3319
0
    return 0;
3320
0
  } else if((name.len==4 && strncasecmp(name.s, "host", 4)==0)
3321
0
      || (name.len==6 && strncasecmp(name.s, "domain", 6)==0)) {
3322
0
    t->subtype = TR_URI_HOST;
3323
0
    return 0;
3324
0
  } else if(name.len==6 && strncasecmp(name.s, "passwd", 6)==0) {
3325
0
    t->subtype = TR_URI_PASSWD;
3326
0
    return 0;
3327
0
  } else if(name.len==4 && strncasecmp(name.s, "port", 4)==0) {
3328
0
    t->subtype = TR_URI_PORT;
3329
0
    return 0;
3330
0
  } else if(name.len==6 && strncasecmp(name.s, "params", 6)==0) {
3331
0
    t->subtype = TR_URI_PARAMS;
3332
0
    return 0;
3333
0
  } else if(name.len==5 && strncasecmp(name.s, "param", 5)==0) {
3334
0
    t->subtype = TR_URI_PARAM;
3335
0
    if(*p!=TR_PARAM_MARKER)
3336
0
    {
3337
0
      LM_ERR("invalid param transformation: %.*s\n", in->len, in->s);
3338
0
      goto error;
3339
0
    }
3340
0
    p++;
3341
0
    if (tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_NO_WS) == NULL)
3342
0
      goto error;
3343
0
    t->params = tp;
3344
0
    return 0;
3345
0
  } else if(name.len==9 && strncasecmp(name.s, "transport", 9)==0) {
3346
0
    t->subtype = TR_URI_TRANSPORT;
3347
0
    return 0;
3348
0
  } else if(name.len==7 && strncasecmp(name.s, "headers", 7)==0) {
3349
0
    t->subtype = TR_URI_HEADERS;
3350
0
    return 0;
3351
0
  } else if(name.len==3 && strncasecmp(name.s, "ttl", 3)==0) {
3352
0
    t->subtype = TR_URI_TTL;
3353
0
    return 0;
3354
0
  } else if(name.len==6 && strncasecmp(name.s, "uparam", 6)==0) {
3355
0
    t->subtype = TR_URI_UPARAM;
3356
0
    return 0;
3357
0
  } else if(name.len==5 && strncasecmp(name.s, "maddr", 5)==0) {
3358
0
    t->subtype = TR_URI_MADDR;
3359
0
    return 0;
3360
0
  } else if(name.len==6 && strncasecmp(name.s, "method", 6)==0) {
3361
0
    t->subtype = TR_URI_METHOD;
3362
0
    return 0;
3363
0
  } else if(name.len==2 && strncasecmp(name.s, "lr", 2)==0) {
3364
0
    t->subtype = TR_URI_LR;
3365
0
    return 0;
3366
0
  } else if(name.len==2 && strncasecmp(name.s, "r2", 2)==0) {
3367
0
    t->subtype = TR_URI_R2;
3368
0
    return 0;
3369
0
  } else if (name.len==6 && strncasecmp(name.s, "schema", 6)==0) {
3370
0
    t->subtype = TR_URI_SCHEMA;
3371
0
    return 0;
3372
0
  }
3373
3374
0
  LM_ERR("unknown transformation: %.*s/%.*s!\n", in->len,
3375
0
      in->s, name.len, name.s);
3376
0
error:
3377
0
  return -1;
3378
0
}
3379
3380
3381
int tr_parse_via(str* in, trans_t *t)
3382
0
{
3383
0
  char *p;
3384
0
  str name;
3385
0
  tr_param_t *tp = NULL;
3386
3387
0
  if(in==NULL || in->s==NULL || t==NULL)
3388
0
    return -1;
3389
0
  p = in->s;
3390
0
  name.s = in->s;
3391
3392
  /* find next token */
3393
0
  while(*p && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3394
0
  if(*p=='\0')
3395
0
  {
3396
0
    LM_ERR("invalid transformation: %.*s\n", in->len, in->s);
3397
0
    goto error;
3398
0
  }
3399
0
  name.len = p - name.s;
3400
0
  trim(&name);
3401
3402
0
  if(name.len==4 && strncasecmp(name.s, "name", 4)==0)
3403
0
  {
3404
0
    t->subtype = TR_VIA_NAME;
3405
0
    return 0;
3406
0
  } else if(name.len==7 && strncasecmp(name.s, "version", 7)==0)
3407
0
  {
3408
0
    t->subtype = TR_VIA_VERSION;
3409
0
    return 0;
3410
0
  } else if(name.len==9 && strncasecmp(name.s, "transport", 9)==0) {
3411
0
    t->subtype = TR_VIA_TRANSPORT;
3412
0
    return 0;
3413
0
  } else if((name.len==4 && strncasecmp(name.s, "host", 4)==0)
3414
0
      || (name.len==6 && strncasecmp(name.s, "domain", 6)==0)) {
3415
0
    t->subtype = TR_VIA_HOST;
3416
0
    return 0;
3417
0
  } else if(name.len==4 && strncasecmp(name.s, "port", 4)==0) {
3418
0
    t->subtype = TR_VIA_PORT;
3419
0
    return 0;
3420
0
  } else if(name.len==6 && strncasecmp(name.s, "params", 6)==0) {
3421
0
    t->subtype = TR_VIA_PARAMS;
3422
0
    return 0;
3423
0
  } else if(name.len==5 && strncasecmp(name.s, "param", 5)==0) {
3424
0
    t->subtype = TR_VIA_PARAM;
3425
0
    if(*p!=TR_PARAM_MARKER)
3426
0
    {
3427
0
      LM_ERR("invalid param transformation: %.*s\n", in->len, in->s);
3428
0
      goto error;
3429
0
    }
3430
0
    p++;
3431
0
    if (tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_NO_WS) == NULL)
3432
0
      goto error;
3433
0
    t->params = tp;
3434
3435
0
    return 0;
3436
0
  } else if(name.len==7 && strncasecmp(name.s, "comment", 7)==0) {
3437
0
    t->subtype = TR_VIA_COMMENT;
3438
0
    return 0;
3439
0
  } else if(name.len==6 && strncasecmp(name.s, "branch", 6)==0) {
3440
0
    t->subtype = TR_VIA_BRANCH;
3441
0
    return 0;
3442
0
  } else if(name.len==8 && strncasecmp(name.s, "received", 8)==0) {
3443
0
    t->subtype = TR_VIA_RECEIVED;
3444
0
    return 0;
3445
0
  } else if(name.len==5 && strncasecmp(name.s, "rport", 5)==0) {
3446
0
    t->subtype = TR_VIA_RPORT;
3447
0
    return 0;
3448
0
  }
3449
3450
3451
0
  LM_ERR("unknown transformation: %.*s/%.*s!\n", in->len,
3452
0
      in->s, name.len, name.s);
3453
0
error:
3454
0
  return -1;
3455
0
}
3456
3457
int tr_parse_paramlist(str* in, trans_t *t)
3458
0
{
3459
0
  char *p;
3460
0
  str name;
3461
0
  tr_param_t *tp = NULL;
3462
3463
0
  if(in==NULL || in->s==NULL || t==NULL)
3464
0
    return -1;
3465
3466
0
  p = in->s;
3467
0
  name.s = in->s;
3468
3469
  /* find next token */
3470
0
  while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3471
0
  if(*p=='\0')
3472
0
  {
3473
0
    LM_ERR("invalid transformation: %.*s\n",
3474
0
        in->len, in->s);
3475
0
    goto error;
3476
0
  }
3477
0
  name.len = p - name.s;
3478
0
  trim(&name);
3479
3480
0
  if(name.len==5 && strncasecmp(name.s, "value", 5)==0)
3481
0
  {
3482
0
    t->subtype = TR_PL_VALUE;
3483
0
    if(*p!=TR_PARAM_MARKER)
3484
0
    {
3485
0
      LM_ERR("invalid value transformation: %.*s\n",
3486
0
          in->len, in->s);
3487
0
      goto error;
3488
0
    }
3489
0
    p++;
3490
0
    if (tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_NO_WS) == NULL)
3491
0
      goto error;
3492
0
    t->params = tp;
3493
3494
0
    return 0;
3495
3496
0
  } else if(str_match(&name, &(str_const_init("exist")))
3497
0
            || str_match(&name, &(str_const_init("exists")))) {
3498
0
    t->subtype = TR_PL_EXIST;
3499
0
    if(*p!=TR_PARAM_MARKER)
3500
0
    {
3501
0
      LM_ERR("invalid value transformation: %.*s\n",
3502
0
          in->len, in->s);
3503
0
      goto error;
3504
0
    }
3505
0
    p++;
3506
0
    if (tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_NO_WS) == NULL)
3507
0
      goto error;
3508
0
    t->params = tp;
3509
3510
0
    return 0;
3511
0
  } else if(name.len==7 && strncasecmp(name.s, "valueat", 7)==0) {
3512
0
    t->subtype = TR_PL_VALUEAT;
3513
0
    if(*p!=TR_PARAM_MARKER)
3514
0
    {
3515
0
      LM_ERR("invalid name transformation: %.*s\n",
3516
0
          in->len, in->s);
3517
0
      goto error;
3518
0
    }
3519
0
    p++;
3520
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3521
0
      goto error;
3522
0
    t->params = tp;
3523
3524
0
    return 0;
3525
0
  } else if(name.len==4 && strncasecmp(name.s, "name", 4)==0) {
3526
0
    t->subtype = TR_PL_NAME;
3527
0
    if(*p!=TR_PARAM_MARKER)
3528
0
    {
3529
0
      LM_ERR("invalid name transformation: %.*s\n",
3530
0
          in->len, in->s);
3531
0
      goto error;
3532
0
    }
3533
0
    p++;
3534
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3535
0
      goto error;
3536
0
    t->params = tp;
3537
3538
0
    return 0;
3539
0
  } else if(name.len==5 && strncasecmp(name.s, "count", 5)==0) {
3540
0
    t->subtype = TR_PL_COUNT;
3541
0
    return 0;
3542
0
  }
3543
3544
0
  LM_ERR("unknown transformation: %.*s/%.*s!\n",
3545
0
      in->len, in->s, name.len, name.s);
3546
0
error:
3547
0
  return -1;
3548
0
}
3549
3550
int tr_parse_nameaddr(str* in, trans_t *t)
3551
0
{
3552
0
  char *p;
3553
0
  str name;
3554
0
  tr_param_t *tp = NULL;
3555
3556
3557
0
  if(in==NULL || t==NULL)
3558
0
    return -1;
3559
3560
0
  p = in->s;
3561
0
parse_name:
3562
0
  name.s = p;
3563
3564
  /* find next token */
3565
0
  while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET && *p!=TR_CLASS_MARKER) p++;
3566
0
  if(*p=='\0')
3567
0
  {
3568
0
    LM_ERR("invalid transformation: %.*s\n",
3569
0
        in->len, in->s);
3570
0
    goto error;
3571
0
  }
3572
0
  name.len = p - name.s;
3573
0
  trim(&name);
3574
0
  if (*p == TR_CLASS_MARKER) {
3575
0
    if (t->params) {
3576
0
      LM_ERR("transformation [%.*s] already has an index!\n",
3577
0
          in->len, in->s);
3578
0
      goto error;
3579
0
    }
3580
    /* we either have a pvar, or an index */
3581
0
    if (tr_parse_nparam(name.s, &name, &tp) == NULL) {
3582
0
      LM_ERR("invalid index: %.*s\n", name.len, name.s);
3583
0
      goto error;
3584
0
    }
3585
0
    t->params = tp;
3586
0
    tp = 0;
3587
0
    p++;
3588
0
    goto parse_name;
3589
0
  }
3590
3591
0
  if(name.len==3 && strncasecmp(name.s, "uri", 3)==0)
3592
0
  {
3593
0
    t->subtype = TR_NA_URI;
3594
0
    return 0;
3595
0
  } else if(name.len==3 && strncasecmp(name.s, "len", 3)==0)
3596
0
  {
3597
0
    t->subtype = TR_NA_LEN;
3598
0
    return 0;
3599
0
  } else if(name.len==4 && strncasecmp(name.s, "name", 4)==0) {
3600
0
    t->subtype = TR_NA_NAME;
3601
0
    return 0;
3602
0
  } else if(name.len==5 && strncasecmp(name.s, "param", 5)==0) {
3603
0
    t->subtype = TR_NA_PARAM;
3604
0
    if(*p!=TR_PARAM_MARKER)
3605
0
    {
3606
0
      LM_ERR("invalid value transformation: %.*s\n",
3607
0
          in->len, in->s);
3608
0
      goto error;
3609
0
    }
3610
0
    p++;
3611
0
    if (tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_NO_WS) == NULL)
3612
0
      goto error;
3613
0
    if (t->params)
3614
0
      t->params->next = tp;
3615
0
    else
3616
0
      t->params = tp;
3617
0
    tp = 0;
3618
3619
0
    return 0;
3620
0
  } else if(name.len==6 && strncasecmp(name.s, "params", 6)==0) {
3621
0
    t->subtype = TR_NA_PARAMS;
3622
0
    return 0;
3623
0
  }
3624
3625
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3626
0
      name.len, name.s, name.len);
3627
0
error:
3628
0
  return -1;
3629
0
}
3630
3631
int tr_parse_csv(str *in, trans_t *t)
3632
0
{
3633
0
  char *p;
3634
0
  str name;
3635
0
  tr_param_t *tp = NULL;
3636
3637
0
  if (in == NULL || t == NULL)
3638
0
    return -1;
3639
3640
0
  p = in->s;
3641
0
  name.s = in->s;
3642
3643
  /* find next token */
3644
0
  while (is_in_str(p,in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3645
0
  if (*p == '\0')
3646
0
  {
3647
0
    LM_ERR("invalid transformation: %.*s\n",in->len,in->s);
3648
0
    return -1;
3649
0
  }
3650
3651
0
  name.len = p - name.s;
3652
0
  trim(&name);
3653
3654
0
  if (name.len==5 && strncasecmp(name.s,"count",5)==0)
3655
0
  {
3656
0
    t->subtype = TR_CSV_COUNT;
3657
0
    return 0;
3658
0
  }
3659
0
  else if (name.len==5 && strncasecmp(name.s,"value",5)==0)
3660
0
  {
3661
0
    t->subtype = TR_CSV_VALUEAT;
3662
0
    if(*p!=TR_PARAM_MARKER)
3663
0
    {
3664
0
      LM_ERR("invalid name transformation: %.*s\n",
3665
0
          in->len, in->s);
3666
0
      goto error;
3667
0
    }
3668
0
    p++;
3669
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3670
0
      goto error;
3671
0
    t->params = tp;
3672
0
    tp = 0;
3673
3674
0
    return 0;
3675
0
  }
3676
3677
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3678
0
      name.len, name.s, name.len);
3679
0
error:
3680
0
  return -1;
3681
3682
0
}
3683
3684
int tr_parse_sdp(str *in, trans_t *t)
3685
0
{
3686
0
  int tmp;
3687
0
  char *p;
3688
0
  str name;
3689
0
  tr_param_t *tp = NULL;
3690
3691
0
  if (in == NULL || t == NULL)
3692
0
    return -1;
3693
3694
0
  p = in->s;
3695
0
  name.s = in->s;
3696
3697
  /* find next token */
3698
0
  while (is_in_str(p,in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3699
0
  if (*p == '\0')
3700
0
  {
3701
0
    LM_ERR("invalid transformation: %.*s\n",in->len,in->s);
3702
0
    return -1;
3703
0
  }
3704
3705
0
  name.len = p - name.s;
3706
0
  trim(&name);
3707
3708
0
  if (name.len==4 && strncasecmp(name.s,"line",4)==0)
3709
0
  {
3710
0
    t->subtype = TR_SDP_LINEAT;
3711
0
    if(*p!=TR_PARAM_MARKER)
3712
0
    {
3713
0
      LM_ERR("invalid lineat transformation: %.*s!\n", in->len, in->s);
3714
0
      goto error;
3715
0
    }
3716
0
    p++;
3717
0
    if ((p = tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_NO_WS)) == NULL)
3718
0
      goto error;
3719
0
    t->params = tp;
3720
0
    tp = 0;
3721
0
    trim_ws(p);
3722
0
    if(*p!=TR_PARAM_MARKER)
3723
0
    {
3724
      /* lineat has only one parameter */
3725
0
      tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t));
3726
0
      if (!tp)
3727
0
      {
3728
0
        LM_ERR("no more pkg memory\n");
3729
0
        goto error;
3730
0
      }
3731
0
      memset(tp, 0, sizeof(tr_param_t));
3732
0
      tp->type = TR_PARAM_NUMBER;
3733
0
      tp->v.n = 0;
3734
0
      t->params->next = tp;
3735
0
      LM_DBG("sdp.lineat with only one parameter. default = 1\n");
3736
0
      return 0;
3737
0
    }
3738
0
    p++;
3739
3740
0
    if (tr_parse_nparam(p, in, &tp) == NULL)
3741
0
      goto error;
3742
0
    if(tp->type==TR_PARAM_NUMBER && tp->v.n<0)
3743
0
    {
3744
0
      LM_ERR("lineat negative argument\n");
3745
0
      goto error;
3746
0
    }
3747
0
    t->params->next = tp;
3748
0
    tp = 0;
3749
3750
0
    return 0;
3751
0
  } else if ((name.len==13 && strncasecmp(name.s,"stream-delete",13)==0) ||
3752
0
        (name.len==6 && strncasecmp(name.s,"stream",6)==0)) {
3753
0
    if (name.len == 6)
3754
0
      t->subtype = TR_SDP_STREAM;
3755
0
    else
3756
0
      t->subtype = TR_SDP_STREAM_DEL;
3757
0
    if(*p!=TR_PARAM_MARKER)
3758
0
    {
3759
0
      LM_ERR("media delete without type or index: %.*s!\n", in->len, in->s);
3760
0
      goto error;
3761
0
    }
3762
0
    p++;
3763
0
    if ((p = tr_parse_sparam(p, in, &tp, TR_PARSE_SPARAM_NO_WS)) == NULL)
3764
0
      goto error;
3765
    /* if it is a static numeric, convert it now */
3766
0
    if (tp->type == TR_PARAM_STRING) {
3767
      /* try to convert it now to an int, if possible */
3768
0
      if (str2sint(&tp->v.s, &tmp) >= 0) {
3769
0
        tp->v.n = tmp;
3770
0
        tp->type = TR_PARAM_NUMBER;
3771
0
      }
3772
0
    }
3773
0
    t->params = tp;
3774
0
    tp = 0;
3775
3776
0
    return 0;
3777
0
  }
3778
3779
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3780
0
      name.len, name.s, name.len);
3781
0
error:
3782
0
  return -1;
3783
0
}
3784
3785
int tr_parse_ip(str *in, trans_t *t)
3786
0
{
3787
0
  char *p;
3788
0
  str name;
3789
3790
0
  if (in == NULL || t == NULL)
3791
0
    return -1;
3792
3793
0
  p = in->s;
3794
0
  name.s = in->s;
3795
3796
  /* find next token */
3797
0
  while (is_in_str(p,in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3798
0
  if (*p == '\0')
3799
0
  {
3800
0
    LM_ERR("invalid transformation: %.*s\n",in->len,in->s);
3801
0
    goto error;
3802
0
  }
3803
3804
0
  name.len = p - name.s;
3805
0
  trim(&name);
3806
3807
0
  if (name.len==6 && strncasecmp(name.s,"family",6)==0) {
3808
0
    t->subtype = TR_IP_FAMILY;
3809
0
    return 0;
3810
0
  } else if (name.len==4 && strncasecmp(name.s,"ntop",4)==0) {
3811
0
    t->subtype = TR_IP_NTOP;
3812
0
    return 0;
3813
0
  } else if (name.len == 4 && strncasecmp(name.s,"isip",4) == 0) {
3814
0
    t->subtype = TR_IP_ISIP;
3815
0
    return 0;
3816
0
        } else if (name.len == 5 && strncasecmp(name.s,"isip4",5) == 0) {
3817
0
                t->subtype = TR_IP_ISIP4;
3818
0
                return 0;
3819
0
        } else if (name.len == 5 && strncasecmp(name.s,"isip6",5) == 0) {
3820
0
                t->subtype = TR_IP_ISIP6;
3821
0
                return 0;
3822
0
  } else if (name.len == 4 && strncasecmp(name.s,"pton",4) == 0) {
3823
0
    t->subtype = TR_IP_PTON;
3824
0
    return 0;
3825
0
  } else if (name.len == 7 && strncasecmp(name.s,"resolve",7) == 0) {
3826
0
    t->subtype = TR_IP_RESOLVE;
3827
0
    return 0;
3828
0
  } else if (name.len == 8 && strncasecmp(name.s,"resolve4",8) == 0) {
3829
0
    t->subtype = TR_IP_RESOLVE_V4;
3830
0
    return 0;
3831
0
  } else if (name.len == 8 && strncasecmp(name.s,"resolve6",8) == 0) {
3832
0
    t->subtype = TR_IP_RESOLVE_V6;
3833
0
    return 0;
3834
0
  } else if (name.len == 7 && strncasecmp(name.s,"matches",5) == 0) {
3835
0
    t->subtype = TR_IP_MATCHES;
3836
0
    if(*p!=TR_PARAM_MARKER)
3837
0
    {
3838
0
      LM_ERR("invalid value transformation: %.*s\n",
3839
0
          in->len, in->s);
3840
0
      goto error;
3841
0
    }
3842
0
    p++;
3843
0
    LM_DBG("preparing to parse param\n");
3844
0
    if (tr_parse_sparam(p, in, &t->params, TR_PARSE_SPARAM_NO_WS) == NULL)
3845
0
      goto error;
3846
0
    return 0;
3847
0
  } else if (name.len == 9 && strncasecmp(name.s,"isprivate",9) == 0) {
3848
0
    t->subtype = TR_IP_ISPRIVATE;
3849
0
    return 0;
3850
0
  }
3851
3852
3853
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3854
0
      name.len, name.s, name.len);
3855
0
error:
3856
0
  return -1;
3857
3858
0
}
3859
3860
int tr_parse_re(str *in,trans_t *t)
3861
0
{
3862
0
  char *p;
3863
0
  str name;
3864
0
  tr_param_t *tp = NULL;
3865
3866
0
  if (in == NULL || t == NULL)
3867
0
    return -1;
3868
3869
0
  p = in->s;
3870
0
  name.s = in->s;
3871
3872
  /* find next token */
3873
0
  while (is_in_str(p,in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
3874
0
  if (*p == '\0')
3875
0
  {
3876
0
    LM_ERR("invalid transformation: %.*s\n",in->len,in->s);
3877
0
    goto error;
3878
0
  }
3879
3880
0
  name.len = p - name.s;
3881
0
  trim(&name);
3882
3883
0
  if (name.len==5 && strncasecmp(name.s,"subst",5)==0)
3884
0
  {
3885
0
    t->subtype = TR_RE_SUBST;
3886
0
    if(*p!=TR_PARAM_MARKER)
3887
0
    {
3888
0
      LM_ERR("invalid value transformation: %.*s\n",
3889
0
          in->len, in->s);
3890
0
      goto error;
3891
0
    }
3892
0
    p++;
3893
0
    LM_DBG("preparing to parse param\n");
3894
    /* The substitution expression may contain unescaped regex braces. */
3895
0
    if (tr_parse_sparam(p, in, &tp,
3896
0
        TR_PARSE_SPARAM_WS_RBRACKET) == NULL)
3897
0
      goto error;
3898
0
    t->params = tp;
3899
0
    tp = 0;
3900
3901
0
    return 0;
3902
0
  }
3903
3904
0
  LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
3905
0
      name.len, name.s, name.len);
3906
0
error:
3907
0
  return -1;
3908
0
}
3909
3910
void free_transformation(trans_t *t)
3911
0
{
3912
0
  trans_t *t0;
3913
3914
0
  while(t)
3915
0
  {
3916
0
    t0 = t;
3917
0
    t = t->next;
3918
0
    free_tr_param(t0->params);
3919
0
    pkg_free(t0);
3920
0
  }
3921
0
}
3922
3923
void free_tr_param(tr_param_t *tp)
3924
0
{
3925
0
  tr_param_t *tp0;
3926
3927
0
  if(tp==NULL) return;
3928
0
  while(tp)
3929
0
  {
3930
0
    tp0 = tp;
3931
0
    tp = tp->next;
3932
0
    if(tp0->type==TR_PARAM_SPEC)
3933
0
      pv_spec_free((pv_spec_t*)tp0->v.data);
3934
0
    pkg_free(tp0);
3935
0
  }
3936
0
}