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"
36 #include "sip_miscdefs.h"
37 #include "sip_parse_generic.h"
38 #include "sip_parse_uri.h"
42 * Accept = "Accept" HCOLON [ accept-range *(COMMA accept-range) ]
43 * accept-range = media-range *(SEMI accept-param)
44 * media-range = ("* / *" | (m-type SLASH "*") | (m-type SLASH m-subtype))
46 * accept-param = ("q" EQUAL qvalue) | generic-param
47 * qvalue = ("0" ["." 0*3DIGIT]) | ("1" ["." 0*3DIGIT])
48 * generic-param = token [ EQUAL gen-value]
49 * gen-value = token | host | quoted-str
52 sip_parse_acpt_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
54 if (sip_is_empty_hdr(sip_header
))
55 return (sip_parse_hdr_empty(sip_header
, header
));
56 return (sip_parse_hdr_parser1(sip_header
, header
, SIP_SLASH
));
60 * Accept-Encoding = "Accept-Encoding" ":" 1#(codings [ ";" "q" "=" qval])
61 * codings = (content-coding | "*")
62 * content-coding = token
65 sip_parse_acpt_encode_header(_sip_header_t
*sip_header
,
66 sip_parsed_header_t
**header
)
68 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
72 * Accept-Language = "Accept-Language" ":" [ lang * (COMMA lang) ]
73 * lang = lang-range *(SEMI accept-param)
74 * lang-range = ((1*8ALPHA * ("-" 1*8ALPHA)) | "*"
77 sip_parse_acpt_lang_header(_sip_header_t
*sip_header
,
78 sip_parsed_header_t
**header
)
80 if (sip_is_empty_hdr(sip_header
))
81 return (sip_parse_hdr_empty(sip_header
, header
));
82 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
86 * Alert-Info = "Alert-Info" ":" alert-param *(COMMA alert-param)
87 * alert-param = LAQUOT absoluteURI RAQUOT * (SEMI generic-param)
90 sip_parse_alert_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
92 return (sip_parse_hdr_parser3(sip_header
, header
, SIP_STR_VAL
, B_TRUE
));
96 * Allow = "Allow" ":" method-name1[, method-name2..]
99 sip_parse_allow_header(_sip_header_t
*hdr
, sip_parsed_header_t
**phdr
)
101 sip_parsed_header_t
*parsed_header
;
102 sip_hdr_value_t
*value
= NULL
;
103 sip_hdr_value_t
*last_value
= NULL
;
107 boolean_t multi_value
= B_FALSE
;
109 if ((ret
= sip_prim_parsers(hdr
, phdr
)) != 0)
115 parsed_header
= calloc(1, sizeof (sip_parsed_header_t
));
116 if (parsed_header
== NULL
)
118 parsed_header
->sip_parsed_header_version
= SIP_PARSED_HEADER_VERSION_1
;
119 parsed_header
->sip_header
= hdr
;
121 while (hdr
->sip_hdr_current
< hdr
->sip_hdr_end
) {
122 value
= calloc(1, sizeof (sip_hdr_value_t
));
124 sip_free_phdr(parsed_header
);
127 if (last_value
!= NULL
)
128 last_value
->sip_next_value
= value
;
130 parsed_header
->value
= (sip_value_t
*)value
;
132 value
->sip_value_start
= hdr
->sip_hdr_current
;
133 value
->sip_value_header
= parsed_header
;
135 if (sip_find_separator(hdr
, SIP_COMMA
, (char)NULL
,
136 (char)NULL
, B_FALSE
) == 0) {
137 multi_value
= B_TRUE
;
140 len
= hdr
->sip_hdr_current
- value
->sip_value_start
;
141 for (i
= 1; i
< MAX_SIP_METHODS
; i
++) {
142 if (strncmp(sip_methods
[i
].name
, value
->sip_value_start
,
147 if (i
>= MAX_SIP_METHODS
) {
149 value
->sip_value_state
= SIP_VALUE_BAD
;
159 if (sip_find_token(hdr
, SIP_COMMA
) != 0)
161 value
->sip_value_end
= hdr
->sip_hdr_current
- 1;
163 (void) sip_skip_white_space(hdr
);
167 *phdr
= parsed_header
;
173 * Call-Info = "Call-Info" HCOLON info * (COMMA info)
174 * info = LAQUOT absoluteURI RAQUOT * (SEMI info-param)
175 * info-param = ("purpose" EQUAL ("icon" | "info" | "card" | token)) |
179 sip_parse_callinfo_header(_sip_header_t
*sip_header
,
180 sip_parsed_header_t
**header
)
182 return (sip_parse_hdr_parser3(sip_header
, header
, SIP_STR_VAL
, B_TRUE
));
186 * Content-Disposition = "Content-Disposition" HCOLON disp-type *
188 * disp-type = "render" | "session" | "icon" | "alert" | disp-ext-token
189 * disp-param = handling-param | generic-param
190 * handling-param = "handling" EQUAL("optional" | "required" | other-handling)
191 * other-handling = token
192 * disp-ext-token = token
196 sip_parse_contentdis_header(_sip_header_t
*sip_header
,
197 sip_parsed_header_t
**header
)
199 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
203 * Content-Encoding = ("Content-Encoding" | "e") HCOLON content-coding *
204 * (COMMA content-coding)
207 sip_parse_contentencode_header(_sip_header_t
*sip_header
,
208 sip_parsed_header_t
**header
)
210 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
214 * Content-Language = ("Content-Language" | "l") HCOLON lang-tag *
216 * lang-tag = primary-tag *("-" subtag)
217 * prmary-tag = 1*8ALPHA
221 sip_parse_contentlang_header(_sip_header_t
*sip_header
,
222 sip_parsed_header_t
**header
)
224 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
228 * Date = "Date" HCOLON SIPdate
229 * SIPdate = wkday "," SP date1 SP time SP "GMT"
230 * date1 = 2DIGIT SP mnth SP 4DIGIT; day month year
231 * time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
232 * wkday = "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun"
233 * month = "Jan" | "Feb" etc
236 sip_parse_date_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
238 sip_parsed_header_t
*parsed_header
;
240 sip_hdr_value_t
*value
= NULL
;
242 if ((r
= sip_prim_parsers(sip_header
, header
)) != 0)
248 parsed_header
= calloc(1, sizeof (sip_parsed_header_t
));
249 if (parsed_header
== NULL
)
251 parsed_header
->sip_parsed_header_version
= SIP_PARSED_HEADER_VERSION_1
;
252 parsed_header
->sip_header
= sip_header
;
254 value
= calloc(1, sizeof (sip_hdr_value_t
));
256 sip_free_phdr(parsed_header
);
259 parsed_header
->value
= (sip_value_t
*)value
;
261 value
->sip_value_start
= sip_header
->sip_hdr_current
;
262 value
->sip_value_header
= parsed_header
;
263 value
->date_wd_ptr
= sip_header
->sip_hdr_current
;
264 if (sip_find_token(sip_header
, SIP_COMMA
) == 0) {
265 value
->date_wd_len
= sip_header
->sip_hdr_current
-
266 value
->date_wd_ptr
- 1;
267 sip_header
->sip_hdr_current
++;
268 if (sip_skip_white_space(sip_header
) != 0) {
269 value
->sip_value_state
= SIP_VALUE_BAD
;
273 value
->sip_value_state
= SIP_VALUE_BAD
;
277 if (sip_skip_white_space(sip_header
) != 0) {
278 value
->sip_value_state
= SIP_VALUE_BAD
;
281 r
= sip_atoi(sip_header
, &value
->date_d
);
282 if (r
!= 0 || value
->date_d
< 0 || value
->date_d
> 31) {
283 value
->sip_value_state
= SIP_VALUE_BAD
;
286 if (sip_skip_white_space(sip_header
) != 0) {
287 value
->sip_value_state
= SIP_VALUE_BAD
;
290 value
->date_m_ptr
= sip_header
->sip_hdr_current
;
291 if (sip_find_token(sip_header
, SIP_SP
) == 0) {
292 value
->date_m_len
= sip_header
->sip_hdr_current
-
293 value
->date_m_ptr
- 1;
295 value
->sip_value_state
= SIP_VALUE_BAD
;
299 r
= sip_atoi(sip_header
, &value
->date_y
);
300 if (r
!= 0 || value
->date_y
< 0) {
301 value
->sip_value_state
= SIP_VALUE_BAD
;
304 if (sip_skip_white_space(sip_header
) != 0) {
305 value
->sip_value_state
= SIP_VALUE_BAD
;
308 value
->date_t_ptr
= sip_header
->sip_hdr_current
;
309 if (sip_find_token(sip_header
, SIP_SP
) == 0) {
310 value
->date_t_len
= sip_header
->sip_hdr_current
-
311 value
->date_t_ptr
- 1;
313 value
->sip_value_state
= SIP_VALUE_BAD
;
317 value
->date_tz_ptr
= sip_header
->sip_hdr_current
;
319 * minus 2 to get rid of the CRLF
321 value
->date_tz_len
= sip_header
->sip_hdr_end
-
322 sip_header
->sip_hdr_current
- 2;
324 *header
= parsed_header
;
326 sip_header
->sip_hdr_parsed
= *header
;
331 * Error-Info = "Error-Info" HCOLON error-uri *(COMMA error-uri)
332 * error-uri = LAQUOT absoluteURI RAQUOT *(SEMI generic-param)
335 sip_parse_errorinfo_header(_sip_header_t
*sip_header
,
336 sip_parsed_header_t
**header
)
338 return (sip_parse_hdr_parser3(sip_header
, header
, SIP_STR_VAL
, B_TRUE
));
342 * Expires = "Expires" HCOLON delta-seconds
345 sip_parse_expire_header(_sip_header_t
*sip_header
,
346 sip_parsed_header_t
**header
)
348 return (sip_parse_hdr_parser2(sip_header
, header
, SIP_INT_VAL
));
352 * In-Reply-To = "In-Reply-To" HCOLON callid *(COMMA callid)
355 sip_parse_inreplyto_header(_sip_header_t
*sip_header
,
356 sip_parsed_header_t
**header
)
358 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
362 * RSeq = "RSeq" HCOLON response-num
365 sip_parse_rseq(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
368 sip_hdr_value_t
*rseq_value
;
370 r
= sip_parse_hdr_parser2(sip_header
, header
, SIP_INT_VAL
);
372 * Additionally, a value of 0 is bad_value
374 if (sip_header
->sip_hdr_parsed
!= NULL
&&
375 sip_header
->sip_hdr_parsed
->value
!= NULL
) {
376 rseq_value
= (sip_hdr_value_t
*)
377 sip_header
->sip_hdr_parsed
->value
;
378 if (rseq_value
->int_val
== 0)
379 rseq_value
->sip_value_state
= SIP_VALUE_BAD
;
385 * Min-Expires = "Min-Expires" HCOLON delta-seconds
388 sip_parse_minexpire_header(_sip_header_t
*sip_header
,
389 sip_parsed_header_t
**header
)
391 return (sip_parse_hdr_parser2(sip_header
, header
, SIP_INT_VAL
));
395 * MIME-Version = "MIME-Version" HCOLON 1*DIGIT "." 1*DIGIT
398 sip_parse_mimeversion_header(_sip_header_t
*sip_header
,
399 sip_parsed_header_t
**header
)
401 return (sip_parse_hdr_parser4(sip_header
, header
));
405 * Organization = "Organization" HCOLON [TEXT-UTF8-TRIM]
408 sip_parse_org_header(_sip_header_t
*sip_header
,
409 sip_parsed_header_t
**header
)
411 if (sip_is_empty_hdr(sip_header
))
412 return (sip_parse_hdr_empty(sip_header
, header
));
413 return (sip_parse_hdr_parser4(sip_header
, header
));
417 * Priority = "Priority" HCOLON priority-val
418 * priority-val = "emergency" | "urgent" | "normal" | "non-urgent" | other
422 sip_parse_priority_header(_sip_header_t
*sip_header
,
423 sip_parsed_header_t
**header
)
425 return (sip_parse_hdr_parser4(sip_header
, header
));
429 * Reply-To = "Reply-To" HCOLON rplyto-spec
430 * rplyto-spec = (name-addr | addr-spec) *(SEMI rplyto-param)
431 * rplyto-param = generic-param
432 * name-addr = [ display-name ] LAQUOT addr-spec RAQUOT
433 * addr-spec = SIP-URI | SIPS-URI | absolute URI
436 sip_parse_replyto_header(_sip_header_t
*sip_header
,
437 sip_parsed_header_t
**header
)
439 return (sip_parse_hdr_parser3(sip_header
, header
, SIP_STRS_VAL
,
444 * PRIVACY = "Privacy" HCOLON priv-value *(COMMA priv-value)
445 * priv-value = "header" / "session" / "user" / "none" / "critical"
449 sip_parse_privacy_header(_sip_header_t
*sip_header
,
450 sip_parsed_header_t
**header
)
452 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
457 * Require = "Require" HCOLON option-tag * (COMMA option-tag)
460 sip_parse_require_header(_sip_header_t
*sip_header
,
461 sip_parsed_header_t
**header
)
463 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
467 * Retry-After = "Retry-After" HCOLON delta-seconds [ comment ] *
469 * retry-param = "duration" EQUAL delta-seconds
472 sip_parse_retryaft_header(_sip_header_t
*sip_header
,
473 sip_parsed_header_t
**header
)
475 sip_parsed_header_t
*parsed_header
;
476 sip_hdr_value_t
*value
= NULL
;
479 if ((ret
= sip_prim_parsers(sip_header
, header
)) != 0)
485 parsed_header
= calloc(1, sizeof (sip_parsed_header_t
));
486 if (parsed_header
== NULL
)
488 parsed_header
->sip_parsed_header_version
= SIP_PARSED_HEADER_VERSION_1
;
489 parsed_header
->sip_header
= sip_header
;
491 value
= calloc(1, sizeof (sip_hdr_value_t
));
493 sip_free_phdr(parsed_header
);
497 parsed_header
->value
= (sip_value_t
*)value
;
498 value
->sip_value_start
= sip_header
->sip_hdr_current
;
499 value
->sip_value_header
= parsed_header
;
501 ret
= sip_atoi(sip_header
, &(value
->intstr_int
));
503 value
->sip_value_state
= SIP_VALUE_BAD
;
504 if (sip_find_token(sip_header
, SIP_LPAR
) == 0) {
505 value
->intstr_str_ptr
= sip_header
->sip_hdr_current
;
506 if (sip_find_token(sip_header
, SIP_RPAR
) == 0) {
507 value
->intstr_str_len
=
508 sip_header
->sip_hdr_current
-
509 value
->intstr_str_ptr
- 1;
510 if (sip_find_token(sip_header
, SIP_SEMI
) == 0) {
511 sip_header
->sip_hdr_current
--;
512 (void) sip_parse_params(sip_header
,
513 &(value
->sip_param_list
));
516 value
->sip_value_state
= SIP_VALUE_BAD
;
520 value
->intstr_str_ptr
= NULL
;
521 value
->intstr_str_len
= 0;
524 * from value start, search if parameter list
526 sip_header
->sip_hdr_current
= value
->sip_value_start
;
527 if (sip_find_token(sip_header
, SIP_SEMI
) == 0) {
528 sip_header
->sip_hdr_current
--;
529 (void) sip_parse_params(sip_header
,
530 &(value
->sip_param_list
));
534 *header
= parsed_header
;
535 sip_header
->sip_hdr_parsed
= *header
;
540 * Server = "Server" HCOLON servel-val *(LWS server-val)
541 * servel-val = product|comment
542 * product = token [SLASH version]
544 * Treated as one single string
547 sip_parse_server_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
549 return (sip_parse_hdr_parser4(sip_header
, header
));
553 * Subject = ("Subject" | "s")HCOLON [TEXT-UTF8-TRIM]
556 sip_parse_subject_header(_sip_header_t
*sip_header
,
557 sip_parsed_header_t
**header
)
559 if (sip_is_empty_hdr(sip_header
))
560 return (sip_parse_hdr_empty(sip_header
, header
));
561 return (sip_parse_hdr_parser4(sip_header
, header
));
565 * Supported = ("Supported" | "k") HCOLON [option-tag * (COMMA option-tag) ]
568 sip_parse_support_header(_sip_header_t
*sip_header
,
569 sip_parsed_header_t
**header
)
571 if (sip_is_empty_hdr(sip_header
))
572 return (sip_parse_hdr_empty(sip_header
, header
));
573 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
577 * Timestamp = "Timestamp" HCOLON 1*DIGIT ["." *(DIGIT)] [LWS delay]
580 sip_parse_timestamp_header(_sip_header_t
*sip_header
,
581 sip_parsed_header_t
**header
)
583 sip_parsed_header_t
*parsed_header
;
584 sip_hdr_value_t
*value
= NULL
;
587 if ((ret
= sip_prim_parsers(sip_header
, header
)) != 0)
593 parsed_header
= calloc(1, sizeof (sip_parsed_header_t
));
594 if (parsed_header
== NULL
)
596 parsed_header
->sip_parsed_header_version
= SIP_PARSED_HEADER_VERSION_1
;
597 parsed_header
->sip_header
= sip_header
;
599 value
= calloc(1, sizeof (sip_hdr_value_t
));
601 sip_free_phdr(parsed_header
);
604 parsed_header
->value
= (sip_value_t
*)value
;
606 value
->sip_value_start
= sip_header
->sip_hdr_current
;
607 value
->sip_value_header
= parsed_header
;
609 if (sip_skip_white_space(sip_header
) != 0) {
610 value
->sip_value_state
= SIP_VALUE_BAD
;
613 value
->strs1_val_ptr
= sip_header
->sip_hdr_current
;
615 if (sip_find_white_space(sip_header
) == 0) {
617 * timestamp and delay, timestamp in str1, delay in str2
619 value
->strs1_val_len
= sip_header
->sip_hdr_current
-
620 value
->strs1_val_ptr
;
621 (void) sip_skip_white_space(sip_header
);
623 value
->strs2_val_ptr
= sip_header
->sip_hdr_current
;
624 if (sip_find_cr(sip_header
) != 0) {
625 value
->sip_value_state
= SIP_VALUE_BAD
;
628 if (sip_header
->sip_hdr_current
< value
->strs2_val_ptr
) {
629 value
->strs2_val_ptr
= NULL
;
630 value
->strs2_val_len
= 0;
632 value
->strs2_val_len
= sip_header
->sip_hdr_current
-
633 value
->strs2_val_ptr
;
637 * no delay information
639 value
->strs1_val_len
= sip_header
->sip_hdr_current
640 - value
->strs1_val_ptr
;
641 value
->strs2_val_ptr
= NULL
;
642 value
->strs2_val_len
= 0;
645 *header
= parsed_header
;
646 sip_header
->sip_hdr_parsed
= *header
;
651 * Unsupported = "Unsupported" HCOLON option-tag * (COMMA option-tag)
654 sip_parse_usupport_header(_sip_header_t
*sip_header
,
655 sip_parsed_header_t
**header
)
657 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
661 * User-Agent = "User-Agent" HCOLON server-val * (LWS server-val)
662 * servel-val = product |comment
663 * product = token [SLASH version]
667 sip_parse_useragt_header(_sip_header_t
*sip_header
,
668 sip_parsed_header_t
**header
)
670 return (sip_parse_hdr_parser4(sip_header
, header
));
674 * Warning = "Warning" HCOLON warning-value *(COMMA warning-value)
675 * warning-value = warn-code SP warn-agent SP warn-text
677 * warn-agent = hostport | pseudonym ;
678 * the name or pseudonym of the server adding;
679 * the Warning header, for use in debugging
680 * warn-text = quoted-string
684 sip_parse_warn_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
686 sip_parsed_header_t
*parsed_header
;
688 sip_hdr_value_t
*value
= NULL
;
689 sip_hdr_value_t
*last_value
= NULL
;
691 if ((ret
= sip_prim_parsers(sip_header
, header
)) != 0)
697 parsed_header
= calloc(1, sizeof (sip_parsed_header_t
));
698 if (parsed_header
== NULL
)
700 parsed_header
->sip_parsed_header_version
= SIP_PARSED_HEADER_VERSION_1
;
701 parsed_header
->sip_header
= sip_header
;
703 while (sip_header
->sip_hdr_current
< sip_header
->sip_hdr_end
) {
704 value
= calloc(1, sizeof (sip_hdr_value_t
));
706 sip_free_phdr(parsed_header
);
710 if (last_value
!= NULL
)
711 last_value
->sip_next_value
= value
;
713 parsed_header
->value
= (sip_value_t
*)value
;
715 value
->sip_value_start
= sip_header
->sip_hdr_current
;
716 value
->sip_value_header
= parsed_header
;
718 ret
= sip_atoi(sip_header
, &value
->warn_code
);
719 if (ret
!= 0 || value
->warn_code
< 100 ||
720 value
->warn_code
> 999) {
721 value
->sip_value_state
= SIP_VALUE_BAD
;
724 if (sip_skip_white_space(sip_header
) != 0) {
725 value
->sip_value_state
= SIP_VALUE_BAD
;
728 value
->warn_agt_ptr
= sip_header
->sip_hdr_current
;
730 if (sip_find_token(sip_header
, SIP_QUOTE
) == 0) {
734 sip_header
->sip_hdr_current
--;
735 (void) sip_reverse_skip_white_space(sip_header
);
736 value
->warn_agt_len
= sip_header
->sip_hdr_current
-
737 value
->warn_agt_ptr
- 1;
738 if (value
->warn_agt_len
<= 0) {
739 value
->warn_agt_ptr
= NULL
;
740 value
->sip_value_state
= SIP_VALUE_BAD
;
744 * We will have a SIP_QUOTE here
746 (void) sip_find_token(sip_header
, SIP_QUOTE
);
748 value
->warn_text_ptr
= sip_header
->sip_hdr_current
;
749 if (sip_find_token(sip_header
, SIP_QUOTE
) == 0) {
750 value
->warn_text_len
=
751 sip_header
->sip_hdr_current
-
752 value
->warn_text_ptr
- 1;
754 value
->sip_value_state
= SIP_VALUE_BAD
;
759 * warning text must present
761 value
->sip_value_state
= SIP_VALUE_BAD
;
764 if (sip_find_token(sip_header
, SIP_COMMA
) != 0)
766 value
->sip_value_end
= sip_header
->sip_hdr_current
- 1;
768 (void) sip_skip_white_space(sip_header
);
771 *header
= parsed_header
;
773 sip_header
->sip_hdr_parsed
= *header
;
779 * "RAck" HCOLON response-num LWS CSeq-num LWS Method
780 * response-num = 1*DIGIT
784 sip_parse_rack(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
786 sip_parsed_header_t
*parsed_header
;
787 sip_hdr_value_t
*rack_value
;
793 if ((ret
= sip_prim_parsers(sip_header
, header
)) != 0)
799 parsed_header
= calloc(1, sizeof (sip_parsed_header_t
));
800 if (parsed_header
== NULL
)
802 parsed_header
->sip_parsed_header_version
= SIP_PARSED_HEADER_VERSION_1
;
803 parsed_header
->sip_header
= sip_header
;
805 parsed_header
->value
= calloc(1, sizeof (sip_hdr_value_t
));
806 if (parsed_header
->value
== NULL
) {
810 rack_value
= (sip_hdr_value_t
*)parsed_header
->value
;
811 rack_value
->sip_value_version
= SIP_VALUE_VERSION_1
;
812 rack_value
->sip_value_start
= sip_header
->sip_hdr_current
;
813 rack_value
->sip_value_header
= parsed_header
;
814 if (sip_atoi(sip_header
, &rack_value
->rack_resp
) ||
815 rack_value
->rack_resp
== 0) {
816 rack_value
->sip_value_state
= SIP_VALUE_BAD
;
817 rack_value
->sip_value_end
= sip_header
->sip_hdr_end
- 2;
818 goto rack_parse_done
;
820 rack_value
->sip_value_header
= parsed_header
;
824 if (sip_skip_white_space(sip_header
) != 0) {
825 rack_value
->sip_value_state
= SIP_VALUE_BAD
;
826 rack_value
->sip_value_end
= sip_header
->sip_hdr_end
- 2;
827 goto rack_parse_done
;
829 if (sip_atoi(sip_header
, &rack_value
->rack_cseq
)) {
830 rack_value
->sip_value_state
= SIP_VALUE_BAD
;
831 rack_value
->sip_value_end
= sip_header
->sip_hdr_end
- 2;
832 goto rack_parse_done
;
837 if (sip_skip_white_space(sip_header
) != 0) {
838 rack_value
->sip_value_state
= SIP_VALUE_BAD
;
839 rack_value
->sip_value_end
= sip_header
->sip_hdr_end
- 2;
840 goto rack_parse_done
;
843 tmp_ptr
= sip_header
->sip_hdr_current
;
844 if (sip_find_white_space(sip_header
)) {
845 rack_value
->sip_value_state
= SIP_VALUE_BAD
;
846 rack_value
->sip_value_end
= sip_header
->sip_hdr_end
- 2;
847 goto rack_parse_done
;
850 len
= sip_header
->sip_hdr_current
- tmp_ptr
;
852 for (i
= 1; i
< MAX_SIP_METHODS
; i
++) {
853 if (strncmp(sip_methods
[i
].name
, tmp_ptr
, len
) == 0)
857 if (i
>= MAX_SIP_METHODS
) {
858 rack_value
->sip_value_state
= SIP_VALUE_BAD
;
859 rack_value
->sip_value_end
= sip_header
->sip_hdr_end
- 2;
860 goto rack_parse_done
;
863 rack_value
->rack_method
= i
;
864 rack_value
->sip_value_end
= sip_header
->sip_hdr_current
;
867 sip_header
->sip_hdr_parsed
= parsed_header
;
869 *header
= parsed_header
;
874 * Allow = "Allow" HCOLON [Method *(COMMA Method)]
877 sip_parse_allow_events_header(_sip_header_t
*sip_header
,
878 sip_parsed_header_t
**header
)
880 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
884 * Event = ( "Event" / "o" ) HCOLON event-type
885 * *( SEMI event-param )
886 * event-type = event-package *( "." event-template )
887 * event-package = token-nodot
888 * event-template = token-nodot
889 * token-nodot = 1*( alphanum / "-" / "!" / "%" / "*"
890 * / "_" / "+" / "`" / "'" / "~" )
891 * event-param = generic-param / ( "id" EQUAL token )
894 sip_parse_event_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
896 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
900 * Subscription-State = "Subscription-State" HCOLON substate-value
901 * *( SEMI subexp-params )
902 * substate-value = "active" / "pending" / "terminated"
903 * / extension-substate
904 * extension-substate = token
905 * subexp-params = ("reason" EQUAL event-reason-value)
906 * / ("expires" EQUAL delta-seconds)*
907 * / ("retry-after" EQUAL delta-seconds)
909 * event-reason-value = "deactivated"
915 * / event-reason-extension
916 * event-reason-extension = token
919 sip_parse_substate_header(_sip_header_t
*sip_header
,
920 sip_parsed_header_t
**header
)
922 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
926 * Authorization = "Authorization" HCOLON credentials
927 * credentials = ("Digest" LWS digest-response)
929 * digest-response = dig-resp *(COMMA dig-resp)
930 * dig-resp = username / realm / nonce / digest-uri
931 * / dresponse / algorithm / cnonce
932 * / opaque / message-qop
933 * / nonce-count / auth-param
934 * username = "username" EQUAL username-value
935 * username-value = quoted-string
936 * digest-uri = "uri" EQUAL LDQUOT digest-uri-value RDQUOT
937 * digest-uri-value = rquest-uri ; Equal to request-uri as specified
939 * message-qop = "qop" EQUAL qop-value
940 * cnonce = "cnonce" EQUAL cnonce-value
941 * cnonce-value = nonce-value
942 * nonce-count = "nc" EQUAL nc-value
944 * dresponse = "response" EQUAL request-digest
945 * request-digest = LDQUOT 32LHEX RDQUOT
946 * auth-param = auth-param-name EQUAL
947 * ( token / quoted-string )
948 * auth-param-name = token
949 * other-response = auth-scheme LWS auth-param
950 * *(COMMA auth-param)
951 * auth-scheme = token
954 sip_parse_author_header(_sip_header_t
*sip_header
,
955 sip_parsed_header_t
**header
)
957 return (sip_parse_hdr_parser5(sip_header
, header
, B_TRUE
));
961 * Authentication-Info = "Authentication-Info" HCOLON ainfo
963 * ainfo = nextnonce / message-qop
964 * / response-auth / cnonce
966 * nextnonce = "nextnonce" EQUAL nonce-value
967 * response-auth = "rspauth" EQUAL response-digest
968 * response-digest = LDQUOT *LHEX RDQUOT
972 sip_parse_ainfo_header(_sip_header_t
*sip_header
,
973 sip_parsed_header_t
**header
)
975 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
979 * Proxy-Authenticate = "Proxy-Authenticate" HCOLON challenge
980 * challenge = ("Digest" LWS digest-cln *(COMMA digest-cln))
982 * other-challenge = auth-scheme LWS auth-param
983 * *(COMMA auth-param)
984 * digest-cln = realm / domain / nonce
985 * / opaque / stale / algorithm
986 * / qop-options / auth-param
987 * realm = "realm" EQUAL realm-value
988 * realm-value = quoted-string
989 * domain = "domain" EQUAL LDQUOT URI
990 * *( 1*SP URI ) RDQUOT
991 * URI = absoluteURI / abs-path
992 * nonce = "nonce" EQUAL nonce-value
993 * nonce-value = quoted-string
994 * opaque = "opaque" EQUAL quoted-string
995 * stale = "stale" EQUAL ( "true" / "false" )
996 * algorithm = "algorithm" EQUAL ( "MD5" / "MD5-sess"
998 * qop-options = "qop" EQUAL LDQUOT qop-value
999 * *("," qop-value) RDQUOT
1000 * qop-value = "auth" / "auth-int" / token
1004 sip_parse_pauthen_header(_sip_header_t
*sip_header
,
1005 sip_parsed_header_t
**header
)
1007 return (sip_parse_hdr_parser5(sip_header
, header
, B_TRUE
));
1011 * Proxy-Authorization = "Proxy-Authorization" HCOLON credentials
1014 sip_parse_pauthor_header(_sip_header_t
*sip_header
,
1015 sip_parsed_header_t
**header
)
1017 return (sip_parse_hdr_parser5(sip_header
, header
, B_TRUE
));
1021 * Proxy-Require = "Proxy-Require" HCOLON option-tag
1022 * *(COMMA option-tag)
1023 * option-tag = token
1026 sip_parse_preq_header(_sip_header_t
*sip_header
,
1027 sip_parsed_header_t
**header
)
1029 return (sip_parse_hdr_parser1(sip_header
, header
, (char)NULL
));
1033 * WWW-Authenticate = "WWW-Authenticate" HCOLON challenge
1034 * extension-header = header-name HCOLON header-value
1035 * header-name = token
1036 * header-value = *(TEXT-UTF8char / UTF8-CONT / LWS)
1037 * message-body = *OCTET
1041 sip_parse_wauthen_header(_sip_header_t
*sip_header
,
1042 sip_parsed_header_t
**header
)
1044 return (sip_parse_hdr_parser5(sip_header
, header
, B_TRUE
));
1048 * Call-ID = ( "Call-ID" / "i" ) HCOLON callid
1051 sip_parse_cid_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
1053 return (sip_parse_hdr_parser4(sip_header
, header
));
1057 * CSeq = "CSeq" HCOLON 1*DIGIT LWS Method
1060 sip_parse_cseq_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
1062 sip_parsed_header_t
*parsed_header
;
1063 sip_hdr_value_t
*cseq_value
;
1069 if ((ret
= sip_prim_parsers(sip_header
, header
)) != 0)
1072 if (*header
!= NULL
)
1075 parsed_header
= calloc(1, sizeof (sip_parsed_header_t
));
1076 if (parsed_header
== NULL
)
1078 parsed_header
->sip_parsed_header_version
= SIP_PARSED_HEADER_VERSION_1
;
1079 parsed_header
->sip_header
= sip_header
;
1081 parsed_header
->value
= calloc(1, sizeof (sip_hdr_value_t
));
1082 if (parsed_header
->value
== NULL
) {
1083 free(parsed_header
);
1086 cseq_value
= (sip_hdr_value_t
*)parsed_header
->value
;
1087 cseq_value
->sip_value_version
= SIP_VALUE_VERSION_1
;
1088 cseq_value
->sip_value_start
= sip_header
->sip_hdr_current
;
1089 if (sip_atoi(sip_header
, &cseq_value
->cseq_num
)) {
1090 cseq_value
->sip_value_state
= SIP_VALUE_BAD
;
1091 cseq_value
->sip_value_end
= sip_header
->sip_hdr_end
- 2;
1092 goto cseq_parse_done
;
1094 cseq_value
->sip_value_header
= parsed_header
;
1098 if (sip_skip_white_space(sip_header
) != 0) {
1099 cseq_value
->sip_value_state
= SIP_VALUE_BAD
;
1100 cseq_value
->sip_value_end
= sip_header
->sip_hdr_end
- 2;
1101 goto cseq_parse_done
;
1104 tmp_ptr
= sip_header
->sip_hdr_current
;
1106 if (sip_find_white_space(sip_header
)) {
1107 cseq_value
->sip_value_state
= SIP_VALUE_BAD
;
1108 cseq_value
->sip_value_end
= sip_header
->sip_hdr_current
;
1109 goto cseq_parse_done
;
1112 len
= sip_header
->sip_hdr_current
- tmp_ptr
;
1114 for (i
= 1; i
< MAX_SIP_METHODS
; i
++) {
1115 if (strncmp(sip_methods
[i
].name
, tmp_ptr
, len
) == 0)
1119 if (i
>= MAX_SIP_METHODS
) {
1120 cseq_value
->sip_value_state
= SIP_VALUE_BAD
;
1121 cseq_value
->sip_value_end
= sip_header
->sip_hdr_current
;
1122 goto cseq_parse_done
;
1125 cseq_value
->cseq_method
= i
;
1126 cseq_value
->sip_value_end
= sip_header
->sip_hdr_current
;
1129 sip_header
->sip_hdr_parsed
= parsed_header
;
1131 *header
= parsed_header
;
1137 * Via = ( "Via" / "v" ) HCOLON via-parm *(COMMA via-parm)
1138 * via-parm = sent-protocol LWS sent-by *( SEMI via-params )
1139 * via-params = via-ttl / via-maddr
1140 * / via-received / via-branch
1142 * via-ttl = "ttl" EQUAL ttl
1143 * via-maddr = "maddr" EQUAL host
1144 * via-received = "received" EQUAL (IPv4address / IPv6address)
1145 * via-branch = "branch" EQUAL token
1146 * via-extension = generic-param
1147 * sent-protocol = protocol-name SLASH protocol-version
1149 * protocol-name = "SIP" / token
1150 * protocol-version = token
1151 * transport = "UDP" / "TCP" / "TLS" / "SCTP"
1153 * sent-by = host [ COLON port ]
1154 * ttl = 1*3DIGIT ; 0 to 255
1156 * There can be multiple via headers we always append the header.
1159 sip_parse_via_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
1161 sip_parsed_header_t
*parsed_header
;
1163 sip_hdr_value_t
*value
= NULL
;
1164 sip_hdr_value_t
*last_value
= NULL
;
1166 if ((ret
= sip_prim_parsers(sip_header
, header
)) != 0)
1169 if (*header
!= NULL
)
1172 parsed_header
= calloc(1, sizeof (sip_parsed_header_t
));
1173 if (parsed_header
== NULL
)
1175 parsed_header
->sip_parsed_header_version
= SIP_PARSED_HEADER_VERSION_1
;
1176 parsed_header
->sip_header
= sip_header
;
1178 while (sip_header
->sip_hdr_current
< sip_header
->sip_hdr_end
) {
1180 value
= calloc(1, sizeof (sip_hdr_value_t
));
1181 if (value
== NULL
) {
1182 sip_free_phdr(parsed_header
);
1185 if (last_value
!= NULL
)
1186 last_value
->sip_next_value
= value
;
1188 parsed_header
->value
= (sip_value_t
*)value
;
1190 value
->sip_value_version
= SIP_VALUE_VERSION_1
;
1191 value
->sip_value_start
= sip_header
->sip_hdr_current
;
1192 value
->sip_value_header
= parsed_header
;
1193 value
->via_protocol_name
.sip_str_ptr
=
1194 sip_header
->sip_hdr_current
;
1197 * Check to see if there is a version number
1199 if (sip_get_protocol_version(sip_header
,
1200 &value
->via_protocol
) != 0) {
1201 if (sip_goto_next_value(sip_header
) != 0) {
1202 sip_free_phdr(parsed_header
);
1205 value
->sip_value_state
= SIP_VALUE_BAD
;
1206 goto get_next_via_value
;
1209 if (sip_find_token(sip_header
, SIP_SLASH
) != 0) {
1210 if (sip_goto_next_value(sip_header
) != 0) {
1211 sip_free_phdr(parsed_header
);
1214 value
->sip_value_state
= SIP_VALUE_BAD
;
1215 goto get_next_via_value
;
1218 if (sip_skip_white_space(sip_header
) != 0) {
1219 if (sip_goto_next_value(sip_header
) != 0) {
1220 sip_free_phdr(parsed_header
);
1223 value
->sip_value_state
= SIP_VALUE_BAD
;
1224 goto get_next_via_value
;
1227 value
->via_protocol_transport
.sip_str_ptr
=
1228 sip_header
->sip_hdr_current
;
1229 if (sip_find_white_space(sip_header
) != 0) {
1230 if (sip_goto_next_value(sip_header
) != 0) {
1231 sip_free_phdr(parsed_header
);
1234 value
->sip_value_state
= SIP_VALUE_BAD
;
1235 goto get_next_via_value
;
1238 value
->via_protocol_transport
.sip_str_len
=
1239 sip_header
->sip_hdr_current
-
1240 value
->via_protocol_transport
.sip_str_ptr
;
1242 if (sip_skip_white_space(sip_header
) != 0) {
1243 if (sip_goto_next_value(sip_header
) != 0) {
1244 sip_free_phdr(parsed_header
);
1247 value
->sip_value_state
= SIP_VALUE_BAD
;
1248 goto get_next_via_value
;
1251 value
->via_sent_by_host
.sip_str_ptr
=
1252 sip_header
->sip_hdr_current
;
1253 if (*sip_header
->sip_hdr_current
== '[') {
1254 if (sip_find_token(sip_header
, ']')) {
1255 if (sip_goto_next_value(sip_header
) != 0) {
1256 sip_free_phdr(parsed_header
);
1259 value
->sip_value_state
= SIP_VALUE_BAD
;
1260 goto get_next_via_value
;
1262 } else if (sip_find_separator(sip_header
, SIP_SEMI
, SIP_COMMA
,
1263 SIP_HCOLON
, B_FALSE
)) {
1264 if (sip_goto_next_value(sip_header
) != 0) {
1265 sip_free_phdr(parsed_header
);
1268 value
->sip_value_state
= SIP_VALUE_BAD
;
1269 goto get_next_via_value
;
1271 value
->via_sent_by_host
.sip_str_len
=
1272 sip_header
->sip_hdr_current
-
1273 value
->via_sent_by_host
.sip_str_ptr
;
1275 if (sip_skip_white_space(sip_header
) != 0) {
1276 if (sip_goto_next_value(sip_header
) != 0) {
1277 sip_free_phdr(parsed_header
);
1280 value
->sip_value_state
= SIP_VALUE_BAD
;
1281 goto get_next_via_value
;
1284 if (*sip_header
->sip_hdr_current
== SIP_HCOLON
) {
1285 sip_header
->sip_hdr_current
++;
1287 * We have a port number
1289 if (sip_atoi(sip_header
, &value
->via_sent_by_port
) !=
1291 if (sip_goto_next_value(sip_header
) != 0) {
1292 sip_free_phdr(parsed_header
);
1295 value
->sip_value_state
= SIP_VALUE_BAD
;
1296 goto get_next_via_value
;
1302 * Do some sanity checking.
1303 * This should be replaced by a v4/v6 address check.
1305 if (value
->via_sent_by_host
.sip_str_len
== 0 ||
1306 (!isalnum(*value
->via_sent_by_host
.sip_str_ptr
) &&
1307 *value
->via_sent_by_host
.sip_str_ptr
!= '[')) {
1308 if (sip_goto_next_value(sip_header
) != 0) {
1309 sip_free_phdr(parsed_header
);
1312 value
->sip_value_state
= SIP_VALUE_BAD
;
1313 goto get_next_via_value
;
1316 ret
= sip_parse_params(sip_header
, &value
->sip_param_list
);
1317 if (ret
== EPROTO
) {
1318 value
->sip_value_state
= SIP_VALUE_BAD
;
1319 } else if (ret
!= 0) {
1320 sip_free_phdr(parsed_header
);
1324 value
->sip_value_end
= sip_header
->sip_hdr_current
;
1326 if (sip_find_token(sip_header
, SIP_COMMA
) != 0)
1329 (void) sip_skip_white_space(sip_header
);
1332 sip_header
->sip_hdr_parsed
= parsed_header
;
1334 *header
= parsed_header
;
1339 * Max-Forwards = "Max-Forwards" HCOLON 1*DIGIT
1342 sip_parse_maxf_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
1344 return (sip_parse_hdr_parser2(sip_header
, header
, SIP_INT_VAL
));
1348 * Content-Type = ( "Content-Type" / "c" ) HCOLON media-type
1349 * media-type = m-type SLASH m-subtype *(SEMI m-parameter)
1350 * m-type = discrete-type / composite-type
1351 * discrete-type = "text" / "image" / "audio" / "video"
1352 * / "application" / extension-token
1353 * composite-type = "message" / "multipart" / extension-token
1354 * extension-token = ietf-token / x-token
1355 * ietf-token = token
1356 * x-token = "x-" token
1357 * m-subtype = extension-token / iana-token
1358 * iana-token = token
1359 * m-parameter = m-attribute EQUAL m-value
1360 * m-attribute = token
1361 * m-value = token / quoted-string
1364 sip_parse_ctype_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
1366 return (sip_parse_hdr_parser1(sip_header
, header
, SIP_SLASH
));
1370 * Content-Length = ( "Content-Length" / "l" ) HCOLON 1*DIGIT
1373 sip_parse_clen_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
1375 return (sip_parse_hdr_parser2(sip_header
, header
, SIP_INT_VAL
));
1379 * Generic parser for Contact, From, To, Route and Record-Route headers
1381 * Contact = ("Contact" / "m" ) HCOLON
1382 * ( STAR / (contact-param *(COMMA contact-param)))
1383 * contact-param = (name-addr / addr-spec) *(SEMI contact-params)
1384 * name-addr = [ display-name ] LAQUOT addr-spec RAQUOT
1385 * addr-spec = SIP-URI / SIPS-URI / absoluteURI
1386 * display-name = *(token LWS)/ quoted-string
1387 * contact-params = c-p-q / c-p-expires
1388 * / contact-extension
1390 * From = ( "From" / "f" ) HCOLON from-spec
1391 * from-spec = ( name-addr / addr-spec )
1392 * *( SEMI from-param )
1393 * from-param = tag-param / generic-param
1394 * tag-param = "tag" EQUAL token
1396 * To = ( "To" / "t" ) HCOLON ( name-addr
1397 * / addr-spec ) *( SEMI to-param )
1398 * to-param = tag-param / generic-param
1400 * Route = "Route" HCOLON route-param *(COMMA route-param)
1401 * route-param = name-addr *( SEMI rr-param )
1403 * Record-Route = "Record-Route" HCOLON rec-route *(COMMA rec-route)
1404 * rec-route = name-addr *( SEMI rr-param )
1405 * rr-param = generic-param
1407 * We could have multiple values for these headers. For the ones that have
1408 * a display name we will have a LAQUOT/RAQUOT. If we encounter an error
1409 * when parsing a value, we mark the value as bad and start paring the
1410 * next value, if present. Before we start parsing the next value, we
1411 * check for any parameters, if present.
1414 sip_parse_cftr_header(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
1416 sip_parsed_header_t
*parsed_header
;
1420 sip_hdr_value_t
*value
= NULL
;
1421 sip_hdr_value_t
*last_value
= NULL
;
1423 if ((ret
= sip_prim_parsers(sip_header
, header
)) != 0)
1426 if (*header
!= NULL
)
1429 parsed_header
= calloc(1, sizeof (sip_parsed_header_t
));
1430 if (parsed_header
== NULL
)
1432 parsed_header
->sip_parsed_header_version
= SIP_PARSED_HEADER_VERSION_1
;
1433 parsed_header
->sip_header
= sip_header
;
1434 while (sip_header
->sip_hdr_current
< sip_header
->sip_hdr_end
) {
1435 boolean_t quoted_name
= B_FALSE
;
1437 value
= calloc(1, sizeof (sip_hdr_value_t
));
1438 if (value
== NULL
) {
1439 sip_free_cftr_header(parsed_header
);
1442 if (last_value
!= NULL
)
1443 last_value
->sip_next_value
= value
;
1445 parsed_header
->value
= (sip_value_t
*)value
;
1446 if (*sip_header
->sip_hdr_current
== SIP_QUOTE
) {
1447 sip_header
->sip_hdr_current
++;
1448 quoted_name
= B_TRUE
;
1450 value
->sip_value_version
= SIP_VALUE_VERSION_1
;
1451 value
->sip_value_start
= sip_header
->sip_hdr_current
;
1452 value
->sip_value_header
= parsed_header
;
1454 * let's see if there is a display name
1456 if (*sip_header
->sip_hdr_current
!= SIP_LAQUOT
) {
1458 tmp_ptr
= sip_header
->sip_hdr_current
;
1460 * According to 20.10 '<' may not have a leading
1464 sip_find_token(sip_header
, SIP_QUOTE
) != 0) {
1465 if (sip_goto_next_value(sip_header
) != 0) {
1466 sip_free_cftr_header(parsed_header
);
1469 value
->sip_value_state
= SIP_VALUE_BAD
;
1470 goto get_next_cftr_value
;
1471 } else if (sip_find_separator(sip_header
, SIP_SEMI
,
1472 SIP_LAQUOT
, SIP_COMMA
, B_TRUE
) != 0) {
1476 value
->cftr_uri
.sip_str_ptr
= tmp_ptr
;
1477 value
->cftr_uri
.sip_str_len
=
1478 sip_header
->sip_hdr_current
- tmp_ptr
;
1480 * It's an error not to have a uri.
1482 if (value
->cftr_uri
.sip_str_len
== 0) {
1483 if (sip_goto_next_value(sip_header
) !=
1485 sip_free_cftr_header(
1489 value
->sip_value_state
= SIP_VALUE_BAD
;
1490 goto get_next_cftr_value
;
1492 goto get_next_cftr_value
;
1495 * This is needed to get rid of leading white spaces of
1496 * display name or uri
1498 --sip_header
->sip_hdr_current
;
1499 (void) sip_reverse_skip_white_space(sip_header
);
1500 ++sip_header
->sip_hdr_current
;
1501 tmp_ptr_2
= sip_header
->sip_hdr_current
;
1502 if (*sip_header
->sip_hdr_current
== SIP_SP
) {
1503 if (sip_skip_white_space(sip_header
) != 0) {
1507 value
->cftr_uri
.sip_str_ptr
= tmp_ptr
;
1508 value
->cftr_uri
.sip_str_len
=
1509 tmp_ptr_2
- tmp_ptr
;
1511 * It's an error not to have a uri.
1513 if (value
->cftr_uri
.sip_str_len
== 0) {
1514 if (sip_goto_next_value(
1516 sip_free_cftr_header(
1520 value
->sip_value_state
=
1522 goto get_next_cftr_value
;
1524 goto get_next_cftr_value
;
1528 if (*sip_header
->sip_hdr_current
!= SIP_LAQUOT
) {
1530 * No display name here.
1532 value
->cftr_uri
.sip_str_ptr
= tmp_ptr
;
1533 value
->cftr_uri
.sip_str_len
= tmp_ptr_2
-
1536 * It's an error not to have a uri.
1538 if (value
->cftr_uri
.sip_str_len
== 0) {
1539 if (sip_goto_next_value(sip_header
) !=
1541 sip_free_cftr_header(
1545 value
->sip_value_state
= SIP_VALUE_BAD
;
1546 goto get_next_cftr_value
;
1551 value
->cftr_name
= malloc(sizeof (sip_str_t
));
1552 if (value
->cftr_name
== NULL
) {
1553 sip_free_cftr_header(parsed_header
);
1556 value
->cftr_name
->sip_str_ptr
= tmp_ptr
;
1557 value
->cftr_name
->sip_str_len
= tmp_ptr_2
- tmp_ptr
;
1559 value
->cftr_name
->sip_str_len
--;
1562 if (sip_find_token(sip_header
, SIP_LAQUOT
) != 0) {
1563 if (sip_goto_next_value(sip_header
) != 0) {
1564 sip_free_cftr_header(parsed_header
);
1567 value
->sip_value_state
= SIP_VALUE_BAD
;
1568 goto get_next_cftr_value
;
1571 if (*sip_header
->sip_hdr_current
== SIP_SP
) {
1572 if (sip_skip_white_space(sip_header
) != 0) {
1573 if (sip_goto_next_value(sip_header
) != 0) {
1574 sip_free_cftr_header(parsed_header
);
1577 value
->sip_value_state
= SIP_VALUE_BAD
;
1578 goto get_next_cftr_value
;
1582 tmp_ptr
= sip_header
->sip_hdr_current
;
1584 if (sip_find_separator(sip_header
, SIP_RAQUOT
, (char)NULL
,
1585 (char)NULL
, B_FALSE
)) {
1586 if (sip_goto_next_value(sip_header
) != 0) {
1587 sip_free_cftr_header(parsed_header
);
1590 value
->sip_value_state
= SIP_VALUE_BAD
;
1591 goto get_next_cftr_value
;
1594 value
->cftr_uri
.sip_str_ptr
= tmp_ptr
;
1595 value
->cftr_uri
.sip_str_len
=
1596 sip_header
->sip_hdr_current
- tmp_ptr
;
1598 if (sip_find_token(sip_header
, SIP_RAQUOT
) != 0) {
1599 if (sip_goto_next_value(sip_header
) != 0) {
1600 sip_free_cftr_header(parsed_header
);
1603 value
->sip_value_state
= SIP_VALUE_BAD
;
1604 goto get_next_cftr_value
;
1607 if (value
->cftr_uri
.sip_str_len
<= strlen("<>")) {
1608 if (sip_goto_next_value(sip_header
) != 0) {
1609 sip_free_cftr_header(parsed_header
);
1612 value
->sip_value_state
= SIP_VALUE_BAD
;
1613 goto get_next_cftr_value
;
1617 ret
= sip_parse_params(sip_header
, &value
->sip_param_list
);
1618 if (ret
== EPROTO
) {
1619 value
->sip_value_state
= SIP_VALUE_BAD
;
1620 } else if (ret
!= 0) {
1621 sip_free_cftr_header(parsed_header
);
1624 get_next_cftr_value
:
1625 value
->sip_value_end
= sip_header
->sip_hdr_current
;
1630 if (value
->cftr_uri
.sip_str_len
> 0) {
1632 uint_t uri_errflags
;
1634 _sip_msg_t
*sip_msg
;
1635 sip_message_type_t
*msg_type
;
1637 value
->sip_value_parsed_uri
= sip_parse_uri(
1638 &value
->cftr_uri
, &error
);
1639 if (value
->sip_value_parsed_uri
== NULL
) {
1640 sip_free_cftr_header(parsed_header
);
1643 uri_errflags
= ((_sip_uri_t
*)value
->
1644 sip_value_parsed_uri
)->sip_uri_errflags
;
1645 if (error
!= 0 || uri_errflags
!= 0) {
1646 if ((strcmp(SIP_CONTACT
, sip_header
->
1647 sip_header_functions
->header_name
) == 0) &&
1648 (strncmp(value
->cftr_uri
.sip_str_ptr
, uri
,
1649 strlen(uri
)) == 0) && (strlen(uri
) ==
1650 value
->cftr_uri
.sip_str_len
)) {
1651 sip_msg
= sip_header
->sip_hdr_sipmsg
;
1652 msg_type
= sip_msg
->sip_msg_req_res
;
1653 if (msg_type
->is_request
&& msg_type
->
1654 sip_req_method
== REGISTER
) {
1656 ((_sip_uri_t
*)value
->
1657 sip_value_parsed_uri
)->
1658 sip_uri_errflags
= 0;
1660 value
->sip_value_state
=
1664 value
->sip_value_state
= SIP_VALUE_BAD
;
1669 (void) sip_find_token(sip_header
, SIP_COMMA
);
1671 (void) sip_skip_white_space(sip_header
);
1674 sip_header
->sip_hdr_parsed
= parsed_header
;
1676 *header
= parsed_header
;
1681 * PAssertedID = "P-Asserted-Identity" HCOLON PAssertedID-value
1682 * *(COMMA PAssertedID-value)
1683 * PAssertedID-value = name-addr / addr-spec
1686 sip_parse_passertedid(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
1688 return (sip_parse_hdr_parser3(sip_header
, header
, SIP_STRS_VAL
,
1693 * PPreferredID = "P-Preferred-Identity" HCOLON PPreferredID-value
1694 * *(COMMA PAssertedID-value)
1695 * PPreferredID-value = name-addr / addr-spec
1698 sip_parse_ppreferredid(_sip_header_t
*sip_header
, sip_parsed_header_t
**header
)
1700 return (sip_parse_hdr_parser3(sip_header
, header
, SIP_STRS_VAL
,
1706 * We don't do anything for a header we don't understand
1710 sip_parse_unknown_header(_sip_header_t
*sip_header
,
1711 sip_parsed_header_t
**header
)