4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
38 #include "sip_miscdefs.h"
39 #include "sip_parse_generic.h"
41 sip_methods_t sip_methods
[MAX_SIP_METHODS
] = {
57 * Built-In Header function table
59 sip_header_function_t sip_header_function_table
[] = {
60 {"Unknown", NULL
, sip_parse_unknown_header
, NULL
, NULL
, NULL
},
61 {"CONTACT", "m", sip_parse_cftr_header
, NULL
, NULL
,
62 sip_free_cftr_header
},
63 {"FROM", "F", sip_parse_cftr_header
, NULL
, NULL
, sip_free_cftr_header
},
64 {"TO", "T", sip_parse_cftr_header
, NULL
, NULL
, sip_free_cftr_header
},
65 {"CONTENT-LENGTH", "l", sip_parse_clen_header
, NULL
, NULL
,
67 {"CONTENT-TYPE", "c", sip_parse_ctype_header
, NULL
, NULL
,
69 {"CALL-ID", "i", sip_parse_cid_header
, NULL
, NULL
, sip_free_phdr
},
70 {"CSEQ", NULL
, sip_parse_cseq_header
, NULL
, NULL
, sip_free_phdr
},
71 {"VIA", "v", sip_parse_via_header
, NULL
, NULL
, sip_free_phdr
},
72 {"Max-Forwards", NULL
, sip_parse_maxf_header
, NULL
, NULL
,
74 {"RECORD-ROUTE", NULL
, sip_parse_cftr_header
, NULL
, NULL
,
75 sip_free_cftr_header
},
76 {"ROUTE", NULL
, sip_parse_cftr_header
, NULL
, NULL
,
77 sip_free_cftr_header
},
78 {"ACCEPT", NULL
, sip_parse_acpt_header
, NULL
, NULL
, sip_free_phdr
},
79 {"ACCEPT-ENCODING", NULL
, sip_parse_acpt_encode_header
, NULL
, NULL
,
81 {"ACCEPT-LANGUAGE", NULL
, sip_parse_acpt_lang_header
, NULL
, NULL
,
83 {"ALERT-INFO", NULL
, sip_parse_alert_header
, NULL
, NULL
, sip_free_phdr
},
84 {"ALLOW", NULL
, sip_parse_allow_header
, NULL
, NULL
, sip_free_phdr
},
85 {"CALL-INFO", NULL
, sip_parse_callinfo_header
, NULL
, NULL
,
87 {"CONTENT-DISPOSITION", NULL
, sip_parse_contentdis_header
, NULL
, NULL
,
89 {"CONTENT-ENCODING", "e", sip_parse_contentencode_header
, NULL
, NULL
,
91 {"CONTENT-LANGUAGE", NULL
, sip_parse_contentlang_header
, NULL
, NULL
,
93 {"DATE", NULL
, sip_parse_date_header
, NULL
, NULL
, sip_free_phdr
},
94 {"ERROR-INFO", NULL
, sip_parse_errorinfo_header
, NULL
, NULL
,
96 {"EXPIRES", NULL
, sip_parse_expire_header
, NULL
, NULL
, sip_free_phdr
},
97 {"IN-REPLY-TO", NULL
, sip_parse_inreplyto_header
, NULL
, NULL
,
99 {"MIN-EXPIRES", NULL
, sip_parse_minexpire_header
, NULL
, NULL
,
101 {"MIME-VERSION", NULL
, sip_parse_mimeversion_header
, NULL
, NULL
,
103 {"ORGANIZATION", NULL
, sip_parse_org_header
, NULL
, NULL
, sip_free_phdr
},
104 {"PRIORITY", NULL
, sip_parse_priority_header
, NULL
, NULL
,
106 {"REQUIRE", NULL
, sip_parse_require_header
, NULL
, NULL
, sip_free_phdr
},
107 {"REPLY-TO", NULL
, sip_parse_replyto_header
, NULL
, NULL
, sip_free_phdr
},
108 {"RETRY-AFTER", NULL
, sip_parse_retryaft_header
, NULL
, NULL
,
110 {"SERVER", NULL
, sip_parse_server_header
, NULL
, NULL
, sip_free_phdr
},
111 {"SUBJECT", "s", sip_parse_subject_header
, NULL
, NULL
, sip_free_phdr
},
112 {"TIMESTAMP", NULL
, sip_parse_timestamp_header
, NULL
, NULL
,
114 {"UNSUPPORTED", NULL
, sip_parse_usupport_header
, NULL
, NULL
,
116 {"SUPPORTED", "k", sip_parse_support_header
, NULL
, NULL
, sip_free_phdr
},
117 {"USER-AGENT", NULL
, sip_parse_useragt_header
, NULL
, NULL
,
119 {"WARNING", NULL
, sip_parse_warn_header
, NULL
, NULL
, sip_free_phdr
},
120 {"ALLOW-EVENTS", "u", sip_parse_allow_events_header
, NULL
, NULL
,
122 {"EVENT", "o", sip_parse_event_header
, NULL
, NULL
, sip_free_phdr
},
123 {"SUBSCRIPTION-STATE", NULL
, sip_parse_substate_header
, NULL
, NULL
,
125 {"AUTHORIZATION", NULL
, sip_parse_author_header
, NULL
, NULL
,
127 {"AUTHENTICATION-INFO", NULL
, sip_parse_ainfo_header
, NULL
, NULL
,
129 {"PROXY-AUTHORIZATION", NULL
, sip_parse_pauthor_header
, NULL
, NULL
,
131 {"PROXY-AUTHENTICATE", NULL
, sip_parse_pauthen_header
, NULL
, NULL
,
133 {"PROXY-REQUIRE", NULL
, sip_parse_preq_header
, NULL
, NULL
,
135 {"WWW-AUTHENTICATE", NULL
, sip_parse_wauthen_header
, NULL
, NULL
,
137 {"RSEQ", NULL
, sip_parse_rseq
, NULL
, NULL
, sip_free_phdr
},
138 {"RACK", NULL
, sip_parse_rack
, NULL
, NULL
, sip_free_phdr
},
139 {"P-ASSERTED-IDENTITY", NULL
, sip_parse_passertedid
, NULL
, NULL
,
141 {"P-PREFERRED-IDENTITY", NULL
, sip_parse_ppreferredid
, NULL
, NULL
,
143 {"PRIVACY", NULL
, sip_parse_privacy_header
, NULL
, NULL
, sip_free_phdr
},
144 {NULL
, NULL
, NULL
, NULL
, NULL
, NULL
},
147 #define MAX_SIP_HEADERS \
148 sizeof (sip_header_function_table) / sizeof (sip_header_function_t)
151 * External/application provided function table
153 sip_header_function_t
*sip_header_function_table_external
= NULL
;
156 * Free parameter list
159 sip_free_params(sip_param_t
*param_list
)
161 sip_param_t
*param
, *next_param
;
165 while (param
!= NULL
) {
166 next_param
= param
->param_next
;
173 * Common header free routine
176 sip_free_phdr(sip_parsed_header_t
*header
)
178 sip_hdr_value_t
*value
;
179 sip_hdr_value_t
*next_value
;
183 value
= (sip_hdr_value_t
*)header
->value
;
184 while (value
!= NULL
) {
185 sip_free_params(value
->sip_param_list
);
186 next_value
= value
->sip_next_value
;
194 * Free Contact/From/To header
197 sip_free_cftr_header(sip_parsed_header_t
*header
)
199 sip_hdr_value_t
*value
;
200 sip_hdr_value_t
*next_value
;
204 value
= (sip_hdr_value_t
*)header
->value
;
205 while (value
!= NULL
) {
206 next_value
= value
->sip_next_value
;
207 sip_free_params(value
->sip_param_list
);
208 if (value
->cftr_name
!= NULL
)
209 free(value
->cftr_name
);
210 if (value
->sip_value_parsed_uri
!= NULL
) {
211 sip_free_parsed_uri(value
->sip_value_parsed_uri
);
212 value
->sip_value_parsed_uri
= NULL
;
224 sip_new_header(int header_size
)
226 _sip_header_t
*new_header
;
228 new_header
= calloc(1, sizeof (_sip_header_t
));
229 if (new_header
== NULL
)
233 * We are using snprintf which adds a null character
234 * so allocate an extra byte which is not part of
237 new_header
->sip_hdr_start
= calloc(1, header_size
+ 1);
238 if (new_header
->sip_hdr_start
== NULL
) {
242 new_header
->sip_hdr_end
= new_header
->sip_hdr_start
+ header_size
;
243 new_header
->sip_hdr_current
= new_header
->sip_hdr_start
;
244 new_header
->sip_hdr_allocated
= B_TRUE
;
249 * Free the given header
252 sip_free_header(_sip_header_t
*sip_header
)
254 if (sip_header
->sip_hdr_allocated
) {
255 assert(sip_header
->sip_hdr_start
!= NULL
);
256 free(sip_header
->sip_hdr_start
);
258 if (sip_header
->sip_hdr_parsed
!= NULL
) {
259 assert(sip_header
->sip_header_functions
!= NULL
);
260 if (sip_header
->sip_header_functions
->header_free
!= NULL
) {
261 sip_header
->sip_header_functions
->header_free(
262 sip_header
->sip_hdr_parsed
);
269 * Return a copy of the header passed in.
272 sip_dup_header(_sip_header_t
*from
)
277 hdr_size
= from
->sip_hdr_end
- from
->sip_hdr_start
;
278 to
= sip_new_header(hdr_size
);
281 if (from
->sip_header_state
== SIP_HEADER_DELETED_VAL
) {
282 to
->sip_hdr_end
= to
->sip_hdr_start
+
283 sip_copy_values(to
->sip_hdr_start
, from
);
285 (void) memcpy(to
->sip_hdr_start
, from
->sip_hdr_start
, hdr_size
);
286 to
->sip_hdr_end
= to
->sip_hdr_start
+ hdr_size
;
288 to
->sip_header_functions
= from
->sip_header_functions
;
293 * Copy header with extra_param, if any, to sip_msg
296 _sip_copy_header(_sip_msg_t
*sip_msg
, _sip_header_t
*header
, char *extra_param
,
299 _sip_header_t
*new_header
;
306 assert(mutex_held(&sip_msg
->sip_msg_mutex
));
308 if (extra_param
!= NULL
) {
309 extra_len
= SIP_SPACE_LEN
+ sizeof (char) + SIP_SPACE_LEN
+
313 * Just take one if there are more, i.e. if this is the last header
314 * before the content.
317 if (header
->sip_hdr_end
- strlen(SIP_CRLF
) <=
318 header
->sip_hdr_start
) {
321 p
= header
->sip_hdr_end
- strlen(SIP_CRLF
);
322 while (strncmp(SIP_CRLF
, p
, strlen(SIP_CRLF
)) == 0) {
324 if (p
- strlen(SIP_CRLF
) < header
->sip_hdr_start
)
326 p
-= strlen(SIP_CRLF
);
331 ncrlf
= (ncrlf
- 1) * strlen(SIP_CRLF
);
334 hdrlen
= header
->sip_hdr_end
- header
->sip_hdr_start
- ncrlf
;
335 new_header
= sip_new_header(hdrlen
+ extra_len
);
336 if (new_header
== NULL
)
338 if (header
->sip_header_state
== SIP_HEADER_DELETED_VAL
) {
341 len
= sip_copy_values(new_header
->sip_hdr_start
, header
);
342 new_header
->sip_hdr_end
= new_header
->sip_hdr_start
+ len
;
343 hdrlen
= hdrlen
- len
+ extra_len
;
345 (void) memcpy(new_header
->sip_hdr_start
, header
->sip_hdr_start
,
347 new_header
->sip_hdr_end
= new_header
->sip_hdr_start
+ hdrlen
;
350 if (extra_param
!= NULL
) {
354 if (sip_find_cr(new_header
) != 0) {
355 sip_free_header(new_header
);
358 hdrlen
+= new_header
->sip_hdr_end
- new_header
->sip_hdr_current
;
359 (void) snprintf(new_header
->sip_hdr_current
, hdrlen
+ 1,
360 " %c %s%s", SIP_SEMI
, extra_param
, SIP_CRLF
);
363 new_header
->sip_hdr_end
+= extra_len
;
364 new_header
->sip_header_functions
= header
->sip_header_functions
;
365 _sip_add_header(sip_msg
, new_header
, B_TRUE
, B_FALSE
, NULL
);
370 * Copy all "header_name" headers from _old_msg to _new_msg
373 _sip_find_and_copy_all_header(_sip_msg_t
*_old_msg
, _sip_msg_t
*_new_msg
,
376 _sip_header_t
*header
;
379 if (_old_msg
== NULL
|| _new_msg
== NULL
)
382 assert(mutex_held(&_old_msg
->sip_msg_mutex
));
384 if (_old_msg
!= _new_msg
)
385 (void) pthread_mutex_lock(&_new_msg
->sip_msg_mutex
);
386 header
= sip_search_for_header(_old_msg
, header_name
, NULL
);
387 while (header
!= NULL
) {
388 ret
= _sip_copy_header(_new_msg
, header
, NULL
, B_TRUE
);
391 header
= sip_search_for_header(_old_msg
, header_name
, header
);
393 if (_old_msg
!= _new_msg
)
394 (void) pthread_mutex_unlock(&_new_msg
->sip_msg_mutex
);
399 * Copy header_name from _old_msg to _new_msg with extra_parm.
402 _sip_find_and_copy_header(sip_msg_t _old_msg
, sip_msg_t _new_msg
,
403 char *header_name
, char *extra_param
, boolean_t lock_newmsg
)
405 _sip_header_t
*header
;
408 if (_old_msg
== NULL
|| _new_msg
== NULL
)
411 assert(mutex_held(&_old_msg
->sip_msg_mutex
));
413 header
= sip_search_for_header(_old_msg
, header_name
, NULL
);
417 (void) pthread_mutex_lock(&_new_msg
->sip_msg_mutex
);
418 ret
= _sip_copy_header(_new_msg
, header
, extra_param
, B_TRUE
);
420 (void) pthread_mutex_unlock(&_new_msg
->sip_msg_mutex
);
425 * Copy all headers from old_msg to new_msg
428 sip_copy_all_headers(sip_msg_t old_msg
, sip_msg_t new_msg
)
430 _sip_header_t
*header
;
431 _sip_msg_t
*_old_msg
;
432 _sip_msg_t
*_new_msg
;
435 if (old_msg
== NULL
|| new_msg
== NULL
)
437 _old_msg
= (_sip_msg_t
*)old_msg
;
438 _new_msg
= (_sip_msg_t
*)new_msg
;
440 (void) pthread_mutex_lock(&_old_msg
->sip_msg_mutex
);
441 (void) pthread_mutex_lock(&_new_msg
->sip_msg_mutex
);
442 header
= sip_search_for_header(_old_msg
, NULL
, NULL
);
443 while (header
!= NULL
) {
444 ret
= _sip_copy_header(_new_msg
, header
, NULL
, B_FALSE
);
447 header
= sip_search_for_header(_old_msg
, NULL
, header
);
450 (void) pthread_mutex_unlock(&_new_msg
->sip_msg_mutex
);
451 (void) pthread_mutex_unlock(&_old_msg
->sip_msg_mutex
);
456 * Copy start line from msg to sip_msg
459 sip_copy_start_line(sip_msg_t msg
, sip_msg_t sip_msg
)
462 _sip_header_t
*new_header
;
463 _sip_msg_t
*_old_msg
;
464 _sip_msg_t
*_sip_msg
;
466 if (msg
== NULL
|| sip_msg
== NULL
)
468 _old_msg
= (_sip_msg_t
*)msg
;
469 _sip_msg
= (_sip_msg_t
*)sip_msg
;
471 (void) pthread_mutex_lock(&_old_msg
->sip_msg_mutex
);
472 if (_old_msg
->sip_msg_start_line
== NULL
) {
473 (void) pthread_mutex_unlock(&_old_msg
->sip_msg_mutex
);
476 len
= _old_msg
->sip_msg_start_line
->sip_hdr_end
-
477 _old_msg
->sip_msg_start_line
->sip_hdr_start
;
478 new_header
= sip_new_header(len
);
479 if (new_header
== NULL
) {
480 (void) pthread_mutex_unlock(&_old_msg
->sip_msg_mutex
);
483 new_header
->sip_hdr_sipmsg
= _sip_msg
;
484 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
485 _sip_msg
->sip_msg_start_line
= new_header
;
486 _sip_msg
->sip_msg_len
= len
;
487 (void) strncpy(_sip_msg
->sip_msg_start_line
->sip_hdr_start
,
488 _old_msg
->sip_msg_start_line
->sip_hdr_start
, len
);
489 (void) sip_parse_first_line(_sip_msg
->sip_msg_start_line
,
490 &_sip_msg
->sip_msg_req_res
);
491 (void) pthread_mutex_unlock(&_old_msg
->sip_msg_mutex
);
492 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
497 * Delete start line from sip_msg
500 sip_delete_start_line_locked(_sip_msg_t
*_sip_msg
)
502 _sip_header_t
*header
;
503 _sip_header_t
*next_header
;
505 if (_sip_msg
->sip_msg_start_line
== NULL
)
508 header
= _sip_msg
->sip_msg_start_line
;
509 while (header
!= NULL
) {
510 next_header
= header
->sip_hdr_next
;
511 _sip_msg
->sip_msg_len
-= (header
->sip_hdr_end
-
512 header
->sip_hdr_start
);
513 sip_free_header(header
);
514 header
= next_header
;
516 _sip_msg
->sip_msg_start_line
= NULL
;
519 * Also delete the sip_msg_req_res info since we don't have a start
522 while (_sip_msg
->sip_msg_req_res
!= NULL
) {
523 sip_message_type_t
*sip_msg_type_ptr
;
525 sip_msg_type_ptr
= _sip_msg
->sip_msg_req_res
->sip_next
;
526 if (_sip_msg
->sip_msg_req_res
->is_request
) {
527 sip_request_t
*reqline
;
529 reqline
= &_sip_msg
->sip_msg_req_res
->U
.sip_request
;
530 if (reqline
->sip_parse_uri
!= NULL
) {
531 sip_free_parsed_uri(reqline
->sip_parse_uri
);
532 reqline
->sip_parse_uri
= NULL
;
535 free(_sip_msg
->sip_msg_req_res
);
536 _sip_msg
->sip_msg_req_res
= sip_msg_type_ptr
;
543 * Delete start line from sip_msg
546 sip_delete_start_line(sip_msg_t sip_msg
)
548 _sip_msg_t
*_sip_msg
;
554 _sip_msg
= (_sip_msg_t
*)sip_msg
;
555 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
556 ret
= sip_delete_start_line_locked(_sip_msg
);
557 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
563 * Delete all headers from _sip_msg
566 sip_delete_all_headers(_sip_msg_t
*_sip_msg
)
568 _sip_header_t
*header
;
571 assert(mutex_held(&_sip_msg
->sip_msg_mutex
));
574 header
= _sip_msg
->sip_msg_headers_start
;
575 while (header
!= NULL
) {
576 _sip_header_t
*next_header
;
577 next_header
= header
->sip_hdr_next
;
578 sip_free_header(header
);
579 header
= next_header
;
581 _sip_msg
->sip_msg_headers_start
= NULL
;
582 _sip_msg
->sip_msg_headers_end
= NULL
;
586 * Delete and free the named header. If header_name is null
590 sip_delete_headers(sip_msg_t sip_msg
, char *header_name
)
592 _sip_header_t
*header
;
593 _sip_msg_t
*_sip_msg
;
595 _sip_msg
= (_sip_msg_t
*)sip_msg
;
597 assert(mutex_held(&_sip_msg
->sip_msg_mutex
));
599 header
= sip_search_for_header(_sip_msg
, header_name
, NULL
);
602 while (header
!= NULL
) {
603 if (_sip_msg
->sip_msg_headers_start
== header
) {
604 _sip_msg
->sip_msg_headers_start
= header
->sip_hdr_next
;
606 header
->sip_hdr_prev
->sip_hdr_next
=
607 header
->sip_hdr_next
;
609 if (_sip_msg
->sip_msg_headers_end
== header
) {
610 _sip_msg
->sip_msg_headers_end
= header
->sip_hdr_prev
;
612 header
->sip_hdr_next
->sip_hdr_prev
=
613 header
->sip_hdr_prev
;
615 sip_free_header(header
);
616 if (header_name
!= NULL
)
619 header
= sip_search_for_header(_sip_msg
, NULL
, NULL
);
624 * Add a header to sip_msg. If header_name is provided then the new header
625 * is added before that header, if first is set, or after. If append is
626 * set, then the header is added to the end of the header list.
629 _sip_add_header(_sip_msg_t
*sip_msg
, _sip_header_t
*new_header
,
630 boolean_t append
, boolean_t first
, char *header_name
)
632 _sip_header_t
*header
= NULL
;
634 if (sip_msg
== NULL
|| new_header
== NULL
)
637 assert(mutex_held(&sip_msg
->sip_msg_mutex
));
639 new_header
->sip_hdr_sipmsg
= sip_msg
;
640 if (header_name
!= NULL
) {
641 _sip_header_t
*header_tmp
;
643 header
= sip_search_for_header(sip_msg
, header_name
, NULL
);
646 while (header
!= NULL
) {
648 header
= sip_search_for_header(sip_msg
,
649 header_name
, header
);
657 if (header
!= NULL
) {
659 new_header
->sip_hdr_prev
= header
;
660 if (sip_msg
->sip_msg_headers_end
== header
) {
661 sip_msg
->sip_msg_headers_end
= new_header
;
662 new_header
->sip_hdr_next
= NULL
;
664 header
->sip_hdr_next
->sip_hdr_prev
= new_header
;
665 new_header
->sip_hdr_next
= header
->sip_hdr_next
;
667 header
->sip_hdr_next
= new_header
;
669 new_header
->sip_hdr_next
= header
;
670 if (sip_msg
->sip_msg_headers_start
== header
) {
671 sip_msg
->sip_msg_headers_start
= new_header
;
672 new_header
->sip_hdr_prev
= NULL
;
674 header
->sip_hdr_prev
->sip_hdr_next
= new_header
;
675 new_header
->sip_hdr_prev
= header
->sip_hdr_prev
;
677 header
->sip_hdr_prev
= new_header
;
681 if (sip_msg
->sip_msg_headers_end
!= NULL
) {
682 sip_msg
->sip_msg_headers_end
->sip_hdr_next
=
685 sip_msg
->sip_msg_headers_start
= new_header
;
687 new_header
->sip_hdr_prev
=
688 sip_msg
->sip_msg_headers_end
;
689 new_header
->sip_hdr_next
= NULL
;
690 sip_msg
->sip_msg_headers_end
= new_header
;
692 if (sip_msg
->sip_msg_headers_start
!= NULL
) {
693 sip_msg
->sip_msg_headers_start
->sip_hdr_prev
=
696 sip_msg
->sip_msg_headers_end
= new_header
;
698 new_header
->sip_hdr_next
=
699 sip_msg
->sip_msg_headers_start
;
700 new_header
->sip_hdr_prev
= NULL
;
701 sip_msg
->sip_msg_headers_start
= new_header
;
704 sip_msg
->sip_msg_len
+= new_header
->sip_hdr_end
-
705 new_header
->sip_hdr_start
;
709 * Scan through the function table and return the entry for the given header
712 sip_header_function_t
*
713 _sip_get_header_functions(sip_header_function_t
*sip_header_function_table
,
714 _sip_header_t
*sip_header
, char *header_name
)
719 if (sip_header
== NULL
&& header_name
== NULL
)
723 * If header_name is NULL we first have to locate the name
725 if (header_name
== NULL
) {
726 if (sip_skip_white_space(sip_header
) != 0) {
729 header_name
= sip_header
->sip_hdr_current
;
730 if (sip_find_separator(sip_header
, SIP_HCOLON
, (char)NULL
,
731 (char)NULL
, B_FALSE
) != 0) {
734 len
= sip_header
->sip_hdr_current
- header_name
;
736 len
= strlen(header_name
);
740 while (sip_header_function_table
[i
].header_name
!= NULL
||
741 sip_header_function_table
[i
].header_short_name
!= NULL
) {
742 if (sip_header_function_table
[i
].header_name
!= NULL
&&
744 strlen(sip_header_function_table
[i
].header_name
)) {
745 if (strncasecmp(header_name
,
746 sip_header_function_table
[i
].
747 header_name
, len
) == 0) {
750 } else if (sip_header_function_table
[i
].
751 header_short_name
!= NULL
&& len
==
752 strlen(sip_header_function_table
[i
].
753 header_short_name
)) {
754 if (strncasecmp(header_name
,
755 sip_header_function_table
[i
].
756 header_short_name
, len
) == 0) {
764 if (sip_header
!= NULL
)
765 sip_header
->sip_hdr_current
= sip_header
->sip_hdr_start
;
766 if (sip_header_function_table
[i
].header_name
== NULL
)
768 return (&sip_header_function_table
[i
]);
772 * Return the entry from the function table for the given header
774 sip_header_function_t
*
775 sip_get_header_functions(_sip_header_t
*sip_header
, char *header_name
)
777 sip_header_function_t
*func
;
778 sip_header_function_t
*header_f_table
= NULL
;
780 if (sip_header_function_table_external
!= NULL
) {
781 header_f_table
= _sip_get_header_functions(
782 sip_header_function_table_external
,
783 sip_header
, header_name
);
784 if (header_f_table
!= NULL
)
785 return (header_f_table
);
787 func
= _sip_get_header_functions(sip_header_function_table
, sip_header
,
793 * Search for the header name passed in.
796 sip_search_for_header(_sip_msg_t
*sip_msg
, char *header_name
,
797 _sip_header_t
*old_header
)
802 _sip_header_t
*header
= NULL
;
803 char *compact_name
= NULL
;
804 char *full_name
= NULL
;
805 sip_header_function_t
*header_f_table
= NULL
;
810 assert(mutex_held(&sip_msg
->sip_msg_mutex
));
813 if (header_name
!= NULL
) {
814 header_f_table
= sip_get_header_functions(NULL
, header_name
);
815 if (header_f_table
!= NULL
) {
816 full_name
= header_f_table
->header_name
;
817 compact_name
= header_f_table
->header_short_name
;
818 if (full_name
!= NULL
)
819 full_len
= strlen(full_name
);
820 if (compact_name
!= NULL
)
821 compact_len
= strlen(compact_name
);
823 header_f_table
= &sip_header_function_table
[0];
824 full_name
= header_name
;
825 full_len
= strlen(full_name
);
829 if (old_header
!= NULL
)
830 header
= old_header
->sip_hdr_next
;
832 header
= sip_msg
->sip_msg_headers_start
;
834 while (header
!= NULL
) {
836 if (header
->sip_header_state
== SIP_HEADER_DELETED
) {
837 header
= header
->sip_hdr_next
;
841 if (compact_len
== 0 && full_len
== 0)
844 header
->sip_hdr_current
= header
->sip_hdr_start
;
846 if (sip_skip_white_space(header
)) {
847 header
= header
->sip_hdr_next
;
851 len
= header
->sip_hdr_end
- header
->sip_hdr_current
;
853 if (full_name
!= NULL
&& (full_len
<= len
) &&
854 strncasecmp(header
->sip_hdr_current
, full_name
,
856 header
->sip_hdr_current
+= full_len
;
857 if (sip_skip_white_space(header
)) {
858 header
= header
->sip_hdr_next
;
862 if (*header
->sip_hdr_current
== SIP_HCOLON
) {
863 header_name
= full_name
;
868 if (compact_name
!= NULL
&& (compact_len
<= len
) &&
869 strncasecmp(header
->sip_hdr_current
, compact_name
,
871 header
->sip_hdr_current
+= compact_len
;
872 if (sip_skip_white_space(header
)) {
873 header
= header
->sip_hdr_next
;
876 if (*header
->sip_hdr_current
== SIP_HCOLON
) {
877 header_name
= compact_name
;
881 header
= header
->sip_hdr_next
;
884 if (header
!= NULL
) {
885 header
->sip_hdr_current
= header
->sip_hdr_start
;
886 if (header_f_table
== NULL
) {
888 sip_get_header_functions(header
, header_name
);
889 if (header_f_table
== NULL
)
890 header_f_table
= &sip_header_function_table
[0];
893 header
->sip_header_functions
= header_f_table
;
899 * Return the start line as a string. Caller frees string
902 _sip_startline_to_str(_sip_msg_t
*sip_msg
, int *error
)
910 if (sip_msg
== NULL
|| sip_msg
->sip_msg_start_line
== NULL
) {
915 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
916 len
= sip_msg
->sip_msg_start_line
->sip_hdr_end
-
917 sip_msg
->sip_msg_start_line
->sip_hdr_start
- 2;
918 if ((slstr
= malloc(len
+ 1)) == NULL
) {
919 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
924 (void) strncpy(slstr
, sip_msg
->sip_msg_start_line
->sip_hdr_start
, len
);
925 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
931 * Return the given header as a string. Caller frees string
934 sip_hdr_to_str(sip_header_t sip_header
, int *error
)
938 _sip_header_t
*_sip_header
;
944 if (sip_header
== NULL
) {
949 _sip_header
= (_sip_header_t
*)sip_header
;
950 if (_sip_header
->sip_header_state
== SIP_HEADER_DELETED
) {
951 if (_sip_header
->sip_hdr_sipmsg
!= NULL
) {
952 (void) pthread_mutex_unlock(
953 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
959 if (_sip_header
->sip_hdr_sipmsg
!= NULL
) {
960 (void) pthread_mutex_lock(
961 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
963 len
= _sip_header
->sip_hdr_end
- _sip_header
->sip_hdr_start
;
964 hdrstr
= malloc(len
);
965 if (hdrstr
== NULL
) {
966 if (_sip_header
->sip_hdr_sipmsg
!= NULL
) {
967 (void) pthread_mutex_unlock(
968 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
974 if (_sip_header
->sip_header_state
== SIP_HEADER_DELETED_VAL
) {
975 len
= sip_copy_values(hdrstr
, _sip_header
);
977 (void) strncpy(hdrstr
, _sip_header
->sip_hdr_start
, len
);
979 if (_sip_header
->sip_hdr_sipmsg
!= NULL
) {
980 (void) pthread_mutex_unlock(
981 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
983 tmpptr
= hdrstr
+ len
;
984 while (*tmpptr
-- != '\n') {
985 if (tmpptr
== _sip_header
->sip_hdr_start
) {
997 * Given a param list find the named parameter.
998 * Returns a pointer to the value or NULL.
1001 sip_get_param_from_list(sip_param_t
*param_list
, char *param_name
)
1003 while (param_list
!= NULL
) {
1004 if (param_list
->param_name
.sip_str_len
== strlen(param_name
) &&
1005 strncasecmp(param_list
->param_name
.sip_str_ptr
, param_name
,
1006 strlen(param_name
)) == 0) {
1007 return (param_list
);
1009 param_list
= param_list
->param_next
;