summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsip/common/sip_msg.h
blob: a600c1dfef7d75ecb6d911df2ac88bf63bfdf281 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SIP_MSG_H
#define	_SIP_MSG_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef	__cplusplus
extern "C" {
#endif

#include <pthread.h>
#include <sip.h>
#include <sys/types.h>

#ifdef	__solaris__
extern int mutex_held();
#endif

extern sip_header_function_t *sip_header_function_table_external;

/* Compare Cseq numbers */
#define	SIP_CSEQ_LT(a, b)	((int32_t)((a)-(b)) < 0)
#define	SIP_CSEQ_GT(a, b)	((int32_t)((a)-(b)) > 0)
#define	SIP_CSEQ_GEQ(a, b)	((int32_t)((a)-(b)) >= 0)

#define	SIP_HEADER_ACTIVE	0x0
#define	SIP_HEADER_DELETED	0x1
#define	SIP_HEADER_DELETED_VAL	0x2

/* List of registered sent-by values */
typedef struct sent_by_list_s {
	struct sent_by_list_s	*sb_next;
	struct sent_by_list_s	*sb_prev;
	char			*sb_val;
} sent_by_list_t;

extern sent_by_list_t	*sip_sent_by;
extern int		sip_sent_by_count;
extern pthread_mutex_t	sip_sent_by_lock;

typedef struct sip_header {
	sip_hdr_general_t	sip_hdr_general;
	/* active/deleted or has deleted val */
	int			sip_header_state;
	struct sip_header	*sip_hdr_next;
	struct sip_header	*sip_hdr_prev;
	struct sip_message	*sip_hdr_sipmsg;
	/* True if header was allocated */
	boolean_t		sip_hdr_allocated;
	sip_header_function_t	*sip_header_functions;
}_sip_header_t;

/* Structure for the SIP message body */
typedef struct sip_content {
	char			*sip_content_start;
	char			*sip_content_end;
	char			*sip_content_current;
	struct sip_content	*sip_content_next;
	boolean_t		sip_content_allocated;
}sip_content_t;


/* General definitions */

/* Two string values */
typedef struct sip_2strs {
	sip_str_t	s1;
	sip_str_t	s2;
}sip_2strs_t;

/* An integer and a string value */
typedef struct sip_intstr {
	int		i;
	sip_str_t	s;
} sip_intstr_t;

/* Warn value */
typedef struct sip_warn {
	int		code;
	sip_str_t	agt;
	sip_str_t	text;
} sip_warn_t;

/* Date value */
typedef struct sip_date {
	sip_str_t	t;
	int		d;
	sip_str_t	m;
	int		y;
	sip_str_t	tz;
	sip_str_t	wd;
} sip_date_t;

/* Authorization and authentication value */
typedef struct sip_auth {
	sip_str_t	scheme;
	sip_param_t	*param;
} sip_auth_t;

/* RACK value */
typedef struct sip_rack {
	int		rack_resp_num;
	int		rack_cseq_num;
	sip_method_t	rack_method;
}sip_rack_t;

/* Cseq value */
typedef struct sip_cseq {
	int		num;
	sip_method_t	method;
} sip_cseq_value_t;

/* Value for Contact, From and To header */
typedef struct cftr_value {
	sip_str_t	*display_name;
	sip_str_t	uri;
} sip_cftr_value_t;

/* SIP name/version/transport value in Via */
typedef struct sip_proto_version_s {
	sip_str_t	name;
	sip_str_t	version;
	sip_str_t	transport;
}sip_proto_version_t;

/* Via value */
typedef struct via_value {
	sip_proto_version_t 	sent_protocol;
	sip_str_t		sent_by_host;
	int			sent_by_port;
}sip_via_value_t;

typedef struct sip_hdr_value {
	sip_value_t	sip_value;
	union {
		int			i;
		sip_str_t		str;
		sip_2strs_t		strs;
		sip_intstr_t		intstr;
		sip_warn_t		warn;
		sip_date_t		date;
		sip_auth_t		auth;
		sip_rack_t		rack;
		sip_cseq_value_t	cseq;
		sip_cftr_value_t	cftr;
		sip_via_value_t		via;
	} hdr_value;
} sip_hdr_value_t;

/*
 * NOTE: ALL value structs MUST have sip_value_t as the first field.
 */
#define	sip_value_version	sip_value.sip_value_version
#define	sip_next_value		sip_value.next
#define	sip_param_list		sip_value.param_list
#define	sip_value_state 	sip_value.value_state
#define	sip_value_header 	sip_value.parsed_header
#define	sip_value_start		sip_value.value_start
#define	sip_value_end		sip_value.value_end
#define	sip_value_parsed_uri 	sip_value.sip_value_parse_uri

#define	auth_val		hdr_value.auth
#define	auth_scheme_ptr		hdr_value.auth.scheme.sip_str_ptr
#define	auth_scheme_len		hdr_value.auth.scheme.sip_str_len
#define	auth_param		hdr_value.auth.param
#define	int_val			hdr_value.i
#define	str_val			hdr_value.str
#define	str_val_ptr		hdr_value.str.sip_str_ptr
#define	str_val_len		hdr_value.str.sip_str_len
#define	strs_val		hdr_value.strs
#define	strs_s1			hdr_value.strs.s1
#define	strs_s2			hdr_value.strs.s2
#define	strs1_val_ptr		hdr_value.strs.s1.sip_str_ptr
#define	strs1_val_len		hdr_value.strs.s1.sip_str_len
#define	strs2_val_ptr		hdr_value.strs.s2.sip_str_ptr
#define	strs2_val_len		hdr_value.strs.s2.sip_str_len
#define	intstr_val		hdr_value.intstr
#define	intstr_int		hdr_value.intstr.i
#define	intstr_str		hdr_value.intstr.s
#define	intstr_str_ptr		hdr_value.intstr.s.sip_str_ptr
#define	intstr_str_len		hdr_value.intstr.s.sip_str_len
#define	warn_code		hdr_value.warn.code
#define	warn_agt		hdr_value.warn.agt
#define	warn_text		hdr_value.warn.text
#define	warn_agt_ptr		warn_agt.sip_str_ptr
#define	warn_agt_len		warn_agt.sip_str_len
#define	warn_text_ptr		warn_text.sip_str_ptr
#define	warn_text_len		warn_text.sip_str_len
#define	date_t			hdr_value.date.t
#define	date_d			hdr_value.date.d
#define	date_m			hdr_value.date.m
#define	date_y			hdr_value.date.y
#define	date_tz			hdr_value.date.tz
#define	date_wd			hdr_value.date.wd
#define	date_t_ptr		date_t.sip_str_ptr
#define	date_t_len		date_t.sip_str_len
#define	date_m_ptr		date_m.sip_str_ptr
#define	date_m_len		date_m.sip_str_len
#define	date_tz_ptr		date_tz.sip_str_ptr
#define	date_tz_len		date_tz.sip_str_len
#define	date_wd_ptr		date_wd.sip_str_ptr
#define	date_wd_len		date_wd.sip_str_len
#define	rack_resp		hdr_value.rack.rack_resp_num
#define	rack_cseq		hdr_value.rack.rack_cseq_num
#define	rack_method		hdr_value.rack.rack_method
#define	cftr_name		hdr_value.cftr.display_name
#define	cftr_uri		hdr_value.cftr.uri
#define	cseq_num		hdr_value.cseq.num
#define	cseq_method		hdr_value.cseq.method
#define	via_protocol		hdr_value.via.sent_protocol
#define	via_protocol_name	hdr_value.via.sent_protocol.name
#define	via_protocol_vers	hdr_value.via.sent_protocol.version
#define	via_protocol_transport	hdr_value.via.sent_protocol.transport
#define	via_sent_by_host	hdr_value.via.sent_by_host
#define	via_sent_by_port	hdr_value.via.sent_by_port

#define	SIP_INT_VAL		0x01
#define	SIP_STR_VAL		0x02
#define	SIP_STRS_VAL		0x03
#define	SIP_INTSTR_VAL		0x04
#define	SIP_AUTH_VAL		0x05

/* hdr value contains two string */
typedef sip_hdr_value_t sip_acpt_value_t;
typedef sip_hdr_value_t sip_content_type_value_t;

/* hdr value contains one string only */
typedef sip_hdr_value_t sip_acpt_lang_value_t;
typedef sip_hdr_value_t sip_acpt_encode_value_t;
typedef sip_hdr_value_t sip_alert_value_t;
typedef sip_hdr_value_t sip_cl_info_value_t;
typedef sip_hdr_value_t sip_ct_disp_value_t;
typedef sip_hdr_value_t sip_ct_encode_value_t;
typedef sip_hdr_value_t sip_ct_lang_value_t;
typedef sip_hdr_value_t sip_irt_value_t;
typedef sip_hdr_value_t sip_mime_ver_value_t;
typedef sip_hdr_value_t sip_org_value_t;
typedef sip_hdr_value_t sip_prio_value_t;
typedef sip_hdr_value_t sip_reply_value_t;
typedef sip_hdr_value_t sip_privacy_value_t;
typedef sip_hdr_value_t sip_ppassertedid_value_t;
typedef sip_hdr_value_t sip_ppreferredid_value_t;
typedef sip_hdr_value_t sip_pxy_req_value_t;
typedef sip_hdr_value_t sip_req_value_t;
typedef sip_hdr_value_t sip_subject_value_t;
typedef sip_hdr_value_t sip_svr_value_t;
typedef sip_hdr_value_t sip_support_value_t;
typedef sip_hdr_value_t sip_unsupport_value_t;
typedef sip_hdr_value_t sip_usr_agt_value_t;
typedef sip_hdr_value_t sip_err_info_value_t;
typedef sip_hdr_value_t sip_date_value_t;
typedef sip_hdr_value_t sip_allert_value_t;
typedef sip_hdr_value_t	sip_callid_value_t;

/* hdr value contain one int only */
typedef sip_hdr_value_t sip_expr_value_t;
typedef sip_hdr_value_t sip_min_expr_value_t;
typedef sip_hdr_value_t sip_retry_value_t;
typedef sip_hdr_value_t sip_timestamp_value_t;
typedef sip_hdr_value_t sip_rseq_value_t;
typedef sip_hdr_value_t sip_content_len_value_t;
typedef sip_hdr_value_t sip_max_forwards_value_t;
typedef sip_hdr_value_t sip_allow_value_t;

/* hdr value contain one int, two strings */
typedef sip_hdr_value_t sip_warn_value_t;

/* hdr field value is a list of param=param_val */
typedef sip_hdr_value_t	sip_authen_value_t;
typedef sip_hdr_value_t	sip_authen_info_value_t;
typedef sip_hdr_value_t	sip_pxy_authen_value_t;
typedef sip_hdr_value_t	sip_pxy_author_value_t;
typedef sip_hdr_value_t	sip_3w_authen_value_t;

/* SIP request line structure */
typedef struct sip_request {
	sip_method_t	sip_request_method;
	sip_str_t	sip_request_uri;
	sip_uri_t	sip_parse_uri;
} sip_request_t;

/* SIP response line structure */
typedef struct sip_response {
	int		sip_response_code;
	sip_str_t	sip_response_phrase;
} sip_response_t;

/* SIP message type - request or response */
typedef struct sip_message_type {
	boolean_t		is_request;
	sip_proto_version_t	sip_proto_version;
	union {
	sip_request_t		sip_request;
	sip_response_t		sip_response;
	} U;
	/* This is to save old value when we use a recvd message. */
	struct sip_message_type	*sip_next;
} sip_message_type_t;

/* Increment reference count on SIP message */
#define	SIP_MSG_REFCNT_INCR(sip_msg) {				\
	(void) pthread_mutex_lock(&(sip_msg)->sip_msg_mutex);	\
	(sip_msg)->sip_msg_ref_cnt++;				\
	(void) pthread_mutex_unlock(&(sip_msg)->sip_msg_mutex);	\
}

/* Decrement reference count on SIP message */
#define	SIP_MSG_REFCNT_DECR(sip_msg) {					\
	(void) pthread_mutex_lock(&(sip_msg)->sip_msg_mutex);		\
	assert((sip_msg)->sip_msg_ref_cnt > 0);				\
	if (--(sip_msg)->sip_msg_ref_cnt == 0) {			\
		sip_destroy_msg(sip_msg);				\
	} else {							\
		(void) pthread_mutex_unlock(&(sip_msg)->sip_msg_mutex);	\
	}								\
}

/* SIP message structure */
typedef struct sip_message {
	char			*sip_msg_buf;	/* Message */
	char			*sip_msg_old_buf;
	boolean_t		sip_msg_modified;
	boolean_t		sip_msg_cannot_be_modified;
	int			sip_msg_len;
	size_t			sip_msg_content_len;	/* content length */
	sip_content_t		*sip_msg_content;
	/* All fields synchronizes on this */
	pthread_mutex_t		sip_msg_mutex;
	/* doubly linked list of headers */
	_sip_header_t		*sip_msg_headers_start;
	_sip_header_t		*sip_msg_headers_end;
	_sip_header_t		*sip_msg_start_line;
	sip_message_type_t	*sip_msg_req_res;
	int			sip_msg_ref_cnt;
}_sip_msg_t;

extern char		*sip_get_tcp_msg(sip_conn_object_t, char *, size_t *);
extern char		*sip_msg_to_msgbuf(_sip_msg_t *msg, int *error);
extern char		*_sip_startline_to_str(_sip_msg_t *sip_msg, int *error);
extern int		sip_adjust_msgbuf(_sip_msg_t *msg);
extern void		sip_delete_all_headers(_sip_msg_t *sip_msg);
extern _sip_header_t	*sip_dup_header(_sip_header_t *from);
extern int		_sip_copy_header(_sip_msg_t *, _sip_header_t *, char *,
			    boolean_t);
extern int		_sip_find_and_copy_header(_sip_msg_t *, _sip_msg_t *,
			    char *, char *, boolean_t);
extern int		_sip_find_and_copy_all_header(_sip_msg_t *,
			    _sip_msg_t *, char *header_name);
extern _sip_header_t	*sip_search_for_header(_sip_msg_t *, char *,
			    _sip_header_t *);
extern void		_sip_add_header(_sip_msg_t *, _sip_header_t *,
			    boolean_t, boolean_t, char *);
extern _sip_header_t	*sip_new_header(int);
extern int		sip_create_nonOKack(sip_msg_t, sip_msg_t, sip_msg_t);
extern void		sip_destroy_msg(_sip_msg_t *);
extern void		sip_free_header(_sip_header_t *sip_header);
extern void		sip_free_phdr(sip_parsed_header_t *);
extern void		sip_free_cftr_header(sip_parsed_header_t *);

extern int		sip_parse_allow_events_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_event_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_substate_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_acpt_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_acpt_encode_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_acpt_lang_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_alert_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_allow_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_useragt_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_usupport_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_timestamp_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_support_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_subject_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_server_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_retryaft_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_require_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_replyto_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_passertedid_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_ppreferredid_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_priority_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_org_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_mimeversion_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_minexpire_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_rseq_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_inreplyto_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_privacy_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_expire_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_errorinfo_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_contentlang_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_contentencode_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_contentdis_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_callinfo_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_date_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_warn_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_cftr_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_cseq_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_cid_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_via_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_clen_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_maxf_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_ctype_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_unknown_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_ainfo_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_preq_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_author_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_pauthor_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_pauthen_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_wauthen_header(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_rseq(_sip_header_t *, sip_parsed_header_t **);
extern int		sip_parse_rack(_sip_header_t *, sip_parsed_header_t **);
extern int		sip_parse_passertedid(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_ppreferredid(_sip_header_t *,
			    sip_parsed_header_t **);
extern int		sip_parse_privacy_header(_sip_header_t *,
			    sip_parsed_header_t **);

extern sip_param_t	*sip_get_param_from_list(sip_param_t *, char *);
extern int		sip_copy_values(char *, _sip_header_t *);
extern int		sip_add_content_length(_sip_msg_t *, int);
extern int		sip_delete_start_line_locked(_sip_msg_t *);

/* Useful access macros */
#define	sip_resp_phrase_len	U.sip_response.sip_response_phrase.sip_str_len
#define	sip_resp_phrase_ptr	U.sip_response.sip_response_phrase.sip_str_ptr

#define	sip_resp_code		U.sip_response.sip_response_code
#define	sip_resp_phrase		U.sip_response.sip_response_phrase

#define	sip_req_method		U.sip_request.sip_request_method
#define	sip_req_uri		U.sip_request.sip_request_uri
#define	sip_req_uri_ptr		U.sip_request.sip_request_uri.sip_str_ptr
#define	sip_req_uri_len		U.sip_request.sip_request_uri.sip_str_ptr
#define	sip_req_parse_uri	U.sip_request.sip_parse_uri

#define	sip_header_parse	sip_header_functions->header_parse_func
#define	sip_header_name		sip_header_functions->header_name

#define	sip_hdr_start		sip_hdr_general.sip_hdr_start
#define	sip_hdr_end		sip_hdr_general.sip_hdr_end
#define	sip_hdr_current		sip_hdr_general.sip_hdr_current
#define	sip_hdr_parsed		sip_hdr_general.sip_hdr_parsed

#ifdef	__cplusplus
}
#endif

#endif	/* _SIP_MSG_H */