Coverage Report

Created: 2026-10-10 06:26

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