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