1 /*
2  * This file is part of the Sofia-SIP package
3  *
4  * Copyright (C) 2005 Nokia Corporation.
5  *
6  * Contact: Pekka Pessi <pekka.pessi@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  */
24 
25 #ifndef SIP_HEADER_H
26 /**Defined when <sofia-sip/sip_header.h> has been included.*/
27 #define SIP_HEADER_H
28 
29 /**@file sofia-sip/sip_header.h
30  *
31  * SIP parser library prototypes.
32  *
33  * @author Pekka Pessi <Pekka.Pessi@nokia.com>.
34  *
35  * @date  Created: Tue Jun 13 02:58:26 2000 ppessi
36  */
37 
38 #ifndef SU_ALLOC_H
39 #include <sofia-sip/su_alloc.h>
40 #endif
41 
42 #ifndef SU_TAG_H
43 #include <sofia-sip/su_tag.h>
44 #endif
45 
46 #ifndef SIP_H
47 #include <sofia-sip/sip.h>
48 #endif
49 
50 #ifndef MSG_HEADER_H
51 #include <sofia-sip/msg_header.h>
52 #endif
53 
54 #ifndef _STRING_H
55 #include <string.h>
56 #endif
57 
58 SOFIA_BEGIN_DECLS
59 
60 /** Return a built-in SIP parser object. */
61 SOFIAPUBFUN msg_mclass_t const *sip_default_mclass(void);
62 
63 /** Release SIP parser object if it was cloned. */
64 SOFIAPUBFUN void sip_cloned_parser_destroy(void);
65 
66 SOFIAPUBFUN int sip_update_default_mclass(msg_mclass_t const *mclass);
67 SOFIAPUBFUN msg_mclass_t *sip_extend_mclass(msg_mclass_t *input);
68 
69 /** Check that sip_t is a SIP header structure (not MIME or HTTP). @HIDE */
70 #define sip_is_sip(sip) ((sip) && (sip)->sip_ident == SIP_PROTOCOL_TAG)
71 
72 /** Initializer for a SIP header structure. @HIDE */
73 #define SIP_HDR_INIT(name) {{{ 0, 0, sip_##name##_class }}}
74 
75 /** Initialize a SIP header structure. @HIDE */
76 #define SIP_HEADER_INIT(h, sip_class, size)	       \
77   ((void)memset((h), 0, (size)),		       \
78    (void)(((sip_common_t *)(h))->h_class = (sip_class)),	\
79    (h))
80 
81 /** Serialize headers into the fragment chain. */
82 SOFIAPUBFUN int sip_serialize(msg_t *msg, sip_t *sip);
83 
84 /** Encode a SIP message. */
85 SOFIAPUBFUN issize_t sip_e(sip_t const *sip, int flags, char b[], isize_t size);
86 
87 /** Test if @a header is a pointer to a SIP header object. */
88 SOFIAPUBFUN int sip_is_header(sip_header_t const *header);
89 
90 /** Convert the header @a h to a string allocated from @a home. */
91 SOFIAPUBFUN char *sip_header_as_string(su_home_t *home,
92 				       sip_header_t const *h);
93 
94 /** Add a duplicate of header object to a SIP message. */
95 SOFIAPUBFUN int sip_add_dup(msg_t *, sip_t *, sip_header_t const *);
96 
97 /** Add a duplicate of header object to the SIP message. */
98 SOFIAPUBFUN int sip_add_dup_as(msg_t *msg, sip_t *sip,
99 			       msg_hclass_t *hc, sip_header_t const *o);
100 
101 /** Add duplicates of headers to the SIP message. */
102 SOFIAPUBFUN int sip_add_headers(msg_t *msg, sip_t *sip,
103 				void const *extra, va_list headers);
104 
105 /** Add duplicates of headers from taglist to the SIP message. */
106 SOFIAPUBFUN int sip_add_tl(msg_t *msg, sip_t *sip,
107 			   tag_type_t tag, tag_value_t value, ...);
108 
109 /** Add duplicates of headers from taglist to the SIP message. */
110 SOFIAPUBFUN int sip_add_tagis(msg_t *, sip_t *, tagi_t const **inout_list);
111 
112 /** Parse a string as a header and add it to the SIP message. */
113 SOFIAPUBFUN int sip_add_make(msg_t *, sip_t *, msg_hclass_t *hc, char const *s);
114 
115 /** Convert headers from taglist as URL query. */
116 SOFIAPUBFUN char *sip_headers_as_url_query(su_home_t *home,
117 					   tag_type_t tag, tag_value_t value,
118 					   ...);
119 
120 /** Convert URL query to a tag list. */
121 SOFIAPUBFUN tagi_t *sip_url_query_as_taglist(su_home_t *home,
122 					     char const *query,
123 					     msg_mclass_t const *parser);
124 
125 /** Complete SIP message. */
126 SOFIAPUBFUN int sip_complete_message(msg_t *msg);
127 
128 /** Clear encoded data. @HIDE */
129 #define sip_fragment_clear(a) ((a)->h_data = NULL, (a)->h_len = 0)
130 
131 /* Use __attribute__ to allow argument checking for sip_header_format() */
132 #if !defined(__GNUC__) && !defined(__attribute__)
133 #define __attribute__(x)
134 #endif
135 
136 /** Make a SIP header with formatting provided. */
137 SOFIAPUBFUN sip_header_t *sip_header_format(su_home_t *home,
138 					    msg_hclass_t *hc,
139 					    char const *fmt,
140 					    ...)
141   __attribute__((__format__ (printf, 3, 4)));
142 
143 /** Return current time */
144 SOFIAPUBFUN sip_time_t sip_now(void);
145 
146 SOFIAPUBVAR char const sip_method_name_ack[];
147 SOFIAPUBVAR char const sip_method_name_bye[];
148 SOFIAPUBVAR char const sip_method_name_cancel[];
149 SOFIAPUBVAR char const sip_method_name_invite[];
150 SOFIAPUBVAR char const sip_method_name_options[];
151 SOFIAPUBVAR char const sip_method_name_register[];
152 SOFIAPUBVAR char const sip_method_name_info[];
153 SOFIAPUBVAR char const sip_method_name_prack[];
154 SOFIAPUBVAR char const sip_method_name_comet[];
155 SOFIAPUBVAR char const sip_method_name_message[];
156 SOFIAPUBVAR char const sip_method_name_subscribe[];
157 SOFIAPUBVAR char const sip_method_name_notify[];
158 SOFIAPUBVAR char const sip_method_name_refer[];
159 
160 /** @internal UDP transport version string. */
161 SOFIAPUBVAR char const sip_transport_udp[];
162 /** @internal TCP transport version string. */
163 SOFIAPUBVAR char const sip_transport_tcp[];
164 /** @internal SCTP transport version string. */
165 SOFIAPUBVAR char const sip_transport_sctp[];
166 /** @internal TLS transport version string. */
167 SOFIAPUBVAR char const sip_transport_tls[];
168 /** @internal WS transport version string. */
169 SOFIAPUBVAR char const sip_transport_ws[];
170 /** @internal WSS transport version string. */
171 SOFIAPUBVAR char const sip_transport_wss[];
172 /** @internal SIP version string. */
173 SOFIAPUBVAR char const sip_version_2_0[];
174 
175 #define SIP_VERSION_CURRENT sip_version_2_0
176 
177 /** SIP parser version */
178 SOFIAPUBVAR char const sip_parser_version[];
179 
180 /** Get SIP service name */
181 #define SIP_PORT(s) ((s) ? (s) : "5060")
182 
183 /** Get SIPS service name */
184 #define SIPS_PORT(s) ((s) ? (s) : "5061")
185 
186 /** Return string corresponding to the method. */
187 SOFIAPUBFUN char const *sip_method_name(sip_method_t method, char const *name);
188 
189 /** Return code corresponding to the method code */
190 SOFIAPUBFUN sip_method_t sip_method_code(char const *name);
191 
192 SOFIAPUBVAR char const * const sip_method_names[];
193 
194 #define SIP_METHOD_NAME(method, name) \
195  ((method) == sip_method_unknown ? (name) : sip_method_name(method, name))
196 
197 #define sip_header_make(h, c, s) \
198   ((sip_header_t *)msg_header_make((h), (c), (s)))
199 #define sip_header_vformat(h, c, f, a) \
200   ((sip_header_t *)msg_header_vformat((h), (c), (f), (a)))
201 
202 SOFIA_END_DECLS
203 #ifndef SIP_PROTOS_H
204 #include <sofia-sip/sip_protos.h>
205 #endif
206 SOFIA_BEGIN_DECLS
207 
208 /** Create a request line object. */
209 SOFIAPUBFUN
210 sip_request_t *sip_request_create(su_home_t *home,
211 				  sip_method_t method, const char *name,
212 				  url_string_t const *url,
213 				  char const *version);
214 
215 /** Create a status line object. */
216 SOFIAPUBFUN
217 sip_status_t *sip_status_create(su_home_t *home,
218 				unsigned status,
219 				char const *phrase,
220 				char const *version);
221 
222 /** Create a @CallID header object. */
223 SOFIAPUBFUN sip_call_id_t *sip_call_id_create(su_home_t *home,
224 					      char const *domain);
225 
226 /** Create a @CSeq header object.  */
227 SOFIAPUBFUN sip_cseq_t *sip_cseq_create(su_home_t *, uint32_t seq,
228 					unsigned method, char const *name);
229 
230 /** Create a @Identity header object.  */
231 SOFIAPUBFUN sip_identity_t *sip_identity_create(su_home_t *, uint32_t seq,
232 					unsigned method, char const *name);
233 
234 /** Create a @Contact header object. */
235 SOFIAPUBFUN sip_contact_t * sip_contact_create(su_home_t *,
236 					       url_string_t const *url,
237 					       char const *param,
238 					       /* char const *params, */
239 					       ...);
240 
241 /** Calculate expiration time of a @Contact header. */
242 SOFIAPUBFUN sip_time_t sip_contact_expires(sip_contact_t const *m,
243 					   sip_expires_t const *ex,
244 					   sip_date_t const *date,
245 					   sip_time_t def,
246 					   sip_time_t now);
247 
248 /** Create a @ContentLength header object. */
249 SOFIAPUBFUN
250 sip_content_length_t *sip_content_length_create(su_home_t *, uint32_t n);
251 
252 /** Create an @Date header object. */
253 SOFIAPUBFUN sip_date_t *sip_date_create(su_home_t *, sip_time_t t);
254 
255 /** Create an @Expires header object. */
256 SOFIAPUBFUN sip_expires_t *sip_expires_create(su_home_t *, sip_time_t delta);
257 
258 /** Create a @Route header object. */
259 SOFIAPUBFUN sip_route_t *sip_route_create(su_home_t *home, url_t const *url,
260 					  url_t const *maddr);
261 
262 /** Create a @RecordRoute header object. */
263 SOFIAPUBFUN sip_record_route_t *sip_record_route_create(su_home_t *,
264 							url_t const *rq_url,
265 							url_t const *m_url);
266 
267 /** Create a @From header object. */
268 SOFIAPUBFUN sip_from_t *sip_from_create(su_home_t *, url_string_t const *url);
269 
270 SOFIAPUBFUN int sip_from_tag(su_home_t *, sip_from_t *from, char const *tag);
271 
272 /** Create a @To header object. */
273 SOFIAPUBFUN sip_to_t *sip_to_create(su_home_t *, url_string_t const *url);
274 
275 SOFIAPUBFUN int sip_to_tag(su_home_t *, sip_to_t *to, char const *tag);
276 
277 /** Create a @Via object. */
278 SOFIAPUBFUN sip_via_t *sip_via_create(su_home_t *h,
279 				      char const *host,
280 				      char const *port,
281 				      char const *transport,
282 				      /* char const *params */
283 				      ...);
284 
285 /** Get transport protocol name. */
286 #if SU_HAVE_INLINE
sip_via_transport(sip_via_t const * v)287 su_inline char const *sip_via_transport(sip_via_t const *v)
288 {
289   char const *tp = v->v_protocol;
290   if (tp) {
291     tp = strchr(tp, '/');
292     if (tp) {
293       tp = strchr(tp + 1, '/');
294       if (tp)
295 	return tp + 1;
296     }
297   }
298   return NULL;
299 }
300 #else
301 char const *sip_via_transport(sip_via_t const *v);
302 #endif
303 
304 SOFIAPUBFUN char const *sip_via_port(sip_via_t const *v, int *using_rport);
305 
306 SOFIAPUBFUN
307 sip_payload_t *sip_payload_create(su_home_t *, void const *data, isize_t len);
308 
309 /**@ingroup sip_payload
310  *
311  * Initialize a SIP payload structure with pointer to data and its length.
312  *
313  * The SIP_PAYLOAD_INIT2() macro initializes a #sip_payload_t header
314  * structure with a pointer to data and its length in octets. For
315  * instance,
316  * @code
317  *  sip_payload_t txt_payload = SIP_PAYLOAD_INIT2(txt, strlen(txt));
318  * @endcode
319  *
320  * The SIP_PAYLOAD_INIT2() macro can be used when creating a new payload
321  * from heap is not required, for instance, when the resulting payload
322  * structure is immediately copied.
323  *
324  * @HIDE
325  */
326 #define SIP_PAYLOAD_INIT2(data, length) \
327   {{{ 0, 0, sip_payload_class, data, length }}, NULL, data, length }
328 
329 /** Create a SIP separator line structure. */
330 SOFIAPUBFUN sip_separator_t *sip_separator_create(su_home_t *home);
331 
332 /** Check that a required feature is supported. */
333 SOFIAPUBFUN
334 sip_unsupported_t *sip_has_unsupported(su_home_t *,
335 				       sip_supported_t const *support,
336 				       sip_require_t const *require);
337 
338 SOFIAPUBFUN
339 sip_unsupported_t *sip_has_unsupported2(su_home_t *,
340 					sip_supported_t const *support,
341 					sip_require_t const *by_require,
342 					sip_require_t const *require);
343 
344 SOFIAPUBFUN
345 sip_unsupported_t *
346 sip_has_unsupported_any(su_home_t *,
347 			sip_supported_t const *support,
348 			sip_require_t const *by_require,
349 			sip_proxy_require_t const *by_proxy_require,
350 			sip_require_t const *require,
351 			sip_require_t const *require2,
352 			sip_require_t const *require3);
353 
354 /** Check that a feature is supported. */
355 SOFIAPUBFUN
356 int sip_has_supported(sip_supported_t const *support, char const *feature);
357 
358 /** Check that a feature is in the list. */
359 SOFIAPUBFUN
360 int sip_has_feature(msg_list_t const *supported, char const *feature);
361 
362 /** Return true if the method is listed in @Allow header. */
363 SOFIAPUBFUN int sip_is_allowed(sip_allow_t const *allow,
364 			       sip_method_t method, char const *name);
365 
366 /** Check if the well-known method is listed in @Allow header. @NEW_1_12_6. */
367 #define SIP_IS_ALLOWED(allow, method) \
368   (sip_method_unknown < (method) && (method) < 32 && \
369    (allow) && ((allow)->k_bitmap & (1 << (method))) != 0)
370 
371 /**
372  * Bitmasks for header classifications.
373  *
374  * If parsing of a particular header fails, the error bits in #msg_t are
375  * updated. The error bits can be obtained via msg_extract_errors() after
376  * parsing. The header-specific bits are stored along with the
377  * @ref msg_hclass_t "header class" in the #msg_href_t structure, found in
378  * the parser tables of the #msg_mclass_t object.
379  *
380  * @sa NTATAG_BAD_REQ_MASK(), NTATAG_BAD_RESP_MASK(),
381  * #msg_mclass_t, struct #msg_mclass_s, msg_mclass_clone(),
382  * msg_mclass_insert_with_mask(),
383  * #msg_href_t, struct #msg_href_s, msg_mclass_insert().
384  */
385 enum sip_bad_mask {
386   /** Bit marking essential headers in a request message.
387    *
388    * @ref sip_request \"request line\"", @From, @To, @CSeq, @CallID,
389    * @ContentLength, @Via
390    */
391   sip_mask_request = (1 << 0),
392 
393   /** Bit marking essential headers in a response message.
394    *
395    * @ref sip_status \"status line\"", @From, @To, @CSeq, @CallID,
396    * @ContentLength, @Via
397    */
398   sip_mask_response = (1 << 1),
399 
400   /** Bit marking essential headers for User-Agent.
401    *
402    * @ContentType, @ContentDisposition, @ContentEncoding, @Supported,
403    * @Contact, @Require, and @RecordRoute.
404    */
405   sip_mask_ua = (1 << 2),
406 
407   /** Bit marking essential headers for proxy server.
408    *
409    * @Route, @MaxForwards, @ProxyRequire, @ProxyAuthorization, @Supported,
410    * @Contact, and @RecordRoute.
411    */
412   sip_mask_proxy = (1 << 3),
413 
414   /** Bit marking essential headers for registrar server.
415    *
416    * @MinExpires, @Authorization, @Path, @Supported, @Contact, @Require, and
417    * @Expires.
418    *
419    */
420   sip_mask_registrar = (1 << 4),
421 
422   /** Bit marking essential headers for 100rel extension.
423    *
424    * @RAck and @RSeq.
425    *
426    * @sa @RFC3262.
427    */
428   sip_mask_100rel = (1 << 5),
429 
430   /** Bit marking essential headers for SIP events.
431    *
432    * @Event, @Expires, and @SubscriptionState.
433    *
434    * @sa @RFC3265.
435    */
436   sip_mask_events = (1 << 6),
437 
438   /** Bit marking essential headers for session timer extension.
439    *
440    * @SessionExpires, and @MinSE.
441    *
442    * @RFC4028
443    */
444   sip_mask_timer = (1 << 7),
445 
446   /** Bit marking essential headers for privacy extension.
447    *
448    * @Privacy.
449    *
450    * @sa @RFC3323
451    */
452   sip_mask_privacy = (1 << 8),
453 
454   /** Bit marking essential headers for caller preference extension.
455    *
456    * @RequestDisposition, @AcceptContact, and @RejectContact.
457    *
458    * @sa @RFC3841.
459    */
460   sip_mask_pref = (1 << 9),
461 
462   /** Bit marking essential headers for PUBLISH servers and clients.
463    *
464    * @SIPETag, and @SIPIfMatch.
465    *
466    * @sa @RFC3903.
467    */
468   sip_mask_publish = (1 << 10)
469 
470   /* NOTE:
471    * When adding bits, please update nta_agent_create() and
472    * NTATAG_BAD_RESP_MASK()/NTATAG_BAD_REQ_MASK() documentation.
473    */
474 };
475 
476 /* ------------------------------------------------------------------------- */
477 
478 /* Here are @deprecated functions and names for compatibility */
479 
480 /** Encode a SIP header field (name: contents CRLF). */
481 SOFIAPUBFUN issize_t sip_header_e(char[], isize_t, sip_header_t const *, int);
482 
483 /** Decode a SIP header string (name: contents CRLF?). */
484 SOFIAPUBFUN
485 sip_header_t *sip_header_d(su_home_t *, msg_t const *, char const *);
486 
487 /** Encode contents of a SIP header field. */
488 SOFIAPUBFUN issize_t sip_header_field_e(char[], isize_t, sip_header_t const *, int);
489 
490 /** Decode the string containing header field */
491 SOFIAPUBFUN issize_t sip_header_field_d(su_home_t *, sip_header_t *, char *, isize_t);
492 
493 /** Calculate the size of a SIP header and associated memory areas. */
494 SOFIAPUBFUN isize_t sip_header_size(sip_header_t const *h);
495 
496 /** Duplicate (deep copy) a SIP header or whole list. */
497 SOFIAPUBFUN sip_header_t *sip_header_dup(su_home_t *, sip_header_t const *);
498 
499 /** Copy a SIP header or whole list. */
500 SOFIAPUBFUN sip_header_t *sip_header_copy(su_home_t *, sip_header_t const *o);
501 
502 /** Add an event to @AllowEvents header. */
503 SOFIAPUBFUN int sip_allow_events_add(su_home_t *,
504 				     sip_allow_events_t *ae,
505 				     char const *e);
506 
507 /** Add a parameter to a @Contact header object. */
508 SOFIAPUBFUN int sip_contact_add_param(su_home_t *, sip_contact_t *,
509 				      char const *param);
510 
511 SOFIAPUBFUN int sip_to_add_param(su_home_t *, sip_to_t *, char const *);
512 
513 SOFIAPUBFUN int sip_from_add_param(su_home_t *, sip_from_t *, char const *);
514 
515 /** Add a parameter to a @Via header object. */
516 SOFIAPUBFUN int sip_via_add_param(su_home_t *, sip_via_t *, char const *);
517 
518 #define sip_from_make_url     sip_from_create
519 #define sip_to_make_url       sip_to_create
520 #define sip_params_find       msg_params_find
521 
522 SOFIA_END_DECLS
523 
524 #endif
525