Coverage Report

Created: 2026-10-17 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensips/parser/msg_parser.c
Line
Count
Source
1
/*
2
 * sip msg. header proxy parser
3
 *
4
 * Copyright (C) 2001-2003 FhG Fokus
5
 *
6
 * This file is part of opensips, a free SIP server.
7
 *
8
 * opensips 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
 * opensips 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
 * History:
23
 * ---------
24
 *  2003-02-28  scratchpad compatibility abandoned (jiri)
25
 *  2003-01-29  scrathcpad removed (jiri)
26
 *  2003-01-27  next baby-step to removing ZT - PRESERVE_ZT (jiri)
27
 *  2003-03-31  removed msg->repl_add_rm (andrei)
28
 *  2003-04-26 ZSW (jiri)
29
 *  2003-05-01  parser extended to support Accept header field (janakj)
30
 *  2005-03-02  free_via_list(vb) on via parse error (andrei)
31
 *  2006-02-17 Session-Expires, Min-SE (dhsueh@somanetworks.com)
32
 *  2006-03-02 header of same type are linked as sibling (bogdan)
33
 *  2006-11-28 Added statistic support for bad message headers.
34
 *             (Jeffrey Magder - SOMA Networks)
35
 *  2008-09-09 Added sdp parsing support (osas)
36
 */
37
38
39
#include <string.h>
40
#include <stdlib.h>
41
42
#include "msg_parser.h"
43
#include "parser_f.h"
44
#include "../ut.h"
45
#include "../error.h"
46
#include "../dprint.h"
47
#include "../data_lump.h"
48
#include "../data_lump_rpl.h"
49
#include "../mem/mem.h"
50
#include "../error.h"
51
#include "../globals.h"
52
#include "../core_stats.h"
53
#include "../errinfo.h"
54
#include "../dset.h"
55
#include "../sdp_ops.h"
56
#include "parse_hname2.h"
57
#include "parse_uri.h"
58
#include "parse_content.h"
59
#include "../msg_callbacks.h"
60
61
#ifdef DEBUG_DMALLOC
62
#include <mem/dmalloc.h>
63
#endif
64
65
66
0
#define parse_hname(_b,_e,_h) parse_hname2((_b),(_e),(_h))
67
68
/* number of via's encountered */
69
int via_cnt;
70
71
/* returns pointer to next header line, and fill hdr_f ;
72
 * if at end of header returns pointer to the last crlf  (always buf)*/
73
char* get_hdr_field_aux(char* buf, char* end, struct hdr_field* hdr,int sip_well_known_parse)
74
0
{
75
76
0
  char* tmp;
77
0
  char *match;
78
0
  struct via_body *vb;
79
0
  struct cseq_body* cseq_b;
80
0
  struct to_body* to_b;
81
0
  int integer;
82
83
0
  if ((*buf)=='\n' || (*buf)=='\r'){
84
    /* double crlf or lflf or crcr */
85
0
    LM_DBG("found end of header\n");
86
0
    hdr->type=HDR_EOH_T;
87
0
    return buf;
88
0
  }
89
90
0
  tmp=parse_hname(buf, end, hdr);
91
0
  if (hdr->type==HDR_ERROR_T){
92
0
    LM_ERR("bad header\n");
93
0
    goto error_bad_hdr;
94
0
  }
95
96
  /* eliminate leading whitespace */
97
0
  tmp=eat_lws_end(tmp, end);
98
0
  if (tmp>=end) {
99
0
    LM_ERR("hf empty\n");
100
0
    goto error_bad_hdr;
101
0
  }
102
103
  /* if header-field well-known, parse it, find its end otherwise ;
104
   * after leaving the hdr->type switch, tmp should be set to the
105
   * next header field
106
   */
107
0
  switch(hdr->type){
108
0
    case HDR_VIA_T:
109
      /* keep number of vias parsed -- we want to report it in
110
         replies for diagnostic purposes */
111
0
      if (sip_well_known_parse)
112
0
        via_cnt++;
113
0
      if (sip_well_known_parse) {
114
0
        vb=pkg_malloc(sizeof(struct via_body));
115
0
        if (vb==0){
116
0
          LM_ERR("out of pkg memory\n");
117
0
          goto error;
118
0
        }
119
0
        memset(vb,0,sizeof(struct via_body));
120
0
        hdr->body.s=tmp;
121
0
        tmp=parse_via(tmp, end, vb);
122
0
        if (vb->error==PARSE_ERROR){
123
0
          LM_ERR("bad via\n");
124
0
          free_via_list(vb);
125
0
          set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
126
0
            "error parsing Via");
127
0
          set_err_reply(400, "bad Via header");
128
0
          goto error;
129
0
        }
130
0
        hdr->parsed=vb;
131
0
        vb->hdr.s=hdr->name.s;
132
0
        vb->hdr.len=hdr->name.len;
133
0
        hdr->body.len=tmp-hdr->body.s;
134
0
      } else {
135
        /* just skip over it */
136
0
        hdr->body.s=tmp;
137
        /* find end of header */
138
        /* find lf */
139
0
        do{
140
0
          match=q_memchr(tmp, '\n', end-tmp);
141
0
          if (match){
142
0
            match++;
143
0
          }else {
144
0
            LM_ERR("bad body for <%.*s>(%d)\n",
145
0
               hdr->name.len, hdr->name.s, hdr->type);
146
0
            tmp=end;
147
0
            goto error_bad_hdr;
148
0
          }
149
0
          tmp=match;
150
0
        }while( match<end &&( (*match==' ')||(*match=='\t') ) );
151
0
        tmp=match;
152
0
        hdr->body.len=match-hdr->body.s;
153
0
      }
154
0
      break;
155
0
    case HDR_CSEQ_T:
156
0
      if (sip_well_known_parse) {
157
0
        cseq_b=pkg_malloc(sizeof(struct cseq_body));
158
0
        if (cseq_b==0){
159
0
          LM_ERR("out of pkg memory\n");
160
0
          goto error;
161
0
        }
162
0
        memset(cseq_b, 0, sizeof(struct cseq_body));
163
0
        hdr->body.s=tmp;
164
0
        tmp=parse_cseq(tmp, end, cseq_b);
165
0
        if (cseq_b->error==PARSE_ERROR){
166
0
          LM_ERR("bad cseq\n");
167
0
          pkg_free(cseq_b);
168
0
          set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
169
0
            "error parsing CSeq`");
170
0
          set_err_reply(400, "bad CSeq header");
171
0
          goto error;
172
0
        }
173
0
        hdr->parsed=cseq_b;
174
0
        hdr->body.len=tmp-hdr->body.s;
175
0
        LM_DBG("cseq <%.*s>: <%.*s> <%.*s>\n",
176
0
            hdr->name.len, ZSW(hdr->name.s),
177
0
            cseq_b->number.len, ZSW(cseq_b->number.s),
178
0
            cseq_b->method.len, cseq_b->method.s);
179
0
      } else {
180
        /* just skip over it */
181
0
        hdr->body.s=tmp;
182
        /* find end of header */
183
        /* find lf */
184
0
        do{
185
0
          match=q_memchr(tmp, '\n', end-tmp);
186
0
          if (match){
187
0
            match++;
188
0
          }else {
189
0
            LM_ERR("bad body for <%.*s>(%d)\n",
190
0
               hdr->name.len, hdr->name.s, hdr->type);
191
0
            tmp=end;
192
0
            goto error_bad_hdr;
193
0
          }
194
0
          tmp=match;
195
0
        }while( match<end &&( (*match==' ')||(*match=='\t') ) );
196
0
        tmp=match;
197
0
        hdr->body.len=match-hdr->body.s;
198
0
      }
199
0
      break;
200
0
    case HDR_TO_T:
201
0
      if (sip_well_known_parse) {
202
0
        to_b=pkg_malloc(sizeof(struct to_body));
203
0
        if (to_b==0){
204
0
          LM_ERR("out of pkg memory\n");
205
0
          goto error;
206
0
        }
207
0
        memset(to_b, 0, sizeof(struct to_body));
208
0
        hdr->body.s=tmp;
209
0
        tmp=parse_to(tmp, end,to_b);
210
0
        if (to_b->error==PARSE_ERROR){
211
0
          LM_ERR("bad to header\n");
212
0
          pkg_free(to_b);
213
0
          set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
214
0
            "error parsing To header");
215
0
          set_err_reply(400, "bad header");
216
0
          goto error;
217
0
        }
218
0
        hdr->parsed=to_b;
219
0
        hdr->body.len=tmp-hdr->body.s;
220
0
        LM_DBG("<%.*s> [%d]; uri=[%.*s] \n",
221
0
          hdr->name.len, ZSW(hdr->name.s),
222
0
          hdr->body.len, to_b->uri.len,ZSW(to_b->uri.s));
223
0
        LM_DBG("to body [%.*s]\n",to_b->body.len, ZSW(to_b->body.s));
224
0
      } else {
225
        /* just skip over it */
226
0
        hdr->body.s=tmp;
227
        /* find end of header */
228
        /* find lf */
229
0
        do{
230
0
          match=q_memchr(tmp, '\n', end-tmp);
231
0
          if (match){
232
0
            match++;
233
0
          }else {
234
0
            LM_ERR("bad body for <%.*s>(%d)\n",
235
0
               hdr->name.len, hdr->name.s, hdr->type);
236
0
            tmp=end;
237
0
            goto error_bad_hdr;
238
0
          }
239
0
          tmp=match;
240
0
        }while( match<end &&( (*match==' ')||(*match=='\t') ) );
241
0
        tmp=match;
242
0
        hdr->body.len=match-hdr->body.s;
243
0
      }
244
0
      break;
245
0
    case HDR_CONTENTLENGTH_T:
246
0
      if (sip_well_known_parse) {
247
0
        hdr->body.s=tmp;
248
0
        tmp=parse_content_length(tmp,end, &integer);
249
0
        if (tmp==0){
250
0
          LM_ERR("bad content_length header\n");
251
0
          set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
252
0
            "error parsing Content-Length");
253
0
          set_err_reply(400, "bad Content-Length header");
254
0
          goto error;
255
0
        }
256
0
        hdr->parsed=(void*)(long)integer;
257
0
        hdr->body.len=tmp-hdr->body.s;
258
0
        LM_DBG("content_length=%d\n", (int)(long)hdr->parsed);
259
0
      } else {
260
        /* just skip over it */
261
0
        hdr->body.s=tmp;
262
        /* find end of header */
263
        /* find lf */
264
0
        do{
265
0
          match=q_memchr(tmp, '\n', end-tmp);
266
0
          if (match){
267
0
            match++;
268
0
          }else {
269
0
            LM_ERR("bad body for <%.*s>(%d)\n",
270
0
               hdr->name.len, hdr->name.s, hdr->type);
271
0
            tmp=end;
272
0
            goto error_bad_hdr;
273
0
          }
274
0
          tmp=match;
275
0
        }while( match<end &&( (*match==' ')||(*match=='\t') ) );
276
0
        tmp=match;
277
0
        hdr->body.len=match-hdr->body.s;
278
0
      }
279
0
      break;
280
0
    case HDR_SUPPORTED_T:
281
0
    case HDR_CONTENTTYPE_T:
282
0
    case HDR_FROM_T:
283
0
    case HDR_CALLID_T:
284
0
    case HDR_CONTACT_T:
285
0
    case HDR_ROUTE_T:
286
0
    case HDR_RECORDROUTE_T:
287
0
    case HDR_PATH_T:
288
0
    case HDR_MAXFORWARDS_T:
289
0
    case HDR_AUTHORIZATION_T:
290
0
    case HDR_EXPIRES_T:
291
0
    case HDR_PROXYAUTH_T:
292
0
    case HDR_PROXYREQUIRE_T:
293
0
    case HDR_UNSUPPORTED_T:
294
0
    case HDR_ALLOW_T:
295
0
    case HDR_EVENT_T:
296
0
    case HDR_ACCEPT_T:
297
0
    case HDR_ACCEPTLANGUAGE_T:
298
0
    case HDR_ORGANIZATION_T:
299
0
    case HDR_PRIORITY_T:
300
0
    case HDR_SUBJECT_T:
301
0
    case HDR_USERAGENT_T:
302
0
    case HDR_CONTENTDISPOSITION_T:
303
0
    case HDR_ACCEPTDISPOSITION_T:
304
0
    case HDR_DIVERSION_T:
305
0
    case HDR_RPID_T:
306
0
    case HDR_REFER_TO_T:
307
0
    case HDR_SESSION_EXPIRES_T:
308
0
    case HDR_MIN_SE_T:
309
0
    case HDR_MIN_EXPIRES_T:
310
0
    case HDR_PPI_T:
311
0
    case HDR_PAI_T:
312
0
    case HDR_PRIVACY_T:
313
0
    case HDR_RETRY_AFTER_T:
314
0
    case HDR_CALL_INFO_T:
315
0
    case HDR_WWW_AUTHENTICATE_T:
316
0
    case HDR_PROXY_AUTHENTICATE_T:
317
0
    case HDR_FEATURE_CAPS_T:
318
0
    case HDR_REPLACES_T:
319
0
    case HDR_TO_PATH_T:
320
0
    case HDR_FROM_PATH_T:
321
0
    case HDR_MESSAGE_ID_T:
322
0
    case HDR_BYTE_RANGE_T:
323
0
    case HDR_FAILURE_REPORT_T:
324
0
    case HDR_SUCCESS_REPORT_T:
325
0
    case HDR_STATUS_T:
326
0
    case HDR_USE_PATH_T:
327
0
    case HDR_SECURITY_CLIENT_T:
328
0
    case HDR_SECURITY_SERVER_T:
329
0
    case HDR_SECURITY_VERIFY_T:
330
0
    case HDR_OTHER_T:
331
      /* just skip over it */
332
0
      hdr->body.s=tmp;
333
      /* find end of header */
334
      /* find lf */
335
0
      do{
336
0
        match=q_memchr(tmp, '\n', end-tmp);
337
0
        if (match){
338
0
          match++;
339
0
        }else {
340
0
          LM_ERR("bad body for <%.*s>(%d)\n",
341
0
                   hdr->name.len, hdr->name.s, hdr->type);
342
0
          tmp=end;
343
0
          goto error_bad_hdr;
344
0
        }
345
0
        tmp=match;
346
0
      }while( match<end &&( (*match==' ')||(*match=='\t') ) );
347
0
      tmp=match;
348
0
      hdr->body.len=match-hdr->body.s;
349
0
      break;
350
0
    default:
351
0
      LM_CRIT("unknown header type %d\n", hdr->type);
352
0
      goto error;
353
0
  }
354
  /* jku: if \r covered by current length, shrink it */
355
0
  trim_r( hdr->body );
356
0
  hdr->len=tmp-hdr->name.s;
357
0
  return tmp;
358
359
0
error_bad_hdr:
360
0
  if (sip_well_known_parse) {
361
0
    set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
362
0
      "error parsing headers");
363
0
    set_err_reply(400, "bad headers");
364
0
  }
365
0
error:
366
0
  LM_DBG("error exit\n");
367
0
  if (sip_well_known_parse)
368
0
    update_stat(bad_msg_hdr, 1);
369
0
  hdr->type=HDR_ERROR_T;
370
0
  hdr->len=tmp-hdr->name.s;
371
0
  return tmp;
372
0
}
373
374
/* parse the headers and adds them to msg->headers and msg->to, from etc.
375
 * It stops when all the headers requested in flags were parsed, on error
376
 * (bad header) or end of headers */
377
/* note: it continues where it previously stopped and goes ahead until
378
   end is encountered or desired HFs are found; if you call it twice
379
   for the same HF which is present only once, it will fail the second
380
   time; if you call it twice and the HF is found on second time too,
381
   it's not replaced in the well-known HF pointer but just added to
382
   header list; if you want to use a dumb convenience function which will
383
   give you the first occurrence of a header you are interested in,
384
   look at check_transaction_quadruple
385
*/
386
int parse_headers(struct sip_msg *msg, hdr_flags_t flags, int next)
387
0
{
388
0
  struct hdr_field *hf;
389
0
  char* tmp;
390
0
  char* rest;
391
0
  char* end;
392
0
  hdr_flags_t orig_flag;
393
394
0
#define link_sibling_hdr(_hook, _hdr) _add_last(_hdr, msg->_hook, sibling)
395
396
0
  end=msg->buf+msg->len;
397
0
  tmp=msg->unparsed;
398
399
0
  if (next) {
400
0
    orig_flag = msg->parsed_flag;
401
0
    msg->parsed_flag &= ~flags;
402
0
  }else
403
0
    orig_flag=0;
404
405
0
  LM_DBG("flags=%llx\n", (unsigned long long)flags);
406
0
  while( tmp<end && (flags & msg->parsed_flag) != flags){
407
0
    hf=pkg_malloc(sizeof(struct hdr_field));
408
0
    if (hf==0){
409
0
      ser_error=E_OUT_OF_MEM;
410
0
      LM_ERR("pkg memory allocation failed\n");
411
0
      goto error;
412
0
    }
413
0
    memset(hf,0, sizeof(struct hdr_field));
414
0
    hf->type=HDR_ERROR_T;
415
0
    rest=get_hdr_field_aux(tmp, msg->buf+msg->len, hf, 1);
416
0
    switch (hf->type){
417
0
      case HDR_ERROR_T:
418
0
        LM_INFO("bad header field\n");
419
0
        goto  error;
420
0
      case HDR_EOH_T:
421
0
        msg->eoh=tmp; /* or rest?*/
422
0
        msg->parsed_flag|=HDR_EOH_F;
423
0
        pkg_free(hf);
424
0
        goto skip;
425
0
      case HDR_OTHER_T: /*do nothing*/
426
0
      case HDR_TO_PATH_T:
427
0
      case HDR_FROM_PATH_T:
428
0
      case HDR_MESSAGE_ID_T:
429
0
      case HDR_BYTE_RANGE_T:
430
0
      case HDR_FAILURE_REPORT_T:
431
0
      case HDR_SUCCESS_REPORT_T:
432
0
      case HDR_STATUS_T:
433
0
      case HDR_USE_PATH_T:
434
0
        break;
435
0
      case HDR_CALLID_T:
436
0
        if (msg->callid==0) msg->callid=hf;
437
0
        msg->parsed_flag|=HDR_CALLID_F;
438
0
        break;
439
0
      case HDR_TO_T:
440
0
        if (msg->to==0) msg->to=hf;
441
0
        msg->parsed_flag|=HDR_TO_F;
442
0
        break;
443
0
      case HDR_CSEQ_T:
444
0
        if (msg->cseq==0) msg->cseq=hf;
445
0
        msg->parsed_flag|=HDR_CSEQ_F;
446
0
        break;
447
0
      case HDR_FROM_T:
448
0
        if (msg->from==0) msg->from=hf;
449
0
        msg->parsed_flag|=HDR_FROM_F;
450
0
        break;
451
0
      case HDR_CONTACT_T:
452
0
        link_sibling_hdr(contact,hf);
453
0
        msg->parsed_flag|=HDR_CONTACT_F;
454
0
        break;
455
0
      case HDR_MAXFORWARDS_T:
456
0
        if(msg->maxforwards==0) msg->maxforwards=hf;
457
0
        msg->parsed_flag|=HDR_MAXFORWARDS_F;
458
0
        break;
459
0
      case HDR_ROUTE_T:
460
0
        link_sibling_hdr(route,hf);
461
0
        msg->parsed_flag|=HDR_ROUTE_F;
462
0
        break;
463
0
      case HDR_RECORDROUTE_T:
464
0
        link_sibling_hdr(record_route,hf);
465
0
        msg->parsed_flag|=HDR_RECORDROUTE_F;
466
0
        break;
467
0
      case HDR_PATH_T:
468
0
        link_sibling_hdr(path,hf);
469
0
        msg->parsed_flag|=HDR_PATH_F;
470
0
        break;
471
0
      case HDR_CONTENTTYPE_T:
472
0
        if (msg->content_type==0) msg->content_type = hf;
473
0
        msg->parsed_flag|=HDR_CONTENTTYPE_F;
474
0
        break;
475
0
      case HDR_CONTENTLENGTH_T:
476
0
        if (msg->content_length==0) msg->content_length = hf;
477
0
        msg->parsed_flag|=HDR_CONTENTLENGTH_F;
478
0
        break;
479
0
      case HDR_AUTHORIZATION_T:
480
0
        link_sibling_hdr(authorization,hf);
481
0
        msg->parsed_flag|=HDR_AUTHORIZATION_F;
482
0
        break;
483
0
      case HDR_EXPIRES_T:
484
0
        if (msg->expires==0) msg->expires = hf;
485
0
        msg->parsed_flag|=HDR_EXPIRES_F;
486
0
        break;
487
0
      case HDR_PROXYAUTH_T:
488
0
        link_sibling_hdr(proxy_auth,hf);
489
0
        msg->parsed_flag|=HDR_PROXYAUTH_F;
490
0
        break;
491
0
      case HDR_PROXYREQUIRE_T:
492
0
        link_sibling_hdr(proxy_require,hf);
493
0
        msg->parsed_flag|=HDR_PROXYREQUIRE_F;
494
0
        break;
495
0
      case HDR_SUPPORTED_T:
496
0
        link_sibling_hdr(supported,hf);
497
0
        msg->parsed_flag|=HDR_SUPPORTED_F;
498
0
        break;
499
0
      case HDR_UNSUPPORTED_T:
500
0
        link_sibling_hdr(unsupported,hf);
501
0
        msg->parsed_flag|=HDR_UNSUPPORTED_F;
502
0
        break;
503
0
      case HDR_ALLOW_T:
504
0
        link_sibling_hdr(allow,hf);
505
0
        msg->parsed_flag|=HDR_ALLOW_F;
506
0
        break;
507
0
      case HDR_EVENT_T:
508
0
        link_sibling_hdr(event,hf);
509
0
        msg->parsed_flag|=HDR_EVENT_F;
510
0
        break;
511
0
      case HDR_ACCEPT_T:
512
0
        link_sibling_hdr(accept,hf);
513
0
        msg->parsed_flag|=HDR_ACCEPT_F;
514
0
        break;
515
0
      case HDR_ACCEPTLANGUAGE_T:
516
0
        link_sibling_hdr(accept_language,hf);
517
0
        msg->parsed_flag|=HDR_ACCEPTLANGUAGE_F;
518
0
        break;
519
0
      case HDR_ORGANIZATION_T:
520
0
        if (msg->organization==0) msg->organization = hf;
521
0
        msg->parsed_flag|=HDR_ORGANIZATION_F;
522
0
        break;
523
0
      case HDR_PRIORITY_T:
524
0
        if (msg->priority==0) msg->priority = hf;
525
0
        msg->parsed_flag|=HDR_PRIORITY_F;
526
0
        break;
527
0
      case HDR_SUBJECT_T:
528
0
        if (msg->subject==0) msg->subject = hf;
529
0
        msg->parsed_flag|=HDR_SUBJECT_F;
530
0
        break;
531
0
      case HDR_USERAGENT_T:
532
0
        if (msg->user_agent==0) msg->user_agent = hf;
533
0
        msg->parsed_flag|=HDR_USERAGENT_F;
534
0
        break;
535
0
      case HDR_CONTENTDISPOSITION_T:
536
0
        if (msg->content_disposition==0) msg->content_disposition = hf;
537
0
        msg->parsed_flag|=HDR_CONTENTDISPOSITION_F;
538
0
        break;
539
0
      case HDR_ACCEPTDISPOSITION_T:
540
0
        link_sibling_hdr(accept_disposition,hf);
541
0
        msg->parsed_flag|=HDR_ACCEPTDISPOSITION_F;
542
0
        break;
543
0
      case HDR_DIVERSION_T:
544
0
        link_sibling_hdr(diversion,hf);
545
0
        msg->parsed_flag|=HDR_DIVERSION_F;
546
0
        break;
547
0
      case HDR_RPID_T:
548
0
        if (msg->rpid==0) msg->rpid = hf;
549
0
        msg->parsed_flag|=HDR_RPID_F;
550
0
        break;
551
0
      case HDR_CALL_INFO_T:
552
0
        link_sibling_hdr(call_info,hf);
553
0
        msg->parsed_flag|=HDR_CALL_INFO_F;
554
0
        break;
555
0
      case HDR_WWW_AUTHENTICATE_T:
556
0
        link_sibling_hdr(www_authenticate,hf);
557
0
        msg->parsed_flag|=HDR_WWW_AUTHENTICATE_F;
558
0
        break;
559
0
      case HDR_PROXY_AUTHENTICATE_T:
560
0
        link_sibling_hdr(proxy_authenticate,hf);
561
0
        msg->parsed_flag|=HDR_PROXY_AUTHENTICATE_F;
562
0
        break;
563
0
      case HDR_REFER_TO_T:
564
0
        if (msg->refer_to==0) msg->refer_to = hf;
565
0
        msg->parsed_flag|=HDR_REFER_TO_F;
566
0
        break;
567
0
      case HDR_SESSION_EXPIRES_T:
568
0
        if ( msg->session_expires == 0 ) msg->session_expires = hf;
569
0
        msg->parsed_flag |= HDR_SESSION_EXPIRES_F;
570
0
        break;
571
0
      case HDR_MIN_SE_T:
572
0
        if ( msg->min_se == 0 ) msg->min_se = hf;
573
0
        msg->parsed_flag |= HDR_MIN_SE_F;
574
0
        break;
575
0
      case HDR_MIN_EXPIRES_T:
576
0
        if ( msg->min_expires == 0 ) msg->min_expires = hf;
577
0
        msg->parsed_flag |= HDR_MIN_EXPIRES_F;
578
0
        break;
579
0
      case HDR_PPI_T:
580
0
        link_sibling_hdr(ppi,hf);
581
0
        msg->parsed_flag|=HDR_PPI_F;
582
0
        break;
583
0
      case HDR_PAI_T:
584
0
        link_sibling_hdr(pai,hf);
585
0
        msg->parsed_flag|=HDR_PAI_F;
586
0
        break;
587
0
      case HDR_PRIVACY_T:
588
0
        if (msg->privacy==0) msg->privacy = hf;
589
0
        msg->parsed_flag|=HDR_PRIVACY_F;
590
0
        break;
591
0
      case HDR_RETRY_AFTER_T:
592
0
        break;
593
0
      case HDR_VIA_T:
594
0
        link_sibling_hdr(h_via1,hf);
595
0
        msg->parsed_flag|=HDR_VIA_F;
596
0
        LM_DBG("via found, flags=%llx\n", (unsigned long long)flags);
597
0
        if (msg->via1==0) {
598
0
          LM_DBG("this is the first via\n");
599
0
          msg->h_via1=hf;
600
0
          msg->via1=hf->parsed;
601
0
          if (msg->via1->next){
602
0
            msg->via2=msg->via1->next;
603
0
            msg->parsed_flag|=HDR_VIA2_F;
604
0
          }
605
0
        } else
606
0
          if (msg->via2==0) {
607
0
            msg->via2=hf->parsed;
608
0
            msg->parsed_flag|=HDR_VIA2_F;
609
0
          }
610
0
        break;
611
0
      case HDR_FEATURE_CAPS_T:
612
0
        link_sibling_hdr(feature_caps, hf);
613
0
        msg->parsed_flag |= HDR_FEATURE_CAPS_F;
614
0
        break;
615
0
      case HDR_REPLACES_T:
616
0
        link_sibling_hdr(replaces, hf);
617
0
        msg->parsed_flag |= HDR_REPLACES_F;
618
0
        break;
619
0
      case HDR_SECURITY_CLIENT_T:
620
0
        link_sibling_hdr(security_client, hf);
621
0
        msg->parsed_flag |= HDR_SECURITY_CLIENT_F;
622
0
        break;
623
0
      case HDR_SECURITY_SERVER_T:
624
0
        link_sibling_hdr(security_server, hf);
625
0
        msg->parsed_flag |= HDR_SECURITY_SERVER_F;
626
0
        break;
627
0
      case HDR_SECURITY_VERIFY_T:
628
0
        link_sibling_hdr(security_verify, hf);
629
0
        msg->parsed_flag |= HDR_SECURITY_VERIFY_F;
630
0
        break;
631
0
      default:
632
0
        LM_CRIT("unknown header type %d\n",  hf->type);
633
0
        goto error;
634
0
    }
635
    /* add the header to the list*/
636
0
    if (msg->last_header==0){
637
0
      msg->headers=hf;
638
0
      msg->last_header=hf;
639
0
    }else{
640
0
      msg->last_header->next=hf;
641
0
      msg->last_header=hf;
642
0
    }
643
#ifdef EXTRA_DEBUG
644
    LM_DBG("header field type %d, name=<%.*s>, body=<%.*s>\n",
645
      hf->type,
646
      hf->name.len, ZSW(hf->name.s),
647
      hf->body.len, ZSW(hf->body.s));
648
#endif
649
0
    tmp=rest;
650
0
  }
651
0
skip:
652
0
  msg->unparsed=tmp;
653
0
  return 0;
654
655
0
error:
656
0
  ser_error=E_BAD_REQ;
657
0
  if (hf) pkg_free(hf);
658
0
  if (next) msg->parsed_flag |= orig_flag;
659
0
  return -1;
660
0
}
661
662
/* clones the headers list from the `from` sip_msg
663
 * into the `to` sip_msg structure */
664
int clone_headers(struct sip_msg *from_msg, struct sip_msg *to_msg)
665
0
{
666
0
  int hdrs_no, i;
667
0
  struct hdr_field *hdrs;
668
0
  struct hdr_field *hdr;
669
670
0
#define link_sibling_hdr_case(_hook, _hdr_type) \
671
0
  case _hdr_type: \
672
0
    _add_last(&hdrs[i], to_msg->_hook, sibling);\
673
0
    break
674
0
#define link_hdr_case(_hook, _hdr_type) \
675
0
  case _hdr_type: \
676
0
    to_msg->_hook=&hdrs[i];\
677
0
    break
678
679
   /*
680
   * we need to duplicate the headers because the hdr->parsed field resides
681
   * in shm memory, so there might be a different process that access the
682
   * parsed field and find the structure parsed by the current process in
683
   * pkg
684
   */
685
0
  for (hdrs_no = 0, hdr = from_msg->headers; hdr; hdr = hdr->next)
686
0
    hdrs_no++;
687
688
0
  hdrs = pkg_malloc(hdrs_no * sizeof(struct hdr_field));
689
0
  if (!hdrs) {
690
0
    LM_ERR("could not allocate %d contact headers!\n", hdrs_no);
691
0
    return -1;
692
0
  }
693
694
  /* reset all header fields before populating new ones */
695
0
  to_msg->h_via1 = NULL;
696
0
  to_msg->callid = NULL;
697
0
  to_msg->to = NULL;
698
0
  to_msg->cseq = NULL;
699
0
  to_msg->from = NULL;
700
0
  to_msg->contact = NULL;
701
0
  to_msg->maxforwards = NULL;
702
0
  to_msg->route = NULL;
703
0
  to_msg->record_route = NULL;
704
0
  to_msg->path = NULL;
705
0
  to_msg->content_type = NULL;
706
0
  to_msg->content_length = NULL;
707
0
  to_msg->authorization = NULL;
708
0
  to_msg->expires = NULL;
709
0
  to_msg->proxy_auth = NULL;
710
0
  to_msg->supported = NULL;
711
0
  to_msg->proxy_require = NULL;
712
0
  to_msg->unsupported = NULL;
713
0
  to_msg->allow = NULL;
714
0
  to_msg->event = NULL;
715
0
  to_msg->accept = NULL;
716
0
  to_msg->accept_language = NULL;
717
0
  to_msg->organization = NULL;
718
0
  to_msg->priority = NULL;
719
0
  to_msg->subject = NULL;
720
0
  to_msg->user_agent = NULL;
721
0
  to_msg->content_disposition = NULL;
722
0
  to_msg->accept_disposition = NULL;
723
0
  to_msg->diversion = NULL;
724
0
  to_msg->rpid = NULL;
725
0
  to_msg->refer_to = NULL;
726
0
  to_msg->session_expires = NULL;
727
0
  to_msg->min_se = NULL;
728
0
  to_msg->ppi = NULL;
729
0
  to_msg->pai = NULL;
730
0
  to_msg->privacy = NULL;
731
0
  to_msg->call_info = NULL;
732
0
  to_msg->www_authenticate = NULL;
733
0
  to_msg->proxy_authenticate = NULL;
734
0
  to_msg->min_expires = NULL;
735
0
  to_msg->feature_caps = NULL;
736
0
  to_msg->replaces = NULL;
737
0
  to_msg->security_client = NULL;
738
0
  to_msg->security_server = NULL;
739
0
  to_msg->security_verify = NULL;
740
741
0
  for (i = 0, hdr = from_msg->headers; hdr; i++, hdr = hdr->next) {
742
0
    memcpy(&hdrs[i], hdr, sizeof(struct hdr_field));
743
    /* fix next and sibling */
744
0
    hdrs[i].next = &hdrs[i + 1];
745
0
    hdrs[i].sibling = NULL;
746
0
    switch(hdr->type) {
747
0
      link_sibling_hdr_case(h_via1, HDR_VIA_T);
748
0
      link_hdr_case        (callid, HDR_CALLID_T);
749
0
      link_hdr_case        (to, HDR_TO_T);
750
0
      link_hdr_case        (cseq, HDR_CSEQ_T);
751
0
      link_hdr_case        (from, HDR_FROM_T);
752
0
      link_sibling_hdr_case(contact, HDR_CONTACT_T);
753
0
      link_hdr_case        (maxforwards, HDR_MAXFORWARDS_T);
754
0
      link_sibling_hdr_case(route, HDR_ROUTE_T);
755
0
      link_sibling_hdr_case(record_route, HDR_RECORDROUTE_T);
756
0
      link_sibling_hdr_case(path, HDR_PATH_T);
757
0
      link_hdr_case        (content_type, HDR_CONTENTTYPE_T);
758
0
      link_hdr_case        (content_length, HDR_CONTENTLENGTH_T);
759
0
      link_sibling_hdr_case(authorization, HDR_AUTHORIZATION_T);
760
0
      link_hdr_case        (expires, HDR_EXPIRES_T);
761
0
      link_sibling_hdr_case(proxy_auth, HDR_PROXYAUTH_T);
762
0
      link_sibling_hdr_case(supported, HDR_SUPPORTED_T);
763
0
      link_sibling_hdr_case(proxy_require, HDR_PROXYREQUIRE_T);
764
0
      link_sibling_hdr_case(unsupported, HDR_UNSUPPORTED_T);
765
0
      link_sibling_hdr_case(allow, HDR_ALLOW_T);
766
0
      link_sibling_hdr_case(event, HDR_EVENT_T);
767
0
      link_sibling_hdr_case(accept, HDR_ACCEPT_T);
768
0
      link_sibling_hdr_case(accept_language, HDR_ACCEPTLANGUAGE_T);
769
0
      link_hdr_case        (organization, HDR_ORGANIZATION_T);
770
0
      link_hdr_case        (priority, HDR_PRIORITY_T);
771
0
      link_hdr_case        (subject, HDR_SUBJECT_T);
772
0
      link_hdr_case        (user_agent, HDR_USERAGENT_T);
773
0
      link_hdr_case        (content_disposition, HDR_CONTENTDISPOSITION_T);
774
0
      link_sibling_hdr_case(accept_disposition, HDR_ACCEPTDISPOSITION_T);
775
0
      link_sibling_hdr_case(diversion, HDR_DIVERSION_T);
776
0
      link_hdr_case        (rpid, HDR_RPID_T);
777
0
      link_hdr_case        (refer_to, HDR_REFER_TO_T);
778
0
      link_hdr_case        (session_expires, HDR_SESSION_EXPIRES_T);
779
0
      link_hdr_case        (min_se, HDR_MIN_SE_T);
780
0
      link_sibling_hdr_case(ppi, HDR_PPI_T);
781
0
      link_sibling_hdr_case(pai, HDR_PAI_T);
782
0
      link_hdr_case        (privacy, HDR_PRIVACY_T);
783
0
      link_sibling_hdr_case(call_info, HDR_CALL_INFO_T);
784
0
      link_sibling_hdr_case(www_authenticate, HDR_WWW_AUTHENTICATE_T);
785
0
      link_sibling_hdr_case(proxy_authenticate, HDR_PROXY_AUTHENTICATE_T);
786
0
      link_hdr_case        (min_expires, HDR_MIN_EXPIRES_T);
787
0
      link_sibling_hdr_case(feature_caps, HDR_FEATURE_CAPS_T);
788
0
      link_hdr_case        (replaces, HDR_REPLACES_T);
789
0
      link_sibling_hdr_case(security_client, HDR_SECURITY_CLIENT_T);
790
0
      link_sibling_hdr_case(security_server, HDR_SECURITY_SERVER_T);
791
0
      link_sibling_hdr_case(security_verify, HDR_SECURITY_VERIFY_T);
792
793
      /* not used in sip_msg, used in MSRP */
794
0
      case HDR_TO_PATH_T:
795
0
      case HDR_FROM_PATH_T:
796
0
      case HDR_MESSAGE_ID_T:
797
0
      case HDR_BYTE_RANGE_T:
798
0
      case HDR_FAILURE_REPORT_T:
799
0
      case HDR_SUCCESS_REPORT_T:
800
0
      case HDR_STATUS_T:
801
0
      case HDR_USE_PATH_T:
802
803
      /* not having shortcut */
804
0
      case HDR_RETRY_AFTER_T:
805
0
      case HDR_VIA2_T:
806
807
      /* not actual hdrs */
808
0
      case HDR_OTHER_T:
809
0
      case HDR_ERROR_T:
810
0
      case HDR_EOH_T:
811
0
        break;
812
      /* we do not have a "default" on purpose, so we get
813
       * a compile err/war where a new HDR is added and we do 
814
       * not handle it here.
815
      default:
816
        LM_ERR("unknown header type %d\n", hdr->type);
817
        break;
818
      */
819
0
    }
820
0
  }
821
0
  hdrs[i - 1].next = 0;
822
0
  to_msg->headers = hdrs;
823
0
#undef link_hdr_case
824
0
#undef link_sibling_hdr_case
825
0
  return 0;
826
0
}
827
828
829
/* returns 0 if ok, -1 for errors */
830
int parse_msg_opt(char* buf, unsigned int len, struct sip_msg* msg,
831
                              int free_on_err)
832
0
{
833
834
0
  char *tmp;
835
0
  char* rest;
836
0
  struct msg_start *fl;
837
0
  int offset;
838
0
  hdr_flags_t flags;
839
840
  /* eat crlf from the beginning */
841
0
  for (tmp=buf; (unsigned int)(tmp-buf) < len
842
0
          && (*tmp=='\n' || *tmp=='\r'); tmp++);
843
0
  offset=tmp-buf;
844
0
  fl=&(msg->first_line);
845
0
  rest=parse_first_line(tmp, len-offset, fl);
846
847
0
  offset+=rest-tmp;
848
0
  tmp=rest;
849
0
  switch(fl->type){
850
0
    case SIP_INVALID:
851
0
      LM_DBG("invalid message\n");
852
      /* if failed to parse the first line, we simply consider that the whole
853
         buffer was parsed, so that nothing is left to be parsed :) - this will
854
         do the trick and make "msg" struct acceptable for following parsing
855
         attempts */
856
0
      msg->unparsed = msg->buf + msg->len;
857
0
      goto error;
858
0
      break;
859
0
    case SIP_REQUEST:
860
0
      LM_DBG("SIP Request:\n");
861
0
      LM_DBG(" method:  <%.*s>\n",fl->u.request.method.len,
862
0
        ZSW(fl->u.request.method.s));
863
0
      LM_DBG(" uri:     <%.*s>\n",fl->u.request.uri.len,
864
0
        ZSW(fl->u.request.uri.s));
865
0
      LM_DBG(" version: <%.*s>\n",fl->u.request.version.len,
866
0
        ZSW(fl->u.request.version.s));
867
0
      flags=HDR_EOH_F;
868
0
      break;
869
0
    case SIP_REPLY:
870
0
      LM_DBG("SIP Reply  (status):\n");
871
0
      LM_DBG(" version: <%.*s>\n",fl->u.reply.version.len,
872
0
          ZSW(fl->u.reply.version.s));
873
0
      LM_DBG(" status:  <%.*s>\n", fl->u.reply.status.len,
874
0
          ZSW(fl->u.reply.status.s));
875
0
      LM_DBG(" reason:  <%.*s>\n", fl->u.reply.reason.len,
876
0
          ZSW(fl->u.reply.reason.s));
877
0
      flags=HDR_EOH_F;
878
0
      break;
879
0
    default:
880
0
      LM_DBG("unknown type %d\n",fl->type);
881
0
      goto error;
882
0
  }
883
0
  msg->unparsed=tmp;
884
  /*find first Via: */
885
0
  if (parse_headers(msg, flags, 0)==-1) goto parse_error;
886
887
#ifdef EXTRA_DEBUG
888
  /* dump parsed data */
889
  if (msg->via1){
890
    LM_DBG(" first  via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>\n",
891
      msg->via1->name.len,
892
      ZSW(msg->via1->name.s),
893
      msg->via1->version.len,
894
      ZSW(msg->via1->version.s),
895
      msg->via1->transport.len,
896
      ZSW(msg->via1->transport.s),
897
      msg->via1->host.len,
898
      ZSW(msg->via1->host.s),
899
      msg->via1->port_str.len,
900
      ZSW(msg->via1->port_str.s),
901
      msg->via1->port);
902
    if (msg->via1->params.s)  LM_DBG(";<%.*s>\n",
903
        msg->via1->params.len, ZSW(msg->via1->params.s));
904
    if (msg->via1->comment.s)
905
        LM_DBG(" <%.*s>\n",
906
          msg->via1->comment.len, ZSW(msg->via1->comment.s));
907
    LM_DBG ("\n");
908
  }
909
  if (msg->via2){
910
    LM_DBG(" first  via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>\n",
911
      msg->via2->name.len,
912
      ZSW(msg->via2->name.s),
913
      msg->via2->version.len,
914
      ZSW(msg->via2->version.s),
915
      msg->via2->transport.len,
916
      ZSW(msg->via2->transport.s),
917
      msg->via2->host.len,
918
      ZSW(msg->via2->host.s),
919
      msg->via2->port_str.len,
920
      ZSW(msg->via2->port_str.s),
921
      msg->via2->port);
922
    if (msg->via2->params.s)  LM_DBG(";<%.*s>\n",
923
        msg->via2->params.len, ZSW(msg->via2->params.s));
924
    if (msg->via2->comment.s) LM_DBG(" <%.*s>\n",
925
        msg->via2->comment.len, ZSW(msg->via2->comment.s));
926
    LM_DBG ("\n");
927
  }
928
#endif
929
930
931
#ifdef EXTRA_DEBUG
932
  LM_DBG("exiting\n");
933
#endif
934
935
0
  return 0;
936
937
0
parse_error:
938
0
  if (free_on_err) {
939
    /* Free the SIP message if it has already been created to
940
     * prevent memory leaks */
941
0
    free_sip_msg(msg);
942
0
    memset(msg, 0, sizeof(*msg));
943
0
  }
944
945
0
error:
946
  /* more debugging, msg->orig is/should be null terminated*/
947
0
  LM_ERR("message=<%.*s>\n", (int)len, ZSW(buf));
948
0
  return -1;
949
0
}
950
951
952
953
void free_reply_lump( struct lump_rpl *lump)
954
0
{
955
0
  struct lump_rpl *foo, *bar;
956
0
  for(foo=lump;foo;)
957
0
  {
958
0
    bar=foo->next;
959
0
    free_lump_rpl(foo);
960
0
    foo = bar;
961
0
  }
962
0
}
963
964
965
/* Free only the content, not the msg structure itself
966
 * NOTE: the function doesn't do any cleanup/reset of the subfields */
967
void free_sip_msg(struct sip_msg* msg)
968
0
{
969
0
  if (msg->msg_cb)
970
0
    msg_callback_process(msg, MSG_DESTROY, NULL);
971
0
  if (msg->new_uri.s)
972
0
    pkg_free(msg->new_uri.s);
973
0
  if (msg->set_global_address.s)
974
0
    pkg_free(msg->set_global_address.s);
975
0
  if (msg->set_global_port.s)
976
0
    pkg_free(msg->set_global_port.s);
977
0
  if (msg->dst_uri.s)
978
0
    pkg_free(msg->dst_uri.s);
979
0
  if (msg->path_vec.s)
980
0
    pkg_free(msg->path_vec.s);
981
0
  if (msg->headers)
982
0
    free_hdr_field_lst(msg->headers);
983
0
  if (msg->add_rm)
984
0
    free_lump_list(msg->add_rm);
985
0
  if (msg->body_lumps)
986
0
    free_lump_list(msg->body_lumps);
987
0
  if (msg->sdp_ops )
988
0
    free_sdp_ops(msg->sdp_ops);
989
0
  if (msg->reply_lump)
990
0
    free_reply_lump(msg->reply_lump);
991
0
  if (msg->body )
992
0
    free_sip_body(msg->body);
993
  /* don't free anymore -- now a pointer to a static buffer */
994
0
}
995
996
997
/* make sure all HFs needed for transaction identification have been
998
   parsed; return 0 if those HFs can't be found
999
*/
1000
1001
int check_transaction_quadruple( struct sip_msg* msg )
1002
0
{
1003
0
  if ( parse_headers(msg, HDR_FROM_F|HDR_TO_F|HDR_CALLID_F|HDR_CSEQ_F,0)!=-1
1004
0
    && msg->from && msg->to && msg->callid && msg->cseq ) {
1005
0
    return 1;
1006
0
  } else {
1007
0
    ser_error=E_BAD_TUPEL;
1008
0
    return 0;
1009
0
  }
1010
0
}
1011
1012
1013
/*
1014
 * Make a private copy of the string and assign it to new_uri
1015
 */
1016
int set_ruri(struct sip_msg *msg, str *uri)
1017
0
{
1018
0
  if (!msg || !uri) {
1019
0
    LM_ERR("invalid parameter value\n");
1020
0
    return -1;
1021
0
  }
1022
1023
  /* strange/corrupt input: best to assume it's an empty URI */
1024
0
  if (!uri->s || uri->len == 0) {
1025
0
    pkg_free(msg->new_uri.s);
1026
0
    memset(&msg->new_uri, 0, sizeof msg->new_uri);
1027
0
    return 0;
1028
0
  }
1029
1030
0
  if (msg->new_uri.s && (msg->new_uri.len >= uri->len)) {
1031
0
    memcpy(msg->new_uri.s, uri->s, uri->len);
1032
0
    msg->new_uri.len = uri->len;
1033
0
  } else {
1034
0
    msg->new_uri.s = pkg_realloc(msg->new_uri.s, uri->len + 1);
1035
0
    if (!msg->new_uri.s) {
1036
0
      LM_ERR("not enough pkg memory (%d)\n",uri->len);
1037
0
      return -1;
1038
0
    }
1039
1040
0
    memcpy(msg->new_uri.s, uri->s, uri->len);
1041
0
    msg->new_uri.len = uri->len;
1042
0
  }
1043
1044
0
  set_ruri_q(msg, Q_UNSPECIFIED);
1045
0
  msg->parsed_uri_ok = 0;
1046
0
  return 0;
1047
0
}
1048
1049
1050
1051
/*
1052
 * Make a private copy of the string and assign it to dst_uri
1053
 */
1054
int set_dst_uri(struct sip_msg *msg, str *uri)
1055
0
{
1056
0
  if (!msg || !uri) {
1057
0
    LM_ERR("invalid parameter value\n");
1058
0
    return -1;
1059
0
  }
1060
1061
  /* strange/corrupt input: best to assume it's an empty URI */
1062
0
  if (!uri->s || uri->len == 0) {
1063
0
    pkg_free(msg->dst_uri.s);
1064
0
    memset(&msg->dst_uri, 0, sizeof msg->dst_uri);
1065
0
    return 0;
1066
0
  }
1067
1068
0
  if (msg->dst_uri.s && (msg->dst_uri.len >= uri->len)) {
1069
0
    memcpy(msg->dst_uri.s, uri->s, uri->len);
1070
0
    msg->dst_uri.len = uri->len;
1071
0
  } else {
1072
0
    msg->dst_uri.s = pkg_realloc(msg->dst_uri.s, uri->len);
1073
0
    if (!msg->dst_uri.s) {
1074
0
      LM_ERR("not enough pkg memory\n");
1075
0
      return -1;
1076
0
    }
1077
1078
0
    memcpy(msg->dst_uri.s, uri->s, uri->len);
1079
0
    msg->dst_uri.len = uri->len;
1080
0
  }
1081
1082
0
  return 0;
1083
0
}
1084
1085
void reset_dst_uri(struct sip_msg *msg)
1086
0
{
1087
0
  if(msg->dst_uri.s!=0)
1088
0
    pkg_free(msg->dst_uri.s);
1089
0
  msg->dst_uri.s = 0;
1090
0
  msg->dst_uri.len = 0;
1091
0
}
1092
1093
int set_dst_host_port(struct sip_msg *msg, str *host, str *port)
1094
0
{
1095
0
  char *tmp, *end, *crt, *new_uri;
1096
0
  int len;
1097
0
  struct sip_uri uri;
1098
0
  int user = 0;
1099
1100
0
  tmp = msg->dst_uri.s;
1101
0
  len = msg->dst_uri.len;
1102
1103
0
  if (tmp == NULL || len == 0) {
1104
0
    LM_ERR("failure - null uri\n");
1105
0
    return -1;
1106
0
  }
1107
0
  if (host && (host->s == NULL || host->len == 0)) {
1108
0
    LM_ERR("cannot set a null uri domain\n");
1109
0
    return -1;
1110
0
  }
1111
0
  if (parse_uri(tmp, len, &uri)<0) {
1112
0
    LM_ERR("bad uri <%.*s>, dropping packet\n", len, tmp);
1113
0
    return -1;
1114
0
  }
1115
0
  new_uri=pkg_malloc(MAX_URI_SIZE);
1116
0
  if (new_uri == NULL) {
1117
0
    LM_ERR("memory allocation failure\n");
1118
0
    return -1;
1119
0
  }
1120
0
  end=new_uri+MAX_URI_SIZE;
1121
0
  crt=new_uri;
1122
0
  len = (uri.user.len?uri.user.s:uri.host.s) - tmp;
1123
0
  if (crt+len>end) goto error_uri;
1124
0
  memcpy(crt,tmp,len);
1125
0
  crt += len;
1126
  /* user */
1127
0
  tmp = uri.user.s;
1128
0
  len = uri.user.len;
1129
0
  if (tmp) {
1130
0
    if (crt+len>end) goto error_uri;
1131
0
    memcpy(crt,tmp,len);
1132
0
    crt += len;
1133
0
    user = 1;
1134
0
  }
1135
  /* passwd */
1136
0
  tmp = uri.passwd.s;
1137
0
  len = uri.passwd.len;
1138
0
  if (tmp) {
1139
0
    if (crt+len+1>end) goto error_uri;
1140
0
    *crt++=':';
1141
0
    memcpy(crt, tmp, len);
1142
0
    crt += len;
1143
0
  }
1144
  /* host */
1145
0
  if (host) {
1146
0
    tmp = host->s;
1147
0
    len = host->len;
1148
0
  } else {
1149
0
    tmp = uri.host.s;
1150
0
    len = uri.host.len;
1151
0
  }
1152
0
  if (tmp) {
1153
0
    if (user) {
1154
0
      if (crt+1>end) goto error_uri;
1155
0
      *crt++='@';
1156
0
    }
1157
0
    if (crt+len+1>end) goto error_uri;
1158
0
    memcpy(crt, tmp, len);
1159
0
    crt += len;
1160
0
  }
1161
  /* port */
1162
0
  if (port) {
1163
0
    tmp = port->s;
1164
0
    len = port->len;
1165
0
  } else {
1166
0
    tmp = uri.port.s;
1167
0
    len = uri.port.len;
1168
0
  }
1169
0
  if (tmp && len > 0) {
1170
0
    if (crt+len+1>end) goto error_uri;
1171
0
    *crt++=':';
1172
0
    memcpy(crt, tmp, len);
1173
0
    crt += len;
1174
0
  }
1175
  /* params */
1176
0
  tmp=uri.params.s;
1177
0
  if (tmp){
1178
0
    len=uri.params.len; if(crt+len+1>end) goto error_uri;
1179
0
    *crt++=';';
1180
0
    memcpy(crt,tmp,len);
1181
0
    crt += len;
1182
0
  }
1183
  /* headers */
1184
0
  tmp=uri.headers.s;
1185
0
  if (tmp){
1186
0
    len=uri.headers.len; if(crt+len+1>end) goto error_uri;
1187
0
    *crt++='?';
1188
0
    memcpy(crt,tmp,len);
1189
0
    crt += len;
1190
0
  }
1191
0
  *crt=0; /* null terminate the thing */
1192
  /* copy it to the msg */
1193
0
  pkg_free(msg->dst_uri.s);
1194
0
  msg->dst_uri.s=new_uri;
1195
0
  msg->dst_uri.len=crt-new_uri;
1196
  
1197
0
  return 0;
1198
1199
0
error_uri:
1200
0
  pkg_free(new_uri);
1201
0
  return -1;
1202
0
}
1203
1204
int rewrite_ruri(struct sip_msg *msg, str *sval, int ival,
1205
        enum rw_ruri_part part)
1206
0
{
1207
0
  int user = 0;
1208
0
  char *tmp, *new_uri, *end, *crt;
1209
0
  int len;
1210
0
  struct sip_uri uri;
1211
1212
0
  if (msg->new_uri.s) {
1213
0
    tmp=msg->new_uri.s;
1214
0
    len=msg->new_uri.len;
1215
0
  }else{
1216
0
    tmp=msg->first_line.u.request.uri.s;
1217
0
    len=msg->first_line.u.request.uri.len;
1218
0
  }
1219
0
  if (parse_uri(tmp, len, &uri)<0){
1220
0
    LM_ERR("bad uri <%.*s>, dropping packet\n", len, tmp);
1221
0
    return -1;
1222
0
  }
1223
1224
0
  new_uri=pkg_malloc(MAX_URI_SIZE);
1225
0
  if (new_uri==0){
1226
0
    LM_ERR("memory allocation failure\n");
1227
0
    return -1;
1228
0
  }
1229
0
  end=new_uri+MAX_URI_SIZE;
1230
0
  crt=new_uri;
1231
  /* begin copying */
1232
0
  len = (uri.user.len?uri.user.s:uri.host.s) - tmp;
1233
0
  if (crt+len>end) goto error;
1234
0
  memcpy(crt,tmp,len);crt+=len;
1235
1236
0
  if (part==RW_RURI_PREFIX && sval->len) {
1237
0
    if (crt+sval->len>end) goto error;
1238
0
    memcpy( crt, sval->s, sval->len);
1239
0
    crt+=sval->len;
1240
    /* whatever we had before, with prefix we have username
1241
       now */
1242
0
    user=1;
1243
0
  }
1244
1245
0
  if ((part==RW_RURI_USER)||(part==RW_RURI_USERPASS)) {
1246
0
    tmp=sval->s;
1247
0
    len=sval->len;
1248
0
  } else if (part==RW_RURI_STRIP) {
1249
0
    if (ival>uri.user.len) {
1250
0
      LM_WARN("too long strip asked; "
1251
0
          " deleting username: %d of <%.*s>\n",
1252
0
          ival, uri.user.len, uri.user.s);
1253
0
      len=0;
1254
0
    } else if (ival==uri.user.len) {
1255
0
      len=0;
1256
0
    } else {
1257
0
      tmp=uri.user.s + ival;
1258
0
      len=uri.user.len - ival;
1259
0
    }
1260
0
  } else if (part==RW_RURI_STRIP_TAIL) {
1261
0
    if (ival>uri.user.len) {
1262
0
      LM_WARN("too long strip_tail asked;"
1263
0
          " deleting username: %d of <%.*s>\n",
1264
0
          ival, uri.user.len, uri.user.s);
1265
0
      len=0;
1266
0
    } else if (ival==uri.user.len) {
1267
0
      len=0;
1268
0
    } else {
1269
0
      tmp=uri.user.s;
1270
0
      len=uri.user.len - ival;
1271
0
    }
1272
0
  } else {
1273
0
    tmp=uri.user.s;
1274
0
    len=uri.user.len;
1275
0
  }
1276
1277
0
  if (len){
1278
0
    if(crt+len>end) goto error;
1279
0
    memcpy(crt,tmp,len);crt+=len;
1280
0
    user=1; /* we have an user field so mark it */
1281
0
  }
1282
1283
0
  if (part==RW_RURI_USERPASS) tmp=0;
1284
0
  else tmp=uri.passwd.s;
1285
  /* passwd */
1286
0
  if (tmp){
1287
0
    len=uri.passwd.len; if(crt+len+1>end) goto error;
1288
0
    *crt=':'; crt++;
1289
0
    memcpy(crt,tmp,len);crt+=len;
1290
0
  }
1291
  /* host */
1292
0
  if (user || tmp){ /* add @ */
1293
0
    if(crt+1>end) goto error;
1294
0
    *crt='@'; crt++;
1295
0
  }
1296
0
  if ((part==RW_RURI_HOST) ||(part==RW_RURI_HOSTPORT)) {
1297
0
    tmp=sval->s;
1298
0
    len=sval->len;
1299
0
  } else {
1300
0
    tmp=uri.host.s;
1301
0
    len = uri.host.len;
1302
0
  }
1303
0
  if (tmp){
1304
0
    if(crt+len>end) goto error;
1305
0
    memcpy(crt,tmp,len);crt+=len;
1306
0
  }
1307
  /* port */
1308
0
  if (part==RW_RURI_HOSTPORT) tmp=0;
1309
0
  else if (part==RW_RURI_PORT) {
1310
0
    tmp=sval->s;
1311
0
    len=sval->len;
1312
0
  } else {
1313
0
    tmp=uri.port.s;
1314
0
    len = uri.port.len;
1315
0
  }
1316
0
  if (tmp && len>0){
1317
0
    if(crt+len+1>end) goto error;
1318
0
    *crt=':'; crt++;
1319
0
    memcpy(crt,tmp,len);crt+=len;
1320
0
  }
1321
  /* params */
1322
0
  tmp=uri.params.s;
1323
0
  if (tmp){
1324
    /* include in param string the starting ';' */
1325
0
    len=uri.params.len+1;
1326
0
    tmp--;
1327
0
    if(crt+len+1>end) goto error;
1328
    /* if a maddr param is present, strip it out */
1329
0
    if (uri.maddr.len &&
1330
0
    (part==RW_RURI_HOSTPORT || part==RW_RURI_HOST)) {
1331
0
      memcpy(crt,tmp,uri.maddr.s-tmp-1);
1332
0
      crt+=uri.maddr.s-tmp-1;
1333
0
      memcpy(crt,uri.maddr_val.s+uri.maddr_val.len,
1334
0
        tmp+len-uri.maddr_val.s-uri.maddr_val.len);
1335
0
      crt+=tmp+len-uri.maddr_val.s-uri.maddr_val.len;
1336
0
    } else {
1337
0
      memcpy(crt,tmp,len);crt+=len;
1338
0
    }
1339
0
  }
1340
  /* headers */
1341
0
  tmp=uri.headers.s;
1342
0
  if (tmp){
1343
0
    len=uri.headers.len; if(crt+len+1>end) goto error;
1344
0
    *crt='?'; crt++;
1345
0
    memcpy(crt,tmp,len);crt+=len;
1346
0
  }
1347
0
  *crt=0; /* null terminate the thing */
1348
  /* copy it to the msg */
1349
0
  if (msg->new_uri.s) pkg_free(msg->new_uri.s);
1350
0
  msg->new_uri.s=new_uri;
1351
0
  msg->new_uri.len=crt-new_uri;
1352
0
  msg->parsed_uri_ok=0;
1353
1354
0
  return 0;
1355
1356
0
error:
1357
0
  LM_ERR("uri too long\n");
1358
0
  if (new_uri)
1359
0
    pkg_free(new_uri);
1360
0
  return -1;
1361
0
}
1362
1363
/*
1364
 * Make a private copy of the string and assign it to path_vec
1365
 */
1366
int set_path_vector(struct sip_msg *msg, str *path)
1367
0
{
1368
0
  if (!msg || !path) {
1369
0
    LM_ERR("invalid parameter value\n");
1370
0
    return -1;
1371
0
  }
1372
1373
  /* strange/corrupt input: best to assume it's an empty URI */
1374
0
  if (!path->s || path->len == 0) {
1375
0
    pkg_free(msg->path_vec.s);
1376
0
    memset(&msg->path_vec, 0, sizeof msg->path_vec);
1377
0
    return 0;
1378
0
  }
1379
1380
0
  if (msg->path_vec.s && (msg->path_vec.len >= path->len)) {
1381
0
    memcpy(msg->path_vec.s, path->s, path->len);
1382
0
    msg->path_vec.len = path->len;
1383
0
  } else {
1384
0
    msg->path_vec.s = pkg_realloc(msg->path_vec.s, path->len);
1385
0
    if (!msg->path_vec.s) {
1386
0
      LM_ERR("not enough pkg memory\n");
1387
0
      return -1;
1388
0
    }
1389
1390
0
    memcpy(msg->path_vec.s, path->s, path->len);
1391
0
    msg->path_vec.len = path->len;
1392
0
  }
1393
1394
0
  return 0;
1395
0
}
1396
1397
void clear_path_vector(struct sip_msg *msg)
1398
0
{
1399
0
  if (msg->path_vec.s) {
1400
0
    pkg_free(msg->path_vec.s);
1401
0
    memset(&msg->path_vec, 0, sizeof msg->path_vec);
1402
0
  }
1403
0
}
1404
1405
/* convenience macros */
1406
0
#define LC(_cp) ((*(_cp))|0x20)
1407
#define SET_FOUND(_new_state) \
1408
0
  do{\
1409
0
    fill->s=b;fill->len=p-b;\
1410
0
    LM_DBG("hdr %d extracted as <%.*s>\n",\
1411
0
      flag,fill->len,fill->s);\
1412
0
    flags&=~(flag);\
1413
0
    if (flags) {state=_new_state;}\
1414
0
    else {goto done;}\
1415
0
  }while(0)
1416
#define GET_CSEQ() \
1417
0
  do{\
1418
0
    for(p++;p<end&&isspace((int)*p);p++);\
1419
0
    for(fill->s=b;p<end&&isdigit((int)*p);p++);\
1420
0
    fill->len=p-fill->s;\
1421
0
    if ( (flags&=~(flag))==0) goto done;\
1422
0
    state=1;\
1423
0
  }while(0)
1424
int extract_ftc_hdrs( char *buf, int len, str *from, str *to, str *cseq,str *callid)
1425
0
{
1426
0
  char *end, *p;
1427
0
  char *b;
1428
0
  str  *fill;
1429
0
  int state;
1430
0
  int flags;
1431
0
  int flag;
1432
1433
0
  p = buf;
1434
0
  end = buf+len;
1435
0
  state = 1;
1436
0
  b = 0;
1437
0
  flags = ((from!=0)?0x1:0) | ((to!=0)?0x2:0) | ((cseq!=0)?0x4:0)
1438
0
        | ((callid!=0)?0x8:0);
1439
0
  flag = 0;
1440
0
  fill = 0;
1441
1442
0
  LM_DBG("flags = %d\n",flags);
1443
1444
0
  while(p<end) {
1445
0
    switch (*p) {
1446
0
      case '\n':
1447
0
      case '\r':
1448
0
        switch (state) {
1449
0
          case 4: state=5;break;
1450
0
          case 5: state=6;break;
1451
0
          case 6: if(!(*p=='\n' && *(p-1)=='\r')) SET_FOUND(1);break;
1452
0
          default : state=2;break;
1453
0
        }
1454
0
        break;
1455
0
      case ' ':
1456
0
      case '\t':
1457
0
        switch (state) {
1458
0
          case 4: case 6: state=5; break;
1459
0
          case 2: state=1; break;/*folded line*/
1460
0
        }
1461
0
        break;
1462
0
      case ':':
1463
0
        switch (state) {
1464
0
          case 4:case 5: state=5;if(flag==0x04)GET_CSEQ();break;
1465
0
          case 6: SET_FOUND(1);break;/*found*/
1466
0
          case 2: state=1;break;
1467
0
        }
1468
0
        break;
1469
0
      case 'f':
1470
0
      case 'F':
1471
0
        if (state==5) break;
1472
0
        if (state==6) SET_FOUND(2);/*found*/;
1473
0
        if (state!=2) {state = 1;break;}
1474
        /* hdr starting with 'f' */
1475
0
        if (from==0) break;
1476
0
        b = p;
1477
0
        if (p+3<end && LC(p+1)=='r' && LC(p+2)=='o' && LC(p+3)=='m')
1478
0
          p+=3;
1479
0
        state = 4; /* "f" or "from" found */
1480
0
        fill = from;
1481
0
        flag = 0x1;
1482
0
        break;
1483
0
      case 't':
1484
0
      case 'T':
1485
0
        if (state==5) break;
1486
0
        if (state==6) SET_FOUND(2);/*found*/;
1487
0
        if (state!=2) {state = 1;break;}
1488
        /* hdr starting with 't' */
1489
0
        if (to==0) break;
1490
0
        b = p;
1491
0
        if (p+1<end && LC(p+1)=='o')
1492
0
          p+=1;
1493
0
        state = 4; /* "t" or "to" found */
1494
0
        fill = to;
1495
0
        flag = 0x2;
1496
0
        break;
1497
0
      case 'c':
1498
0
      case 'C':
1499
0
        if (state==5) break;
1500
0
        if (state==6) SET_FOUND(2);/*found*/;
1501
0
        if (state!=2) {state = 1;break;}
1502
        /* hdr starting with 'c' */
1503
0
        if (cseq==0 && callid == 0) break;
1504
0
        if (cseq && p+3<end && LC(p+1)=='s' && LC(p+2)=='e' && LC(p+3)=='q') {
1505
0
          b = p;
1506
0
          p+=3;
1507
0
          state = 4; /* "cseq" found */
1508
0
          fill = cseq;
1509
0
          flag = 0x4;
1510
0
        } else if (callid && p+6<end && LC(p+1)=='a' && LC(p+2) == 'l' &&
1511
0
          LC(p+3) == 'l' && LC(p+4) == '-' && LC(p+5) == 'i' &&
1512
0
          LC(p+6) == 'd') {
1513
0
          b = p;
1514
0
          p+=6;
1515
0
          state = 4; /* callid found */
1516
0
          fill = callid;
1517
0
          flag = 0x8;
1518
0
        }
1519
0
        break;
1520
0
      case 'I':
1521
0
      case 'i':
1522
0
        if (state==5) break;
1523
0
        if (state==6) SET_FOUND(2);/*found*/;
1524
0
        if (state!=2) {state = 1;break;}
1525
0
        if (callid == 0) break;
1526
0
        b = p;
1527
0
        state=4; /* callid found */
1528
0
        fill = callid;
1529
0
        flag=0x8;
1530
0
        break;
1531
0
      default:
1532
0
        switch (state) {
1533
0
          case 2:case 4: state=1; break;
1534
0
          case 6: SET_FOUND(1);break;/*found*/;
1535
0
        }
1536
0
    }
1537
0
    p++;
1538
0
  }
1539
1540
0
  LM_CRIT("no hdrs found in outgoing buffer\n");
1541
0
  return -1;
1542
0
done:
1543
0
  return 0;
1544
0
}
1545
1546
1547
int delete_headers(struct sip_msg *msg, struct hdr_field *hdr)
1548
0
{
1549
0
  for (; hdr; hdr = hdr->sibling) {
1550
0
    if (!del_lump(msg, hdr->name.s - msg->buf, hdr->len, hdr->type)) {
1551
0
      LM_ERR("failed to delete contact '%.*s'\n", hdr->name.len,
1552
0
             hdr->name.s);
1553
0
      return -1;
1554
0
    }
1555
0
  }
1556
1557
0
  return 0;
1558
0
}