b087f5ad1b917911aa49e531de25474c571884fd
[sip-router] / src / modules / pv / pv_core.c
1 /*
2  * Copyright (C) 2001-2005 FhG Fokus
3  * Copyright (C) 2005 Voice Sistem SRL
4  * Copyright (C) 2010 Daniel-Constantin Mierla (asipto.com)
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23
24 #include "../../core/qvalue.h"
25 #include "../../core/ut.h"
26 #include "../../core/route_struct.h"
27 #include "../../core/dset.h"
28 #include "../../core/flags.h"
29 #include "../../core/action.h"
30 #include "../../core/socket_info.h"
31 #include "../../core/data_lump.h"
32 #include "../../core/strutils.h"
33 #include "../../core/tcp_conn.h"
34 #include "../../core/pvapi.h"
35 #include "../../core/trim.h"
36
37 #include "../../core/parser/parse_from.h"
38 #include "../../core/parser/parse_uri.h"
39 #include "../../core/parser/parse_hname2.h"
40 #include "../../core/parser/parse_content.h"
41 #include "../../core/parser/parse_refer_to.h"
42 #include "../../core/parser/parse_rpid.h"
43 #include "../../core/parser/parse_diversion.h"
44 #include "../../core/parser/parse_ppi_pai.h"
45 #include "../../core/parser/digest/digest.h"
46 #include "../../core/parser/contact/contact.h"
47 #include "../../core/parser/contact/parse_contact.h"
48 #include "../../core/parser/parse_expires.h"
49
50 #include "pv_core.h"
51 #include "pv_svar.h"
52
53 #include <string.h>
54 #include <stdlib.h>
55
56 static str str_udp    = { "UDP", 3 };
57 static str str_5060   = { "5060", 4 };
58 static str str_5061   = { "5061", 4 };
59 static str pv_str_1   = { "1", 1 };
60 static str pv_uri_scheme[] = {
61                 { "none", 4 },
62                 { "sip",  3 },
63                 { "sips", 4 },
64                 { "tel",  3 },
65                 { "tels", 4 },
66                 { "urn",  3 },
67                 { 0, 0 }
68         };
69 static char _empty_str[] = "";
70
71 static str pv_af_list[] = {
72                 { "IPv4",  4 },
73                 { "IPv6",  4 },
74                 { 0, 0 }
75         };
76 int _pv_pid = 0;
77
78 #define PV_FIELD_DELIM ", "
79 #define PV_FIELD_DELIM_LEN (sizeof(PV_FIELD_DELIM) - 1)
80
81 #define PV_HDR_DELIM ","
82 #define PV_HDR_DELIM_LEN (sizeof(PV_HDR_DELIM) - 1)
83
84 int pv_get_msgid(struct sip_msg *msg, pv_param_t *param,
85                 pv_value_t *res)
86 {
87         if(msg==NULL)
88                 return -1;
89         return pv_get_uintval(msg, param, res, msg->id);
90 }
91
92 int pv_get_udp(struct sip_msg *msg, pv_param_t *param,
93                 pv_value_t *res)
94 {
95         return pv_get_strintval(msg, param, res, &str_udp, (int)PROTO_UDP);
96 }
97
98 int pv_get_5060(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
99 {
100         return pv_get_strintval(msg, param, res, &str_5060, 5060);
101 }
102
103 int pv_get_5061(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
104 {
105         return pv_get_strintval(msg, param, res, &str_5061, 5061);
106 }
107
108 int pv_get_true(struct sip_msg *msg, pv_param_t *param,
109                 pv_value_t *res)
110 {
111         return pv_get_intstrval(msg, param, res, 1, &pv_str_1);
112 }
113
114 /*extern int _last_returned_code;
115 int pv_get_return_code(struct sip_msg *msg, pv_param_t *param,
116                 pv_value_t *res)
117 {
118         return pv_get_sintval(msg, param, res, _last_returned_code);
119 }
120 */
121
122
123 int pv_get_pid(struct sip_msg *msg, pv_param_t *param,
124                 pv_value_t *res)
125 {
126         if(_pv_pid == 0)
127                 _pv_pid = (int)getpid();
128         return pv_get_sintval(msg, param, res, _pv_pid);
129 }
130
131
132 int pv_get_method(struct sip_msg *msg, pv_param_t *param,
133                 pv_value_t *res)
134 {
135         if(msg==NULL)
136                 return -1;
137
138         if(msg->first_line.type == SIP_REQUEST)
139         {
140                 return pv_get_strintval(msg, param, res,
141                                 &msg->first_line.u.request.method,
142                                 (int)msg->first_line.u.request.method_value);
143         }
144
145         if(msg->cseq==NULL && ((parse_headers(msg, HDR_CSEQ_F, 0)==-1) ||
146                                 (msg->cseq==NULL)))
147         {
148                 LM_ERR("no CSEQ header\n");
149                 return pv_get_null(msg, param, res);
150         }
151
152         return pv_get_strintval(msg, param, res,
153                         &get_cseq(msg)->method,
154                         get_cseq(msg)->method_id);
155 }
156
157 int pv_get_methodid(struct sip_msg *msg, pv_param_t *param,
158                 pv_value_t *res)
159 {
160         if(msg==NULL)
161                 return -1;
162
163         if(msg->first_line.type == SIP_REQUEST)
164         {
165                 return pv_get_uintval(msg, param, res,
166                                 (unsigned int)msg->first_line.u.request.method_value);
167         }
168
169         if(msg->cseq==NULL && ((parse_headers(msg, HDR_CSEQ_F, 0)==-1)
170                                 || (msg->cseq==NULL)))
171         {
172                 LM_ERR("no CSEQ header\n");
173                 return pv_get_null(msg, param, res);
174         }
175
176         return pv_get_uintval(msg, param, res,
177                         (unsigned int)(get_cseq(msg)->method_id));
178 }
179
180 int pv_get_msgtype(struct sip_msg *msg, pv_param_t *param,
181                 pv_value_t *res)
182 {
183         unsigned int type = 0;
184
185         if(msg==NULL)
186                 return -1;
187
188         if(msg->first_line.type == SIP_REQUEST)
189                 type = 1;
190         else if(msg->first_line.type == SIP_REPLY)
191                 type = 2;
192
193         return pv_get_uintval(msg, param, res, type);
194 }
195
196 int pv_get_version(struct sip_msg *msg, pv_param_t *param,
197                 pv_value_t *res)
198 {
199         if(msg==NULL)
200                 return -1;
201
202         if(msg->first_line.type == SIP_REQUEST)
203         {
204                 return pv_get_strval(msg, param, res,
205                                 &msg->first_line.u.request.version);
206         }
207
208         return pv_get_strval(msg, param, res,
209                                 &msg->first_line.u.reply.version);
210 }
211
212 int pv_get_status(struct sip_msg *msg, pv_param_t *param,
213                 pv_value_t *res)
214 {
215         if(msg==NULL)
216                 return -1;
217
218         if(msg->first_line.type != SIP_REPLY)
219                 return pv_get_null(msg, param, res);
220
221         return pv_get_intstrval(msg, param, res,
222                         (int)msg->first_line.u.reply.statuscode,
223                         &msg->first_line.u.reply.status);
224 }
225
226 int pv_get_reason(struct sip_msg *msg, pv_param_t *param,
227                 pv_value_t *res)
228 {
229         if(msg==NULL)
230                 return -1;
231
232         if(msg->first_line.type != SIP_REPLY)
233                 return pv_get_null(msg, param, res);
234
235         return pv_get_strval(msg, param, res, &msg->first_line.u.reply.reason);
236 }
237
238
239 int pv_get_ruri(struct sip_msg *msg, pv_param_t *param,
240                 pv_value_t *res)
241 {
242         if(msg==NULL || res==NULL)
243                 return -1;
244
245         if(msg->first_line.type == SIP_REPLY)   /* REPLY doesnt have a ruri */
246                 return pv_get_null(msg, param, res);
247
248         if(msg->parsed_uri_ok==0 /* R-URI not parsed*/ && parse_sip_msg_uri(msg)<0)
249         {
250                 LM_ERR("failed to parse the R-URI\n");
251                 return pv_get_null(msg, param, res);
252         }
253
254         if (msg->new_uri.s!=NULL)
255                 return pv_get_strval(msg, param, res, &msg->new_uri);
256         return pv_get_strval(msg, param, res, &msg->first_line.u.request.uri);
257 }
258
259 int pv_get_ouri(struct sip_msg *msg, pv_param_t *param,
260                 pv_value_t *res)
261 {
262         if(msg==NULL || res==NULL)
263                 return -1;
264
265         if(msg->first_line.type == SIP_REPLY)   /* REPLY doesnt have a ruri */
266                 return pv_get_null(msg, param, res);
267
268         if(msg->parsed_orig_ruri_ok==0
269                         /* orig R-URI not parsed*/ && parse_orig_ruri(msg)<0)
270         {
271                 LM_ERR("failed to parse the R-URI\n");
272                 return pv_get_null(msg, param, res);
273         }
274         return pv_get_strval(msg, param, res, &msg->first_line.u.request.uri);
275 }
276
277 int pv_get_xuri_attr(struct sip_msg *msg, struct sip_uri *parsed_uri,
278                 pv_param_t *param, pv_value_t *res)
279 {
280         if(param->pvn.u.isname.name.n==1) /* username */
281         {
282                 if(parsed_uri->user.s==NULL || parsed_uri->user.len<=0)
283                         return pv_get_null(msg, param, res);
284                 return pv_get_strval(msg, param, res, &parsed_uri->user);
285         } else if(param->pvn.u.isname.name.n==2) /* domain */ {
286                 if(parsed_uri->host.s==NULL || parsed_uri->host.len<=0)
287                         return pv_get_null(msg, param, res);
288                 return pv_get_strval(msg, param, res, &parsed_uri->host);
289         } else if(param->pvn.u.isname.name.n==3) /* port */ {
290                 if(parsed_uri->port.s==NULL) {
291                         if(parsed_uri->proto==PROTO_TLS) {
292                                 return pv_get_5061(msg, param, res);
293                         } else {
294                                 return pv_get_5060(msg, param, res);
295                         }
296                 }
297                 return pv_get_strintval(msg, param, res, &parsed_uri->port,
298                                 (int)parsed_uri->port_no);
299         } else if(param->pvn.u.isname.name.n==4) /* protocol */ {
300                 if(parsed_uri->transport_val.s==NULL)
301                         return pv_get_udp(msg, param, res);
302                 return pv_get_strintval(msg, param, res, &parsed_uri->transport_val,
303                                 (int)parsed_uri->proto);
304         } else if(param->pvn.u.isname.name.n==5) /* uri scheme */ {
305                 return pv_get_strintval(msg, param, res, &pv_uri_scheme[parsed_uri->type],
306                                 (int)parsed_uri->type);
307         }
308         LM_ERR("unknown specifier\n");
309         return pv_get_null(msg, param, res);
310 }
311
312 int pv_get_ruri_attr(struct sip_msg *msg, pv_param_t *param,
313                 pv_value_t *res)
314 {
315         if(msg==NULL)
316                 return -1;
317
318         if(msg->first_line.type == SIP_REPLY)   /* REPLY doesnt have a ruri */
319                 return pv_get_null(msg, param, res);
320
321         if(msg->parsed_uri_ok==0 /* R-URI not parsed*/ && parse_sip_msg_uri(msg)<0)
322         {
323                 LM_ERR("failed to parse the R-URI\n");
324                 return pv_get_null(msg, param, res);
325         }
326         return pv_get_xuri_attr(msg, &(msg->parsed_uri), param, res);
327 }
328
329 int pv_get_ouri_attr(struct sip_msg *msg, pv_param_t *param,
330                 pv_value_t *res)
331 {
332         if(msg==NULL)
333                 return -1;
334
335         if(msg->first_line.type == SIP_REPLY)   /* REPLY doesnt have a ruri */
336                 return pv_get_null(msg, param, res);
337
338         if(msg->parsed_orig_ruri_ok==0
339                         /* orig R-URI not parsed*/ && parse_orig_ruri(msg)<0)
340         {
341                 LM_ERR("failed to parse the R-URI\n");
342                 return pv_get_null(msg, param, res);
343         }
344         return pv_get_xuri_attr(msg, &(msg->parsed_orig_ruri), param, res);
345 }
346
347 int pv_get_errinfo_attr(struct sip_msg *msg, pv_param_t *param,
348                 pv_value_t *res)
349 {
350         return pv_get_null(msg, param, res);
351 }
352
353 int pv_get_contact(struct sip_msg *msg, pv_param_t *param,
354                 pv_value_t *res)
355 {
356         if(msg==NULL)
357                 return -1;
358
359         if(msg->contact==NULL && parse_headers(msg, HDR_CONTACT_F, 0)==-1)
360         {
361                 LM_DBG("no contact header\n");
362                 return pv_get_null(msg, param, res);
363         }
364
365         if(!msg->contact || !msg->contact->body.s || msg->contact->body.len<=0)
366         {
367                 LM_DBG("no contact header!\n");
368                 return pv_get_null(msg, param, res);
369         }
370
371 //      res->s = ((struct to_body*)msg->contact->parsed)->uri.s;
372 //      res->len = ((struct to_body*)msg->contact->parsed)->uri.len;
373         return pv_get_strval(msg, param, res, &msg->contact->body);
374 }
375
376 int pv_get_xto_attr(struct sip_msg *msg, pv_param_t *param,
377                 pv_value_t *res, struct to_body *xto, int type)
378 {
379         struct sip_uri *uri;
380         if(xto==NULL)
381                 return -1;
382
383         if(param->pvn.u.isname.name.n==1) /* uri */
384                 return pv_get_strval(msg, param, res, &xto->uri);
385
386         if(param->pvn.u.isname.name.n==4) /* tag */
387         {
388                 if (xto->tag_value.s==NULL || xto->tag_value.len<=0)
389                 {
390                         LM_DBG("no Tag parameter\n");
391                         return pv_get_null(msg, param, res);
392                 }
393                 return pv_get_strval(msg, param, res, &xto->tag_value);
394         }
395
396         if(param->pvn.u.isname.name.n==5) /* display name */
397         {
398                 if(xto->display.s==NULL || xto->display.len<=0)
399                 {
400                         LM_DBG("no Display name\n");
401                         return pv_get_null(msg, param, res);
402                 }
403                 return pv_get_strval(msg, param, res, &xto->display);
404         }
405
406         if(type==0)
407         {
408                 if((uri=parse_to_uri(msg))==NULL)
409                 {
410                         LM_ERR("cannot parse To URI\n");
411                         return pv_get_null(msg, param, res);
412                 }
413         } else {
414                 if((uri=parse_from_uri(msg))==NULL)
415                 {
416                         LM_ERR("cannot parse From URI\n");
417                         return pv_get_null(msg, param, res);
418                 }
419         }
420
421         if(param->pvn.u.isname.name.n==2) /* username */
422         {
423                 if(uri->user.s==NULL || uri->user.len<=0)
424                 {
425                         LM_DBG("no username\n");
426                         return pv_get_null(msg, param, res);
427                 }
428                 return pv_get_strval(msg, param, res, &uri->user);
429         } else if(param->pvn.u.isname.name.n==3) /* domain */ {
430                 if(uri->host.s==NULL || uri->host.len<=0)
431                 {
432                         LM_DBG("no domain\n");
433                         return pv_get_null(msg, param, res);
434                 }
435                 return pv_get_strval(msg, param, res, &uri->host);
436         }
437
438         LM_ERR("unknown specifier\n");
439         return pv_get_null(msg, param, res);
440 }
441
442 int pv_get_to_attr(struct sip_msg *msg, pv_param_t *param,
443                 pv_value_t *res)
444 {
445         if(msg==NULL)
446                 return -1;
447
448         if(msg->to==NULL && parse_headers(msg, HDR_TO_F, 0)==-1)
449         {
450                 LM_ERR("cannot parse To header\n");
451                 return pv_get_null(msg, param, res);
452         }
453         if(msg->to==NULL || get_to(msg)==NULL) {
454                 LM_DBG("no To header\n");
455                 return pv_get_null(msg, param, res);
456         }
457         return pv_get_xto_attr(msg, param, res, get_to(msg), 0);
458 }
459
460 int pv_get_from_attr(struct sip_msg *msg, pv_param_t *param,
461                 pv_value_t *res)
462 {
463         if(msg==NULL)
464                 return -1;
465
466         if(parse_from_header(msg)<0)
467         {
468                 LM_ERR("cannot parse From header\n");
469                 return pv_get_null(msg, param, res);
470         }
471
472         if(msg->from==NULL || get_from(msg)==NULL) {
473                 LM_DBG("no From header\n");
474                 return pv_get_null(msg, param, res);
475         }
476         return pv_get_xto_attr(msg, param, res, get_from(msg), 1);
477 }
478
479 int pv_get_cseq(struct sip_msg *msg, pv_param_t *param,
480                 pv_value_t *res)
481 {
482         if(msg==NULL)
483                 return -1;
484
485         if(msg->cseq==NULL && ((parse_headers(msg, HDR_CSEQ_F, 0)==-1)
486                                 || (msg->cseq==NULL)) )
487         {
488                 LM_ERR("cannot parse CSEQ header\n");
489                 return pv_get_null(msg, param, res);
490         }
491         return pv_get_strval(msg, param, res, &(get_cseq(msg)->number));
492 }
493
494 int pv_get_cseq_body(struct sip_msg *msg, pv_param_t *param,
495                 pv_value_t *res)
496 {
497         if(msg==NULL)
498                 return -1;
499
500         if(msg->cseq==NULL && ((parse_headers(msg, HDR_CSEQ_F, 0)==-1)
501                                 || (msg->cseq==NULL)) )
502         {
503                 LM_ERR("cannot parse CSEQ header\n");
504                 return pv_get_null(msg, param, res);
505         }
506         return pv_get_strval(msg, param, res, &msg->cseq->body);
507 }
508
509 int pv_get_msg_buf(struct sip_msg *msg, pv_param_t *param,
510                 pv_value_t *res)
511 {
512         str s;
513         if(msg==NULL)
514                 return -1;
515
516         s.s = msg->buf;
517         s.len = msg->len;
518         return pv_get_strval(msg, param, res, &s);
519 }
520
521 int pv_get_msg_len(struct sip_msg *msg, pv_param_t *param,
522                 pv_value_t *res)
523 {
524         if(msg==NULL)
525                 return -1;
526
527         return pv_get_uintval(msg, param, res, msg->len);
528 }
529
530 int pv_get_flags(struct sip_msg *msg, pv_param_t *param,
531                 pv_value_t *res)
532 {
533         if(msg==NULL)
534                 return -1;
535
536         return pv_get_uintval(msg, param, res, msg->flags);
537 }
538
539 int pv_get_flag(struct sip_msg *msg, pv_param_t *param,
540                 pv_value_t *res)
541 {
542         if(msg==NULL)
543                 return -1;
544
545         if (param->pvn.type != PV_NAME_INTSTR)
546                 return -1;
547
548         return pv_get_uintval(msg, param, res, (msg->flags & (1<<param->pvn.u.isname.name.n)) ? 1 : 0);
549 }
550
551 static inline char* int_to_8hex(int val)
552 {
553         unsigned short digit;
554         int i;
555         static char outbuf[9];
556
557         outbuf[8] = '\0';
558         for(i=0; i<8; i++)
559         {
560                 if(val!=0)
561                 {
562                         digit =  val & 0x0f;
563                         outbuf[7-i] = digit >= 10 ? digit + 'a' - 10 : digit + '0';
564                         val >>= 4;
565                 }
566                 else
567                         outbuf[7-i] = '0';
568         }
569         return outbuf;
570 }
571
572
573 int pv_get_hexflags(struct sip_msg *msg, pv_param_t *param,
574                 pv_value_t *res)
575 {
576         str s;
577         if(msg==NULL || res==NULL)
578                 return -1;
579
580         s.s = int_to_8hex(msg->flags);
581         s.len = 8;
582         return pv_get_strintval(msg, param, res, &s, (int)msg->flags);
583 }
584
585 int pv_get_bflags(struct sip_msg *msg, pv_param_t *param,
586                 pv_value_t *res)
587 {
588         flag_t flags;
589         if (getbflagsval(0, &flags) < 0) {
590                 ERR("pv_get_bflags: Error while obtaining values of branch flags\n");
591                 return -1;
592         }
593         return pv_get_uintval(msg, param, res, flags);
594 }
595
596 int pv_get_bflag(struct sip_msg *msg, pv_param_t *param,
597                 pv_value_t *res)
598 {
599         flag_t flags;
600         if (getbflagsval(0, &flags) < 0) {
601                 ERR("pv_get_bflags: Error while obtaining values of branch flags\n");
602                 return -1;
603         }
604         if (param->pvn.type != PV_NAME_INTSTR)
605                 return -1;
606
607         return pv_get_uintval(msg, param, res, (flags & (1<<param->pvn.u.isname.name.n)) ? 1 : 0);
608 }
609
610 int pv_get_hexbflags(struct sip_msg *msg, pv_param_t *param,
611                 pv_value_t *res)
612 {
613         flag_t flags;
614         str s;
615         if(res==NULL)
616                 return -1;
617
618         if (getbflagsval(0, &flags) < 0) {
619                 ERR("pv_get_hexbflags: Error while obtaining values of branch flags\n");
620                 return -1;
621         }
622         s.s = int_to_8hex((int)flags);
623         s.len = 8;
624         return pv_get_strintval(msg, param, res, &s, (int)flags);
625 }
626
627 int pv_get_sflags(struct sip_msg *msg, pv_param_t *param,
628                 pv_value_t *res)
629 {
630         return pv_get_uintval(msg, param, res, getsflags());
631 }
632
633 int pv_get_sflag(struct sip_msg *msg, pv_param_t *param,
634                 pv_value_t *res)
635
636 {
637         if (param->pvn.type != PV_NAME_INTSTR)
638                 return -1;
639
640         return pv_get_uintval(msg, param, res, (getsflags() & (1<<param->pvn.u.isname.name.n)) ? 1 : 0);
641 }
642
643 int pv_get_hexsflags(struct sip_msg *msg, pv_param_t *param,
644                 pv_value_t *res)
645 {
646         str s;
647         if(res==NULL)
648                 return -1;
649
650         s.s = int_to_8hex((int)getsflags());
651         s.len = 8;
652         return pv_get_strintval(msg, param, res, &s, (int)getsflags());
653 }
654
655 int pv_get_callid(struct sip_msg *msg, pv_param_t *param,
656                 pv_value_t *res)
657 {
658         if(msg==NULL)
659                 return -1;
660
661         if(msg->callid==NULL && ((parse_headers(msg, HDR_CALLID_F, 0)==-1) ||
662                                 (msg->callid==NULL)) )
663         {
664                 LM_ERR("cannot parse Call-Id header\n");
665                 return pv_get_null(msg, param, res);
666         }
667
668         return pv_get_strval(msg, param, res, &msg->callid->body);
669 }
670
671 int pv_get_srcip(struct sip_msg *msg, pv_param_t *param,
672                 pv_value_t *res)
673 {
674         str s;
675         if(msg==NULL)
676                 return -1;
677
678         s.s = ip_addr2a(&msg->rcv.src_ip);
679         s.len = strlen(s.s);
680         return pv_get_strval(msg, param, res, &s);
681 }
682
683 int pv_get_srcipz(struct sip_msg *msg, pv_param_t *param,
684                 pv_value_t *res)
685 {
686         str s;
687         if(msg==NULL)
688                 return -1;
689
690         s.s = ip_addr2strz(&msg->rcv.src_ip);
691         s.len = strlen(s.s);
692         return pv_get_strval(msg, param, res, &s);
693 }
694
695 int pv_get_srcport(struct sip_msg *msg, pv_param_t *param,
696                 pv_value_t *res)
697 {
698         if(msg==NULL)
699                 return -1;
700         return pv_get_uintval(msg, param, res, msg->rcv.src_port);
701 }
702
703 int pv_get_srcaddr_uri_helper(struct sip_msg *msg, pv_param_t *param,
704                 int tmode, pv_value_t *res)
705 {
706         str uri;
707         str sr;
708
709         if(msg==NULL)
710                 return -1;
711
712         if(get_src_uri(msg, tmode, &uri)<0)
713                 return pv_get_null(msg, param, res);
714
715         if (uri.len + 1 >= pv_get_buffer_size())
716         {
717                 LM_ERR("local buffer size exceeded\n");
718                 return pv_get_null(msg, param, res);
719         }
720
721         sr.s = pv_get_buffer();
722         strncpy(sr.s, uri.s, uri.len);
723         sr.len = uri.len;
724         sr.s[sr.len] = '\0';
725
726         return pv_get_strval(msg, param, res, &sr);
727 }
728
729 int pv_get_srcaddr_uri(struct sip_msg *msg, pv_param_t *param,
730                 pv_value_t *res)
731 {
732         return pv_get_srcaddr_uri_helper(msg, param, 0, res);
733 }
734
735 int pv_get_srcaddr_uri_full(struct sip_msg *msg, pv_param_t *param,
736                 pv_value_t *res)
737 {
738         return pv_get_srcaddr_uri_helper(msg, param, 1, res);
739 }
740
741 int pv_get_rcvip(struct sip_msg *msg, pv_param_t *param,
742                 pv_value_t *res)
743 {
744         if(msg==NULL)
745                 return -1;
746
747         if(msg->rcv.bind_address==NULL
748                         || msg->rcv.bind_address->address_str.s==NULL)
749                 return pv_get_null(msg, param, res);
750
751         return pv_get_strval(msg, param, res, &msg->rcv.bind_address->address_str);
752 }
753
754 int pv_get_rcvport(struct sip_msg *msg, pv_param_t *param,
755                 pv_value_t *res)
756 {
757         if(msg==NULL)
758                 return -1;
759
760         if(msg->rcv.bind_address==NULL
761                         || msg->rcv.bind_address->port_no_str.s==NULL)
762                 return pv_get_null(msg, param, res);
763
764         return pv_get_intstrval(msg, param, res,
765                         (int)msg->rcv.bind_address->port_no,
766                         &msg->rcv.bind_address->port_no_str);
767 }
768
769 int pv_get_rcvaddr_uri_helper(struct sip_msg *msg, pv_param_t *param,
770                 int tmode, pv_value_t *res)
771 {
772         str uri;
773         str sr;
774
775         if(msg==NULL)
776                 return -1;
777
778         if(get_rcv_socket_uri(msg, tmode, &uri, 0)<0)
779                 return pv_get_null(msg, param, res);
780
781         if (uri.len + 1 >= pv_get_buffer_size())
782         {
783                 LM_ERR("local buffer size exceeded\n");
784                 return pv_get_null(msg, param, res);
785         }
786
787         sr.s = pv_get_buffer();
788         strncpy(sr.s, uri.s, uri.len);
789         sr.len = uri.len;
790         sr.s[sr.len] = '\0';
791
792         return pv_get_strval(msg, param, res, &sr);
793 }
794
795 int pv_get_rcvaddr_uri(struct sip_msg *msg, pv_param_t *param,
796                 pv_value_t *res)
797 {
798         return pv_get_rcvaddr_uri_helper(msg, param, 0, res);
799 }
800
801 int pv_get_rcvaddr_uri_full(struct sip_msg *msg, pv_param_t *param,
802                 pv_value_t *res)
803 {
804         return pv_get_rcvaddr_uri_helper(msg, param, 1, res);
805 }
806
807 int pv_get_rcv_advertised_ip(struct sip_msg *msg, pv_param_t *param,
808                 pv_value_t *res)
809 {
810         if(msg==NULL)
811                 return -1;
812
813         if(msg->rcv.bind_address!=NULL
814                         && msg->rcv.bind_address->useinfo.address_str.len > 0) {
815                 return pv_get_strval(msg, param, res,
816                                 &msg->rcv.bind_address->useinfo.address_str);
817         }
818
819         return pv_get_rcvip(msg, param, res);
820 }
821
822 int pv_get_rcv_advertised_port(struct sip_msg *msg, pv_param_t *param,
823                 pv_value_t *res)
824 {
825         if(msg==NULL)
826                 return -1;
827
828         if(msg->rcv.bind_address!=NULL
829                         && msg->rcv.bind_address->useinfo.port_no_str.len > 0) {
830                 return pv_get_intstrval(msg, param, res,
831                                 (int)msg->rcv.bind_address->useinfo.port_no,
832                                 &msg->rcv.bind_address->useinfo.port_no_str);
833         }
834
835         return pv_get_rcvport(msg, param, res);
836 }
837
838 int pv_get_rcvadv_uri_helper(struct sip_msg *msg, pv_param_t *param,
839                 int tmode, pv_value_t *res)
840 {
841         str uri;
842         str sr;
843
844         if(msg==NULL)
845                 return -1;
846
847         if(get_rcv_socket_uri(msg, tmode, &uri, 1)<0)
848                 return pv_get_null(msg, param, res);
849
850         if (uri.len + 1 >= pv_get_buffer_size())
851         {
852                 LM_ERR("local buffer size exceeded\n");
853                 return pv_get_null(msg, param, res);
854         }
855
856         sr.s = pv_get_buffer();
857         strncpy(sr.s, uri.s, uri.len);
858         sr.len = uri.len;
859         sr.s[sr.len] = '\0';
860
861         return pv_get_strval(msg, param, res, &sr);
862 }
863
864 int pv_get_rcvadv_uri(struct sip_msg *msg, pv_param_t *param,
865                 pv_value_t *res)
866 {
867         if(msg==NULL)
868                 return -1;
869
870         if(msg->rcv.bind_address!=NULL
871                         && (msg->rcv.bind_address->useinfo.address_str.len > 0
872                                 || msg->rcv.bind_address->useinfo.port_no_str.len > 0)) {
873                 return pv_get_rcvadv_uri_helper(msg, param, 0, res);
874         }
875
876         return pv_get_rcvaddr_uri_helper(msg, param, 0, res);
877 }
878
879 int pv_get_rcvadv_uri_full(struct sip_msg *msg, pv_param_t *param,
880                 pv_value_t *res)
881 {
882         if(msg==NULL)
883                 return -1;
884
885         if(msg->rcv.bind_address!=NULL
886                         && (msg->rcv.bind_address->useinfo.address_str.len > 0
887                                 || msg->rcv.bind_address->useinfo.port_no_str.len > 0)) {
888                 return pv_get_rcvadv_uri_helper(msg, param, 1, res);
889         }
890
891         return pv_get_rcvaddr_uri_helper(msg, param, 1, res);
892 }
893
894 /**
895  *
896  */
897 int pv_parse_af_name(pv_spec_p sp, str *in)
898 {
899         if(sp==NULL || in==NULL || in->len<=0)
900                 return -1;
901
902         switch(in->len)
903         {
904                 case 2:
905                         if(strncmp(in->s, "id", 2)==0)
906                                 sp->pvp.pvn.u.isname.name.n = 0;
907                         else goto error;
908                 break;
909                 case 4:
910                         if(strncmp(in->s, "name", 4)==0)
911                                 sp->pvp.pvn.u.isname.name.n = 1;
912                         else goto error;
913                 break;
914                 default:
915                         goto error;
916         }
917         sp->pvp.pvn.type = PV_NAME_INTSTR;
918         sp->pvp.pvn.u.isname.type = 0;
919
920         return 0;
921
922 error:
923         LM_ERR("unknown PV af key: %.*s\n", in->len, in->s);
924         return -1;
925 }
926
927 /**
928  *
929  */
930 int pv_get_af(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
931 {
932         if(msg==NULL || param==NULL)
933                 return -1;
934
935         switch(param->pvn.u.isname.name.n)
936         {
937                 case 1:
938                         if(msg->rcv.bind_address->address.af==AF_INET6)
939                                 return pv_get_strval(msg, param, res, &pv_af_list[1]);
940                         return pv_get_strval(msg, param, res, &pv_af_list[0]);
941                 default:
942                         return pv_get_uintval(msg, param, res, msg->rcv.bind_address->address.af);
943         }
944 }
945
946 int pv_get_force_sock(struct sip_msg *msg, pv_param_t *param,
947                 pv_value_t *res)
948 {
949         if(msg==NULL)
950                 return -1;
951
952         if (msg->force_send_socket==0)
953                 return pv_get_null(msg, param, res);
954
955         return pv_get_strval(msg, param, res, &msg->force_send_socket->sock_str);
956 }
957
958 int pv_get_useragent(struct sip_msg *msg, pv_param_t *param,
959                 pv_value_t *res)
960 {
961         if(msg==NULL)
962                 return -1;
963         if(msg->user_agent==NULL && ((parse_headers(msg, HDR_USERAGENT_F, 0)==-1)
964                         || (msg->user_agent==NULL)))
965         {
966                 LM_DBG("no User-Agent header\n");
967                 return pv_get_null(msg, param, res);
968         }
969
970         return pv_get_strval(msg, param, res, &msg->user_agent->body);
971 }
972
973 int pv_get_refer_to(struct sip_msg *msg, pv_param_t *param,
974                 pv_value_t *res)
975 {
976         if(msg==NULL)
977                 return -1;
978
979         if(parse_refer_to_header(msg)==-1)
980         {
981                 LM_DBG("no Refer-To header\n");
982                 return pv_get_null(msg, param, res);
983         }
984
985         if(msg->refer_to==NULL || get_refer_to(msg)==NULL)
986                 return pv_get_null(msg, param, res);
987
988         return pv_get_strval(msg, param, res, &(get_refer_to(msg)->uri));
989 }
990
991 int pv_get_diversion(struct sip_msg *msg, pv_param_t *param,
992                 pv_value_t *res)
993 {
994         str *val;
995         str name;
996
997         if(msg == NULL)
998                 return -1;
999
1000         if(parse_diversion_header(msg) == -1)
1001         {
1002                 LM_DBG("no Diversion header\n");
1003                 return pv_get_null(msg, param, res);
1004         }
1005
1006         if(msg->diversion == NULL || get_diversion(msg) == NULL)
1007         {
1008                 LM_DBG("no Diversion header\n");
1009                 return pv_get_null(msg, param, res);
1010         }
1011
1012         if(param->pvn.u.isname.name.n == 1)  { /* uri */
1013                 return pv_get_strval(msg, param, res, &(get_diversion(msg)->uri));
1014         }
1015
1016         if(param->pvn.u.isname.name.n == 2)  { /* reason param */
1017                 name.s = "reason";
1018                 name.len = 6;
1019                 val = get_diversion_param(msg, &name);
1020                 if (val) {
1021                         return pv_get_strval(msg, param, res, val);
1022                 } else {
1023                         return pv_get_null(msg, param, res);
1024                 }
1025         }
1026
1027         if(param->pvn.u.isname.name.n == 3)  { /* privacy param */
1028                 name.s = "privacy";
1029                 name.len = 7;
1030                 val = get_diversion_param(msg, &name);
1031                 if (val) {
1032                         return pv_get_strval(msg, param, res, val);
1033                 } else {
1034                         return pv_get_null(msg, param, res);
1035                 }
1036         }
1037
1038         if(param->pvn.u.isname.name.n == 4)  { /* counter param */
1039                 name.s = "counter";
1040                 name.len = 7;
1041                 val = get_diversion_param(msg, &name);
1042                 if (val) {
1043                         return pv_get_strval(msg, param, res, val);
1044                 } else {
1045                         return pv_get_null(msg, param, res);
1046                 }
1047         }
1048
1049         LM_ERR("unknown diversion specifier\n");
1050         return pv_get_null(msg, param, res);
1051 }
1052
1053 int pv_get_rpid(struct sip_msg *msg, pv_param_t *param,
1054                 pv_value_t *res)
1055 {
1056         if(msg==NULL)
1057                 return -1;
1058
1059         if(parse_rpid_header(msg)==-1)
1060         {
1061                 LM_DBG("no RPID header\n");
1062                 return pv_get_null(msg, param, res);
1063         }
1064
1065         if(msg->rpid==NULL || get_rpid(msg)==NULL)
1066                 return pv_get_null(msg, param, res);
1067
1068         return pv_get_strval(msg, param, res, &(get_rpid(msg)->uri));
1069 }
1070
1071 int pv_get_ppi_attr(struct sip_msg *msg, pv_param_t *param,
1072                 pv_value_t *res)
1073 {
1074         int idxf;
1075         int idx;
1076         struct sip_uri *uri;
1077         p_id_body_t *ppi_body = NULL;
1078         to_body_t *ppi_uri = NULL;
1079         int i, cur_id;
1080
1081         if(msg==NULL)
1082                 return -1;
1083
1084         if(parse_ppi_header(msg) < 0)
1085         {
1086                 LM_DBG("no P-Preferred-Identity header\n");
1087                 return pv_get_null(msg, param, res);
1088         }
1089
1090         if (pv_get_spec_index(msg, param, &idx, &idxf) != 0)
1091         {
1092                 LM_ERR("Invalid index\n");
1093                 return -1;
1094         }
1095
1096         if (idxf == PV_IDX_ALL)
1097         {
1098                 LM_ERR("Unable to return 'all' PPI values\n");
1099                 return -1;
1100         }
1101
1102         ppi_body = get_ppi(msg);
1103         ppi_uri = &ppi_body->id[0];
1104         cur_id = 0;
1105         i = 0;
1106         while (i < idx)
1107         {
1108                 cur_id++;
1109                 if (cur_id < ppi_body->num_ids)
1110                 {
1111                         ppi_uri = &ppi_body->id[cur_id];
1112                         i++;
1113                 }
1114                 else if (ppi_body->next != NULL)
1115                 {
1116                         ppi_body = ppi_body->next;
1117                         ppi_uri = &ppi_body->id[0];
1118                         cur_id = 0;
1119                         i++;
1120                 }
1121                 else
1122                 {
1123                         /* No more PPIs */
1124                         return pv_get_null(msg, param, res);
1125                 }
1126
1127         }
1128         /* Found the ID at index 'idx' */
1129
1130         if(param->pvn.u.isname.name.n == 1) { /* uri */
1131                 return pv_get_strval(msg, param, res, &(ppi_uri->uri));
1132         }
1133
1134         if(param->pvn.u.isname.name.n==4) { /* display name */
1135                 if(ppi_uri->display.s == NULL ||
1136                                 ppi_uri->display.len <= 0) {
1137                         LM_DBG("no P-Preferred-Identity display name\n");
1138                         return pv_get_null(msg, param, res);
1139                 }
1140                 return pv_get_strval(msg, param, res, &(ppi_uri->display));
1141         }
1142
1143         uri = &ppi_uri->parsed_uri;
1144         if (uri->host.s == NULL && uri->user.s == NULL)
1145         {
1146                 if (parse_uri(ppi_uri->uri.s, ppi_uri->uri.len, uri) < 0)
1147                 {
1148                         LM_ERR("cannot parse P-Preferred-Identity URI\n");
1149                         return pv_get_null(msg, param, res);
1150                 }
1151         }
1152
1153         if(param->pvn.u.isname.name.n==2) { /* username */
1154                 if(uri->user.s==NULL || uri->user.len<=0) {
1155                         LM_DBG("no P-Preferred-Identity username\n");
1156                         return pv_get_null(msg, param, res);
1157                 }
1158                 return pv_get_strval(msg, param, res, &uri->user);
1159         } else if(param->pvn.u.isname.name.n==3) { /* domain */
1160                 if(uri->host.s==NULL || uri->host.len<=0) {
1161                         LM_DBG("no P-Preferred-Identity domain\n");
1162                         return pv_get_null(msg, param, res);
1163                 }
1164                 return pv_get_strval(msg, param, res, &uri->host);
1165         }
1166
1167         LM_ERR("unknown specifier\n");
1168         return pv_get_null(msg, param, res);
1169 }
1170
1171
1172 int pv_get_pai(struct sip_msg *msg, pv_param_t *param,
1173                 pv_value_t *res)
1174 {
1175         int idxf;
1176         int idx;
1177         p_id_body_t *pai_body = NULL;
1178         to_body_t *pai_uri = NULL;
1179         int i, cur_id;
1180
1181         if(msg==NULL)
1182                 return -1;
1183
1184         if(parse_pai_header(msg) < 0)
1185         {
1186                 LM_DBG("no P-Asserted-Identity header\n");
1187                 return pv_get_null(msg, param, res);
1188         }
1189
1190         if (pv_get_spec_index(msg, param, &idx, &idxf) != 0)
1191         {
1192                 LM_ERR("Invalid index\n");
1193                 return -1;
1194         }
1195
1196         if (idxf == PV_IDX_ALL)
1197         {
1198                 LM_ERR("Unable to return 'all' PAI values\n");
1199                 return -1;
1200         }
1201
1202         pai_body = get_pai(msg);
1203         if(pai_body==NULL || pai_body->id==NULL)
1204         {
1205                 LM_DBG("no P-Asserted-Identity header or empty body\n");
1206                 return pv_get_null(msg, param, res);
1207         }
1208         pai_uri = &pai_body->id[0];
1209         cur_id = 0;
1210         i = 0;
1211         while (i < idx)
1212         {
1213                 cur_id++;
1214                 if (cur_id < pai_body->num_ids)
1215                 {
1216                         pai_uri = &pai_body->id[cur_id];
1217                         i++;
1218                 }
1219                 else if (pai_body->next != NULL)
1220                 {
1221                         pai_body = pai_body->next;
1222                         pai_uri = &pai_body->id[0];
1223                         cur_id = 0;
1224                         i++;
1225                 }
1226                 else
1227                 {
1228                         /* No more PAIs */
1229                         return pv_get_null(msg, param, res);
1230                 }
1231
1232         }
1233         /* Found the ID at index 'idx' */
1234
1235         return pv_get_strval(msg, param, res, &(pai_uri->uri));
1236 }
1237
1238 /* proto of received message: $pr or $proto*/
1239 int pv_get_proto(struct sip_msg *msg, pv_param_t *param,
1240                 pv_value_t *res)
1241 {
1242         str s;
1243         if(msg==NULL)
1244                 return -1;
1245
1246         if(get_valid_proto_string(msg->rcv.proto, 0, 0, &s)<0)
1247         {
1248                 s.s = "none";
1249                 s.len = 4;
1250         }
1251
1252         return pv_get_strintval(msg, param, res, &s, (int)msg->rcv.proto);
1253 }
1254
1255 /* proto id of received message */
1256 int pv_get_protoid(struct sip_msg *msg, pv_param_t *param,
1257                 pv_value_t *res)
1258 {
1259         if(msg==NULL)
1260                 return -1;
1261
1262         return pv_get_sintval(msg, param, res, (int)msg->rcv.proto);
1263 }
1264
1265 int pv_get_dset(struct sip_msg *msg, pv_param_t *param,
1266                 pv_value_t *res)
1267 {
1268         str s;
1269         if(msg==NULL)
1270                 return -1;
1271
1272         s.s = print_dset(msg, &s.len);
1273         if (s.s == NULL)
1274                 return pv_get_null(msg, param, res);
1275         s.len -= CRLF_LEN;
1276         return pv_get_strval(msg, param, res, &s);
1277 }
1278
1279 int pv_get_dsturi(struct sip_msg *msg, pv_param_t *param,
1280                 pv_value_t *res)
1281 {
1282         if(msg==NULL)
1283                 return -1;
1284
1285         if (msg->dst_uri.s == NULL) {
1286                 LM_DBG("no destination URI\n");
1287                 return pv_get_null(msg, param, res);
1288         }
1289
1290         return pv_get_strval(msg, param, res, &msg->dst_uri);
1291 }
1292
1293 int pv_get_dsturi_attr(struct sip_msg *msg, pv_param_t *param,
1294                 pv_value_t *res)
1295 {
1296         struct sip_uri uri;
1297
1298         if(msg==NULL)
1299                 return -1;
1300
1301         if (msg->dst_uri.s == NULL) {
1302                 LM_DBG("no destination URI\n");
1303                 return pv_get_null(msg, param, res);
1304         }
1305
1306         if(parse_uri(msg->dst_uri.s, msg->dst_uri.len, &uri)!=0)
1307         {
1308                 LM_ERR("failed to parse dst uri\n");
1309                 return pv_get_null(msg, param, res);
1310         }
1311
1312         if(param->pvn.u.isname.name.n==1) /* domain */
1313         {
1314                 if(uri.host.s==NULL || uri.host.len<=0)
1315                         return pv_get_null(msg, param, res);
1316                 return pv_get_strval(msg, param, res, &uri.host);
1317         } else if(param->pvn.u.isname.name.n==2) /* port */ {
1318                 if(uri.port.s==NULL || uri.port.len<=0) {
1319                         if(uri.proto==PROTO_TLS) {
1320                                 return pv_get_5061(msg, param, res);
1321                         } else {
1322                                 return pv_get_5060(msg, param, res);
1323                         }
1324                 }
1325                 return pv_get_strintval(msg, param, res, &uri.port, (int)uri.port_no);
1326         } else if(param->pvn.u.isname.name.n==3) /* proto */ {
1327                 if(uri.transport_val.s==NULL)
1328                         return pv_get_udp(msg, param, res);
1329                 return pv_get_strintval(msg, param, res, &uri.transport_val,
1330                                 (int)uri.proto);
1331         }
1332
1333         LM_ERR("invalid specifier\n");
1334         return pv_get_null(msg, param, res);
1335 }
1336
1337 int pv_get_content_type(struct sip_msg *msg, pv_param_t *param,
1338                 pv_value_t *res)
1339 {
1340         if(msg==NULL)
1341                 return -1;
1342
1343         if(msg->content_type==NULL
1344                         && ((parse_headers(msg, HDR_CONTENTTYPE_F, 0)==-1)
1345                                 || (msg->content_type==NULL)))
1346         {
1347                 LM_DBG("no Content-Type header\n");
1348                 return pv_get_null(msg, param, res);
1349         }
1350
1351         return pv_get_strval(msg, param, res, &msg->content_type->body);
1352 }
1353
1354
1355 int pv_get_content_length(struct sip_msg *msg, pv_param_t *param,
1356                 pv_value_t *res)
1357 {
1358         if(msg==NULL)
1359                 return -1;
1360         if(msg->content_length==NULL
1361                         && ((parse_headers(msg, HDR_CONTENTLENGTH_F, 0)==-1)
1362                                 || (msg->content_length==NULL)))
1363         {
1364                 LM_DBG("no Content-Length header\n");
1365                 return pv_get_null(msg, param, res);
1366         }
1367
1368         return pv_get_intstrval(msg, param, res,
1369                         (int)(long)msg->content_length->parsed,
1370                         &msg->content_length->body);
1371 }
1372
1373 int pv_get_msg_body(struct sip_msg *msg, pv_param_t *param,
1374                 pv_value_t *res)
1375 {
1376         str s;
1377         if(msg==NULL)
1378                 return -1;
1379
1380         s.s = get_body( msg );
1381
1382         if(s.s == NULL)
1383         {
1384                 LM_DBG("no message body\n");
1385                 return pv_get_null(msg, param, res);
1386         }
1387         s.len = msg->buf + msg->len - s.s;
1388
1389         return pv_get_strval(msg, param, res, &s);
1390 }
1391
1392
1393 int pv_get_body_size(struct sip_msg *msg, pv_param_t *param,
1394                 pv_value_t *res)
1395 {
1396         str s;
1397         if(msg==NULL)
1398                 return -1;
1399
1400         s.s = get_body( msg );
1401
1402         s.len = 0;
1403         if (s.s != NULL)
1404                 s.len = msg->buf + msg->len - s.s;
1405         return pv_get_sintval(msg, param, res, s.len);
1406 }
1407
1408
1409 int pv_get_authattr(struct sip_msg *msg, pv_param_t *param,
1410                 pv_value_t *res)
1411 {
1412         struct hdr_field *hdr;
1413
1414         if(msg==NULL)
1415                 return -1;
1416
1417         if ((msg->REQ_METHOD == METHOD_ACK) ||
1418                         (msg->REQ_METHOD == METHOD_CANCEL)) {
1419                 LM_DBG("no [Proxy-]Authorization header\n");
1420                 return pv_get_null(msg, param, res);
1421         }
1422
1423         if ((parse_headers(msg, HDR_PROXYAUTH_F|HDR_AUTHORIZATION_F, 0)==-1)
1424                         || (msg->proxy_auth==0 && msg->authorization==0))
1425         {
1426                 LM_DBG("no [Proxy-]Authorization header\n");
1427                 return pv_get_null(msg, param, res);
1428         }
1429
1430         hdr = (msg->proxy_auth==0)?msg->authorization:msg->proxy_auth;
1431
1432         if(parse_credentials(hdr)!=0) {
1433                 LM_ERR("failed to parse credentials\n");
1434                 return pv_get_null(msg, param, res);
1435         }
1436         switch(param->pvn.u.isname.name.n)
1437         {
1438                 case 10:
1439                         return pv_get_strval(msg, param, res,
1440                                         &((auth_body_t*)(hdr->parsed))->digest.opaque);
1441                 case 9:
1442                         return pv_get_strval(msg, param, res,
1443                                         &((auth_body_t*)(hdr->parsed))->digest.response);
1444                 case 8:
1445                         return pv_get_strval(msg, param, res,
1446                                         &((auth_body_t*)(hdr->parsed))->digest.cnonce);
1447                 case 7:
1448                         return pv_get_strval(msg, param, res,
1449                                         &((auth_body_t*)(hdr->parsed))->digest.nonce);
1450                 case 6:
1451                         return pv_get_strval(msg, param, res,
1452                                         &((auth_body_t*)(hdr->parsed))->digest.alg.alg_str);
1453                 case 4:
1454                         return pv_get_strval(msg, param, res,
1455                                         &((auth_body_t*)(hdr->parsed))->digest.username.domain);
1456                 case 3:
1457                         if(((auth_body_t*)(hdr->parsed))->digest.uri.len==0)
1458                                 return pv_get_null(msg, param, res);
1459                         return pv_get_strval(msg, param, res,
1460                                         &((auth_body_t*)(hdr->parsed))->digest.uri);
1461                 break;
1462                 case 2:
1463                         return pv_get_strval(msg, param, res,
1464                                         &((auth_body_t*)(hdr->parsed))->digest.realm);
1465                 break;
1466                 case 1:
1467                         return pv_get_strval(msg, param, res,
1468                                         &((auth_body_t*)(hdr->parsed))->digest.username.user);
1469                 break;
1470                 default:
1471                         return pv_get_strval(msg, param, res,
1472                                         &((auth_body_t*)(hdr->parsed))->digest.username.whole);
1473         }
1474 }
1475
1476 static inline str *cred_user(struct sip_msg *rq)
1477 {
1478         struct hdr_field* h;
1479         auth_body_t* cred;
1480
1481         get_authorized_cred(rq->proxy_auth, &h);
1482         if (!h) get_authorized_cred(rq->authorization, &h);
1483         if (!h) return 0;
1484         cred=(auth_body_t*)(h->parsed);
1485         if (!cred || !cred->digest.username.user.len)
1486                         return 0;
1487         return &cred->digest.username.user;
1488 }
1489
1490
1491 static inline str *cred_realm(struct sip_msg *rq)
1492 {
1493         str* realm;
1494         struct hdr_field* h;
1495         auth_body_t* cred;
1496
1497         get_authorized_cred(rq->proxy_auth, &h);
1498         if (!h) get_authorized_cred(rq->authorization, &h);
1499         if (!h) return 0;
1500         cred=(auth_body_t*)(h->parsed);
1501         if (!cred) return 0;
1502         realm = GET_REALM(&cred->digest);
1503         if (!realm->len || !realm->s) {
1504                 return 0;
1505         }
1506         return realm;
1507 }
1508
1509 int pv_get_acc_username(struct sip_msg *msg, pv_param_t *param,
1510                 pv_value_t *res)
1511 {
1512         static char buf[MAX_URI_SIZE];
1513         str* user;
1514         str* realm;
1515         struct sip_uri puri;
1516         struct to_body* from;
1517         str s;
1518
1519         /* try to take it from credentials */
1520         user = cred_user(msg);
1521         if (user) {
1522                 realm = cred_realm(msg);
1523                 if (realm) {
1524                         s.len = user->len+1+realm->len;
1525                         if (s.len > MAX_URI_SIZE) {
1526                                 LM_ERR("uri too long\n");
1527                                 return pv_get_null(msg, param, res);
1528                         }
1529                         s.s = buf;
1530                         memcpy(s.s, user->s, user->len);
1531                         (s.s)[user->len] = '@';
1532                         memcpy(s.s+user->len+1, realm->s, realm->len);
1533                         return pv_get_strval(msg, param, res, &s);
1534                 }
1535                 return pv_get_strval(msg, param, res, user);
1536         }
1537
1538         /* from from uri */
1539         if(parse_from_header(msg)<0)
1540         {
1541                 LM_ERR("cannot parse FROM header\n");
1542                 return pv_get_null(msg, param, res);
1543         }
1544         if (msg->from && (from=get_from(msg)) && from->uri.len) {
1545                 if (parse_uri(from->uri.s, from->uri.len, &puri) < 0 ) {
1546                         LM_ERR("bad From URI\n");
1547                         return pv_get_null(msg, param, res);
1548                 }
1549                 s.len = puri.user.len + 1 + puri.host.len;
1550                 if (s.len > MAX_URI_SIZE) {
1551                         LM_ERR("from URI too long\n");
1552                         return pv_get_null(msg, param, res);
1553                 }
1554                 s.s = buf;
1555                 memcpy(s.s, puri.user.s, puri.user.len);
1556                 (s.s)[puri.user.len] = '@';
1557                 memcpy(s.s + puri.user.len + 1, puri.host.s, puri.host.len);
1558         } else {
1559                 s.len = 0;
1560                 s.s = 0;
1561         }
1562         return pv_get_strval(msg, param, res, &s);
1563 }
1564
1565 int pv_get_branch(struct sip_msg *msg, pv_param_t *param,
1566                 pv_value_t *res)
1567 {
1568         str branch;
1569         qvalue_t q;
1570
1571         if(msg==NULL || res==NULL)
1572                 return -1;
1573
1574         if(msg->first_line.type == SIP_REPLY)
1575                 return pv_get_null(msg, param, res);
1576
1577
1578         branch.s = get_branch(0, &branch.len, &q, 0, 0, 0, 0, 0, 0, 0);
1579         if (!branch.s) {
1580                 return pv_get_null(msg, param, res);
1581         }
1582
1583         return pv_get_strval(msg, param, res, &branch);
1584 }
1585
1586 #define Q_PARAM ">;q="
1587 #define Q_PARAM_LEN (sizeof(Q_PARAM) - 1)
1588
1589 int pv_get_branches(struct sip_msg *msg, pv_param_t *param,
1590                 pv_value_t *res)
1591 {
1592         str uri;
1593         str s;
1594         qvalue_t q;
1595         int cnt, i;
1596         unsigned int qlen;
1597         char *p, *qbuf, *p_ini;
1598
1599         if(msg==NULL || res==NULL)
1600                 return -1;
1601
1602         if(msg->first_line.type == SIP_REPLY)
1603                 return pv_get_null(msg, param, res);
1604
1605         cnt = s.len = 0;
1606
1607         while ((uri.s = get_branch(cnt, &uri.len, &q, 0, 0, 0, 0, 0, 0, 0)))
1608         {
1609                 cnt++;
1610                 s.len += uri.len;
1611                 if (q != Q_UNSPECIFIED)
1612                 {
1613                         s.len += 1 + Q_PARAM_LEN + len_q(q);
1614                 }
1615         }
1616
1617         if (cnt == 0)
1618                 return pv_get_null(msg, param, res);
1619
1620         s.len += (cnt - 1) * PV_FIELD_DELIM_LEN;
1621         if (s.len + 1 > pv_get_buffer_size())
1622         {
1623                 LM_ERR("local buffer length exceeded\n");
1624                 return pv_get_null(msg, param, res);
1625         }
1626
1627         i = 0;
1628         p_ini = pv_get_buffer();
1629         p = p_ini;
1630
1631         while ((uri.s = get_branch(i, &uri.len, &q, 0, 0, 0, 0, 0, 0, 0)))
1632         {
1633                 if (i)
1634                 {
1635                         memcpy(p, PV_FIELD_DELIM, PV_FIELD_DELIM_LEN);
1636                         p += PV_FIELD_DELIM_LEN;
1637                 }
1638
1639                 if (q != Q_UNSPECIFIED)
1640                 {
1641                         *p++ = '<';
1642                 }
1643
1644                 memcpy(p, uri.s, uri.len);
1645                 p += uri.len;
1646                 if (q != Q_UNSPECIFIED)
1647                 {
1648                         memcpy(p, Q_PARAM, Q_PARAM_LEN);
1649                         p += Q_PARAM_LEN;
1650
1651                         qbuf = q2str(q, &qlen);
1652                         memcpy(p, qbuf, qlen);
1653                         p += qlen;
1654                 }
1655                 i++;
1656         }
1657
1658         s.s = &(p_ini[0]);
1659         return pv_get_strval(msg, param, res, &s);
1660 }
1661
1662 int pv_get_avp(struct sip_msg *msg,  pv_param_t *param, pv_value_t *res)
1663 {
1664         unsigned short name_type;
1665         int_str avp_name;
1666         int_str avp_value;
1667         struct usr_avp *avp;
1668         int_str avp_value0;
1669         struct usr_avp *avp0;
1670         int idx;
1671         int idxf;
1672         char *p, *p_ini;
1673         int p_size;
1674         int n=0;
1675         struct search_state state;
1676
1677         if(msg==NULL || res==NULL || param==NULL)
1678                 return -1;
1679
1680         /* get the name */
1681         if(pv_get_avp_name(msg, param, &avp_name, &name_type)!=0)
1682         {
1683                 LM_ERR("invalid name\n");
1684                 return -1;
1685         }
1686         /* get the index */
1687         if(pv_get_spec_index(msg, param, &idx, &idxf)!=0)
1688         {
1689                 LM_ERR("invalid index\n");
1690                 return -1;
1691         }
1692
1693         memset(&state, 0, sizeof(struct search_state));
1694         if ((avp=search_first_avp(name_type, avp_name, &avp_value, &state))==0)
1695                 return pv_get_null(msg, param, res);
1696         res->flags = PV_VAL_STR;
1697         if(idxf==0 && idx==0)
1698         {
1699                 if(avp->flags & AVP_VAL_STR)
1700                 {
1701                         res->rs = avp_value.s;
1702                 } else {
1703                         res->rs.s = sint2str(avp_value.n, &res->rs.len);
1704                         res->ri = avp_value.n;
1705                         res->flags |= PV_VAL_INT|PV_TYPE_INT;
1706                 }
1707                 return 0;
1708         }
1709         if(idxf==PV_IDX_ALL)
1710         {
1711                 p_ini = pv_get_buffer();
1712                 p = p_ini;
1713                 p_size = pv_get_buffer_size();
1714                 do {
1715                         if(p!=p_ini)
1716                         {
1717                                 if(p-p_ini+PV_FIELD_DELIM_LEN+1>p_size)
1718                                 {
1719                                         LM_ERR("local buffer length exceeded\n");
1720                                         return pv_get_null(msg, param, res);
1721                                 }
1722                                 memcpy(p, PV_FIELD_DELIM, PV_FIELD_DELIM_LEN);
1723                                 p += PV_FIELD_DELIM_LEN;
1724                         }
1725                         if(avp->flags & AVP_VAL_STR)
1726                         {
1727                                 res->rs = avp_value.s;
1728                         } else {
1729                                 res->rs.s = sint2str(avp_value.n, &res->rs.len);
1730                         }
1731
1732                         if(p-p_ini+res->rs.len+1>p_size)
1733                         {
1734                                 LM_ERR("local buffer length exceeded!\n");
1735                                 return pv_get_null(msg, param, res);
1736                         }
1737                         memcpy(p, res->rs.s, res->rs.len);
1738                         p += res->rs.len;
1739                 } while ((avp=search_next_avp(&state, &avp_value))!=0);
1740                 res->rs.s = p_ini;
1741                 res->rs.len = p - p_ini;
1742                 return 0;
1743         }
1744
1745         /* we have a numeric index */
1746         if(idx<0)
1747         {
1748                 n = 1;
1749                 avp0 = avp;
1750                 while ((avp0=search_next_avp(&state, &avp_value0))!=0) n++;
1751                 idx = -idx;
1752                 if(idx>n)
1753                 {
1754                         LM_DBG("index out of range\n");
1755                         return pv_get_null(msg, param, res);
1756                 }
1757                 idx = n - idx;
1758                 if(idx==0)
1759                 {
1760                         if(avp->flags & AVP_VAL_STR)
1761                         {
1762                                 res->rs = avp_value.s;
1763                         } else {
1764                                 res->rs.s = sint2str(avp_value.n, &res->rs.len);
1765                                 res->ri = avp_value.n;
1766                                 res->flags |= PV_VAL_INT|PV_TYPE_INT;
1767                         }
1768                         return 0;
1769                 }
1770         }
1771         n=0;
1772         while(n<idx
1773                         && (avp=search_next_avp(&state, &avp_value))!=0)
1774                 n++;
1775
1776         if(avp!=0)
1777         {
1778                 if(avp->flags & AVP_VAL_STR)
1779                 {
1780                         res->rs = avp_value.s;
1781                 } else {
1782                         res->rs.s = sint2str(avp_value.n, &res->rs.len);
1783                         res->ri = avp_value.n;
1784                         res->flags |= PV_VAL_INT|PV_TYPE_INT;
1785                 }
1786                 return 0;
1787         }
1788
1789         LM_DBG("index out of range\n");
1790         return pv_get_null(msg, param, res);
1791 }
1792
1793 int pv_get_hdr(struct sip_msg *msg,  pv_param_t *param, pv_value_t *res)
1794 {
1795         int idx;
1796         int idxf;
1797         pv_value_t tv;
1798         struct hdr_field *hf;
1799         struct hdr_field *hf0;
1800         char *p, *p_ini;
1801         int n, p_size;
1802
1803         if(msg==NULL || res==NULL || param==NULL)
1804                 return -1;
1805
1806         /* get the name */
1807         if(param->pvn.type == PV_NAME_PVAR)
1808         {
1809                 if(pv_get_spec_name(msg, param, &tv)!=0 || (!(tv.flags&PV_VAL_STR)))
1810                 {
1811                         LM_ERR("invalid name\n");
1812                         return -1;
1813                 }
1814         } else {
1815                 if(param->pvn.u.isname.type == AVP_NAME_STR)
1816                 {
1817                         tv.flags = PV_VAL_STR;
1818                         tv.rs = param->pvn.u.isname.name.s;
1819                 } else {
1820                         tv.flags = 0;
1821                         tv.ri = param->pvn.u.isname.name.n;
1822                 }
1823         }
1824         /* we need to be sure we have parsed all headers */
1825         if(parse_headers(msg, HDR_EOH_F, 0)<0)
1826         {
1827                 LM_ERR("error parsing headers\n");
1828                 return pv_get_null(msg, param, res);
1829         }
1830
1831         for (hf=msg->headers; hf; hf=hf->next)
1832         {
1833                 if(tv.flags == 0)
1834                 {
1835                         if (tv.ri==hf->type)
1836                                 break;
1837                 } else {
1838                         if (cmp_hdrname_str(&hf->name, &tv.rs)==0)
1839                                 break;
1840                 }
1841         }
1842         if(hf==NULL)
1843                 return pv_get_null(msg, param, res);
1844         /* get the index */
1845         if(pv_get_spec_index(msg, param, &idx, &idxf)!=0)
1846         {
1847                 LM_ERR("invalid index\n");
1848                 return -1;
1849         }
1850
1851         /* get the value */
1852         res->flags = PV_VAL_STR;
1853         if(idxf==0 && idx==0)
1854         {
1855                 res->rs  = hf->body;
1856                 return 0;
1857         }
1858         if(idxf==PV_IDX_ALL)
1859         {
1860                 p_ini = pv_get_buffer();
1861                 p = p_ini;
1862                 p_size = pv_get_buffer_size();
1863                 do {
1864                         if(p!=p_ini)
1865                         {
1866                                 if(p-p_ini+PV_FIELD_DELIM_LEN+1>p_size)
1867                                 {
1868                                         LM_ERR("local buffer length exceeded\n");
1869                                         return pv_get_null(msg, param, res);
1870                                 }
1871                                 memcpy(p, PV_HDR_DELIM, PV_HDR_DELIM_LEN);
1872                                 p += PV_HDR_DELIM_LEN;
1873                         }
1874                         if(p-p_ini+hf->body.len+1>p_size)
1875                         {
1876                                 LM_ERR("local buffer length exceeded [%d/%d]!\n",
1877                                                 (int)(p-p_ini+hf->body.len+1),
1878                                                 hf->body.len);
1879                                 return pv_get_null(msg, param, res);
1880                         }
1881                         memcpy(p, hf->body.s, hf->body.len);
1882                         p += hf->body.len;
1883                         /* next hf */
1884                         for (hf=hf->next; hf; hf=hf->next)
1885                         {
1886                                 if(tv.flags == 0)
1887                                 {
1888                                         if (tv.ri==hf->type)
1889                                                 break;
1890                                 } else {
1891                                         if (cmp_hdrname_str(&hf->name, &tv.rs)==0)
1892                                         break;
1893                                 }
1894                         }
1895                 } while (hf);
1896                 res->rs.s = p_ini;
1897                 res->rs.len = p - p_ini;
1898                 return 0;
1899         }
1900
1901         /* we have a numeric index */
1902         hf0 = 0;
1903         if(idx<0)
1904         {
1905                 n = 1;
1906                 /* count headers */
1907                 for (hf0=hf->next; hf0; hf0=hf0->next)
1908                 {
1909                         if(tv.flags == 0)
1910                         {
1911                                 if (tv.ri==hf0->type)
1912                                         n++;
1913                         } else {
1914                                 if (cmp_hdrname_str(&hf0->name, &tv.rs)==0)
1915                                         n++;
1916                         }
1917                 }
1918                 idx = -idx;
1919                 if(idx>n)
1920                 {
1921                         LM_DBG("index out of range\n");
1922                         return pv_get_null(msg, param, res);
1923                 }
1924                 idx = n - idx;
1925                 if(idx==0)
1926                 {
1927                         res->rs  = hf->body;
1928                         return 0;
1929                 }
1930         }
1931         n=0;
1932         while(n<idx)
1933         {
1934                 for (hf0=hf->next; hf0; hf0=hf0->next)
1935                 {
1936                         if(tv.flags == 0)
1937                         {
1938                                 if (tv.ri==hf0->type)
1939                                         n++;
1940                         } else {
1941                                 if (cmp_hdrname_str(&hf0->name, &tv.rs)==0)
1942                                         n++;
1943                         }
1944                         if(n==idx)
1945                                 break;
1946                 }
1947                 if(hf0==NULL)
1948                         break;
1949         }
1950
1951         if(hf0!=0)
1952         {
1953                 res->rs  = hf0->body;
1954                 return 0;
1955         }
1956
1957         LM_DBG("index out of range\n");
1958         return pv_get_null(msg, param, res);
1959
1960 }
1961
1962 /**
1963  *
1964  */
1965 int pv_get_hdrc(struct sip_msg *msg,  pv_param_t *param, pv_value_t *res)
1966 {
1967         pv_value_t tv;
1968         struct hdr_field *hf;
1969         int hcount;
1970
1971         if(msg==NULL || res==NULL || param==NULL)
1972                 return -1;
1973
1974         hcount = 0;
1975
1976         /* get the name */
1977         if(param->pvn.type == PV_NAME_PVAR)
1978         {
1979                 if(pv_get_spec_name(msg, param, &tv)!=0 || (!(tv.flags&PV_VAL_STR)))
1980                 {
1981                         LM_ERR("invalid name\n");
1982                         return pv_get_sintval(msg, param, res, hcount);
1983                 }
1984         } else {
1985                 if(param->pvn.u.isname.type == AVP_NAME_STR)
1986                 {
1987                         tv.flags = PV_VAL_STR;
1988                         tv.rs = param->pvn.u.isname.name.s;
1989                 } else {
1990                         tv.flags = 0;
1991                         tv.ri = param->pvn.u.isname.name.n;
1992                 }
1993         }
1994         /* we need to be sure we have parsed all headers */
1995         if(parse_headers(msg, HDR_EOH_F, 0)<0)
1996         {
1997                 LM_ERR("error parsing headers\n");
1998                 return pv_get_sintval(msg, param, res, hcount);
1999         }
2000
2001
2002         for (hf=msg->headers; hf; hf=hf->next)
2003         {
2004                 if(tv.flags == 0)
2005                 {
2006                         if (tv.ri==hf->type) {
2007                                 hcount++;
2008                         }
2009                 } else {
2010                         if (cmp_hdrname_str(&hf->name, &tv.rs)==0) {
2011                                 hcount++;
2012                         }
2013                 }
2014         }
2015         return pv_get_sintval(msg, param, res, hcount);
2016 }
2017
2018 /**
2019  *
2020  */
2021 int pv_get_scriptvar(struct sip_msg *msg,  pv_param_t *param,
2022                 pv_value_t *res)
2023 {
2024         int ival = 0;
2025         char *sval = NULL;
2026         script_var_t *sv=NULL;
2027
2028         if(msg==NULL || res==NULL)
2029                 return -1;
2030
2031         if(param==NULL || param->pvn.u.dname==0)
2032                 return pv_get_null(msg, param, res);
2033
2034         sv= (script_var_t*)param->pvn.u.dname;
2035
2036         if((sv->v.flags&VAR_TYPE_NULL) && (sv->v.flags&VAR_VAL_NULL))
2037                         return pv_get_null(msg, param, res);
2038
2039         if(sv->v.flags&VAR_VAL_STR)
2040         {
2041                 res->rs = sv->v.value.s;
2042                 res->flags = PV_VAL_STR;
2043         } else {
2044                 sval = sint2str(sv->v.value.n, &ival);
2045
2046                 res->rs.s = sval;
2047                 res->rs.len = ival;
2048
2049                 res->ri = sv->v.value.n;
2050                 res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT;
2051         }
2052         return 0;
2053 }
2054
2055 int pv_get_server_id(struct sip_msg *msg, pv_param_t *param,
2056                 pv_value_t *res)
2057 {
2058         return pv_get_sintval(msg, param, res, server_id);
2059 }
2060
2061 int pv_get_cnt(struct sip_msg *msg, pv_param_t *param,
2062                 pv_value_t *res)
2063 {
2064         int_str avp_name;
2065         unsigned short avp_type = 0;
2066         avp_search_state_t state;
2067         pv_spec_t *pv=NULL;
2068         unsigned int n = 0;
2069         avp_t *avp;
2070
2071         pv = (pv_spec_t*)param->pvn.u.dname;
2072         if(pv==NULL)
2073                 return pv_get_null(msg, param, res);
2074
2075         if(pv_get_avp_name(0, &pv->pvp, &avp_name, &avp_type)!=0)
2076         {
2077                 LM_ERR("invalid AVP definition\n");
2078                 return pv_get_null(msg, param, res);
2079         }
2080         avp=search_first_avp(avp_type, avp_name, NULL, &state);
2081         while(avp) {
2082                 n++;
2083                 avp=search_next_avp(&state, NULL);
2084         }
2085
2086         return pv_get_uintval(msg, param, res, n);
2087 }
2088
2089 int pv_get_ruid(struct sip_msg *msg, pv_param_t *param,
2090                 pv_value_t *res)
2091 {
2092         if(msg==NULL)
2093                 return -1;
2094
2095         if(msg->first_line.type == SIP_REPLY)
2096                 return pv_get_null(msg, param, res);
2097
2098         if(msg->ruid.len==0)
2099         {
2100                 LM_DBG("no ruid\n");
2101                 return pv_get_null(msg, param, res);
2102         }
2103
2104         return pv_get_strval(msg, param, res, &msg->ruid);
2105 }
2106
2107 int pv_get_location_ua(struct sip_msg *msg, pv_param_t *param,
2108                 pv_value_t *res)
2109 {
2110         if(msg==NULL)
2111                 return -1;
2112
2113         if(msg->first_line.type == SIP_REPLY)
2114                 return pv_get_null(msg, param, res);
2115
2116         if(msg->location_ua.len==0)
2117         {
2118                 LM_DBG("no location_ua\n");
2119                 return pv_get_null(msg, param, res);
2120         }
2121
2122         return pv_get_strval(msg, param, res, &msg->location_ua);
2123 }
2124
2125 int pv_get_tcpconn_id(struct sip_msg *msg, pv_param_t *param,
2126                 pv_value_t *res)
2127 {
2128         struct tcp_connection *con;
2129         int conid;
2130
2131         if (msg == NULL)
2132                 return -1;
2133
2134         if ((con = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0, 0)) == NULL)
2135                 return pv_get_null(msg, param, res);
2136
2137         conid = con->id;
2138         tcpconn_put(con);
2139
2140         return pv_get_sintval(msg, param, res, conid);
2141 }
2142
2143
2144 /********* end PV get functions *********/
2145
2146 /********* start PV set functions *********/
2147 int pv_set_avp(struct sip_msg* msg, pv_param_t *param,
2148                 int op, pv_value_t *val)
2149 {
2150         int_str avp_name;
2151         int_str avp_val;
2152         int flags;
2153         unsigned short name_type;
2154         int idxf;
2155         int idx;
2156
2157         if(param==NULL)
2158         {
2159                 LM_ERR("bad parameters\n");
2160                 return -1;
2161         }
2162
2163         /* get the name */
2164         if(pv_get_avp_name(msg, param, &avp_name, &name_type)!=0)
2165         {
2166                 LM_ALERT("BUG in getting dst AVP name\n");
2167                 goto error;
2168         }
2169         /* get the index */
2170         if(pv_get_spec_index(msg, param, &idx, &idxf)!=0)
2171         {
2172                 LM_ERR("invalid index\n");
2173                 return -1;
2174         }
2175
2176         if((val==NULL) || (val->flags&PV_VAL_NULL))
2177         {
2178                 if(idxf == PV_IDX_ALL)
2179                         destroy_avps(name_type, avp_name, 1);
2180                 else
2181                         destroy_avps(name_type, avp_name, 0);
2182                 return 0;
2183         }
2184         if(idxf == PV_IDX_ALL)
2185                 destroy_avps(name_type, avp_name, 1);
2186         flags = name_type;
2187         if(val->flags&PV_TYPE_INT)
2188         {
2189                 avp_val.n = val->ri;
2190         } else {
2191                 avp_val.s = val->rs;
2192                 flags |= AVP_VAL_STR;
2193         }
2194         if (add_avp(flags, avp_name, avp_val)<0)
2195         {
2196                 LM_ERR("error - cannot add AVP\n");
2197                 goto error;
2198         }
2199         return 0;
2200 error:
2201         return -1;
2202 }
2203
2204 int pv_set_scriptvar(struct sip_msg* msg, pv_param_t *param,
2205                 int op, pv_value_t *val)
2206 {
2207         int_str avp_val;
2208         int flags;
2209
2210         if(param==NULL)
2211         {
2212                 LM_ERR("bad parameters\n");
2213                 return -1;
2214         }
2215
2216         if(param->pvn.u.dname==0)
2217         {
2218                 LM_ERR("error - cannot find svar\n");
2219                 goto error;
2220         }
2221         if((val==NULL) || (val->flags&PV_VAL_NULL))
2222         {
2223                 if(((script_var_t*)param->pvn.u.dname)->v.flags&VAR_TYPE_NULL)
2224                 {
2225                         set_var_value((script_var_t*)param->pvn.u.dname, NULL, 0);
2226                 } else {
2227                         avp_val.n = 0;
2228                         set_var_value((script_var_t*)param->pvn.u.dname, &avp_val, 0);
2229                 }
2230                 return 0;
2231         }
2232         flags = 0;
2233         if(val->flags&PV_TYPE_INT)
2234         {
2235                 avp_val.n = val->ri;
2236         } else {
2237                 avp_val.s = val->rs;
2238                 flags |= VAR_VAL_STR;
2239         }
2240         if(set_var_value((script_var_t*)param->pvn.u.dname, &avp_val, flags)==NULL)
2241         {
2242                 LM_ERR("error - cannot set svar [%.*s] \n",
2243                                 ((script_var_t*)param->pvn.u.dname)->name.len,
2244                                 ((script_var_t*)param->pvn.u.dname)->name.s);
2245                 goto error;
2246         }
2247         return 0;
2248 error:
2249         return -1;
2250 }
2251
2252 int pv_set_dsturi(struct sip_msg* msg, pv_param_t *param,
2253                 int op, pv_value_t *val)
2254 {
2255         if(msg==NULL || param==NULL)
2256         {
2257                 LM_ERR("bad parameters\n");
2258                 return -1;
2259         }
2260
2261         if((val==NULL) || (val->flags&PV_VAL_NULL))
2262         {
2263                 reset_dst_uri(msg);
2264                 return 1;
2265         }
2266         if(!(val->flags&PV_VAL_STR))
2267         {
2268                 LM_ERR("error - str value required to set dst uri\n");
2269                 goto error;
2270         }
2271
2272         if(set_dst_uri(msg, &val->rs)!=0)
2273                 goto error;
2274         /* dst_uri changed, so it makes sense to re-use the current uri for
2275                 forking */
2276         ruri_mark_new(); /* re-use uri for serial forking */
2277
2278         return 0;
2279 error:
2280         return -1;
2281 }
2282
2283 int pv_set_ruri(struct sip_msg* msg, pv_param_t *param,
2284                 int op, pv_value_t *val)
2285 {
2286         struct action  act;
2287         struct run_act_ctx h;
2288         char backup;
2289
2290         if(msg==NULL || param==NULL || val==NULL || (val->flags&PV_VAL_NULL))
2291         {
2292                 LM_ERR("bad parameters\n");
2293                 return -1;
2294         }
2295
2296         if(!(val->flags&PV_VAL_STR))
2297         {
2298                 LM_ERR("str value required to set R-URI\n");
2299                 goto error;
2300         }
2301
2302         memset(&act, 0, sizeof(act));
2303         act.val[0].type = STRING_ST;
2304         act.val[0].u.string = val->rs.s;
2305         backup = val->rs.s[val->rs.len];
2306         val->rs.s[val->rs.len] = '\0';
2307         act.type = SET_URI_T;
2308         init_run_actions_ctx(&h);
2309         if (do_action(&h, &act, msg)<0)
2310         {
2311                 LM_ERR("do action failed\n");
2312                 val->rs.s[val->rs.len] = backup;
2313                 goto error;
2314         }
2315         val->rs.s[val->rs.len] = backup;
2316
2317         return 0;
2318 error:
2319         return -1;
2320 }
2321
2322 int pv_set_ruri_user(struct sip_msg* msg, pv_param_t *param,
2323                 int op, pv_value_t *val)
2324 {
2325         struct action  act;
2326         struct run_act_ctx h;
2327         char backup;
2328
2329         if(msg==NULL || param==NULL)
2330         {
2331                 LM_ERR("bad parameters\n");
2332                 return -1;
2333         }
2334
2335         if((val==NULL) || (val->flags&PV_VAL_NULL)
2336                         || ((val->flags&PV_VAL_STR) && val->rs.len<=0))
2337         {
2338                 memset(&act, 0, sizeof(act));
2339                 act.type = SET_USER_T;
2340                 act.val[0].type = STRING_ST;
2341                 act.val[0].u.string = _empty_str;
2342                 init_run_actions_ctx(&h);
2343                 if (do_action(&h, &act, msg)<0)
2344                 {
2345                         LM_ERR("do action failed)\n");
2346                         goto error;
2347                 }
2348                 return 0;
2349         }
2350
2351         if(!(val->flags&PV_VAL_STR))
2352         {
2353                 LM_ERR("str value required to set R-URI user\n");
2354                 goto error;
2355         }
2356
2357         memset(&act, 0, sizeof(act));
2358         act.val[0].type = STRING_ST;
2359         act.val[0].u.string = val->rs.s;
2360         backup = val->rs.s[val->rs.len];
2361         val->rs.s[val->rs.len] = '\0';
2362         act.type = SET_USER_T;
2363         init_run_actions_ctx(&h);
2364         if (do_action(&h, &act, msg)<0)
2365         {
2366                 LM_ERR("do action failed\n");
2367                 val->rs.s[val->rs.len] = backup;
2368                 goto error;
2369         }
2370         val->rs.s[val->rs.len] = backup;
2371
2372         return 0;
2373 error:
2374         return -1;
2375 }
2376
2377 int pv_set_ruri_host(struct sip_msg* msg, pv_param_t *param,
2378                 int op, pv_value_t *val)
2379 {
2380         struct action  act;
2381         struct run_act_ctx h;
2382         char backup;
2383
2384         if(msg==NULL || param==NULL || val==NULL || (val->flags&PV_VAL_NULL))
2385         {
2386                 LM_ERR("bad parameters\n");
2387                 return -1;
2388         }
2389
2390         if(!(val->flags&PV_VAL_STR))
2391         {
2392                 LM_ERR("str value required to set R-URI hostname\n");
2393                 goto error;
2394         }
2395
2396         memset(&act, 0, sizeof(act));
2397         act.val[0].type = STRING_ST;
2398         act.val[0].u.string = val->rs.s;
2399         backup = val->rs.s[val->rs.len];
2400         val->rs.s[val->rs.len] = '\0';
2401         act.type = SET_HOST_T;
2402         init_run_actions_ctx(&h);
2403         if (do_action(&h, &act, msg)<0)
2404         {
2405                 LM_ERR("do action failed\n");
2406                 val->rs.s[val->rs.len] = backup;
2407                 goto error;
2408         }
2409         val->rs.s[val->rs.len] = backup;
2410
2411         return 0;
2412 error:
2413         return -1;
2414 }
2415
2416 int pv_set_ruri_port(struct sip_msg* msg, pv_param_t *param,
2417                 int op, pv_value_t *val)
2418 {
2419         struct action  act;
2420         struct run_act_ctx h;
2421         char backup;
2422
2423         if(msg==NULL || param==NULL)
2424         {
2425                 LM_ERR("bad parameters\n");
2426                 return -1;
2427         }
2428
2429         if(val == NULL || (val->flags&PV_VAL_NULL))
2430         {
2431                 memset(&act, 0, sizeof(act));
2432                 act.type = SET_PORT_T;
2433                 act.val[0].type = STRING_ST;
2434                 act.val[0].u.string = _empty_str;
2435                 init_run_actions_ctx(&h);
2436                 if (do_action(&h, &act, msg)<0)
2437                 {
2438                         LM_ERR("do action failed)\n");
2439                         goto error;
2440                 }
2441                 return 0;
2442         }
2443
2444         if(!(val->flags&PV_VAL_STR))
2445         {
2446                 val->rs.s = int2str(val->ri, &val->rs.len);
2447                 val->flags |= PV_VAL_STR;
2448         }
2449
2450         memset(&act, 0, sizeof(act));
2451         act.val[0].type = STRING_ST;
2452         act.val[0].u.string = val->rs.s;
2453         backup = val->rs.s[val->rs.len];
2454         val->rs.s[val->rs.len] = '\0';
2455         act.type = SET_PORT_T;
2456         init_run_actions_ctx(&h);
2457         if (do_action(&h, &act, msg)<0)
2458         {
2459                 LM_ERR("do action failed\n");
2460                 val->rs.s[val->rs.len] = backup;
2461                 goto error;
2462         }
2463         val->rs.s[val->rs.len] = backup;
2464
2465         return 0;
2466 error:
2467         return -1;
2468 }
2469
2470 int pv_set_branch(struct sip_msg* msg, pv_param_t *param,
2471                 int op, pv_value_t *val)
2472 {
2473         if(msg==NULL || param==NULL || val==NULL || (val->flags&PV_VAL_NULL))
2474         {
2475                 LM_ERR("bad parameters\n");
2476                 return -1;
2477         }
2478
2479         if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
2480         {
2481                 LM_ERR("str value required to set the branch\n");
2482                 goto error;
2483         }
2484
2485         if (km_append_branch( msg, &val->rs, 0, 0, Q_UNSPECIFIED, 0,
2486                         msg->force_send_socket)!=1 )
2487         {
2488                 LM_ERR("append_branch action failed\n");
2489                 goto error;
2490         }
2491
2492         return 0;
2493 error:
2494         return -1;
2495 }
2496
2497 int pv_set_force_sock(struct sip_msg* msg, pv_param_t *param,
2498                 int op, pv_value_t *val)
2499 {
2500         struct socket_info *si;
2501         int port, proto;
2502         str host;
2503         char backup;
2504
2505         if(msg==NULL || param==NULL)
2506         {
2507                 LM_ERR("bad parameters\n");
2508                 return -1;
2509         }
2510
2511         if(val==NULL || (val->flags&PV_VAL_NULL))
2512         {
2513                 reset_force_socket(msg);
2514                 return 0;
2515         }
2516
2517         if(!(val->flags&PV_VAL_STR) || val->rs.len<=0)
2518         {
2519                 LM_ERR("str value required to set the force send sock\n");
2520                 goto error;
2521         }
2522
2523         backup = val->rs.s[val->rs.len];
2524         val->rs.s[val->rs.len] = '\0';
2525         if (parse_phostport(val->rs.s, &host.s, &host.len, &port, &proto) < 0)
2526         {
2527                 LM_ERR("invalid socket specification\n");
2528                 val->rs.s[val->rs.len] = backup;
2529                 goto error;
2530         }
2531         val->rs.s[val->rs.len] = backup;
2532         si = grep_sock_info(&host, (unsigned short)port, (unsigned short)proto);
2533         if (si!=NULL)
2534         {
2535                 set_force_socket(msg, si);
2536         } else {
2537                 LM_WARN("no socket found to match [%.*s]\n",
2538                                 val->rs.len, val->rs.s);
2539         }
2540
2541         return 0;
2542 error:
2543         return -1;
2544 }
2545
2546 int pv_set_mflags(struct sip_msg* msg, pv_param_t *param,
2547                 int op, pv_value_t *val)
2548 {
2549         if(msg==NULL || param==NULL)
2550         {
2551                 LM_ERR("bad parameters\n");
2552                 return -1;
2553         }
2554
2555         if(val == NULL || (val->flags&PV_VAL_NULL))
2556         {
2557                 msg->flags = 0;
2558                 return 0;
2559         }
2560
2561         if(!(val->flags&PV_VAL_INT))
2562         {
2563                 LM_ERR("assigning non-int value to msg flags\n");
2564                 return -1;
2565         }
2566
2567         msg->flags = val->ri;
2568
2569         return 0;
2570 }
2571
2572 int pv_set_mflag(struct sip_msg* msg, pv_param_t *param,
2573                 int op, pv_value_t *val)
2574 {
2575         if(msg==NULL || param==NULL)
2576         {
2577                 LM_ERR("bad parameters\n");
2578                 return -1;
2579         }
2580
2581         if(val == NULL || (val->flags&PV_VAL_NULL))
2582         {
2583                 msg->flags = 0;
2584                 return 0;
2585         }
2586
2587         if(!(val->flags&PV_VAL_INT))
2588         {
2589                 LM_ERR("assigning non-int value to msg flag\n");
2590                 return -1;
2591         }
2592
2593         if (param->pvn.type != PV_NAME_INTSTR)
2594         {
2595                 LM_ERR("missing flag number\n");
2596                 return -1;
2597         }
2598
2599         if (val->ri)
2600                 setflag(msg, param->pvn.u.isname.name.n);
2601         else
2602                 resetflag(msg, param->pvn.u.isname.name.n);
2603
2604         return 0;
2605 }
2606
2607 int pv_set_sflags(struct sip_msg* msg, pv_param_t *param,
2608                 int op, pv_value_t *val)
2609 {
2610         if(msg==NULL || param==NULL)
2611         {
2612                 LM_ERR("bad parameters\n");
2613                 return -1;
2614         }
2615
2616         if(val == NULL || (val->flags&PV_VAL_NULL))
2617         {
2618                 setsflagsval(0);
2619                 return 0;
2620         }
2621
2622         if(!(val->flags&PV_VAL_INT))
2623         {
2624                 LM_ERR("assigning non-int value to script flags\n");
2625                 return -1;
2626         }
2627
2628         setsflagsval((unsigned int)val->ri);
2629
2630         return 0;
2631 }
2632
2633 int pv_set_sflag(struct sip_msg* msg, pv_param_t *param,
2634                 int op, pv_value_t *val)
2635 {
2636         if(msg==NULL || param==NULL)
2637         {
2638                 LM_ERR("bad parameters\n");
2639                 return -1;
2640         }
2641
2642         if(val == NULL || (val->flags&PV_VAL_NULL))
2643         {
2644                 setsflagsval(0);
2645                 return 0;
2646         }
2647
2648         if(!(val->flags&PV_VAL_INT))
2649         {
2650                 LM_ERR("assigning non-int value to script flags\n");
2651                 return -1;
2652         }
2653
2654         if (param->pvn.type != PV_NAME_INTSTR)
2655         {
2656                 LM_ERR("missing flag number\n");
2657                 return -1;
2658         }
2659
2660         if (val->ri)
2661                 setsflag(param->pvn.u.isname.name.n);
2662         else
2663                 resetsflag(param->pvn.u.isname.name.n);
2664
2665         return 0;
2666 }
2667
2668
2669 int pv_set_bflags(struct sip_msg* msg, pv_param_t *param,
2670                 int op, pv_value_t *val)
2671 {
2672         if(msg==NULL || param==NULL)
2673         {
2674                 LM_ERR("bad parameters\n");
2675                 return -1;
2676         }
2677
2678         if(val == NULL || (val->flags&PV_VAL_NULL))
2679         {
2680                 setbflagsval(0, 0);
2681                 return 0;
2682         }
2683
2684         if(!(val->flags&PV_VAL_INT))
2685         {
2686                 LM_ERR("assigning non-int value to branch 0 flags\n");
2687                 return -1;
2688         }
2689
2690         setbflagsval(0, (flag_t)val->ri);
2691
2692         return 0;
2693 }
2694
2695 int pv_set_bflag(struct sip_msg* msg, pv_param_t *param,
2696                 int op, pv_value_t *val)
2697 {
2698         if(msg==NULL || param==NULL)
2699         {
2700                 LM_ERR("bad parameters\n");
2701                 return -1;
2702         }
2703
2704         if(val == NULL || (val->flags&PV_VAL_NULL))
2705         {
2706                 setbflagsval(0, 0);
2707                 return 0;
2708         }
2709
2710         if(!(val->flags&PV_VAL_INT))
2711         {
2712                 LM_ERR("assigning non-int value to branch 0 flags\n");
2713                 return -1;
2714         }
2715
2716         if (param->pvn.type != PV_NAME_INTSTR)
2717         {
2718                 LM_ERR("missing flag number\n");
2719                 return -1;
2720         }
2721
2722         if (val->ri)
2723                 setbflag(0, param->pvn.u.isname.name.n);
2724         else
2725                 resetbflag(0, param->pvn.u.isname.name.n);
2726
2727         return 0;
2728 }
2729
2730 int pv_set_xto_attr(struct sip_msg* msg, pv_param_t *param,
2731                 int op, pv_value_t *val, struct to_body *tb, int type)
2732 {
2733         str buf = {0, 0};
2734         struct lump *l = NULL;
2735         int loffset = 0;
2736         int llen = 0;
2737
2738         if(msg==NULL || param==NULL)
2739         {
2740                 LM_ERR("bad parameters\n");
2741                 return -1;
2742         }
2743
2744         switch(type)
2745         {
2746                 case 0: /* uri */
2747                         if(val == NULL || (val->flags&PV_VAL_NULL))
2748                         {
2749                                 LM_WARN("To header URI cannot be deleted\n");
2750                                 return 0;
2751                         }
2752                         if(!(val->flags&PV_VAL_STR))
2753                         {
2754                                 LM_ERR("attempt to assign non-str value to To header URI\n");
2755                                 return -1;
2756                         }
2757
2758                         buf.s = pkg_malloc(val->rs.len);
2759                         if (buf.s==0)
2760                         {
2761                                 LM_ERR("no more pkg mem\n");
2762                                 goto error;
2763                         }
2764                         buf.len = val->rs.len;
2765                         memcpy(buf.s, val->rs.s, val->rs.len);
2766                         loffset = tb->uri.s - msg->buf;
2767                         llen    = tb->uri.len;
2768                 break;
2769                 case 1: /* username */
2770                         if(val == NULL || (val->flags&PV_VAL_NULL))
2771                         {
2772                                 if(tb->parsed_uri.user.len==0)
2773                                         return 0; /* nothing to delete */
2774                                 /* delete username */
2775                                 loffset = tb->parsed_uri.user.s - msg->buf;
2776                                 llen    = tb->parsed_uri.user.len;
2777                                 /* delete '@' after */
2778                                 if(tb->parsed_uri.user.s[tb->parsed_uri.user.len]=='@')
2779                                         llen++;
2780                                 break;
2781                         }
2782                         if(!(val->flags&PV_VAL_STR))
2783                         {
2784                                 LM_ERR("attempt to assign non-str value to To header"
2785                                                 " display name\n");
2786                                 return -1;
2787                         }
2788                         buf.s = pkg_malloc(val->rs.len+1);
2789                         if (buf.s==0)
2790                         {
2791                                 LM_ERR("no more pkg mem\n");
2792                                 goto error;
2793                         }
2794                         buf.len = val->rs.len;
2795                         memcpy(buf.s, val->rs.s, val->rs.len);
2796                         if(tb->parsed_uri.user.len==0)
2797                         {
2798                                 l = anchor_lump(msg, tb->parsed_uri.host.s - msg->buf, 0, 0);
2799                                 buf.s[buf.len] = '@';
2800                                 buf.len++;
2801                         } else {
2802                                 /* delete username */
2803                                 loffset = tb->parsed_uri.user.s - msg->buf;
2804                                 llen    = tb->parsed_uri.user.len;
2805                         }
2806                 break;
2807                 case 2: /* domain */
2808                         if(val == NULL || (val->flags&PV_VAL_NULL))
2809                         {
2810                                 LM_WARN("To header URI domain cannot be deleted\n");
2811                                 return 0;
2812                         }
2813                         if(!(val->flags&PV_VAL_STR))
2814                         {
2815                                 LM_ERR("attempt to assign non-str value to To header"
2816                                                 " URI domain\n");
2817                                 return -1;
2818                         }
2819                         buf.s = pkg_malloc(val->rs.len);
2820                         if (buf.s==0)
2821                         {
2822                                 LM_ERR("no more pkg mem\n");
2823                                 goto error;
2824                         }
2825                         buf.len = val->rs.len;
2826                         memcpy(buf.s, val->rs.s, val->rs.len);
2827                         loffset = tb->parsed_uri.host.s - msg->buf;
2828                         llen    = tb->parsed_uri.host.len;
2829                 break;
2830                 case 3: /* display */
2831                         if(val == NULL || (val->flags&PV_VAL_NULL))
2832                         {
2833                                 if(tb->display.len==0)
2834                                         return 0; /* nothing to delete */
2835                                 /* delete display */
2836                                 loffset = tb->display.s - msg->buf;
2837                                 llen    = tb->display.len;
2838                                 /* delete whitespace after */
2839                                 if(tb->display.s[tb->display.len]==' ')
2840                                         llen++;
2841                                 break;
2842                         }
2843                         if(!(val->flags&PV_VAL_STR))
2844                         {
2845                                 LM_ERR("attempt to assign non-str value to To header"
2846                                                 " display name\n");
2847                                 return -1;
2848                         }
2849                         buf.s = pkg_malloc(val->rs.len+1);
2850                         if (buf.s==0)
2851                         {
2852                                 LM_ERR("no more pkg mem\n");
2853                                 goto error;
2854                         }
2855                         buf.len = val->rs.len;
2856                         memcpy(buf.s, val->rs.s, val->rs.len);
2857                         if(tb->display.len==0)
2858                         {
2859                                 l = anchor_lump(msg, tb->body.s - msg->buf, 0, 0);
2860                                 buf.s[buf.len] = ' ';
2861                                 buf.len++;
2862                         } else {
2863                                 /* delete display */
2864                                 loffset = tb->display.s - msg->buf;
2865                                 llen    = tb->display.len;
2866                         }
2867                 break;
2868         }
2869
2870         /* delete old value */
2871         if(llen>0)
2872         {
2873                 if ((l=del_lump(msg, loffset, llen, 0))==0)
2874                 {
2875                         LM_ERR("failed to delete xto attribute %d\n", type);
2876                         goto error;
2877                 }
2878         }
2879         /* set new value when given */
2880         if(l!=NULL && buf.len>0)
2881         {
2882                 if (insert_new_lump_after(l, buf.s, buf.len, 0)==0)
2883                 {
2884                         LM_ERR("failed to set xto attribute %d\n", type);
2885                         goto error;
2886                 }
2887         } else {
2888                 if(buf.s!=0)
2889                         pkg_free(buf.s);
2890         }
2891         return 0;
2892
2893 error:
2894         if(buf.s!=0)
2895                 pkg_free(buf.s);
2896         return -1;
2897 }
2898
2899 int pv_set_to_attr(struct sip_msg* msg, pv_param_t *param,
2900                 int op, pv_value_t *val, int type)
2901 {
2902         if(msg==NULL)
2903                 return -1;
2904
2905         if(msg->to==NULL && parse_headers(msg, HDR_TO_F, 0)==-1) {
2906                 LM_ERR("cannot parse To header\n");
2907                 return -1;
2908         }
2909         if(msg->to==NULL || get_to(msg)==NULL) {
2910                 LM_DBG("no To header\n");
2911                 return -1;
2912         }
2913         if(parse_to_uri(msg)==NULL) {
2914                 LM_ERR("cannot parse To header URI\n");
2915                 return -1;
2916         }
2917         return pv_set_xto_attr(msg, param, op, val, get_to(msg), type);
2918 }
2919
2920 int pv_set_to_uri(struct sip_msg* msg, pv_param_t *param,
2921                 int op, pv_value_t *val)
2922 {
2923         return pv_set_to_attr(msg, param, op, val, 0);
2924 }
2925
2926 int pv_set_to_username(struct sip_msg* msg, pv_param_t *param,
2927                 int op, pv_value_t *val)
2928 {
2929         return pv_set_to_attr(msg, param, op, val, 1);
2930 }
2931
2932 int pv_set_to_domain(struct sip_msg* msg, pv_param_t *param,
2933                 int op, pv_value_t *val)
2934 {
2935         return pv_set_to_attr(msg, param, op, val, 2);
2936 }
2937
2938 int pv_set_to_display(struct sip_msg* msg, pv_param_t *param,
2939                 int op, pv_value_t *val)
2940 {
2941         return pv_set_to_attr(msg, param, op, val, 3);
2942 }
2943
2944 int pv_set_from_attr(struct sip_msg* msg, pv_param_t *param,
2945                 int op, pv_value_t *val, int type)
2946 {
2947         if(msg==NULL)
2948                 return -1;
2949
2950         if(parse_from_header(msg)<0)
2951         {
2952                 LM_ERR("failed to parse From header\n");
2953                 return -1;
2954         }
2955         if(parse_from_uri(msg)==NULL)
2956         {
2957                 LM_ERR("cannot parse From header URI\n");
2958                 return -1;
2959         }
2960         return pv_set_xto_attr(msg, param, op, val, get_from(msg), type);
2961 }
2962
2963 int pv_set_from_uri(struct sip_msg* msg, pv_param_t *param,
2964                 int op, pv_value_t *val)
2965 {
2966         return pv_set_from_attr(msg, param, op, val, 0);
2967 }
2968
2969 int pv_set_from_username(struct sip_msg* msg, pv_param_t *param,
2970                 int op, pv_value_t *val)
2971 {
2972         return pv_set_from_attr(msg, param, op, val, 1);
2973 }
2974
2975 int pv_set_from_domain(struct sip_msg* msg, pv_param_t *param,
2976                 int op, pv_value_t *val)
2977 {
2978         return pv_set_from_attr(msg, param, op, val, 2);
2979 }
2980
2981 int pv_set_from_display(struct sip_msg* msg, pv_param_t *param,
2982                 int op, pv_value_t *val)
2983 {
2984         return pv_set_from_attr(msg, param, op, val, 3);
2985 }
2986
2987 /********* end PV set functions *********/
2988
2989 int pv_parse_scriptvar_name(pv_spec_p sp, str *in)
2990 {
2991         if(in==NULL || in->s==NULL || sp==NULL)
2992                 return -1;
2993
2994         sp->pvp.pvn.type = PV_NAME_PVAR;
2995         sp->pvp.pvn.u.dname = (void*)add_var(in, VAR_TYPE_ZERO);
2996         if(sp->pvp.pvn.u.dname==NULL)
2997         {
2998                 LM_ERR("cannot register var [%.*s]\n", in->len, in->s);
2999                 return -1;
3000         }
3001         return 0;
3002 }
3003
3004 int pv_parse_scriptvarnull_name(pv_spec_p sp, str *in)
3005 {
3006         if(in==NULL || in->s==NULL || sp==NULL)
3007                 return -1;
3008
3009         sp->pvp.pvn.type = PV_NAME_PVAR;
3010         sp->pvp.pvn.u.dname = (void*)add_var(in, VAR_TYPE_NULL);
3011         if(sp->pvp.pvn.u.dname==NULL)
3012         {
3013                 LM_ERR("cannot register var [%.*s]\n", in->len, in->s);
3014                 return -1;
3015         }
3016         return 0;
3017 }
3018
3019 int pv_parse_hdr_name(pv_spec_p sp, str *in)
3020 {
3021         str s;
3022         char *p;
3023         pv_spec_p nsp = 0;
3024         struct hdr_field hdr;
3025
3026         if(in==NULL || in->s==NULL || sp==NULL)
3027                 return -1;
3028
3029         p = in->s;
3030         if(*p==PV_MARKER)
3031         {
3032                 nsp = (pv_spec_p)pkg_malloc(sizeof(pv_spec_t));
3033                 if(nsp==NULL)
3034                 {
3035                         LM_ERR("no more memory\n");
3036                         return -1;
3037                 }
3038                 p = pv_parse_spec(in, nsp);
3039                 if(p==NULL)
3040                 {
3041                         LM_ERR("invalid name [%.*s]\n", in->len, in->s);
3042                         pv_spec_free(nsp);
3043                         return -1;
3044                 }
3045                 //LM_ERR("dynamic name [%.*s]\n", in->len, in->s);
3046                 //pv_print_spec(nsp);
3047                 sp->pvp.pvn.type = PV_NAME_PVAR;
3048                 sp->pvp.pvn.u.dname = (void*)nsp;
3049                 return 0;
3050         }
3051
3052         if(in->len>=pv_get_buffer_size()-1)
3053         {
3054                 LM_ERR("name too long\n");
3055                 return -1;
3056         }
3057         p = pv_get_buffer();
3058         memcpy(p, in->s, in->len);
3059         p[in->len] = ':';
3060         s.s = p;
3061         s.len = in->len+1;
3062
3063         if (parse_hname2_short(s.s, s.s + s.len, &hdr)==0)
3064         {
3065                 LM_ERR("error parsing header name [%.*s]\n", s.len, s.s);
3066                 goto error;
3067         }
3068         sp->pvp.pvn.type = PV_NAME_INTSTR;
3069         if (hdr.type!=HDR_OTHER_T && hdr.type!=HDR_ERROR_T)
3070         {
3071                 LM_DBG("using hdr type (%d) instead of <%.*s>\n",
3072                         hdr.type, in->len, in->s);
3073                 sp->pvp.pvn.u.isname.type = 0;
3074                 sp->pvp.pvn.u.isname.name.n = hdr.type;
3075         } else {
3076                 sp->pvp.pvn.u.isname.type = AVP_NAME_STR;
3077                 sp->pvp.pvn.u.isname.name.s = *in;
3078         }
3079         return 0;
3080 error:
3081         return -1;
3082 }
3083
3084 int pv_parse_cnt_name(pv_spec_p sp, str *in)
3085 {
3086         pv_spec_t *pv=NULL;
3087
3088         if(in->s==NULL || in->len<=0)
3089                 return -1;
3090
3091         pv = pv_cache_get(in);
3092         if(pv==NULL) {
3093                 LM_ERR("cannot find pv name [%.*s]\n", in->len, in->s);
3094                 return -1;
3095         }
3096
3097         if(pv->type!=PVT_AVP) {
3098                 LM_ERR("expected avp name instead of [%.*s]\n", in->len, in->s);
3099                 return -1;
3100         }
3101
3102         sp->pvp.pvn.u.dname = (void*)pv;
3103         sp->pvp.pvn.type = PV_NAME_PVAR;
3104         return 0;
3105 }
3106
3107
3108 /**
3109  *
3110  */
3111 int pv_parse_K_name(pv_spec_p sp, str *in)
3112 {
3113         if(sp==NULL || in==NULL || in->len<=0)
3114                 return -1;
3115
3116         switch(in->len)
3117         {
3118                 case 3:
3119                         if(strncmp(in->s, "UDP", 3)==0)
3120                                 sp->pvp.pvn.u.isname.name.n = 2;
3121                         else if(strncmp(in->s, "TCP", 3)==0)
3122                                 sp->pvp.pvn.u.isname.name.n = 3;
3123                         else if(strncmp(in->s, "TLS", 3)==0)
3124                                 sp->pvp.pvn.u.isname.name.n = 4;
3125                         else goto error;
3126                 break;
3127                 case 4:
3128                         if(strncmp(in->s, "IPv4", 4)==0)
3129                                 sp->pvp.pvn.u.isname.name.n = 0;
3130                         else if(strncmp(in->s, "IPv6", 4)==0)
3131                                 sp->pvp.pvn.u.isname.name.n = 1;
3132                         else if(strncmp(in->s, "SCTP", 4)==0)
3133                                 sp->pvp.pvn.u.isname.name.n = 5;
3134                         else goto error;
3135                 break;
3136                 default:
3137                         goto error;
3138         }
3139         sp->pvp.pvn.type = PV_NAME_INTSTR;
3140         sp->pvp.pvn.u.isname.type = 0;
3141
3142         return 0;
3143
3144 error:
3145         LM_ERR("unknown PV af key: %.*s\n", in->len, in->s);
3146         return -1;
3147 }
3148
3149 int pv_parse_flag_param(pv_spec_p sp, str *in)
3150 {
3151         int n;
3152
3153         if(sp==NULL || in==NULL || in->len<=0)
3154                 return -1;
3155
3156         if (str2sint(in, &n) != 0)
3157         {
3158                 if ((n = get_flag_no(in->s, in->len)) < 0)
3159                 {
3160                         LM_ERR("flag not declared: [%.*s]\n", in->len, in->s);
3161                         return -1;
3162                 }
3163         } else if (check_flag(n) < 0)
3164         {
3165                 LM_ERR("bad flag value: [%.*s]\n", in->len, in->s);
3166                 return -1;
3167         }
3168
3169         sp->pvp.pvn.u.isname.name.n = n;
3170         sp->pvp.pvn.type = PV_NAME_INTSTR;
3171         sp->pvp.pvn.u.isname.type = 0;
3172
3173         return 0;
3174 }
3175
3176 /**
3177  *
3178  */
3179 int pv_get_K(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
3180 {
3181         if(param==NULL)
3182                 return -1;
3183
3184         switch(param->pvn.u.isname.name.n)
3185         {
3186                 case 1:
3187                         return pv_get_uintval(msg, param, res, AF_INET6);
3188                 case 2:
3189                         return pv_get_uintval(msg, param, res, PROTO_UDP);
3190                 case 3:
3191                         return pv_get_uintval(msg, param, res, PROTO_TCP);
3192                 case 4:
3193                         return pv_get_uintval(msg, param, res, PROTO_TLS);
3194                 case 5:
3195                         return pv_get_uintval(msg, param, res, PROTO_SCTP);
3196                 default:
3197                         return pv_get_uintval(msg, param, res, AF_INET);
3198         }
3199 }
3200
3201 /**
3202  *
3203  */
3204 int pv_parse__s_name(pv_spec_p sp, str *in)
3205 {
3206         pv_elem_t *fmt = NULL;
3207
3208         if(in->s==NULL || in->len<=0)
3209                 return -1;
3210         if(pv_parse_format(in, &fmt)<0 || fmt==NULL)
3211         {
3212                 LM_ERR("wrong format[%.*s]\n", in->len, in->s);
3213                 return -1;
3214         }
3215         sp->pvp.pvn.u.dname = (void*)fmt;
3216         sp->pvp.pvn.type = PV_NAME_OTHER;
3217         return 0;
3218 }
3219
3220 /**
3221  *
3222  */
3223 int pv_get__s(sip_msg_t *msg, pv_param_t *param,
3224                 pv_value_t *res)
3225 {
3226         str sdata = {0};
3227         pv_elem_t *fmt = NULL;
3228         fmt = (pv_elem_t*)param->pvn.u.dname;
3229
3230         if(fmt==NULL)
3231         {
3232                 return pv_get_null(msg, param, res);
3233         }
3234         if(pv_printf_s(msg, fmt, &sdata)!=0)
3235         {
3236                 LM_ERR("cannot evaluate the string\n");
3237                 return -1;
3238         }
3239         return pv_get_strval(msg, param, res, &sdata);
3240 }
3241
3242 /**
3243  *
3244  */
3245 int pv_parse_expires_name(pv_spec_p sp, str *in)
3246 {
3247         if(sp==NULL || in==NULL || in->len<=0)
3248                 return -1;
3249
3250         switch(in->len)
3251         {
3252                 case 3:
3253                         if(strncmp(in->s, "min", 3)==0)
3254                                 sp->pvp.pvn.u.isname.name.n = 0;
3255                         else if(strncmp(in->s, "max", 3)==0)
3256                                 sp->pvp.pvn.u.isname.name.n = 1;
3257                         else goto error;
3258                 break;
3259                 default:
3260                         goto error;
3261         }
3262         sp->pvp.pvn.type = PV_NAME_INTSTR;
3263         sp->pvp.pvn.u.isname.type = 0;
3264
3265         return 0;
3266
3267 error:
3268         LM_ERR("unknown PV expires key: %.*s\n", in->len, in->s);
3269         return -1;
3270 }
3271
3272 /**
3273  *
3274  */
3275 int pv_get_expires(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
3276 {
3277         unsigned int exp_min = 0xffffffff;
3278         unsigned int exp_max = 0;
3279         hdr_field_t* hdr;
3280         contact_t* c;
3281         contact_t* c0;
3282         unsigned int eval = 0;
3283         unsigned int ehdr = 0;
3284         unsigned int efound = 0;
3285
3286         if(param==NULL)
3287                 return -1;
3288
3289         if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
3290                 LM_ERR("failed to parse headers\n");
3291                 return pv_get_null(msg, param, res);
3292         }
3293
3294         if (msg->expires) {
3295                 if(!msg->expires->parsed && (parse_expires(msg->expires) < 0)) {
3296                         LM_ERR("failed to parse hdr expires body\n");
3297                         return pv_get_null(msg, param, res);
3298                 }
3299                 ehdr = ((exp_body_t*)msg->expires->parsed)->val;
3300         }
3301
3302         if (msg->contact) {
3303                 hdr = msg->contact;
3304                 while(hdr) {
3305                         if (hdr->type == HDR_CONTACT_T) {
3306                                 if (!hdr->parsed && (parse_contact(hdr) < 0)) {
3307                                         LM_ERR("failed to parse Contact body\n");
3308                                         return pv_get_null(msg, param, res);
3309                                 }
3310                                 c = ((contact_body_t*)hdr->parsed)->contacts;
3311                                 while(c) {
3312                                         c0 = c->next;
3313                                         if(c->expires && c->expires->body.len) {
3314                                                 if (str2int(&c->expires->body, &eval) < 0) {
3315                                                         LM_ERR("failed to parse expires\n");
3316                                                         return pv_get_null(msg, param, res);
3317                                                 }
3318                                                 efound = 1;
3319                                                 if(eval>exp_max) exp_max = eval;
3320                                                 if(eval<exp_min) exp_min = eval;
3321                                         } else if(msg->expires && msg->expires->parsed) {
3322                                                 eval = ehdr;
3323                                                 efound = 1;
3324                                                 if(eval>exp_max) exp_max = eval;
3325                                                 if(eval<exp_min) exp_min = eval;
3326                                         }
3327                                         c = c0;
3328                                 }
3329                         }
3330                         hdr = hdr->next;
3331                 }
3332         }
3333
3334         if(efound==0 && msg->expires && msg->expires->parsed) {
3335                 eval = ehdr;
3336                 efound = 1;
3337                 if(eval>exp_max) exp_max = eval;
3338                 if(eval<exp_min) exp_min = eval;
3339         }
3340
3341         if(efound==0) {
3342                 return pv_get_null(msg, param, res);
3343         }
3344
3345         switch(param->pvn.u.isname.name.n)
3346         {
3347                 case 0:
3348                         return pv_get_uintval(msg, param, res, exp_min);
3349                 case 1:
3350                         return pv_get_uintval(msg, param, res, exp_max);
3351                 default:
3352                         return pv_get_null(msg, param, res);
3353         }
3354 }
3355
3356 /**
3357  *
3358  */
3359 int pv_parse_msg_attrs_name(pv_spec_p sp, str *in)
3360 {
3361         if(sp==NULL || in==NULL || in->len<=0)
3362                 return -1;
3363
3364         switch(in->len)
3365         {
3366                 case 3:
3367                         if(strncmp(in->s, "len", 3)==0)
3368                                 sp->pvp.pvn.u.isname.name.n = 0;
3369                         else if(strncmp(in->s, "buf", 3)==0)
3370                                 sp->pvp.pvn.u.isname.name.n = 1;
3371                         else goto error;
3372                 break;
3373                 case 4:
3374                         if(strncmp(in->s, "body", 4)==0)
3375                                 sp->pvp.pvn.u.isname.name.n = 2;
3376                         else if(strncmp(in->s, "hdrs", 4)==0)
3377                                 sp->pvp.pvn.u.isname.name.n = 3;
3378                         else goto error;
3379                 break;
3380                 case 5:
3381                         if(strncmp(in->s, "fline", 5)==0)
3382                                 sp->pvp.pvn.u.isname.name.n = 4;
3383                         else goto error;
3384                 break;
3385                 case 8:
3386                         if(strncmp(in->s, "body_len", 8)==0)
3387                                 sp->pvp.pvn.u.isname.name.n = 5;
3388                         else goto error;
3389                 break;
3390                 default:
3391                         goto error;
3392         }
3393         sp->pvp.pvn.type = PV_NAME_INTSTR;
3394         sp->pvp.pvn.u.isname.type = 0;
3395
3396         return 0;
3397
3398 error:
3399         LM_ERR("unknown PV expires key: %.*s\n", in->len, in->s);
3400         return -1;
3401 }
3402
3403 /**
3404  *
3405  */
3406 int pv_get_msg_attrs(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
3407 {
3408         str s;
3409         if(msg==NULL)
3410                 return pv_get_null(msg, param, res);
3411
3412         if(param==NULL)
3413                 return pv_get_null(msg, param, res);
3414
3415         if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
3416                 LM_ERR("failed to parse headers\n");
3417                 return pv_get_null(msg, param, res);
3418         }
3419
3420         switch(param->pvn.u.isname.name.n)
3421         {
3422                 case 0: /* length */
3423                         return pv_get_uintval(msg, param, res, msg->len);
3424                 case 1: /* buffer */
3425                         s.s = msg->buf;
3426                         s.len = msg->len;
3427                         return pv_get_strval(msg, param, res, &s);
3428                 case 2: /* body */
3429                         s.s = get_body(msg);
3430                         if(s.s == NULL) {
3431                                 LM_DBG("no message body\n");
3432                                 return pv_get_null(msg, param, res);
3433                         }
3434                         s.len = msg->buf + msg->len - s.s;
3435                         return pv_get_strval(msg, param, res, &s);
3436                 case 3: /* headers */
3437                         if(msg->unparsed==NULL)
3438                                 return pv_get_null(msg, param, res);
3439                         s.s = msg->buf + msg->first_line.len;
3440                         s.len = msg->unparsed - s.s;
3441                         trim(&s);
3442                         return pv_get_strval(msg, param, res, &s);
3443                 case 4: /* first line */
3444                         s.s = msg->buf;
3445                         s.len = msg->first_line.len;
3446                         trim(&s);
3447                         return pv_get_strval(msg, param, res, &s);
3448                 case 5: /* body size */
3449                         s.s = get_body( msg );
3450                         s.len = 0;
3451                         if (s.s != NULL)
3452                                 s.len = msg->buf + msg->len - s.s;
3453                         return pv_get_sintval(msg, param, res, s.len);
3454
3455                 default:
3456                         return pv_get_null(msg, param, res);
3457         }
3458 }
3459
3460 int pv_parse_env_name(pv_spec_p sp, str *in)
3461 {
3462         char *csname;
3463
3464         if(in->s==NULL || in->len<=0)
3465                 return -1;
3466
3467         csname = pkg_malloc(in->len + 1);
3468
3469         if (csname == NULL) {
3470                 LM_ERR("no more pkg memory");
3471                 return -1;
3472         }
3473
3474         memcpy(csname, in->s, in->len);
3475         csname[in->len] = '\0';
3476
3477         sp->pvp.pvn.u.dname = (void*)csname;
3478         sp->pvp.pvn.type = PV_NAME_OTHER;
3479         return 0;
3480 }
3481
3482 int pv_get_env(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
3483 {
3484         char *val;
3485         char *csname = (char *) param->pvn.u.dname;
3486
3487         if (csname) {
3488                 val = getenv(csname);
3489
3490                 if (val) {
3491                         return pv_get_strzval(msg, param, res, val);
3492                 }
3493         }
3494         return pv_get_null(msg, param, res);
3495 }
3496