1 /* 2 * $Id$ 3 * 4 * Copyright (C) 2012 Smile Communications, jason.penton@smilecoms.com 5 * Copyright (C) 2012 Smile Communications, richard.good@smilecoms.com 6 * The initial version of this code was written by Dragos Vingarzan 7 * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the 8 * Fruanhofer Institute. It was and still is maintained in a separate 9 * branch of the original SER. We are therefore migrating it to 10 * Kamailio/SR and look forward to maintaining it from here on out. 11 * 2011/2012 Smile Communications, Pty. Ltd. 12 * ported/maintained/improved by 13 * Jason Penton (jason(dot)penton(at)smilecoms.com and 14 * Richard Good (richard(dot)good(at)smilecoms.com) as part of an 15 * effort to add full IMS support to Kamailio/SR using a new and 16 * improved architecture 17 * 18 * NB: Alot of this code was originally part of OpenIMSCore, 19 * FhG Fokus. 20 * Copyright (C) 2004-2006 FhG Fokus 21 * Thanks for great work! This is an effort to 22 * break apart the various CSCF functions into logically separate 23 * components. We hope this will drive wider use. We also feel 24 * that in this way the architecture is more complete and thereby easier 25 * to manage in the Kamailio/SR environment 26 * 27 * This file is part of Kamailio, a free SIP server. 28 * 29 * Kamailio is free software; you can redistribute it and/or modify 30 * it under the terms of the GNU General Public License as published by 31 * the Free Software Foundation; either version 2 of the License, or 32 * (at your option) any later version 33 * 34 * Kamailio is distributed in the hope that it will be useful, 35 * but WITHOUT ANY WARRANTY; without even the implied warranty of 36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37 * GNU General Public License for more details. 38 * 39 * You should have received a copy of the GNU General Public License 40 * along with this program; if not, write to the Free Software 41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 42 * 43 */ 44 45 #ifndef __IMS_GETTERS_H 46 #define __IMS_GETTERS_H 47 48 #include "../../core/str.h" 49 50 #include "../../core/parser/contact/parse_contact.h" 51 52 /** Return and break the execution of routng script */ 53 #define CSCF_RETURN_BREAK 0 54 /** Return true in the routing script */ 55 #define CSCF_RETURN_TRUE 1 56 /** Return false in the routing script */ 57 #define CSCF_RETURN_FALSE -1 58 /** Return error in the routing script */ 59 #define CSCF_RETURN_ERROR -2 60 61 /** Enumeration for dialog directions */ 62 enum cscf_dialog_direction { 63 CSCF_MOBILE_ORIGINATING=0, 64 CSCF_MOBILE_TERMINATING=1, 65 CSCF_MOBILE_UNKNOWN=2 66 }; 67 68 /** 69 * Duplicate a str, safely. 70 * \Note This checks if: 71 * - src was an empty string 72 * - malloc failed 73 * \Note On any error, the dst values are reset for safety 74 * \Note A label "out_of_memory" must be defined in the calling function to handle 75 * allocation errors. 76 * @param dst - destination str 77 * @param src - source src 78 * @param mem - type of mem to duplicate into (shm/pkg) 79 */ 80 #define str_dup(dst,src,mem) \ 81 do {\ 82 if ((src).len) {\ 83 (dst).s = mem##_malloc((src).len);\ 84 if (!(dst).s){\ 85 LM_ERR("Error allocating %d bytes in %s!\n",(src).len,#mem);\ 86 (dst).len = 0;\ 87 goto out_of_memory;\ 88 }\ 89 memcpy((dst).s,(src).s,(src).len);\ 90 (dst).len = (src).len;\ 91 }else{\ 92 (dst).s=0;(dst).len=0;\ 93 }\ 94 } while (0) 95 96 /** 97 * Frees a str content. 98 * @param x - the str to free 99 * @param mem - type of memory that the content is using (shm/pkg) 100 */ 101 #define str_free(x,mem) \ 102 do {\ 103 if ((x).s) mem##_free((x).s);\ 104 (x).s=0;(x).len=0;\ 105 } while(0) 106 107 /** 108 * Parses all the contact headers. 109 * @param msg - the SIP message 110 * @returns the first contact_body 111 */ 112 contact_body_t *cscf_parse_contacts(struct sip_msg *msg); 113 /** 114 * Returns the Private Identity extracted from the Authorization header. 115 * If none found there takes the SIP URI in To without the "sip:" prefix 116 * \todo - remove the fallback case to the To header 117 * @param msg - the SIP message 118 * @param realm - the realm to match in an Authorization header 119 * @returns the str containing the private id, no mem dup 120 */ 121 str cscf_get_private_identity(struct sip_msg *msg, str realm); 122 /** 123 * Returns the Private Identity extracted from the Authorization header. 124 * If none found there takes the SIP URI in from without the "sip:" prefix 125 * @param msg - the SIP message 126 * @param realm - the realm to match in an Authorization header 127 * @returns the str containing the private id, no mem dup 128 */ 129 str cscf_get_private_identity_from(struct sip_msg *msg, str realm); 130 /** 131 * Returns the Public Identity extracted from the To header 132 * @param msg - the SIP message 133 * @returns the str containing the public id, no mem dup 134 */ 135 str cscf_get_public_identity(struct sip_msg *msg); 136 /** 137 * Returns the Public Identity extracted from the From header 138 * @param msg - the SIP message 139 * @returns the str containing the public id, no mem dup 140 */ 141 str cscf_get_public_identity_from(struct sip_msg *msg); 142 /** 143 * Returns the expires value from the Expires header in the message. 144 * It searches into the Expires header and if not found returns -1 145 * @param msg - the SIP message, if available 146 * @is_shm - msg from from shared memory 147 * @returns the value of the expire or -1 if not found 148 */ 149 int cscf_get_expires_hdr(struct sip_msg *msg, int is_shm); 150 /** 151 * Returns the expires value from the message. 152 * First it searches into the Expires header and if not found it also looks 153 * into the expires parameter in the contact header 154 * @param msg - the SIP message 155 * @param is_shm - msg from shared memory 156 * @returns the value of the expire or the default 3600 if none found 157 */ 158 int cscf_get_max_expires(struct sip_msg *msg, int is_shm); 159 /** 160 * Finds if the message contains the orig parameter in the first Route header 161 * @param msg - the SIP message 162 * @param str1 - not used 163 * @param str2 - not used 164 * @returns #CSCF_RETURN_TRUE if yes, else #CSCF_RETURN_FALSE 165 */ 166 int cscf_has_originating(struct sip_msg *msg, char *str1, char *str2); 167 /** 168 * Looks for the P-Asserted-Identity header and extracts its content 169 * @param msg - the sip message 170 * @is_shm - is the message a shm message 171 * @returns the asserted identity 172 */ 173 str cscf_get_asserted_identity(struct sip_msg *msg, int is_shm); 174 /** 175 * Extracts the realm from a SIP/TEL URI. 176 * - SIP - the hostname 177 * - TEL - the phone-context parameter 178 * @param msg - the SIP message 179 * @returns the realm 180 */ 181 str cscf_get_realm_from_uri(str uri); 182 /** 183 * Delivers the Realm from request URI 184 * @param msg sip message 185 * @returns realm as String on success 0 on fail 186 */ 187 str cscf_get_realm_from_ruri(struct sip_msg *msg); 188 /** 189 * Get the Public Identity from the Request URI of the message 190 * @param msg - the SIP message 191 * @returns the public identity 192 */ 193 str cscf_get_public_identity_from_requri(struct sip_msg *msg); 194 195 /** 196 * Get the contact from the Request URI of the message 197 * NB: free returned result str when done from shm 198 * @param msg - the SIP message 199 * @returns the contact (don't forget to free from shm) 200 * 201 * NOTE: should only be called when REQ URI has been converted sip:user@IP_ADDRESS:PORT or tel:IP_ADDRESS:PORT 202 */ 203 str cscf_get_contact_from_requri(struct sip_msg *msg); 204 205 /** 206 * Looks for the Call-ID header 207 * @param msg - the sip message 208 * @param hr - ptr to return the found hdr_field 209 * @returns the callid value 210 */ 211 str cscf_get_call_id(struct sip_msg *msg, struct hdr_field **hr); 212 /** 213 * Check if the contact has an URI parameter with the value "sos", 214 * used for detecting an Emergency Registration 215 * http://tools.ietf.org/html/draft-patel-ecrit-sos-parameter-0x 216 * @param uri - contact uri to be checked 217 * @return 1 if found, 0 if not, -1 on error 218 */ 219 int cscf_get_sos_uri_param(str uri); 220 /** 221 * Return the P-Visited-Network-ID header 222 * @param msg - the SIP message 223 * @returns the str with the header's body 224 */ 225 str cscf_get_visited_network_id(struct sip_msg *msg, struct hdr_field **h); 226 /** 227 * Adds a header to the message as the first one in the message 228 * @param msg - the message to add a header to 229 * @param content - the str containing the new header 230 * @returns 1 on succes, 0 on failure 231 */ 232 int cscf_add_header_first(struct sip_msg *msg, str *hdr, int type); 233 234 /** 235 * Returns the next header structure for a given header name. 236 * @param msg - the SIP message to look into 237 * @param header_name - the name of the header to search for 238 * @param last_header - last header to ignore in the search, or NULL if to start from the first one 239 * @returns the hdr_field on success or NULL if not found 240 */ 241 struct hdr_field* cscf_get_next_header(struct sip_msg * msg, 242 /** 243 * Looks for the First Via header and returns its body. 244 * @param msg - the SIP message 245 * @param h - the hdr_field to fill with the result 246 * @returns the first via_body 247 */ str header_name, struct hdr_field* last_header); 248 struct via_body* cscf_get_first_via(struct sip_msg *msg, struct hdr_field **h); 249 /** 250 * Looks for the Last Via header and returns it. 251 * @param msg - the SIP message 252 * @returns the last via body body 253 */ 254 struct via_body* cscf_get_last_via(struct sip_msg *msg); 255 /** 256 * Looks for the UE Via in First Via header if its a request 257 * or in the last if its a response and returns its body 258 * @param msg - the SIP message 259 * @returns the via of the UE 260 */ 261 struct via_body* cscf_get_ue_via(struct sip_msg *msg); 262 /** 263 * Looks for the WWW-Authenticate header and returns its body. 264 * @param msg - the SIP message 265 * @param h - the hdr_field to fill with the result 266 * @returns the www-authenticate body 267 */ 268 str cscf_get_authenticate(struct sip_msg *msg, struct hdr_field **h); 269 /** 270 * Adds a header to the message 271 * @param msg - the message to add a header to 272 * @param content - the str containing the new header 273 * @returns 1 on succes, 0 on failure 274 */ 275 int cscf_add_header(struct sip_msg *msg, str *hdr, int type); 276 /** 277 * Get the expires header value from a message. 278 * @param msg - the SIP message 279 * @returns the expires value or -1 if not found 280 */ 281 int cscf_get_expires(struct sip_msg *msg); 282 /** 283 * Check if the message is an initial request for a dialog. 284 * - BYE, PRACK, UPDATE, NOTIFY belong to an already existing dialog 285 * @param msg - the message to check 286 * @returns 1 if initial, 0 if not 287 */ 288 int cscf_is_initial_request(struct sip_msg *msg); 289 290 /** 291 * Get the public identity from P-Asserted-Identity, or From if asserted not found. 292 * @param msg - the SIP message 293 * @param uri - uri to fill into 294 * @returns 1 if found, 0 if not 295 */ 296 int cscf_get_originating_user(struct sip_msg * msg, str *uri); 297 298 /** 299 * Get public identity from Request-URI for terminating. 300 * returns in uri the freshly pkg allocated uri - don't forget to free 301 * @param msg - the SIP message 302 * @param uri - uri to fill into 303 * @returns 1 if found, else 0 304 */ 305 int cscf_get_terminating_user(struct sip_msg * msg, str *uri); 306 307 /** 308 * Return the P-Access-Network-Info header 309 * @param msg - the SIP message 310 * @returns the str with the header's body 311 */ 312 313 str cscf_get_access_network_info(struct sip_msg *msg, struct hdr_field **h); 314 315 /** 316 * Return the P-Charging-Vector header 317 * @param msg - the SIP message 318 * @returns the str with the header's body 319 */ 320 321 str cscf_get_charging_vector(struct sip_msg *msg, struct hdr_field **h); 322 323 /** 324 * Return the P-Charging-Vector tokens 325 * @param msg - the SIP message 326 * @returns the str with icid, orig_ioi and term_ioi 327 */ 328 int cscf_get_p_charging_vector(struct sip_msg *msg, str * icid, str * orig_ioi, 329 str * term_ioi); 330 331 332 /** 333 * Get the to tag 334 * @param msg - the SIP Message to look into 335 * @param tag - the pointer to the tag to write to 336 * @returns 0 on error or 1 on success 337 */ 338 int cscf_get_to_tag(struct sip_msg* msg, str* tag); 339 340 /** 341 * Get the from tag 342 * @param msg - the SIP message to look into 343 * @param tag - the pointer to the tag to write to 344 * @returns 0 on error or 1 on success 345 */ 346 int cscf_get_from_tag(struct sip_msg* msg, str* tag); 347 348 349 350 /** 351 * Get the local uri from the From header. 352 * @param msg - the message to look into 353 * @param local_uri - ptr to fill with the value 354 * @returns 1 on success or 0 on error 355 */ 356 int cscf_get_from_uri(struct sip_msg* msg, str *local_uri); 357 358 /** 359 * Get the local uri from the To header. 360 * @param msg - the message to look into 361 * @param local_uri - ptr to fill with the value 362 * @returns 1 on success or 0 on error 363 */ 364 int cscf_get_to_uri(struct sip_msg* msg, str *local_uri); 365 366 /** 367 * Looks for the Event header and extracts its content. 368 * @param msg - the sip message 369 * @returns the string event value or an empty string if none found 370 */ 371 str cscf_get_event(struct sip_msg *msg); 372 373 /*! \brief 374 * Check if the originating REGISTER message was formed correctly 375 * The whole message must be parsed before calling the function 376 * _s indicates whether the contact was star 377 */ 378 int cscf_check_contacts(struct sip_msg* _m, int* _s); 379 380 /*! \brief 381 * parse all the messages required by the registrar 382 */ 383 int cscf_parse_message_for_register(struct sip_msg* _m); 384 385 /** 386 * Returns the content of the P-Associated-URI header 387 * Public_id is pkg_alloced and should be later freed. 388 * Inside values are not duplicated. 389 * @param msg - the SIP message to look into 390 * @param public_id - array to be allocated and filled with the result 391 * @param public_id_cnt - the size of the public_id array 392 * @param is_shm - msg from shared memory 393 * @returns 1 on success or 0 on error 394 */ 395 int cscf_get_p_associated_uri(struct sip_msg *msg,str **public_id,int *public_id_cnt, int is_shm); 396 397 /** 398 * Looks for the realm parameter in the Authorization header and returns its value. 399 * @param msg - the SIP message 400 * @returns the realm 401 */ 402 str cscf_get_realm(struct sip_msg *msg); 403 404 /** 405 * Returns the content of the Service-Route header. 406 * data vector is pkg_alloced and should be later freed 407 * inside values are not duplicated 408 * @param msg - the SIP message 409 * @param size - size of the returned vector, filled with the result 410 * @param is_shm - msg from shared memory 411 * @returns - the str vector of uris 412 */ 413 str* cscf_get_service_route(struct sip_msg *msg, int *size, int is_shm); 414 415 /** 416 * Returns the s_dialog_direction from the direction string. 417 * @param direction - "orig" or "term" 418 * @returns the s_dialog_direction if ok or #DLG_MOBILE_UNKNOWN if not found 419 */ 420 enum cscf_dialog_direction cscf_get_dialog_direction(char *direction); 421 422 long cscf_get_content_length (struct sip_msg* msg); 423 424 /** 425 * Looks for the Contact header and extracts its content 426 * @param msg - the sip message 427 * @returns the first contact in the message 428 */ 429 str cscf_get_contact(struct sip_msg *msg); 430 431 /** 432 * Adds a header to the reply message 433 * @param msg - the request to add a header to its reply 434 * @param content - the str containing the new header 435 * @returns 1 on succes, 0 on failure 436 */ 437 int cscf_add_header_rpl(struct sip_msg *msg, str *hdr); 438 439 /** 440 * Looks for the Call-ID header 441 * @param msg - the sip message 442 * @param hr - ptr to return the found hdr_field 443 * @returns the callid value 444 */ 445 int cscf_get_cseq(struct sip_msg *msg,struct hdr_field **hr); 446 447 /** 448 * Looks for the P-Called-Party-ID header and extracts the public identity from it 449 * @param msg - the sip message 450 * @param hr - ptr to return the found hdr_field 451 * @returns the P-Called_Party-ID 452 */ 453 str cscf_get_public_identity_from_called_party_id(struct sip_msg *msg,struct hdr_field **hr); 454 455 #endif 456 457