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.
36 #include "sip_miscdefs.h"
37 #include "sip_parse_generic.h"
39 sip_methods_t sip_methods
[MAX_SIP_METHODS
] = {
55 * Built-In Header function table
57 sip_header_function_t sip_header_function_table
[] = {
58 {"Unknown", NULL
, sip_parse_unknown_header
, NULL
, NULL
, NULL
},
59 {"CONTACT", "m", sip_parse_cftr_header
, NULL
, NULL
,
60 sip_free_cftr_header
},
61 {"FROM", "F", sip_parse_cftr_header
, NULL
, NULL
, sip_free_cftr_header
},
62 {"TO", "T", sip_parse_cftr_header
, NULL
, NULL
, sip_free_cftr_header
},
63 {"CONTENT-LENGTH", "l", sip_parse_clen_header
, NULL
, NULL
,
65 {"CONTENT-TYPE", "c", sip_parse_ctype_header
, NULL
, NULL
,
67 {"CALL-ID", "i", sip_parse_cid_header
, NULL
, NULL
, sip_free_phdr
},
68 {"CSEQ", NULL
, sip_parse_cseq_header
, NULL
, NULL
, sip_free_phdr
},
69 {"VIA", "v", sip_parse_via_header
, NULL
, NULL
, sip_free_phdr
},
70 {"Max-Forwards", NULL
, sip_parse_maxf_header
, NULL
, NULL
,
72 {"RECORD-ROUTE", NULL
, sip_parse_cftr_header
, NULL
, NULL
,
73 sip_free_cftr_header
},
74 {"ROUTE", NULL
, sip_parse_cftr_header
, NULL
, NULL
,
75 sip_free_cftr_header
},
76 {"ACCEPT", NULL
, sip_parse_acpt_header
, NULL
, NULL
, sip_free_phdr
},
77 {"ACCEPT-ENCODING", NULL
, sip_parse_acpt_encode_header
, NULL
, NULL
,
79 {"ACCEPT-LANGUAGE", NULL
, sip_parse_acpt_lang_header
, NULL
, NULL
,
81 {"ALERT-INFO", NULL
, sip_parse_alert_header
, NULL
, NULL
, sip_free_phdr
},
82 {"ALLOW", NULL
, sip_parse_allow_header
, NULL
, NULL
, sip_free_phdr
},
83 {"CALL-INFO", NULL
, sip_parse_callinfo_header
, NULL
, NULL
,
85 {"CONTENT-DISPOSITION", NULL
, sip_parse_contentdis_header
, NULL
, NULL
,
87 {"CONTENT-ENCODING", "e", sip_parse_contentencode_header
, NULL
, NULL
,
89 {"CONTENT-LANGUAGE", NULL
, sip_parse_contentlang_header
, NULL
, NULL
,
91 {"DATE", NULL
, sip_parse_date_header
, NULL
, NULL
, sip_free_phdr
},
92 {"ERROR-INFO", NULL
, sip_parse_errorinfo_header
, NULL
, NULL
,
94 {"EXPIRES", NULL
, sip_parse_expire_header
, NULL
, NULL
, sip_free_phdr
},
95 {"IN-REPLY-TO", NULL
, sip_parse_inreplyto_header
, NULL
, NULL
,
97 {"MIN-EXPIRES", NULL
, sip_parse_minexpire_header
, NULL
, NULL
,
99 {"MIME-VERSION", NULL
, sip_parse_mimeversion_header
, NULL
, NULL
,
101 {"ORGANIZATION", NULL
, sip_parse_org_header
, NULL
, NULL
, sip_free_phdr
},
102 {"PRIORITY", NULL
, sip_parse_priority_header
, NULL
, NULL
,
104 {"REQUIRE", NULL
, sip_parse_require_header
, NULL
, NULL
, sip_free_phdr
},
105 {"REPLY-TO", NULL
, sip_parse_replyto_header
, NULL
, NULL
, sip_free_phdr
},
106 {"RETRY-AFTER", NULL
, sip_parse_retryaft_header
, NULL
, NULL
,
108 {"SERVER", NULL
, sip_parse_server_header
, NULL
, NULL
, sip_free_phdr
},
109 {"SUBJECT", "s", sip_parse_subject_header
, NULL
, NULL
, sip_free_phdr
},
110 {"TIMESTAMP", NULL
, sip_parse_timestamp_header
, NULL
, NULL
,
112 {"UNSUPPORTED", NULL
, sip_parse_usupport_header
, NULL
, NULL
,
114 {"SUPPORTED", "k", sip_parse_support_header
, NULL
, NULL
, sip_free_phdr
},
115 {"USER-AGENT", NULL
, sip_parse_useragt_header
, NULL
, NULL
,
117 {"WARNING", NULL
, sip_parse_warn_header
, NULL
, NULL
, sip_free_phdr
},
118 {"ALLOW-EVENTS", "u", sip_parse_allow_events_header
, NULL
, NULL
,
120 {"EVENT", "o", sip_parse_event_header
, NULL
, NULL
, sip_free_phdr
},
121 {"SUBSCRIPTION-STATE", NULL
, sip_parse_substate_header
, NULL
, NULL
,
123 {"AUTHORIZATION", NULL
, sip_parse_author_header
, NULL
, NULL
,
125 {"AUTHENTICATION-INFO", NULL
, sip_parse_ainfo_header
, NULL
, NULL
,
127 {"PROXY-AUTHORIZATION", NULL
, sip_parse_pauthor_header
, NULL
, NULL
,
129 {"PROXY-AUTHENTICATE", NULL
, sip_parse_pauthen_header
, NULL
, NULL
,
131 {"PROXY-REQUIRE", NULL
, sip_parse_preq_header
, NULL
, NULL
,
133 {"WWW-AUTHENTICATE", NULL
, sip_parse_wauthen_header
, NULL
, NULL
,
135 {"RSEQ", NULL
, sip_parse_rseq
, NULL
, NULL
, sip_free_phdr
},
136 {"RACK", NULL
, sip_parse_rack
, NULL
, NULL
, sip_free_phdr
},
137 {"P-ASSERTED-IDENTITY", NULL
, sip_parse_passertedid
, NULL
, NULL
,
139 {"P-PREFERRED-IDENTITY", NULL
, sip_parse_ppreferredid
, NULL
, NULL
,
141 {"PRIVACY", NULL
, sip_parse_privacy_header
, NULL
, NULL
, sip_free_phdr
},
142 {NULL
, NULL
, NULL
, NULL
, NULL
, NULL
},
145 #define MAX_SIP_HEADERS \
146 sizeof (sip_header_function_table) / sizeof (sip_header_function_t)
149 * External/application provided function table
151 sip_header_function_t
*sip_header_function_table_external
= NULL
;
154 * Free parameter list
157 sip_free_params(sip_param_t
*param_list
)
159 sip_param_t
*param
, *next_param
;
163 while (param
!= NULL
) {
164 next_param
= param
->param_next
;
171 * Common header free routine
174 sip_free_phdr(sip_parsed_header_t
*header
)
176 sip_hdr_value_t
*value
;
177 sip_hdr_value_t
*next_value
;
181 value
= (sip_hdr_value_t
*)header
->value
;
182 while (value
!= NULL
) {
183 sip_free_params(value
->sip_param_list
);
184 next_value
= value
->sip_next_value
;
192 * Free Contact/From/To header
195 sip_free_cftr_header(sip_parsed_header_t
*header
)
197 sip_hdr_value_t
*value
;
198 sip_hdr_value_t
*next_value
;
202 value
= (sip_hdr_value_t
*)header
->value
;
203 while (value
!= NULL
) {
204 next_value
= value
->sip_next_value
;
205 sip_free_params(value
->sip_param_list
);
206 free(value
->cftr_name
);
207 if (value
->sip_value_parsed_uri
!= NULL
) {
208 sip_free_parsed_uri(value
->sip_value_parsed_uri
);
209 value
->sip_value_parsed_uri
= NULL
;
221 sip_new_header(int header_size
)
223 _sip_header_t
*new_header
;
225 new_header
= calloc(1, sizeof (_sip_header_t
));
226 if (new_header
== NULL
)
230 * We are using snprintf which adds a null character
231 * so allocate an extra byte which is not part of
234 new_header
->sip_hdr_start
= calloc(1, header_size
+ 1);
235 if (new_header
->sip_hdr_start
== NULL
) {
239 new_header
->sip_hdr_end
= new_header
->sip_hdr_start
+ header_size
;
240 new_header
->sip_hdr_current
= new_header
->sip_hdr_start
;
241 new_header
->sip_hdr_allocated
= B_TRUE
;
246 * Free the given header
249 sip_free_header(_sip_header_t
*sip_header
)
251 if (sip_header
->sip_hdr_allocated
) {
252 assert(sip_header
->sip_hdr_start
!= NULL
);
253 free(sip_header
->sip_hdr_start
);
255 if (sip_header
->sip_hdr_parsed
!= NULL
) {
256 assert(sip_header
->sip_header_functions
!= NULL
);
257 if (sip_header
->sip_header_functions
->header_free
!= NULL
) {
258 sip_header
->sip_header_functions
->header_free(
259 sip_header
->sip_hdr_parsed
);
266 * Return a copy of the header passed in.
269 sip_dup_header(_sip_header_t
*from
)
274 hdr_size
= from
->sip_hdr_end
- from
->sip_hdr_start
;
275 to
= sip_new_header(hdr_size
);
278 if (from
->sip_header_state
== SIP_HEADER_DELETED_VAL
) {
279 to
->sip_hdr_end
= to
->sip_hdr_start
+
280 sip_copy_values(to
->sip_hdr_start
, from
);
282 (void) memcpy(to
->sip_hdr_start
, from
->sip_hdr_start
, hdr_size
);
283 to
->sip_hdr_end
= to
->sip_hdr_start
+ hdr_size
;
285 to
->sip_header_functions
= from
->sip_header_functions
;
290 * Copy header with extra_param, if any, to sip_msg
293 _sip_copy_header(_sip_msg_t
*sip_msg
, _sip_header_t
*header
, char *extra_param
,
296 _sip_header_t
*new_header
;
303 assert(mutex_held(&sip_msg
->sip_msg_mutex
));
305 if (extra_param
!= NULL
) {
306 extra_len
= SIP_SPACE_LEN
+ sizeof (char) + SIP_SPACE_LEN
+
310 * Just take one if there are more, i.e. if this is the last header
311 * before the content.
314 if (header
->sip_hdr_end
- strlen(SIP_CRLF
) <=
315 header
->sip_hdr_start
) {
318 p
= header
->sip_hdr_end
- strlen(SIP_CRLF
);
319 while (strncmp(SIP_CRLF
, p
, strlen(SIP_CRLF
)) == 0) {
321 if (p
- strlen(SIP_CRLF
) < header
->sip_hdr_start
)
323 p
-= strlen(SIP_CRLF
);
328 ncrlf
= (ncrlf
- 1) * strlen(SIP_CRLF
);
331 hdrlen
= header
->sip_hdr_end
- header
->sip_hdr_start
- ncrlf
;
332 new_header
= sip_new_header(hdrlen
+ extra_len
);
333 if (new_header
== NULL
)
335 if (header
->sip_header_state
== SIP_HEADER_DELETED_VAL
) {
338 len
= sip_copy_values(new_header
->sip_hdr_start
, header
);
339 new_header
->sip_hdr_end
= new_header
->sip_hdr_start
+ len
;
340 hdrlen
= hdrlen
- len
+ extra_len
;
342 (void) memcpy(new_header
->sip_hdr_start
, header
->sip_hdr_start
,
344 new_header
->sip_hdr_end
= new_header
->sip_hdr_start
+ hdrlen
;
347 if (extra_param
!= NULL
) {
351 if (sip_find_cr(new_header
) != 0) {
352 sip_free_header(new_header
);
355 hdrlen
+= new_header
->sip_hdr_end
- new_header
->sip_hdr_current
;
356 (void) snprintf(new_header
->sip_hdr_current
, hdrlen
+ 1,
357 " %c %s%s", SIP_SEMI
, extra_param
, SIP_CRLF
);
360 new_header
->sip_hdr_end
+= extra_len
;
361 new_header
->sip_header_functions
= header
->sip_header_functions
;
362 _sip_add_header(sip_msg
, new_header
, B_TRUE
, B_FALSE
, NULL
);
367 * Copy all "header_name" headers from _old_msg to _new_msg
370 _sip_find_and_copy_all_header(_sip_msg_t
*_old_msg
, _sip_msg_t
*_new_msg
,
373 _sip_header_t
*header
;
376 if (_old_msg
== NULL
|| _new_msg
== NULL
)
379 assert(mutex_held(&_old_msg
->sip_msg_mutex
));
381 if (_old_msg
!= _new_msg
)
382 (void) pthread_mutex_lock(&_new_msg
->sip_msg_mutex
);
383 header
= sip_search_for_header(_old_msg
, header_name
, NULL
);
384 while (header
!= NULL
) {
385 ret
= _sip_copy_header(_new_msg
, header
, NULL
, B_TRUE
);
388 header
= sip_search_for_header(_old_msg
, header_name
, header
);
390 if (_old_msg
!= _new_msg
)
391 (void) pthread_mutex_unlock(&_new_msg
->sip_msg_mutex
);
396 * Copy header_name from _old_msg to _new_msg with extra_parm.
399 _sip_find_and_copy_header(sip_msg_t _old_msg
, sip_msg_t _new_msg
,
400 char *header_name
, char *extra_param
, boolean_t lock_newmsg
)
402 _sip_header_t
*header
;
405 if (_old_msg
== NULL
|| _new_msg
== NULL
)
408 assert(mutex_held(&_old_msg
->sip_msg_mutex
));
410 header
= sip_search_for_header(_old_msg
, header_name
, NULL
);
414 (void) pthread_mutex_lock(&_new_msg
->sip_msg_mutex
);
415 ret
= _sip_copy_header(_new_msg
, header
, extra_param
, B_TRUE
);
417 (void) pthread_mutex_unlock(&_new_msg
->sip_msg_mutex
);
422 * Copy all headers from old_msg to new_msg
425 sip_copy_all_headers(sip_msg_t old_msg
, sip_msg_t new_msg
)
427 _sip_header_t
*header
;
428 _sip_msg_t
*_old_msg
;
429 _sip_msg_t
*_new_msg
;
432 if (old_msg
== NULL
|| new_msg
== NULL
)
434 _old_msg
= (_sip_msg_t
*)old_msg
;
435 _new_msg
= (_sip_msg_t
*)new_msg
;
437 (void) pthread_mutex_lock(&_old_msg
->sip_msg_mutex
);
438 (void) pthread_mutex_lock(&_new_msg
->sip_msg_mutex
);
439 header
= sip_search_for_header(_old_msg
, NULL
, NULL
);
440 while (header
!= NULL
) {
441 ret
= _sip_copy_header(_new_msg
, header
, NULL
, B_FALSE
);
444 header
= sip_search_for_header(_old_msg
, NULL
, header
);
447 (void) pthread_mutex_unlock(&_new_msg
->sip_msg_mutex
);
448 (void) pthread_mutex_unlock(&_old_msg
->sip_msg_mutex
);
453 * Copy start line from msg to sip_msg
456 sip_copy_start_line(sip_msg_t msg
, sip_msg_t sip_msg
)
459 _sip_header_t
*new_header
;
460 _sip_msg_t
*_old_msg
;
461 _sip_msg_t
*_sip_msg
;
463 if (msg
== NULL
|| sip_msg
== NULL
)
465 _old_msg
= (_sip_msg_t
*)msg
;
466 _sip_msg
= (_sip_msg_t
*)sip_msg
;
468 (void) pthread_mutex_lock(&_old_msg
->sip_msg_mutex
);
469 if (_old_msg
->sip_msg_start_line
== NULL
) {
470 (void) pthread_mutex_unlock(&_old_msg
->sip_msg_mutex
);
473 len
= _old_msg
->sip_msg_start_line
->sip_hdr_end
-
474 _old_msg
->sip_msg_start_line
->sip_hdr_start
;
475 new_header
= sip_new_header(len
);
476 if (new_header
== NULL
) {
477 (void) pthread_mutex_unlock(&_old_msg
->sip_msg_mutex
);
480 new_header
->sip_hdr_sipmsg
= _sip_msg
;
481 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
482 _sip_msg
->sip_msg_start_line
= new_header
;
483 _sip_msg
->sip_msg_len
= len
;
484 (void) strncpy(_sip_msg
->sip_msg_start_line
->sip_hdr_start
,
485 _old_msg
->sip_msg_start_line
->sip_hdr_start
, len
);
486 (void) sip_parse_first_line(_sip_msg
->sip_msg_start_line
,
487 &_sip_msg
->sip_msg_req_res
);
488 (void) pthread_mutex_unlock(&_old_msg
->sip_msg_mutex
);
489 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
494 * Delete start line from sip_msg
497 sip_delete_start_line_locked(_sip_msg_t
*_sip_msg
)
499 _sip_header_t
*header
;
500 _sip_header_t
*next_header
;
502 if (_sip_msg
->sip_msg_start_line
== NULL
)
505 header
= _sip_msg
->sip_msg_start_line
;
506 while (header
!= NULL
) {
507 next_header
= header
->sip_hdr_next
;
508 _sip_msg
->sip_msg_len
-= (header
->sip_hdr_end
-
509 header
->sip_hdr_start
);
510 sip_free_header(header
);
511 header
= next_header
;
513 _sip_msg
->sip_msg_start_line
= NULL
;
516 * Also delete the sip_msg_req_res info since we don't have a start
519 while (_sip_msg
->sip_msg_req_res
!= NULL
) {
520 sip_message_type_t
*sip_msg_type_ptr
;
522 sip_msg_type_ptr
= _sip_msg
->sip_msg_req_res
->sip_next
;
523 if (_sip_msg
->sip_msg_req_res
->is_request
) {
524 sip_request_t
*reqline
;
526 reqline
= &_sip_msg
->sip_msg_req_res
->U
.sip_request
;
527 if (reqline
->sip_parse_uri
!= NULL
) {
528 sip_free_parsed_uri(reqline
->sip_parse_uri
);
529 reqline
->sip_parse_uri
= NULL
;
532 free(_sip_msg
->sip_msg_req_res
);
533 _sip_msg
->sip_msg_req_res
= sip_msg_type_ptr
;
540 * Delete start line from sip_msg
543 sip_delete_start_line(sip_msg_t sip_msg
)
545 _sip_msg_t
*_sip_msg
;
551 _sip_msg
= (_sip_msg_t
*)sip_msg
;
552 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
553 ret
= sip_delete_start_line_locked(_sip_msg
);
554 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
560 * Delete all headers from _sip_msg
563 sip_delete_all_headers(_sip_msg_t
*_sip_msg
)
565 _sip_header_t
*header
;
568 assert(mutex_held(&_sip_msg
->sip_msg_mutex
));
571 header
= _sip_msg
->sip_msg_headers_start
;
572 while (header
!= NULL
) {
573 _sip_header_t
*next_header
;
574 next_header
= header
->sip_hdr_next
;
575 sip_free_header(header
);
576 header
= next_header
;
578 _sip_msg
->sip_msg_headers_start
= NULL
;
579 _sip_msg
->sip_msg_headers_end
= NULL
;
583 * Delete and free the named header. If header_name is null
587 sip_delete_headers(sip_msg_t sip_msg
, char *header_name
)
589 _sip_header_t
*header
;
590 _sip_msg_t
*_sip_msg
;
592 _sip_msg
= (_sip_msg_t
*)sip_msg
;
594 assert(mutex_held(&_sip_msg
->sip_msg_mutex
));
596 header
= sip_search_for_header(_sip_msg
, header_name
, NULL
);
599 while (header
!= NULL
) {
600 if (_sip_msg
->sip_msg_headers_start
== header
) {
601 _sip_msg
->sip_msg_headers_start
= header
->sip_hdr_next
;
603 header
->sip_hdr_prev
->sip_hdr_next
=
604 header
->sip_hdr_next
;
606 if (_sip_msg
->sip_msg_headers_end
== header
) {
607 _sip_msg
->sip_msg_headers_end
= header
->sip_hdr_prev
;
609 header
->sip_hdr_next
->sip_hdr_prev
=
610 header
->sip_hdr_prev
;
612 sip_free_header(header
);
613 if (header_name
!= NULL
)
616 header
= sip_search_for_header(_sip_msg
, NULL
, NULL
);
621 * Add a header to sip_msg. If header_name is provided then the new header
622 * is added before that header, if first is set, or after. If append is
623 * set, then the header is added to the end of the header list.
626 _sip_add_header(_sip_msg_t
*sip_msg
, _sip_header_t
*new_header
,
627 boolean_t append
, boolean_t first
, char *header_name
)
629 _sip_header_t
*header
= NULL
;
631 if (sip_msg
== NULL
|| new_header
== NULL
)
634 assert(mutex_held(&sip_msg
->sip_msg_mutex
));
636 new_header
->sip_hdr_sipmsg
= sip_msg
;
637 if (header_name
!= NULL
) {
638 _sip_header_t
*header_tmp
;
640 header
= sip_search_for_header(sip_msg
, header_name
, NULL
);
643 while (header
!= NULL
) {
645 header
= sip_search_for_header(sip_msg
,
646 header_name
, header
);
654 if (header
!= NULL
) {
656 new_header
->sip_hdr_prev
= header
;
657 if (sip_msg
->sip_msg_headers_end
== header
) {
658 sip_msg
->sip_msg_headers_end
= new_header
;
659 new_header
->sip_hdr_next
= NULL
;
661 header
->sip_hdr_next
->sip_hdr_prev
= new_header
;
662 new_header
->sip_hdr_next
= header
->sip_hdr_next
;
664 header
->sip_hdr_next
= new_header
;
666 new_header
->sip_hdr_next
= header
;
667 if (sip_msg
->sip_msg_headers_start
== header
) {
668 sip_msg
->sip_msg_headers_start
= new_header
;
669 new_header
->sip_hdr_prev
= NULL
;
671 header
->sip_hdr_prev
->sip_hdr_next
= new_header
;
672 new_header
->sip_hdr_prev
= header
->sip_hdr_prev
;
674 header
->sip_hdr_prev
= new_header
;
678 if (sip_msg
->sip_msg_headers_end
!= NULL
) {
679 sip_msg
->sip_msg_headers_end
->sip_hdr_next
=
682 sip_msg
->sip_msg_headers_start
= new_header
;
684 new_header
->sip_hdr_prev
=
685 sip_msg
->sip_msg_headers_end
;
686 new_header
->sip_hdr_next
= NULL
;
687 sip_msg
->sip_msg_headers_end
= new_header
;
689 if (sip_msg
->sip_msg_headers_start
!= NULL
) {
690 sip_msg
->sip_msg_headers_start
->sip_hdr_prev
=
693 sip_msg
->sip_msg_headers_end
= new_header
;
695 new_header
->sip_hdr_next
=
696 sip_msg
->sip_msg_headers_start
;
697 new_header
->sip_hdr_prev
= NULL
;
698 sip_msg
->sip_msg_headers_start
= new_header
;
701 sip_msg
->sip_msg_len
+= new_header
->sip_hdr_end
-
702 new_header
->sip_hdr_start
;
706 * Scan through the function table and return the entry for the given header
709 sip_header_function_t
*
710 _sip_get_header_functions(sip_header_function_t
*sip_header_function_table
,
711 _sip_header_t
*sip_header
, char *header_name
)
716 if (sip_header
== NULL
&& header_name
== NULL
)
720 * If header_name is NULL we first have to locate the name
722 if (header_name
== NULL
) {
723 if (sip_skip_white_space(sip_header
) != 0) {
726 header_name
= sip_header
->sip_hdr_current
;
727 if (sip_find_separator(sip_header
, SIP_HCOLON
, SIP_NUL
,
728 SIP_NUL
, B_FALSE
) != 0) {
731 len
= sip_header
->sip_hdr_current
- header_name
;
733 len
= strlen(header_name
);
737 while (sip_header_function_table
[i
].header_name
!= NULL
||
738 sip_header_function_table
[i
].header_short_name
!= NULL
) {
739 if (sip_header_function_table
[i
].header_name
!= NULL
&&
741 strlen(sip_header_function_table
[i
].header_name
)) {
742 if (strncasecmp(header_name
,
743 sip_header_function_table
[i
].
744 header_name
, len
) == 0) {
747 } else if (sip_header_function_table
[i
].
748 header_short_name
!= NULL
&& len
==
749 strlen(sip_header_function_table
[i
].
750 header_short_name
)) {
751 if (strncasecmp(header_name
,
752 sip_header_function_table
[i
].
753 header_short_name
, len
) == 0) {
761 if (sip_header
!= NULL
)
762 sip_header
->sip_hdr_current
= sip_header
->sip_hdr_start
;
763 if (sip_header_function_table
[i
].header_name
== NULL
)
765 return (&sip_header_function_table
[i
]);
769 * Return the entry from the function table for the given header
771 sip_header_function_t
*
772 sip_get_header_functions(_sip_header_t
*sip_header
, char *header_name
)
774 sip_header_function_t
*func
;
775 sip_header_function_t
*header_f_table
= NULL
;
777 if (sip_header_function_table_external
!= NULL
) {
778 header_f_table
= _sip_get_header_functions(
779 sip_header_function_table_external
,
780 sip_header
, header_name
);
781 if (header_f_table
!= NULL
)
782 return (header_f_table
);
784 func
= _sip_get_header_functions(sip_header_function_table
, sip_header
,
790 * Search for the header name passed in.
793 sip_search_for_header(_sip_msg_t
*sip_msg
, char *header_name
,
794 _sip_header_t
*old_header
)
799 _sip_header_t
*header
= NULL
;
800 char *compact_name
= NULL
;
801 char *full_name
= NULL
;
802 sip_header_function_t
*header_f_table
= NULL
;
807 assert(mutex_held(&sip_msg
->sip_msg_mutex
));
810 if (header_name
!= NULL
) {
811 header_f_table
= sip_get_header_functions(NULL
, header_name
);
812 if (header_f_table
!= NULL
) {
813 full_name
= header_f_table
->header_name
;
814 compact_name
= header_f_table
->header_short_name
;
815 if (full_name
!= NULL
)
816 full_len
= strlen(full_name
);
817 if (compact_name
!= NULL
)
818 compact_len
= strlen(compact_name
);
820 header_f_table
= &sip_header_function_table
[0];
821 full_name
= header_name
;
822 full_len
= strlen(full_name
);
826 if (old_header
!= NULL
)
827 header
= old_header
->sip_hdr_next
;
829 header
= sip_msg
->sip_msg_headers_start
;
831 while (header
!= NULL
) {
833 if (header
->sip_header_state
== SIP_HEADER_DELETED
) {
834 header
= header
->sip_hdr_next
;
838 if (compact_len
== 0 && full_len
== 0)
841 header
->sip_hdr_current
= header
->sip_hdr_start
;
843 if (sip_skip_white_space(header
)) {
844 header
= header
->sip_hdr_next
;
848 len
= header
->sip_hdr_end
- header
->sip_hdr_current
;
850 if (full_name
!= NULL
&& (full_len
<= len
) &&
851 strncasecmp(header
->sip_hdr_current
, full_name
,
853 header
->sip_hdr_current
+= full_len
;
854 if (sip_skip_white_space(header
)) {
855 header
= header
->sip_hdr_next
;
859 if (*header
->sip_hdr_current
== SIP_HCOLON
) {
860 header_name
= full_name
;
865 if (compact_name
!= NULL
&& (compact_len
<= len
) &&
866 strncasecmp(header
->sip_hdr_current
, compact_name
,
868 header
->sip_hdr_current
+= compact_len
;
869 if (sip_skip_white_space(header
)) {
870 header
= header
->sip_hdr_next
;
873 if (*header
->sip_hdr_current
== SIP_HCOLON
) {
874 header_name
= compact_name
;
878 header
= header
->sip_hdr_next
;
881 if (header
!= NULL
) {
882 header
->sip_hdr_current
= header
->sip_hdr_start
;
883 if (header_f_table
== NULL
) {
885 sip_get_header_functions(header
, header_name
);
886 if (header_f_table
== NULL
)
887 header_f_table
= &sip_header_function_table
[0];
890 header
->sip_header_functions
= header_f_table
;
896 * Return the start line as a string. Caller frees string
899 _sip_startline_to_str(_sip_msg_t
*sip_msg
, int *error
)
907 if (sip_msg
== NULL
|| sip_msg
->sip_msg_start_line
== NULL
) {
912 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
913 len
= sip_msg
->sip_msg_start_line
->sip_hdr_end
-
914 sip_msg
->sip_msg_start_line
->sip_hdr_start
- 2;
915 if ((slstr
= malloc(len
+ 1)) == NULL
) {
916 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
921 (void) strncpy(slstr
, sip_msg
->sip_msg_start_line
->sip_hdr_start
, len
);
922 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
923 slstr
[len
] = SIP_NUL
;
928 * Return the given header as a string. Caller frees string
931 sip_hdr_to_str(sip_header_t sip_header
, int *error
)
935 _sip_header_t
*_sip_header
;
941 if (sip_header
== NULL
) {
946 _sip_header
= (_sip_header_t
*)sip_header
;
947 if (_sip_header
->sip_header_state
== SIP_HEADER_DELETED
) {
948 if (_sip_header
->sip_hdr_sipmsg
!= NULL
) {
949 (void) pthread_mutex_unlock(
950 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
956 if (_sip_header
->sip_hdr_sipmsg
!= NULL
) {
957 (void) pthread_mutex_lock(
958 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
960 len
= _sip_header
->sip_hdr_end
- _sip_header
->sip_hdr_start
;
961 hdrstr
= malloc(len
);
962 if (hdrstr
== NULL
) {
963 if (_sip_header
->sip_hdr_sipmsg
!= NULL
) {
964 (void) pthread_mutex_unlock(
965 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
971 if (_sip_header
->sip_header_state
== SIP_HEADER_DELETED_VAL
) {
972 len
= sip_copy_values(hdrstr
, _sip_header
);
974 (void) strncpy(hdrstr
, _sip_header
->sip_hdr_start
, len
);
976 if (_sip_header
->sip_hdr_sipmsg
!= NULL
) {
977 (void) pthread_mutex_unlock(
978 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
980 tmpptr
= hdrstr
+ len
;
981 while (*tmpptr
-- != '\n') {
982 if (tmpptr
== _sip_header
->sip_hdr_start
) {
994 * Given a param list find the named parameter.
995 * Returns a pointer to the value or NULL.
998 sip_get_param_from_list(sip_param_t
*param_list
, char *param_name
)
1000 while (param_list
!= NULL
) {
1001 if (param_list
->param_name
.sip_str_len
== strlen(param_name
) &&
1002 strncasecmp(param_list
->param_name
.sip_str_ptr
, param_name
,
1003 strlen(param_name
)) == 0) {
1004 return (param_list
);
1006 param_list
= param_list
->param_next
;