Coverage Report

Created: 2024-02-25 06:34

/src/kamailio/src/core/select_core.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2005-2006 iptelorg GmbH
3
 *
4
 * This file is part of Kamailio, a free SIP server.
5
 *
6
 * Kamailio 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
 * Kamailio 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
/*!
23
 * \file
24
 * \brief Kamailio core :: select framework, basic core functions (mma)
25
 * \ingroup core
26
 * Module: \ref core
27
 */
28
29
#include <stdlib.h>
30
#include <stdint.h>
31
#include "select.h"
32
#include "select_core.h"
33
#include "select_buf.h"
34
#include "dprint.h"
35
#include "trim.h"
36
#include "ut.h"
37
#include "globals.h"
38
#include "parser/parser_f.h"
39
#include "parser/hf.h"
40
#include "parser/parse_from.h"
41
#include "parser/parse_to.h"
42
#include "parser/contact/parse_contact.h"
43
#include "parser/contact/contact.h"
44
#include "parser/parse_via.h"
45
#include "parser/parse_uri.h"
46
#include "parser/parse_event.h"
47
#include "parser/parse_rr.h"
48
#include "parser/digest/digest.h"
49
#include "mem/mem.h"
50
#include "parser/parse_hname2.h"
51
#include "ip_addr.h"
52
#include "parser/parse_expires.h"
53
#include "parser/parse_refer_to.h"
54
#include "parser/parse_rpid.h"
55
#include "parser/parse_content.h"
56
#include "parser/parse_body.h"
57
#include "dset.h"
58
#include "sr_module.h"
59
#include "resolve.h"
60
#include "forward.h"
61
#include "rand/kam_rand.h"
62
63
#define RETURN0_res(x) \
64
0
  {                  \
65
0
    *res = (x);    \
66
0
    return 0;      \
67
0
  }
68
#define TRIM_RET0_res(x) \
69
  {                    \
70
    *res = (x);      \
71
    trim(res);       \
72
    return 0;        \
73
  }
74
#define TEST_RET_res_body(x) \
75
0
  if(x) {                  \
76
0
    *res = (x)->body;    \
77
0
    return 0;            \
78
0
  } else                   \
79
0
    return 1;
80
#define TEST_RET_res_value(x) \
81
0
  if(x) {                   \
82
0
    *res = (x)->value;    \
83
0
    return 0;             \
84
0
  } else                    \
85
0
    return 1;
86
87
int select_ruri(str *res, select_t *s, struct sip_msg *msg)
88
0
{
89
  /* Parse the RURI even if it is not needed right now
90
   * because the nested select calls can access the
91
   * parsed URI in this case.
92
   * Go ahead even if the parsing fails, so the
93
   * value of the broken RURI can be accessed at least.
94
   * Subsequent select calls will fail when they try to parse
95
   * the URI anyway. (Miklos)
96
   */
97
0
  if(parse_sip_msg_uri(msg) < 0) {
98
0
    LM_ERR("failed to parse sip msg uri\n");
99
0
    return -1;
100
0
  }
101
102
0
  if(msg->parsed_uri_ok)
103
0
    select_uri_p = &msg->parsed_uri;
104
105
0
  if(msg->first_line.type == SIP_REQUEST) {
106
0
    if(msg->new_uri.s) {
107
0
      RETURN0_res(msg->new_uri);
108
0
    } else {
109
0
      RETURN0_res(msg->first_line.u.request.uri);
110
0
    }
111
0
  }
112
0
  return -1;
113
0
}
114
115
int select_dst_uri(str *res, select_t *s, struct sip_msg *msg)
116
0
{
117
0
  if(msg->first_line.type != SIP_REQUEST)
118
0
    return -1;
119
0
  RETURN0_res(msg->dst_uri);
120
0
}
121
122
int select_next_hop(str *res, select_t *s, struct sip_msg *msg)
123
0
{
124
0
  if(msg->first_line.type == SIP_REQUEST) {
125
0
    if(msg->dst_uri.s) {
126
0
      RETURN0_res(msg->dst_uri);
127
0
    } else if(msg->new_uri.s) {
128
0
      if(msg->parsed_uri_ok)
129
0
        select_uri_p = &msg->parsed_uri;
130
0
      RETURN0_res(msg->new_uri);
131
0
    } else {
132
0
      if(msg->parsed_uri_ok)
133
0
        select_uri_p = &msg->parsed_uri;
134
0
      else if(msg->parsed_orig_ruri_ok)
135
0
        select_uri_p = &msg->parsed_orig_ruri;
136
0
      RETURN0_res(msg->first_line.u.request.uri);
137
0
    }
138
0
  }
139
0
  return -1;
140
0
}
141
142
int select_next_hop_src_ip(str *res, select_t *s, struct sip_msg *msg)
143
0
{
144
0
  struct socket_info *socket_info;
145
0
  union sockaddr_union to;
146
0
  char proto;
147
0
  struct sip_uri *u, next_hop;
148
0
  str *dst_host;
149
150
0
  if(msg->first_line.type != SIP_REQUEST)
151
0
    return -1;
152
153
0
  if(msg->force_send_socket) {
154
0
    *res = msg->force_send_socket->address_str;
155
0
    return 0;
156
0
  }
157
158
0
  if(msg->dst_uri.len) {
159
0
    if(parse_uri(msg->dst_uri.s, msg->dst_uri.len, &next_hop) < 0)
160
0
      return -1;
161
0
    u = &next_hop;
162
0
  } else {
163
0
    if(parse_sip_msg_uri(msg) < 0)
164
0
      return -1;
165
0
    u = &msg->parsed_uri;
166
0
  }
167
0
#ifdef USE_TLS
168
0
  if(u->type == SIPS_URI_T)
169
0
    proto = PROTO_TLS;
170
0
  else
171
0
#endif
172
0
    proto = u->proto;
173
174
#ifdef HONOR_MADDR
175
  if(u->maddr_val.s && u->maddr_val.len)
176
    dst_host = &u->maddr_val;
177
  else
178
#endif
179
0
    dst_host = &u->host;
180
181
0
  if(sip_hostport2su(&to, dst_host, u->port_no, &proto) < 0)
182
0
    return -1;
183
0
  socket_info = get_send_socket(msg, &to, proto);
184
0
  if(!socket_info)
185
0
    return -1;
186
187
0
  *res = socket_info->address_str;
188
0
  return 0;
189
0
}
190
191
#define SELECT_uri_header(_name_)                                            \
192
  int select_##_name_(str *res, select_t *s, struct sip_msg *msg)          \
193
0
  {                                                                        \
194
0
    if(parse_##_name_##_header(msg) < 0)                                 \
195
0
      return -1;                                                       \
196
0
    RETURN0_res(msg->_name_->body);                                      \
197
0
  }                                                                        \
Unexecuted instantiation: select_to
Unexecuted instantiation: select_from
Unexecuted instantiation: select_refer_to
Unexecuted instantiation: select_rpid
198
                                                                             \
199
  int select_##_name_##_uri(str *res, select_t *s, struct sip_msg *msg)    \
200
0
  {                                                                        \
201
0
    if(parse_##_name_##_header(msg) < 0)                                 \
202
0
      return -1;                                                       \
203
0
    RETURN0_res(get_##_name_(msg)->uri);                                 \
204
0
  }                                                                        \
Unexecuted instantiation: select_to_uri
Unexecuted instantiation: select_from_uri
Unexecuted instantiation: select_refer_to_uri
Unexecuted instantiation: select_rpid_uri
205
                                                                             \
206
  int select_##_name_##_tag(str *res, select_t *s, struct sip_msg *msg)    \
207
0
  {                                                                        \
208
0
    if(parse_##_name_##_header(msg) < 0)                                 \
209
0
      return -1;                                                       \
210
0
    RETURN0_res(get_##_name_(msg)->tag_value);                           \
211
0
  }                                                                        \
Unexecuted instantiation: select_to_tag
Unexecuted instantiation: select_from_tag
Unexecuted instantiation: select_refer_to_tag
Unexecuted instantiation: select_rpid_tag
212
                                                                             \
213
  int select_##_name_##_name(str *res, select_t *s, struct sip_msg *msg)   \
214
0
  {                                                                        \
215
0
    if(parse_##_name_##_header(msg) < 0)                                 \
216
0
      return -1;                                                       \
217
0
    RETURN0_res(get_##_name_(msg)->display);                             \
218
0
  }                                                                        \
Unexecuted instantiation: select_to_name
Unexecuted instantiation: select_from_name
Unexecuted instantiation: select_refer_to_name
Unexecuted instantiation: select_rpid_name
219
                                                                             \
220
  int select_##_name_##_params(str *res, select_t *s, struct sip_msg *msg) \
221
0
  {                                                                        \
222
0
    struct to_param *p;                                                  \
223
0
    if(parse_##_name_##_header(msg) < 0)                                 \
224
0
      return -1;                                                       \
225
0
                                                                             \
226
0
    p = get_##_name_(msg)->param_lst;                                    \
227
0
    while(p) {                                                           \
228
0
      if((p->name.len == s->params[s->n - 1].v.s.len)                  \
229
0
          && !strncasecmp(p->name.s, s->params[s->n - 1].v.s.s,    \
230
0
              p->name.len)) {                                  \
231
0
        RETURN0_res(p->value);                                       \
232
0
      }                                                                \
233
0
      p = p->next;                                                     \
234
0
    }                                                                    \
235
0
    return 1;                                                            \
236
0
  }
Unexecuted instantiation: select_to_params
Unexecuted instantiation: select_from_params
Unexecuted instantiation: select_refer_to_params
Unexecuted instantiation: select_rpid_params
237
238
SELECT_uri_header(to) SELECT_uri_header(from) SELECT_uri_header(refer_to)
239
    SELECT_uri_header(rpid)
240
241
242
0
#define get_contact(msg) ((contact_body_t *)(msg->contact->parsed))
243
244
        int select_contact(str *res, select_t *s, struct sip_msg *msg)
245
0
{
246
0
  if(parse_contact_header(msg) < 0)
247
0
    return -1;
248
0
  RETURN0_res(msg->contact->body);
249
0
}
250
251
int select_contact_uri(str *res, select_t *s, struct sip_msg *msg)
252
0
{
253
0
  contact_t *c;
254
0
  if(parse_contact_header(msg) < 0)
255
0
    return -1;
256
257
0
  c = get_contact(msg)->contacts;
258
0
  if(!c)
259
0
    return 1;
260
0
  RETURN0_res(c->uri);
261
0
}
262
263
int select_contact_name(str *res, select_t *s, struct sip_msg *msg)
264
0
{
265
0
  contact_t *c;
266
0
  if(parse_contact_header(msg) < 0)
267
0
    return -1;
268
269
0
  c = get_contact(msg)->contacts;
270
0
  if(!c)
271
0
    return 1;
272
0
  RETURN0_res(c->name);
273
0
}
274
275
int select_contact_params_spec(str *res, select_t *s, struct sip_msg *msg)
276
0
{
277
0
  contact_t *c;
278
279
0
  if(s->params[s->n - 1].type != SEL_PARAM_DIV) {
280
0
    BUG("Last parameter should have type DIV (converted)\n");
281
0
    return -1;
282
0
  }
283
284
0
  if(parse_contact_header(msg) < 0)
285
0
    return -1;
286
287
0
  c = get_contact(msg)->contacts;
288
0
  if(!c)
289
0
    return 1;
290
291
0
  switch(s->params[s->n - 1].v.i) {
292
0
    case SEL_PARAM_Q:
293
0
      TEST_RET_res_body(c->q);
294
0
    case SEL_PARAM_EXPIRES:
295
0
      TEST_RET_res_body(c->expires);
296
0
    case SEL_PARAM_METHODS:
297
0
      TEST_RET_res_body(c->methods);
298
0
    case SEL_PARAM_RECEIVED:
299
0
      TEST_RET_res_body(c->received);
300
0
    case SEL_PARAM_INSTANCE:
301
0
      TEST_RET_res_body(c->instance);
302
0
    default:
303
0
      BUG("Unexpected parameter value \"%d\"\n", s->params[s->n - 1].v.i);
304
0
      return -1;
305
0
  }
306
0
  return -1;
307
0
}
308
309
int select_contact_params(str *res, select_t *s, struct sip_msg *msg)
310
0
{
311
0
  contact_t *c;
312
0
  param_t *p;
313
0
  if(parse_contact_header(msg) < 0)
314
0
    return -1;
315
316
0
  c = get_contact(msg)->contacts;
317
0
  if(!c)
318
0
    return 1;
319
0
  p = c->params;
320
0
  while(p) {
321
0
    if((p->name.len == s->params[s->n - 1].v.s.len)
322
0
        && !strncasecmp(
323
0
            p->name.s, s->params[s->n - 1].v.s.s, p->name.len)) {
324
0
      RETURN0_res(p->body)
325
0
    }
326
0
    p = p->next;
327
0
  }
328
0
  return 1;
329
0
}
330
331
int select_via(str *res, select_t *s, struct sip_msg *msg)
332
0
{
333
0
  struct via_body *p = NULL;
334
335
0
  if((s->n == 1) || (s->params[1].type == SEL_PARAM_STR)) {
336
0
    if(parse_via_header(msg, 1, &p) < 0)
337
0
      return -1;
338
0
  } else if(parse_via_header(msg, s->params[1].v.i, &p) < 0)
339
0
    return -1;
340
0
  if(!p)
341
0
    return -1;
342
0
  res->s = p->name.s;
343
0
  res->len = p->bsize;
344
0
  trim(res);
345
0
  return 0;
346
0
}
347
348
int select_via_name(str *res, select_t *s, struct sip_msg *msg)
349
0
{
350
0
  struct via_body *p = NULL;
351
352
  // it's not necessary to test if (s->n > 1)
353
0
  if(s->params[1].type == SEL_PARAM_STR) {
354
0
    if(parse_via_header(msg, 1, &p) < 0)
355
0
      return -1;
356
0
  } else if(parse_via_header(msg, s->params[1].v.i, &p) < 0)
357
0
    return -1;
358
0
  if(!p)
359
0
    return -1;
360
0
  RETURN0_res(p->name);
361
0
}
362
363
int select_via_version(str *res, select_t *s, struct sip_msg *msg)
364
0
{
365
0
  struct via_body *p = NULL;
366
367
  // it's not necessary to test if (s->n > 1)
368
0
  if(s->params[1].type == SEL_PARAM_STR) {
369
0
    if(parse_via_header(msg, 1, &p) < 0)
370
0
      return -1;
371
0
  } else if(parse_via_header(msg, s->params[1].v.i, &p) < 0)
372
0
    return -1;
373
0
  if(!p)
374
0
    return -1;
375
0
  RETURN0_res(p->version);
376
0
}
377
378
int select_via_transport(str *res, select_t *s, struct sip_msg *msg)
379
0
{
380
0
  struct via_body *p = NULL;
381
382
  // it's not necessary to test if (s->n > 1)
383
0
  if(s->params[1].type == SEL_PARAM_STR) {
384
0
    if(parse_via_header(msg, 1, &p) < 0)
385
0
      return -1;
386
0
  } else if(parse_via_header(msg, s->params[1].v.i, &p) < 0)
387
0
    return -1;
388
0
  if(!p)
389
0
    return -1;
390
0
  RETURN0_res(p->transport);
391
0
}
392
393
int select_via_host(str *res, select_t *s, struct sip_msg *msg)
394
0
{
395
0
  struct via_body *p = NULL;
396
397
  // it's not necessary to test if (s->n > 1)
398
0
  if(s->params[1].type == SEL_PARAM_STR) {
399
0
    if(parse_via_header(msg, 1, &p) < 0)
400
0
      return -1;
401
0
  } else if(parse_via_header(msg, s->params[1].v.i, &p) < 0)
402
0
    return -1;
403
0
  if(!p)
404
0
    return -1;
405
0
  RETURN0_res(p->host);
406
0
}
407
408
int select_via_port(str *res, select_t *s, struct sip_msg *msg)
409
0
{
410
0
  struct via_body *p = NULL;
411
412
  // it's not necessary to test if (s->n > 1)
413
0
  if(s->params[1].type == SEL_PARAM_STR) {
414
0
    if(parse_via_header(msg, 1, &p) < 0)
415
0
      return -1;
416
0
  } else if(parse_via_header(msg, s->params[1].v.i, &p) < 0)
417
0
    return -1;
418
0
  if(!p)
419
0
    return -1;
420
0
  RETURN0_res(p->port_str);
421
0
}
422
423
int select_via_comment(str *res, select_t *s, struct sip_msg *msg)
424
0
{
425
0
  struct via_body *p = NULL;
426
427
  // it's not necessary to test if (s->n > 1)
428
0
  if(s->params[1].type == SEL_PARAM_STR) {
429
0
    if(parse_via_header(msg, 1, &p) < 0)
430
0
      return -1;
431
0
  } else if(parse_via_header(msg, s->params[1].v.i, &p) < 0)
432
0
    return -1;
433
0
  if(!p)
434
0
    return -1;
435
0
  RETURN0_res(p->comment);
436
0
}
437
438
int select_via_params(str *res, select_t *s, struct sip_msg *msg)
439
0
{
440
0
  struct via_body *p = NULL;
441
0
  struct via_param *q;
442
443
  // it's not necessary to test if (s->n > 1)
444
0
  if(s->params[1].type == SEL_PARAM_STR) {
445
0
    if(parse_via_header(msg, 1, &p) < 0)
446
0
      return -1;
447
0
  } else if(parse_via_header(msg, s->params[1].v.i, &p) < 0)
448
0
    return -1;
449
0
  if(!p)
450
0
    return -1;
451
452
0
  for(q = p->param_lst; q; q = q->next) {
453
0
    if((q->name.len == s->params[s->n - 1].v.s.len)
454
0
        && !strncasecmp(
455
0
            q->name.s, s->params[s->n - 1].v.s.s, q->name.len)) {
456
0
      RETURN0_res(q->value);
457
0
    }
458
0
  }
459
0
  return 1;
460
0
}
461
462
int select_via_params_spec(str *res, select_t *s, struct sip_msg *msg)
463
0
{
464
0
  struct via_body *p = NULL;
465
466
0
  if(s->params[s->n - 1].type != SEL_PARAM_DIV) {
467
0
    BUG("Last parameter should have type DIV (converted)\n");
468
0
    return -1;
469
0
  }
470
471
  // it's not necessary to test if (s->n > 1)
472
0
  if(s->params[1].type != SEL_PARAM_INT) {
473
0
    if(parse_via_header(msg, 1, &p) < 0)
474
0
      return -1;
475
0
  } else if(parse_via_header(msg, s->params[1].v.i, &p) < 0)
476
0
    return -1;
477
0
  if(!p)
478
0
    return -1;
479
480
0
  switch(s->params[s->n - 1].v.i) {
481
0
    case SEL_PARAM_BRANCH:
482
0
      TEST_RET_res_value(p->branch);
483
0
    case SEL_PARAM_RECEIVED:
484
0
      TEST_RET_res_value(p->received);
485
0
    case SEL_PARAM_RPORT:
486
0
      TEST_RET_res_value(p->rport);
487
0
    case SEL_PARAM_I:
488
0
      TEST_RET_res_value(p->i);
489
0
    case SEL_PARAM_ALIAS:
490
0
      TEST_RET_res_value(p->alias);
491
0
    default:
492
0
      BUG("Unexpected parameter value \"%d\"\n", s->params[s->n - 1].v.i);
493
0
      return -1;
494
0
  }
495
0
  return -1;
496
0
}
497
498
int select_msg(str *res, select_t *s, struct sip_msg *msg)
499
0
{
500
0
  res->s = msg->buf;
501
0
  res->len = msg->len;
502
0
  return 0;
503
0
}
504
505
int select_msg_first_line(str *res, select_t *s, struct sip_msg *msg)
506
0
{
507
0
  res->s = SIP_MSG_START(msg);
508
0
  res->len = msg->first_line.len;
509
0
  trim_trailing(res);
510
0
  return 0;
511
0
}
512
513
int select_msg_type(str *res, select_t *s, struct sip_msg *msg)
514
0
{
515
0
  return uint_to_static_buffer(res, msg->first_line.type);
516
0
}
517
518
int select_msg_len(str *res, select_t *s, struct sip_msg *msg)
519
0
{
520
0
  return uint_to_static_buffer(res, msg->len);
521
0
}
522
523
int select_msg_id(str *res, select_t *s, struct sip_msg *msg)
524
0
{
525
0
  return uint_to_static_buffer(res, msg->id);
526
0
}
527
528
int select_msg_id_hex(str *res, select_t *s, struct sip_msg *msg)
529
0
{
530
0
  return uint_to_static_buffer_ex(res, msg->id, 16, 8);
531
0
}
532
533
int select_msg_flags(str *res, select_t *s, struct sip_msg *msg)
534
0
{
535
0
  return uint_to_static_buffer(res, msg->flags);
536
0
}
537
538
int select_msg_body(str *res, select_t *s, struct sip_msg *msg)
539
0
{
540
0
  res->s = get_body(msg);
541
0
  res->len = msg->buf + msg->len - res->s;
542
0
  return 0;
543
0
}
544
545
/* returns the sdp part of the message body */
546
int select_msg_body_sdp(str *res, select_t *sel, struct sip_msg *msg)
547
0
{
548
  /* try to get the body part with application/sdp */
549
0
  if((res->s = get_body_part(msg, TYPE_APPLICATION, SUBTYPE_SDP, &res->len)))
550
0
    return 0;
551
0
  else
552
0
    return -1;
553
0
}
554
555
/* returns the value of the requested SDP line */
556
int select_sdp_line(str *res, select_t *sel, struct sip_msg *msg)
557
0
{
558
0
  int len;
559
0
  char *buf;
560
0
  char *buf_end, *line_end;
561
0
  char line;
562
563
0
  if(msg == NULL) {
564
0
    if(res != NULL)
565
0
      return -1;
566
0
    if(sel->n < 5)
567
0
      return -1;
568
569
0
    if(sel->params[4].type != SEL_PARAM_STR) {
570
0
      LM_ERR("wrong parameter type");
571
0
      return -1;
572
0
    }
573
0
    if((sel->params[4].v.s.len < 1) || (sel->params[4].v.s.len > 2)
574
0
        || ((sel->params[4].v.s.len == 2)
575
0
            && (sel->params[4].v.s.s[1] != '='))) {
576
0
      LM_ERR("wrong sdp line format: %.*s\n", sel->params[4].v.s.len,
577
0
          sel->params[4].v.s.s);
578
0
      return -1;
579
0
    }
580
0
    return 0;
581
0
  }
582
583
  /* try to get the body part with application/sdp */
584
0
  if(!(buf = get_body_part(msg, TYPE_APPLICATION, SUBTYPE_SDP, &len)))
585
0
    return -1;
586
587
0
  buf_end = buf + len;
588
0
  line = *(sel->params[4].v.s.s);
589
590
0
  while(buf < buf_end) {
591
0
    if(*buf == line) {
592
      /* the requested SDP line is found, return its value */
593
0
      buf++;
594
0
      if((buf >= buf_end) || (*buf != '=')) {
595
0
        LM_ERR("wrong SDP line format\n");
596
0
        return -1;
597
0
      }
598
0
      buf++;
599
600
0
      line_end = buf;
601
0
      while((line_end < buf_end) && (*line_end != '\n'))
602
0
        line_end++;
603
604
0
      if(line_end >= buf_end) {
605
0
        LM_ERR("wrong SDP line format\n");
606
0
        return -1;
607
0
      }
608
0
      line_end--;
609
0
      if(*line_end == '\r')
610
0
        line_end--;
611
612
0
      if(line_end < buf) {
613
0
        LM_ERR("wrong SDP line format\n");
614
0
        return -1;
615
0
      }
616
617
0
      res->s = buf;
618
0
      res->len = line_end - buf + 1;
619
0
      return 0;
620
0
    }
621
0
    while((buf < buf_end) && (*buf != '\n'))
622
0
      buf++;
623
0
    buf++;
624
0
  }
625
626
0
  return -1;
627
0
}
628
629
int select_msg_header(str *res, select_t *s, struct sip_msg *msg)
630
0
{
631
  /* get all headers */
632
0
  char *c;
633
0
  res->s = SIP_MSG_START(msg) + msg->first_line.len;
634
0
  c = get_body(msg);
635
0
  res->len = c - res->s;
636
0
  return 0;
637
0
}
638
639
int select_anyheader(str *res, select_t *s, struct sip_msg *msg)
640
0
{
641
0
  struct hdr_field *hf, *hf0;
642
0
  int hi;
643
0
  char c;
644
0
  struct hdr_field hdr;
645
646
0
  if(msg == NULL) {
647
0
    if(res != NULL)
648
0
      return -1;
649
650
    /* "fixup" call, res & msg are NULL */
651
0
    if(s->n < 3)
652
0
      return -1;
653
654
0
    if(s->params[2].type == SEL_PARAM_STR) {
655
      /* replace _ with - (for P-xxx headers) */
656
0
      for(hi = s->params[2].v.s.len - 1; hi > 0; hi--)
657
0
        if(s->params[2].v.s.s[hi] == '_')
658
0
          s->params[2].v.s.s[hi] = '-';
659
      /* if header name is parseable, parse it and set SEL_PARAM_DIV */
660
0
      c = s->params[2].v.s.s[s->params[2].v.s.len];
661
0
      s->params[2].v.s.s[s->params[2].v.s.len] = ':';
662
0
      parse_hname2_short(s->params[2].v.s.s,
663
0
          s->params[2].v.s.s
664
0
              + (s->params[2].v.s.len < 3
665
0
                      ? 4
666
0
                      : s->params[2].v.s.len + 1),
667
0
          &hdr);
668
0
      if(hdr.type == HDR_ERROR_T) {
669
0
        LM_ERR("fixup_call:parse error\n");
670
0
        return -1;
671
0
      }
672
0
      s->params[2].v.s.s[s->params[2].v.s.len] = c;
673
674
0
      if(hdr.type != HDR_OTHER_T && hdr.type != HDR_ERROR_T) {
675
        /* pkg_free(s->params[1].v.s.s); */
676
        /* don't free it (the mem can leak only once at startup)
677
         * the parsed string can live inside larger string block
678
         * e.g. when xlog's select is parsed
679
         */
680
0
        s->params[2].type = SEL_PARAM_DIV;
681
0
        s->params[2].v.i = hdr.type;
682
0
      }
683
0
    }
684
0
    return 1;
685
0
  }
686
687
0
  hf0 = NULL;
688
689
  /* extract header index if present */
690
0
  if(s->param_offset[select_level + 1] == 4) {
691
0
    if(s->params[3].type == SEL_PARAM_INT) {
692
0
      hi = s->params[3].v.i;
693
0
    } else {
694
0
      hi = -1;
695
0
    }
696
0
  } else {
697
0
    hi = 1;
698
0
  }
699
700
  /* we need to be sure we have parsed all headers */
701
0
  if(!msg->eoh && (parse_headers(msg, HDR_EOH_F, 0) == -1 || !msg->eoh)) {
702
0
    LM_ERR("bad msg while parsing to EOH \n");
703
0
    return -1;
704
0
  }
705
0
  for(hf = msg->headers; hf; hf = hf->next) {
706
0
    if(s->params[2].type == SEL_PARAM_DIV) {
707
0
      if(s->params[2].v.i != hf->type)
708
0
        continue;
709
0
    } else if(s->params[2].type == SEL_PARAM_STR) {
710
0
      if(s->params[2].v.s.len != hf->name.len)
711
0
        continue;
712
0
      if(strncasecmp(s->params[2].v.s.s, hf->name.s, hf->name.len) != 0)
713
0
        continue;
714
0
    }
715
0
    hf0 = hf;
716
0
    hi--;
717
0
    if(!hi)
718
0
      break;
719
0
  }
720
0
  if(hf0 == NULL || hi > 0)
721
0
    return 1;
722
0
  res->s = hf0->body.s;
723
0
  res->len = hf0->body.len;
724
0
  trim(res);
725
0
  return 0;
726
0
}
727
728
ABSTRACT_F(select_anyheader_params)
729
730
ABSTRACT_F(select_any_uri)
731
732
static struct sip_uri uri;
733
734
int select_uri_type(str *res, select_t *s, struct sip_msg *msg)
735
0
{
736
0
  if(select_uri_p == NULL) {
737
0
    trim(res);
738
0
    if(parse_uri(res->s, res->len, &uri) < 0)
739
0
      return -1;
740
0
    select_uri_p = &uri;
741
0
  }
742
743
0
  if(select_uri_p->type == ERROR_URI_T)
744
0
    return -1;
745
746
0
  uri_type_to_str(select_uri_p->type, res);
747
0
  return 0;
748
0
}
749
750
int select_uri_user(str *res, select_t *s, struct sip_msg *msg)
751
0
{
752
0
  if(select_uri_p == NULL) {
753
0
    if(parse_uri(res->s, res->len, &uri) < 0)
754
0
      return -1;
755
0
    select_uri_p = &uri;
756
0
  }
757
758
0
  if(select_uri_p->flags & URI_USER_NORMALIZE) {
759
0
    if(!(res->s = get_static_buffer(select_uri_p->user.len)))
760
0
      return -1;
761
0
    if((res->len = normalize_tel_user(res->s, (&select_uri_p->user))) == 0)
762
0
      return 1;
763
0
    return 0;
764
0
  }
765
0
  RETURN0_res(select_uri_p->user);
766
0
}
767
768
/* search for a parameter with "name"
769
 * Return value:
770
 *  0: not found
771
 *  1: found
772
 *  -1: error
773
 *
774
 * val is set to the value of the parameter.
775
 */
776
static inline int search_param(str params, char *name, int name_len, str *val)
777
0
{
778
0
  param_hooks_t h;
779
0
  param_t *p, *list;
780
781
0
  if(params.s == NULL)
782
0
    return 0;
783
784
0
  if(parse_params(&params, CLASS_ANY, &h, &list) < 0)
785
0
    return -1;
786
0
  for(p = list; p; p = p->next) {
787
0
    if((p->name.len == name_len)
788
0
        && (strncasecmp(p->name.s, name, name_len) == 0)) {
789
0
      *val = p->body;
790
0
      free_params(list);
791
0
      return 1;
792
0
    }
793
0
  }
794
0
  free_params(list);
795
0
  return 0;
796
0
}
797
798
/* Return the value of the "rn" parameter if exists, otherwise the user name.
799
 * The user name is normalized if needed, i.e. visual separators are removed,
800
 * the "rn" param is always normalized. */
801
int select_uri_rn_user(str *res, select_t *s, struct sip_msg *msg)
802
0
{
803
0
  int ret;
804
0
  str val;
805
806
0
  if(select_uri_p == NULL) {
807
0
    if(parse_uri(res->s, res->len, &uri) < 0)
808
0
      return -1;
809
0
    select_uri_p = &uri;
810
0
  }
811
812
  /* search for the "rn" parameter */
813
0
  if((ret = search_param(select_uri_p->params, "rn", 2, &val)) != 0)
814
0
    goto done;
815
816
0
  if(select_uri_p->sip_params.s != select_uri_p->params.s) {
817
    /* check also the original sip: URI parameters */
818
0
    if((ret = search_param(select_uri_p->sip_params, "rn", 2, &val)) != 0)
819
0
      goto done;
820
0
  }
821
822
0
  if((select_uri_p->flags & URI_USER_NORMALIZE) == 0)
823
0
    RETURN0_res(select_uri_p->user);
824
  /* else normalize the user name */
825
0
  val = select_uri_p->user;
826
0
done:
827
0
  if(ret < 0)
828
0
    return -1; /* error */
829
830
0
  if(!(res->s = get_static_buffer(val.len)))
831
0
    return -1;
832
0
  if((res->len = normalize_tel_user(res->s, &val)) == 0)
833
0
    return 1;
834
0
  return 0;
835
0
}
836
837
int select_uri_pwd(str *res, select_t *s, struct sip_msg *msg)
838
0
{
839
0
  if(select_uri_p == NULL) {
840
0
    if(parse_uri(res->s, res->len, &uri) < 0)
841
0
      return -1;
842
0
    select_uri_p = &uri;
843
0
  }
844
845
0
  RETURN0_res(select_uri_p->passwd);
846
0
}
847
848
int select_uri_host(str *res, select_t *s, struct sip_msg *msg)
849
0
{
850
0
  if(select_uri_p == NULL) {
851
0
    if(parse_uri(res->s, res->len, &uri) < 0)
852
0
      return -1;
853
0
    select_uri_p = &uri;
854
0
  }
855
856
0
  RETURN0_res(select_uri_p->host);
857
0
}
858
859
int select_uri_port(str *res, select_t *s, struct sip_msg *msg)
860
0
{
861
0
  if(select_uri_p == NULL) {
862
0
    if(parse_uri(res->s, res->len, &uri) < 0)
863
0
      return -1;
864
0
    select_uri_p = &uri;
865
0
  }
866
867
0
  RETURN0_res(select_uri_p->port);
868
0
}
869
870
int select_uri_hostport(str *res, select_t *s, struct sip_msg *msg)
871
0
{
872
0
  char *p;
873
0
  int size;
874
875
0
  if(select_uri_p == NULL) {
876
0
    if(parse_uri(res->s, res->len, &uri) < 0)
877
0
      return -1;
878
0
    select_uri_p = &uri;
879
0
  }
880
881
0
  if(!select_uri_p->host.len)
882
0
    return -1;
883
884
0
  if(select_uri_p->port.len) {
885
0
    res->s = select_uri_p->host.s;
886
0
    res->len = select_uri_p->host.len + select_uri_p->port.len + 1;
887
0
    return 0;
888
0
  }
889
890
0
  size = select_uri_p->host.len + 5;
891
0
  if(!(p = get_static_buffer(size)))
892
0
    return -1;
893
894
0
  memcpy(p, select_uri_p->host.s, select_uri_p->host.len);
895
0
  switch(select_uri_p->type) {
896
0
    case SIPS_URI_T:
897
0
    case TELS_URI_T:
898
0
      memcpy(p + select_uri_p->host.len, ":5061", 5);
899
0
      break;
900
0
    case SIP_URI_T:
901
0
    case TEL_URI_T:
902
0
    case URN_URI_T:
903
0
      memcpy(p + select_uri_p->host.len, ":5060", 5);
904
0
      break;
905
0
    case ERROR_URI_T:
906
0
      return -1;
907
0
  }
908
0
  res->s = p;
909
0
  res->len = size;
910
0
  return 0;
911
0
}
912
913
int select_uri_proto(str *res, select_t *s, struct sip_msg *msg)
914
0
{
915
0
  if(select_uri_p == NULL) {
916
0
    if(parse_uri(res->s, res->len, &uri) < 0)
917
0
      return -1;
918
0
    select_uri_p = &uri;
919
0
  }
920
921
0
  if(select_uri_p->proto != PROTO_NONE) {
922
0
    proto_type_to_str(select_uri_p->proto, res);
923
0
  } else {
924
0
    switch(select_uri_p->type) {
925
0
      case SIPS_URI_T:
926
0
      case TELS_URI_T:
927
0
        proto_type_to_str(PROTO_TLS, res);
928
0
        break;
929
0
      case SIP_URI_T:
930
0
      case TEL_URI_T:
931
0
      case URN_URI_T:
932
0
        proto_type_to_str(PROTO_UDP, res);
933
0
        break;
934
0
      case ERROR_URI_T:
935
0
        return -1;
936
0
    }
937
0
  }
938
0
  return 0;
939
0
}
940
941
int select_uri_params(str *res, select_t *s, struct sip_msg *msg)
942
0
{
943
0
  int ret;
944
0
  if(!msg || !res) {
945
0
    return select_any_params(res, s, msg);
946
0
  }
947
948
0
  if(select_uri_p == NULL) {
949
0
    if(parse_uri(res->s, res->len, &uri) < 0)
950
0
      return -1;
951
0
    select_uri_p = &uri;
952
0
  }
953
954
0
  if(s->param_offset[select_level + 1] - s->param_offset[select_level] == 1)
955
0
    RETURN0_res(select_uri_p->params);
956
957
0
  *res = select_uri_p->params;
958
0
  ret = select_any_params(res, s, msg);
959
0
  if((ret < 0) && (select_uri_p->sip_params.s != NULL)
960
0
      && (select_uri_p->sip_params.s != select_uri_p->params.s)) {
961
    /* Search also in the original sip: uri parameters. */
962
0
    *res = select_uri_p->sip_params;
963
0
    ret = select_any_params(res, s, msg);
964
0
  }
965
0
  return ret;
966
0
}
967
968
int select_any_params(str *res, select_t *s, struct sip_msg *msg)
969
0
{
970
0
  str *wanted;
971
0
  int i;
972
973
0
  if(!msg || !res) {
974
0
    if(s->param_offset[select_level + 1] - s->param_offset[select_level]
975
0
        == 1)
976
0
      return 0;
977
0
    if(s->params[s->param_offset[select_level] + 1].type != SEL_PARAM_STR)
978
0
      return -1;
979
0
    wanted = &s->params[s->param_offset[select_level] + 1].v.s;
980
0
    for(i = 0; i < wanted->len; i++)
981
0
      if(wanted->s[i] == '_')
982
0
        wanted->s[i] = '-';
983
0
    return 0;
984
0
  }
985
986
0
  if(s->params[s->param_offset[select_level] + 1].type != SEL_PARAM_STR)
987
0
    return -1;
988
0
  wanted = &s->params[s->param_offset[select_level] + 1].v.s;
989
990
0
  if(!res->len)
991
0
    return -1;
992
993
0
  if(search_param(*res, wanted->s, wanted->len, res) <= 0) {
994
0
    LM_DBG("uri.params.%s NOT FOUND !\n", wanted->s);
995
0
    return -1;
996
0
  } else {
997
0
    return (res->len) ? 0 : 1;
998
0
  }
999
0
}
1000
1001
int select_event(str *res, select_t *s, struct sip_msg *msg)
1002
0
{
1003
0
  if(!msg->event && parse_headers(msg, HDR_EVENT_F, 0) == -1) {
1004
0
    LM_ERR("Error while searching Event header field\n");
1005
0
    return -1;
1006
0
  }
1007
1008
0
  if(!msg->event) {
1009
0
    LM_DBG("Event header field not found\n");
1010
0
    return -1;
1011
0
  }
1012
1013
0
  if(parse_event(msg->event) < 0) {
1014
0
    LM_ERR("Error while parsing Event header field\n");
1015
0
    return -1;
1016
0
  }
1017
1018
0
  *res = ((event_t *)msg->event->parsed)->name;
1019
0
  return 0;
1020
0
}
1021
1022
1023
static int parse_rr_header(struct sip_msg *msg)
1024
0
{
1025
0
  if(!msg->record_route && (parse_headers(msg, HDR_RECORDROUTE_F, 0) == -1)) {
1026
0
    LM_ERR("bad msg or missing Record-Route header\n");
1027
0
    return -1;
1028
0
  }
1029
1030
0
  if(!msg->record_route) {
1031
0
    LM_DBG("No Record-Route header field found\n");
1032
0
    return -1;
1033
0
  }
1034
1035
0
  return parse_rr(msg->record_route);
1036
0
}
1037
1038
0
#define get_rr(msg) ((rr_t *)(msg->record_route->parsed))
1039
1040
1041
int select_rr(str *res, select_t *s, struct sip_msg *msg)
1042
0
{
1043
0
  if(parse_rr_header(msg) < 0)
1044
0
    return -1;
1045
0
  RETURN0_res(msg->record_route->body);
1046
0
}
1047
1048
int select_rr_uri(str *res, select_t *s, struct sip_msg *msg)
1049
0
{
1050
0
  rr_t *r;
1051
0
  if(parse_rr_header(msg) < 0)
1052
0
    return -1;
1053
1054
0
  r = get_rr(msg);
1055
0
  if(!r)
1056
0
    return 1;
1057
0
  RETURN0_res(r->nameaddr.uri);
1058
0
}
1059
1060
int select_rr_name(str *res, select_t *s, struct sip_msg *msg)
1061
0
{
1062
0
  rr_t *r;
1063
0
  if(parse_rr_header(msg) < 0)
1064
0
    return -1;
1065
1066
0
  r = get_rr(msg);
1067
0
  if(!r)
1068
0
    return 1;
1069
0
  RETURN0_res(r->nameaddr.name);
1070
0
}
1071
1072
int select_rr_params(str *res, select_t *s, struct sip_msg *msg)
1073
0
{
1074
0
  rr_t *r;
1075
0
  param_t *p;
1076
0
  if(parse_rr_header(msg) < 0)
1077
0
    return -1;
1078
1079
0
  r = get_rr(msg);
1080
0
  if(!r)
1081
0
    return 1;
1082
0
  p = r->params;
1083
0
  while(p) {
1084
0
    if((p->name.len == s->params[s->n - 1].v.s.len)
1085
0
        && !strncasecmp(
1086
0
            p->name.s, s->params[s->n - 1].v.s.s, p->name.len)) {
1087
0
      RETURN0_res(p->body)
1088
0
    }
1089
0
    p = p->next;
1090
0
  }
1091
0
  return 0;
1092
0
}
1093
1094
1095
static inline struct cseq_body *sel_parse_cseq(struct sip_msg *msg)
1096
0
{
1097
0
  if(!msg->cseq && (parse_headers(msg, HDR_CSEQ_F, 0) == -1)) {
1098
0
    LM_ERR("Unable to parse CSeq header\n");
1099
0
    return 0;
1100
0
  }
1101
1102
0
  if(!msg->cseq) {
1103
0
    LM_DBG("No CSeq header field found\n");
1104
0
    return 0;
1105
0
  }
1106
1107
0
  return get_cseq(msg);
1108
0
}
1109
1110
1111
int select_cseq(str *res, select_t *s, struct sip_msg *msg)
1112
0
{
1113
0
  struct cseq_body *cs;
1114
1115
0
  cs = sel_parse_cseq(msg);
1116
0
  if(!cs)
1117
0
    return -1;
1118
0
  *res = msg->cseq->body;
1119
0
  return 0;
1120
0
}
1121
1122
int select_cseq_num(str *res, select_t *s, struct sip_msg *msg)
1123
0
{
1124
0
  struct cseq_body *cs;
1125
1126
0
  cs = sel_parse_cseq(msg);
1127
0
  if(!cs)
1128
0
    return -1;
1129
0
  *res = cs->number;
1130
0
  return 0;
1131
0
}
1132
1133
int select_cseq_method(str *res, select_t *s, struct sip_msg *msg)
1134
0
{
1135
0
  struct cseq_body *cs;
1136
1137
0
  cs = sel_parse_cseq(msg);
1138
0
  if(!cs)
1139
0
    return -1;
1140
0
  *res = cs->method;
1141
0
  return 0;
1142
0
}
1143
1144
int get_credentials(struct sip_msg *msg, select_t *s, struct hdr_field **hdr)
1145
0
{
1146
0
  int ret;
1147
0
  str realm;
1148
0
  hdr_types_t hdr_type;
1149
1150
0
  *hdr = NULL;
1151
1152
0
  if(!msg) {
1153
    /* fix-up call check domain for fparam conversion */
1154
0
    void *ptr;
1155
0
    char chr;
1156
0
    ptr = (void *)(s->params[1].v.s.s);
1157
0
    chr = s->params[1].v.s.s[s->params[1].v.s.len];
1158
0
    s->params[1].v.s.s[s->params[1].v.s.len] = 0;
1159
0
    ret = fixup_var_str_12(&ptr, 0);
1160
0
    if(ret >= 0) {
1161
0
      s->params[1].v.s.s[s->params[1].v.s.len] = chr;
1162
0
      s->params[1].v.p = ptr;
1163
0
      s->params[1].type = SEL_PARAM_PTR;
1164
0
    }
1165
0
    return ret;
1166
0
  }
1167
1168
1169
  /* Try to find credentials with corresponding realm
1170
   * in the message, parse them and return pointer to
1171
   * parsed structure
1172
   */
1173
0
  if(s->params[1].type == SEL_PARAM_PTR) {
1174
0
    if(get_str_fparam(&realm, msg, s->params[1].v.p) < 0)
1175
0
      return -1;
1176
0
  } else {
1177
0
    realm = s->params[1].v.s;
1178
0
  }
1179
1180
0
  switch(s->params[0].v.i) {
1181
0
    case SEL_AUTH_WWW:
1182
0
      hdr_type = HDR_AUTHORIZATION_T;
1183
0
      break;
1184
1185
0
    case SEL_AUTH_PROXY:
1186
0
      hdr_type = HDR_PROXYAUTH_T;
1187
0
      break;
1188
1189
0
    default:
1190
0
      BUG("Unexpected parameter value \"%d\"\n", s->params[0].v.i);
1191
0
      return -1;
1192
0
  }
1193
1194
0
  ret = find_credentials(msg, &realm, hdr_type, hdr);
1195
0
  return ret;
1196
0
}
1197
1198
1199
int select_auth(str *res, select_t *s, struct sip_msg *msg)
1200
0
{
1201
0
  int ret;
1202
0
  struct hdr_field *hdr;
1203
1204
0
  if(s->n != 2 && s->params[1].type != SEL_PARAM_STR
1205
0
      && s->params[1].type != SEL_PARAM_PTR)
1206
0
    return -1;
1207
1208
0
  if(s->params[0].type != SEL_PARAM_DIV) {
1209
0
    BUG("Last parameter should have type DIV (converted)\n");
1210
0
    return -1;
1211
0
  }
1212
1213
0
  ret = get_credentials(msg, s, &hdr);
1214
0
  if(!hdr)
1215
0
    return ret;
1216
0
  RETURN0_res(hdr->body);
1217
0
}
1218
1219
int select_auth_param(str *res, select_t *s, struct sip_msg *msg)
1220
0
{
1221
0
  int ret;
1222
0
  struct hdr_field *hdr;
1223
0
  dig_cred_t *cred;
1224
1225
0
  if((s->n != 3 && s->n != 4) || (s->params[s->n - 1].type != SEL_PARAM_DIV))
1226
0
    return -1;
1227
1228
0
  ret = get_credentials(msg, s, &hdr);
1229
0
  if(!hdr)
1230
0
    return ret;
1231
0
  cred = &((auth_body_t *)hdr->parsed)->digest;
1232
1233
0
  switch(s->params[s->n - 1].v.i) {
1234
0
    case SEL_AUTH_USER:
1235
0
      RETURN0_res(cred->username.user);
1236
0
    case SEL_AUTH_DOMAIN:
1237
0
      RETURN0_res(cred->username.domain);
1238
0
    case SEL_AUTH_USERNAME:
1239
0
      RETURN0_res(cred->username.whole);
1240
0
    case SEL_AUTH_REALM:
1241
0
      RETURN0_res(cred->realm);
1242
0
    case SEL_AUTH_NONCE:
1243
0
      RETURN0_res(cred->nonce);
1244
0
    case SEL_AUTH_URI:
1245
0
      RETURN0_res(cred->uri);
1246
0
    case SEL_AUTH_CNONCE:
1247
0
      RETURN0_res(cred->cnonce);
1248
0
    case SEL_AUTH_NC:
1249
0
      RETURN0_res(cred->nc);
1250
0
    case SEL_AUTH_RESPONSE:
1251
0
      RETURN0_res(cred->response);
1252
0
    case SEL_AUTH_OPAQUE:
1253
0
      RETURN0_res(cred->opaque);
1254
0
    case SEL_AUTH_ALG:
1255
0
      RETURN0_res(cred->alg.alg_str);
1256
0
    case SEL_AUTH_QOP:
1257
0
      RETURN0_res(cred->qop.qop_str);
1258
0
    default:
1259
0
      BUG("Unsupported digest credentials parameter in select\n");
1260
0
      return -1;
1261
0
  }
1262
0
}
1263
1264
int select_auth_username(str *res, select_t *s, struct sip_msg *msg)
1265
0
{
1266
0
  return select_auth_param(res, s, msg);
1267
0
}
1268
1269
int select_auth_username_comp(str *res, select_t *s, struct sip_msg *msg)
1270
0
{
1271
0
  return select_auth_param(res, s, msg);
1272
0
}
1273
1274
ABSTRACT_F(select_any_nameaddr)
1275
1276
int select_nameaddr_name(str *res, select_t *s, struct sip_msg *msg)
1277
0
{
1278
0
  char *p;
1279
1280
0
  p = find_not_quoted(res, '<');
1281
0
  if(!p) {
1282
0
    LM_DBG("no < found, whole string is uri\n");
1283
0
    res->len = 0;
1284
0
    return 1;
1285
0
  }
1286
1287
0
  res->len = p - res->s;
1288
0
  while(res->len && SP(res->s[res->len - 1]))
1289
0
    res->len--;
1290
0
  return 0;
1291
0
}
1292
1293
int select_nameaddr_uri(str *res, select_t *s, struct sip_msg *msg)
1294
0
{
1295
0
  char *p;
1296
1297
0
  p = find_not_quoted(res, '<');
1298
0
  if(!p) {
1299
0
    LM_DBG("no < found, string up to first semicolon is uri\n");
1300
0
    p = q_memchr(res->s, ';', res->len);
1301
0
    if(p)
1302
0
      res->len = p - res->s;
1303
0
    return 0;
1304
0
  }
1305
1306
0
  res->len = res->len - (p - res->s) - 1;
1307
0
  res->s = p + 1;
1308
1309
0
  p = find_not_quoted(res, '>');
1310
0
  if(!p) {
1311
0
    LM_ERR("no > found, invalid nameaddr value\n");
1312
0
    return -1;
1313
0
  }
1314
1315
0
  res->len = p - res->s;
1316
0
  return 0;
1317
0
}
1318
1319
int select_nameaddr_params(str *res, select_t *s, struct sip_msg *msg)
1320
0
{
1321
0
  char *p;
1322
1323
0
  p = find_not_quoted(res, '<');
1324
0
  if(!p) {
1325
0
    p = find_not_quoted(res, ';');
1326
0
  } else {
1327
0
    res->len = res->len - (p - res->s) - 1;
1328
0
    res->s = p + 1;
1329
0
    p = find_not_quoted(res, '>');
1330
0
    if(!p) {
1331
0
      LM_ERR("no > found, invalid nameaddr value\n");
1332
0
      return -1;
1333
0
    }
1334
0
    res->len = res->len - (p - res->s) - 1;
1335
0
    res->s = p + 1;
1336
1337
0
    p = find_not_quoted(res, ';');
1338
0
  }
1339
0
  if(!p)
1340
0
    return 1;
1341
1342
0
  res->len = res->len - (p - res->s) - 1;
1343
0
  res->s = p + 1;
1344
1345
0
  if(s->param_offset[select_level + 1] - s->param_offset[select_level] == 1)
1346
0
    return (res->len ? 0 : 1);
1347
1348
0
  return select_any_params(res, s, msg);
1349
0
}
1350
1351
ABSTRACT_F(select_src)
1352
ABSTRACT_F(select_dst)
1353
ABSTRACT_F(select_rcv)
1354
int select_ip_port(str *res, select_t *s, struct sip_msg *msg)
1355
0
{
1356
0
  str ip_str = STR_NULL, port_str = STR_NULL, proto_str = str_init("udp");
1357
0
  int param, pos;
1358
1359
1360
0
  if((s->n != 2) || (s->params[1].type != SEL_PARAM_DIV))
1361
0
    return -1;
1362
0
  param = s->params[1].v.i;
1363
1364
0
  if(param & SEL_SRC) {
1365
0
    if(param & SEL_IP) {
1366
0
      ip_str.s = ip_addr2a(&msg->rcv.src_ip);
1367
0
      ip_str.len = strlen(ip_str.s);
1368
0
    }
1369
0
    if(param & SEL_PORT) {
1370
0
      port_str.s = int2str(msg->rcv.src_port, &port_str.len);
1371
0
    }
1372
0
  } else if(param & SEL_DST) {
1373
0
    if(param & SEL_IP) {
1374
0
      ip_str.s = ip_addr2a(&msg->rcv.dst_ip);
1375
0
      ip_str.len = strlen(ip_str.s);
1376
0
    }
1377
0
    if(param & SEL_PORT) {
1378
0
      port_str.s = int2str(msg->rcv.dst_port, &port_str.len);
1379
0
    }
1380
0
  } else if(param & SEL_RCV) {
1381
0
    if(param & SEL_IP) {
1382
0
      ip_str = msg->rcv.bind_address->address_str;
1383
0
    }
1384
0
    if(param & SEL_PORT) {
1385
0
      port_str = msg->rcv.bind_address->port_no_str;
1386
0
    }
1387
0
    if(param & SEL_PROTO) {
1388
0
      switch(msg->rcv.proto) {
1389
0
        case PROTO_NONE:
1390
0
          proto_str.s = 0;
1391
0
          proto_str.len = 0;
1392
0
          break;
1393
1394
0
        case PROTO_UDP:
1395
0
          proto_str.s = "udp";
1396
0
          proto_str.len = 3;
1397
0
          break;
1398
1399
0
        case PROTO_TCP:
1400
0
          proto_str.s = "tcp";
1401
0
          proto_str.len = 3;
1402
0
          break;
1403
1404
0
        case PROTO_TLS:
1405
0
          proto_str.s = "tls";
1406
0
          proto_str.len = 3;
1407
0
          break;
1408
1409
0
        case PROTO_SCTP:
1410
0
          proto_str.s = "sctp";
1411
0
          proto_str.len = 4;
1412
0
          break;
1413
1414
0
        default:
1415
0
          LM_ERR("Unknown transport protocol\n");
1416
0
          return -1;
1417
0
      }
1418
0
    }
1419
0
  } else {
1420
0
    return -1;
1421
0
  }
1422
1423
0
  res->s = get_static_buffer(ip_str.len + port_str.len + proto_str.len + 3);
1424
0
  if(!res->s)
1425
0
    return -1;
1426
1427
0
  pos = 0;
1428
0
  if(param & SEL_PROTO) {
1429
0
    memcpy(res->s, proto_str.s, proto_str.len);
1430
0
    pos += proto_str.len;
1431
0
  }
1432
0
  if(param & SEL_IP) {
1433
0
    if(pos)
1434
0
      res->s[pos++] = ':';
1435
0
    memcpy(res->s + pos, ip_str.s, ip_str.len);
1436
0
    pos += ip_str.len;
1437
0
  }
1438
0
  if(param & SEL_PORT) {
1439
0
    if(pos)
1440
0
      res->s[pos++] = ':';
1441
0
    memcpy(res->s + pos, port_str.s, port_str.len);
1442
0
    pos += port_str.len;
1443
0
  }
1444
0
  res->s[pos] = 0;
1445
0
  res->len = pos;
1446
0
  return (pos == 0 ? 1 : 0);
1447
0
}
1448
1449
1450
int select_expires(str *res, select_t *s, struct sip_msg *msg)
1451
0
{
1452
0
  if(!msg->expires && (parse_headers(msg, HDR_EXPIRES_F, 0) == -1)) {
1453
0
    return -1; /* error */
1454
0
  }
1455
1456
0
  if(!msg->expires) {
1457
0
    return 1; /* null */
1458
0
  }
1459
1460
0
  if(msg->expires->parsed == NULL && parse_expires(msg->expires) < 0) {
1461
0
    return -1;
1462
0
  }
1463
1464
0
  RETURN0_res(((struct exp_body *)msg->expires->parsed)->text);
1465
0
}
1466
1467
#define SELECT_plain_header(_sel_name_, _fld_name_, _hdr_f_)             \
1468
  int select_##_sel_name_(str *res, select_t *s, struct sip_msg *msg)  \
1469
0
  {                                                                    \
1470
0
    if(!msg->_fld_name_ && (parse_headers(msg, _hdr_f_, 0) == -1)) { \
1471
0
      return -1;                                                   \
1472
0
    }                                                                \
1473
0
    if(!msg->_fld_name_) {                                           \
1474
0
      return 1;                                                    \
1475
0
    }                                                                \
1476
0
    RETURN0_res(msg->_fld_name_->body);                              \
1477
0
  }
Unexecuted instantiation: select_call_id
Unexecuted instantiation: select_max_forwards
Unexecuted instantiation: select_content_type
Unexecuted instantiation: select_content_length
Unexecuted instantiation: select_user_agent
Unexecuted instantiation: select_subject
Unexecuted instantiation: select_organization
Unexecuted instantiation: select_priority
Unexecuted instantiation: select_session_expires
Unexecuted instantiation: select_min_se
Unexecuted instantiation: select_sip_if_match
Unexecuted instantiation: select_date
Unexecuted instantiation: select_identity
Unexecuted instantiation: select_identity_info
1478
1479
SELECT_plain_header(call_id, callid, HDR_CALLID_F) SELECT_plain_header(
1480
    max_forwards, maxforwards,
1481
    HDR_MAXFORWARDS_F) SELECT_plain_header(content_type, content_type,
1482
    HDR_CONTENTTYPE_F) SELECT_plain_header(content_length, content_length,
1483
    HDR_CONTENTLENGTH_F) SELECT_plain_header(user_agent, user_agent,
1484
    HDR_USERAGENT_F) SELECT_plain_header(subject, subject,
1485
    HDR_SUBJECT_F) SELECT_plain_header(organization, organization,
1486
    HDR_ORGANIZATION_F) SELECT_plain_header(priority, priority,
1487
    HDR_PRIORITY_F) SELECT_plain_header(session_expires, session_expires,
1488
    HDR_SESSIONEXPIRES_F) SELECT_plain_header(min_se, min_se, HDR_MIN_SE_F)
1489
    SELECT_plain_header(sip_if_match, sipifmatch, HDR_SIPIFMATCH_F)
1490
        SELECT_plain_header(date, date, HDR_DATE_F) SELECT_plain_header(
1491
            identity, identity, HDR_IDENTITY_F)
1492
            SELECT_plain_header(identity_info, identity_info,
1493
                HDR_IDENTITY_INFO_F)
1494
1495
                int select_msg_request(str *res, select_t *s,
1496
                    struct sip_msg *msg)
1497
0
{
1498
0
  if(msg->first_line.type == SIP_REQUEST) {
1499
0
    return select_msg(res, s, msg);
1500
0
  } else
1501
0
    return -1;
1502
0
}
1503
1504
int select_msg_response(str *res, select_t *s, struct sip_msg *msg)
1505
0
{
1506
0
  if(msg->first_line.type == SIP_REPLY) {
1507
0
    return select_msg(res, s, msg);
1508
0
  } else
1509
0
    return -1;
1510
0
}
1511
1512
#define SELECT_first_line(_sel_name_, _type_, _fld_)                        \
1513
  int select_msg_##_sel_name_(str *res, select_t *s, struct sip_msg *msg) \
1514
0
  {                                                                       \
1515
0
    if(msg->first_line.type == _type_) {                                \
1516
0
      RETURN0_res(msg->first_line._fld_);                             \
1517
0
    } else                                                              \
1518
0
      return -1;                                                      \
1519
0
  }
Unexecuted instantiation: select_msg_request_method
Unexecuted instantiation: select_msg_request_uri
Unexecuted instantiation: select_msg_request_version
Unexecuted instantiation: select_msg_response_version
Unexecuted instantiation: select_msg_response_status
Unexecuted instantiation: select_msg_response_reason
1520
1521
SELECT_first_line(request_method, SIP_REQUEST, u.request.method)
1522
    SELECT_first_line(request_uri, SIP_REQUEST,
1523
        u.request.uri) SELECT_first_line(request_version, SIP_REQUEST,
1524
        u.request.version) SELECT_first_line(response_version,
1525
        SIP_REPLY, u.reply.version) SELECT_first_line(response_status,
1526
        SIP_REPLY, u.reply.status) SELECT_first_line(response_reason,
1527
        SIP_REPLY, u.reply.reason)
1528
1529
1530
        int select_version(str *res, select_t *s, struct sip_msg *msg)
1531
0
{
1532
0
  switch(msg->first_line.type) {
1533
0
    case SIP_REQUEST:
1534
0
      RETURN0_res(msg->first_line.u.request.version) break;
1535
0
    case SIP_REPLY:
1536
0
      RETURN0_res(msg->first_line.u.reply.version) break;
1537
0
    default:
1538
0
      return -1;
1539
0
  }
1540
0
}
1541
1542
ABSTRACT_F(select_sys)
1543
1544
int select_sys_pid(str *res, select_t *s, struct sip_msg *msg)
1545
0
{
1546
0
  return uint_to_static_buffer(res, getpid());
1547
0
}
1548
1549
int select_sys_server_id(str *res, select_t *s, struct sip_msg *msg)
1550
0
{
1551
0
  return int_to_static_buffer(res, server_id);
1552
0
}
1553
1554
int select_sys_unique(str *res, select_t *s, struct sip_msg *msg)
1555
0
{
1556
0
#define UNIQUE_ID_PID_LEN 4
1557
0
#define UNIQUE_ID_TIME_LEN 8
1558
0
#define UNIQUE_ID_FIX_LEN (UNIQUE_ID_PID_LEN + 1 + UNIQUE_ID_TIME_LEN + 1)
1559
0
#define UNIQUE_ID_RAND_LEN 8
1560
0
  static char uniq_id[UNIQUE_ID_FIX_LEN + UNIQUE_ID_RAND_LEN];
1561
0
  static int uniq_for_pid = -1;
1562
0
  int i;
1563
1564
0
  if(uniq_for_pid != getpid()) {
1565
    /* first call for this process */
1566
0
    int cb, rb, x, l;
1567
0
    char *c;
1568
    /* init gloabally uniq part */
1569
0
    c = int2str_base_0pad(getpid(), &l, 16, UNIQUE_ID_PID_LEN);
1570
0
    memcpy(uniq_id, c, UNIQUE_ID_PID_LEN);
1571
0
    uniq_id[UNIQUE_ID_PID_LEN] = '-';
1572
0
    c = int2str_base_0pad(
1573
0
        (unsigned int)(uint64_t)time(NULL), &l, 16, UNIQUE_ID_TIME_LEN);
1574
0
    memcpy(uniq_id + UNIQUE_ID_PID_LEN + 1, c, UNIQUE_ID_TIME_LEN);
1575
0
    uniq_id[UNIQUE_ID_PID_LEN + 1 + UNIQUE_ID_TIME_LEN] = '-';
1576
1577
    /* init random part */
1578
0
    for(i = KAM_RAND_MAX, rb = 0; i; rb++, i >>= 1)
1579
0
      ;
1580
0
    for(i = UNIQUE_ID_FIX_LEN, cb = 0, x = 0;
1581
0
        i < UNIQUE_ID_FIX_LEN + UNIQUE_ID_RAND_LEN; i++) {
1582
0
      if(!cb) {
1583
0
        cb = rb;
1584
0
        x = kam_rand();
1585
0
      }
1586
0
      uniq_id[i] = fourbits2char[x & 0x0F];
1587
0
      x >>= rb;
1588
0
      cb -= rb;
1589
0
    }
1590
0
    uniq_for_pid = getpid();
1591
0
  }
1592
0
  for(i = UNIQUE_ID_FIX_LEN + UNIQUE_ID_RAND_LEN - 1; i >= UNIQUE_ID_FIX_LEN;
1593
0
      i--) {
1594
0
    switch(uniq_id[i]) {
1595
0
      case '9':
1596
0
        uniq_id[i] = 'a';
1597
0
        i = 0;
1598
0
        break;
1599
0
      case 'f':
1600
0
        uniq_id[i] = '0';
1601
        /* go on */
1602
0
        break;
1603
0
      default:
1604
0
        uniq_id[i]++;
1605
0
        i = 0;
1606
0
        break;
1607
0
    }
1608
0
  }
1609
0
  res->s =
1610
0
      uniq_id; /* I think it's not worth copying at static buffer, I hope there is no real meaning of @sys.unique==@sys.unique */
1611
0
  res->len = UNIQUE_ID_FIX_LEN + UNIQUE_ID_RAND_LEN;
1612
0
  return 0;
1613
0
}
1614
1615
1616
int select_sys_now(str *res, select_t *s, struct sip_msg *msg)
1617
0
{
1618
0
  return uint_to_static_buffer(res, (unsigned int)(uint64_t)time(NULL));
1619
0
}
1620
1621
int select_sys_now_fmt(str *res, select_t *s, struct sip_msg *msg)
1622
0
{
1623
0
#define SEL_POS 2
1624
0
  time_t t;
1625
0
  struct tm tm;
1626
1627
0
  t = time(NULL);
1628
0
  switch(s->params[SEL_POS].v.i) {
1629
0
    case SEL_NOW_GMT:
1630
0
      if(!gmtime_r(&t, &tm)) {
1631
0
        ERR("Invalid UTC time value\n");
1632
0
        return -1;
1633
0
      }
1634
0
      break;
1635
1636
0
    case SEL_NOW_LOCAL:
1637
0
      if(!localtime_r(&t, &tm)) {
1638
0
        ERR("Invalid local time value\n");
1639
0
        return -1;
1640
0
      }
1641
0
      break;
1642
0
    default:
1643
0
      BUG("Unexpected parameter value 'now' \"%d\" (%p)\n",
1644
0
          s->params[SEL_POS].v.i, select_core_table.next);
1645
0
      return -1;
1646
0
  }
1647
0
  if(s->n <= SEL_POS + 1) {
1648
0
    char buff[26];
1649
0
    if(!asctime_r(&tm, buff)) {
1650
0
      ERR("Invalid time value\n");
1651
0
      return -1;
1652
0
    }
1653
0
    res->len = strlen(buff);
1654
0
    while(res->len && buff[res->len - 1] < ' ')
1655
0
      res->len--; /* rtrim */
1656
0
    res->s = get_static_buffer(res->len);
1657
0
    if(!res->s)
1658
0
      return -1;
1659
0
    memcpy(res->s, &buff, res->len);
1660
0
  } else {
1661
0
    char c, buff[80];
1662
0
    c = s->params[SEL_POS + 1].v.s.s[s->params[SEL_POS + 1].v.s.len];
1663
0
    s->params[SEL_POS + 1].v.s.s[s->params[SEL_POS + 1].v.s.len] = '\0';
1664
0
    res->len = strftime(
1665
0
        buff, sizeof(buff) - 1, s->params[SEL_POS + 1].v.s.s, &tm);
1666
0
    s->params[SEL_POS + 1].v.s.s[s->params[SEL_POS + 1].v.s.len] = c;
1667
0
    res->s = get_static_buffer(res->len);
1668
0
    if(!res->s)
1669
0
      return -1;
1670
0
    memcpy(res->s, buff, res->len);
1671
0
  }
1672
0
  return 0;
1673
0
#undef SEL_POS
1674
0
}
1675
1676
ABSTRACT_F(select_branch)
1677
1678
int select_branch_count(str *res, select_t *s, struct sip_msg *msg)
1679
0
{
1680
0
  return uint_to_static_buffer(res, nr_branches);
1681
0
}
1682
1683
int select_branch_uri(str *res, select_t *s, struct sip_msg *msg)
1684
0
{
1685
0
#define SEL_POS 1
1686
0
#define Q_PARAM ">;q="
1687
0
#define Q_PARAM_LEN (sizeof(Q_PARAM) - 1)
1688
1689
0
  qvalue_t q;
1690
0
  int l, n;
1691
0
  str dst_uri;
1692
0
  if(s->n <= SEL_POS + 1
1693
0
      && nr_branches
1694
0
             > 1) { /* get all branches, if nr_branches==1 then use faster algorithm */
1695
0
    int len;
1696
0
    unsigned l2;
1697
0
    char *c;
1698
0
    init_branch_iterator();
1699
0
    len = 0;
1700
0
    while((c = next_branch(&l, &q, &dst_uri, 0, 0, 0, 0, 0, 0))) {
1701
1702
0
      if(s->params[SEL_POS].v.i & SEL_BRANCH_DST_URI) {
1703
0
        l = dst_uri.len;
1704
0
        c = dst_uri.s;
1705
0
      }
1706
0
      if(s->params[SEL_POS].v.i & (SEL_BRANCH_URI | SEL_BRANCH_DST_URI)) {
1707
0
        len += l;
1708
0
      }
1709
0
      if(q != Q_UNSPECIFIED && (s->params[SEL_POS].v.i & SEL_BRANCH_Q)) {
1710
0
        len += len_q(q);
1711
0
        if(s->params[SEL_POS].v.i & SEL_BRANCH_URI) {
1712
0
          len += 1 + Q_PARAM_LEN;
1713
0
        }
1714
0
      }
1715
0
      len += 1;
1716
0
    }
1717
0
    if(!len)
1718
0
      return 1;
1719
0
    res->s = get_static_buffer(len);
1720
0
    if(!res->s)
1721
0
      return -1;
1722
1723
0
    init_branch_iterator();
1724
0
    res->len = 0;
1725
0
    n = 0;
1726
0
    while((c = next_branch(&l, &q, &dst_uri, 0, 0, 0, 0, 0, 0))) {
1727
0
      if(s->params[SEL_POS].v.i & SEL_BRANCH_DST_URI) {
1728
0
        l = dst_uri.len;
1729
0
        c = dst_uri.s;
1730
0
      }
1731
0
      if(n) {
1732
0
        res->s[res->len] = ',';
1733
0
        res->len++;
1734
0
      }
1735
0
      if((s->params[SEL_POS].v.i & SEL_BRANCH_Q) == 0) {
1736
0
        q = Q_UNSPECIFIED;
1737
0
      }
1738
0
      if((s->params[SEL_POS].v.i & (SEL_BRANCH_URI | SEL_BRANCH_DST_URI))
1739
0
          && q != Q_UNSPECIFIED) {
1740
0
        res->s[res->len] = '<';
1741
0
        res->len++;
1742
0
        memcpy(res->s + res->len, c, l);
1743
0
        res->len += l;
1744
0
        memcpy(res->s + res->len, Q_PARAM, Q_PARAM_LEN);
1745
0
        res->len += Q_PARAM_LEN;
1746
0
        c = q2str(q, &l2);
1747
0
        l = l2;
1748
0
        memcpy(res->s + res->len, c, l);
1749
0
        res->len += l;
1750
0
      } else if(s->params[SEL_POS].v.i
1751
0
            & (SEL_BRANCH_URI | SEL_BRANCH_DST_URI)) {
1752
0
        memcpy(res->s + res->len, c, l);
1753
0
        res->len += l;
1754
0
      } else if(q != Q_UNSPECIFIED) {
1755
0
        c = q2str(q, &l2);
1756
0
        l = l2;
1757
0
        memcpy(res->s + res->len, c, l);
1758
0
        res->len += l;
1759
0
      }
1760
0
      n++;
1761
0
    }
1762
0
  } else {
1763
0
    unsigned l2;
1764
0
    char *c;
1765
0
    n = s->params[SEL_POS + 1].v.i;
1766
0
    if(n < 0 || n >= nr_branches)
1767
0
      return -1;
1768
0
    init_branch_iterator();
1769
0
    for(; (c = next_branch(&l, &q, &dst_uri, 0, 0, 0, 0, 0, 0)) && n; n--)
1770
0
      ;
1771
0
    if(!c)
1772
0
      return 1;
1773
1774
0
    if(s->params[SEL_POS].v.i & SEL_BRANCH_DST_URI) {
1775
0
      l = dst_uri.len;
1776
0
      c = dst_uri.s;
1777
0
    }
1778
0
    if((s->params[SEL_POS].v.i & SEL_BRANCH_Q) == 0) {
1779
0
      q = Q_UNSPECIFIED;
1780
0
    }
1781
0
    if((s->params[SEL_POS].v.i & (SEL_BRANCH_URI | SEL_BRANCH_DST_URI))
1782
0
        && q != Q_UNSPECIFIED) {
1783
1784
0
      res->s = get_static_buffer(l + 1 + Q_PARAM_LEN + len_q(q));
1785
0
      if(!res->s)
1786
0
        return -1;
1787
0
      res->len = 1;
1788
0
      res->s[0] = '<';
1789
0
      memcpy(res->s + res->len, c, l);
1790
0
      res->len += l;
1791
0
      memcpy(res->s + res->len, Q_PARAM, Q_PARAM_LEN);
1792
0
      res->len += Q_PARAM_LEN;
1793
0
      c = q2str(q, &l2);
1794
0
      l = l2;
1795
0
      memcpy(res->s + res->len, c, l);
1796
0
      res->len += l;
1797
0
    } else if(s->params[SEL_POS].v.i
1798
0
          & (SEL_BRANCH_URI | SEL_BRANCH_DST_URI)) {
1799
0
      res->s = c; /* not necessary to copy to static buffer */
1800
0
      res->len = l;
1801
0
    } else if(q != Q_UNSPECIFIED) {
1802
0
      c = q2str(q, &l2);
1803
0
      res->len = l2;
1804
0
      res->s = get_static_buffer(res->len);
1805
0
      if(!res->s)
1806
0
        return -1;
1807
0
      memcpy(res->s, c, res->len);
1808
0
    } else {
1809
0
      res->len = 0;
1810
0
    }
1811
0
  }
1812
0
  return 0;
1813
0
#undef SEL_POS
1814
0
}
1815
1816
int select_branch_uriq(str *res, select_t *s, struct sip_msg *msg)
1817
0
{
1818
0
  return select_branch_uri(res, s, msg);
1819
0
}
1820
1821
int select_branch_q(str *res, select_t *s, struct sip_msg *msg)
1822
0
{
1823
0
  return select_branch_uri(res, s, msg);
1824
0
}
1825
1826
int select_branch_dst_uri(str *res, select_t *s, struct sip_msg *msg)
1827
0
{
1828
0
  return select_branch_uri(res, s, msg);
1829
0
}