Coverage Report

Created: 2025-07-11 06:28

/src/opensips/parser/parse_ppi.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2006 Juha Heinanen
3
 *
4
 *
5
 * This file is part of opensips, a free SIP server.
6
 *
7
 * opensips is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version
11
 *
12
 * opensips is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
20
 */
21
22
#include "parse_ppi.h"
23
#include "parse_to.h"
24
#include "parse_uri.h"
25
#include <stdlib.h>
26
#include <string.h>
27
#include "../dprint.h"
28
#include "msg_parser.h"
29
#include "../ut.h"
30
#include "../errinfo.h"
31
#include "../mem/mem.h"
32
33
34
/*
35
 * This method is used to parse P-Preferred-Identity header (RFC 3325).
36
 *
37
 * params: msg : sip msg
38
 * returns 0 on success,
39
 *        -1 on failure.
40
 */
41
int parse_ppi_header( struct sip_msg *msg )
42
0
{
43
0
  struct to_body* ppi_b;
44
45
0
  if ( !msg->ppi &&
46
0
    (parse_headers(msg, HDR_PPI_F,0)==-1 || !msg->ppi)) {
47
0
    goto error;
48
0
  }
49
50
  /* maybe the header is already parsed! */
51
0
  if (msg->ppi->parsed)
52
0
    return 0;
53
54
  /* bad luck! :-( - we have to parse it */
55
  /* first, get some memory */
56
0
  ppi_b = pkg_malloc(sizeof(struct to_body));
57
0
  if (ppi_b == 0) {
58
0
    LM_ERR("out of pkg_memory\n");
59
0
    goto error;
60
0
  }
61
62
  /* now parse it!! */
63
0
  parse_multi_to(msg->ppi->body.s,
64
0
    msg->ppi->body.s + msg->ppi->body.len+1,
65
0
    ppi_b);
66
0
  if (ppi_b->error == PARSE_ERROR) {
67
0
    LM_ERR("bad P-Preferred-Identity header\n");
68
0
    pkg_free(ppi_b);
69
0
    set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
70
0
      "error parsing PPI header");
71
0
    set_err_reply(400, "bad header");
72
0
    goto error;
73
0
  }
74
0
  msg->ppi->parsed = ppi_b;
75
76
0
  return 0;
77
0
error:
78
0
  return -1;
79
0
}
80
81
82
/**
83
 * Parse P-Preferred-Identity header URI
84
 */
85
struct sip_uri *parse_ppi_uri(struct sip_msg *msg)
86
0
{
87
0
  struct to_body *tb = NULL;
88
89
0
  if(msg==NULL)
90
0
    return NULL;
91
92
0
  if(parse_ppi_header(msg)<0)
93
0
  {
94
0
    LM_ERR("cannot parse P-P-I header\n");
95
0
    return NULL;
96
0
  }
97
98
0
  if(msg->ppi==NULL || get_ppi(msg)==NULL)
99
0
    return NULL;
100
101
0
  tb = get_ppi(msg);
102
103
0
  if(tb->parsed_uri.user.s!=NULL || tb->parsed_uri.host.s!=NULL)
104
0
    return &tb->parsed_uri;
105
106
0
  if (parse_uri(tb->uri.s, tb->uri.len , &tb->parsed_uri)<0)
107
0
  {
108
0
    LM_ERR("failed to parse P-P-I URI\n");
109
0
    memset(&tb->parsed_uri, 0, sizeof(struct sip_uri));
110
0
    set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM, "error parsing P-P-I URI");
111
0
    set_err_reply(400, "bad P-Preferred-Identity uri");
112
0
    return NULL;
113
0
  }
114
115
0
  return &tb->parsed_uri;
116
0
}