msg_parser.h
512dcd98
 /*
  * $Id$
  */
 
 #ifndef msg_parser_h
 #define msg_parser_h
 
f8d46776
 #include "str.h"
831faabf
 #include "data_lump.h"
 
512dcd98
 #define SIP_REQUEST 1
 #define SIP_REPLY   2
 #define SIP_INVALID 0
 
 
e72b5b50
 
 /*header types and flags*/
 #define HDR_EOH           -1
 #define HDR_ERROR          0
 #define HDR_VIA            1
 #define HDR_VIA1           1
 #define HDR_VIA2           2  /*only used as flag*/
 #define HDR_TO             4
 #define HDR_FROM           8
 #define HDR_CSEQ          16
 #define HDR_CALLID        32
 #define HDR_CONTACT       64
 #define HDR_MAXFORWARDS  128
 #define HDR_ROUTE        256
f2278164
 #define HDR_RECORDROUTE  512
e72b5b50
 #define HDR_OTHER       65536 /*unknown header type*/
f8d46776
 
0a6afa42
 /* maximum length of values appended to Via-branch parameter */
efd6c2fe
 #ifdef USE_SYNONIM
 #define MAX_BRANCH_PARAM_LEN  22
 #else
 #define MAX_BRANCH_PARAM_LEN  48
 #endif
89e74c57
 /* via param types
  * WARNING: keep in sync w/ FIN_*, GEN_PARAM and PARAM_ERROR from via_parse.c*/
 enum{
 		PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, PARAM_MADDR, PARAM_RECEIVED,
 		GEN_PARAM,
 		PARAM_ERROR
 };
 
0fcc2741
 enum{
 		TAG_PARAM=400, GENERAL_PARAM
 };
 
0a6afa42
 /* casting macro for accessing CSEQ body */
0fcc2741
 #define get_cseq( p_msg)  ((struct cseq_body*)(p_msg)->cseq->parsed)
 #define get_to( p_msg)      ((struct to_body*)(p_msg)->to->parsed)
0a6afa42
 
89e74c57
 
 
f571aa35
 #define INVITE_LEN	6
 #define ACK_LEN		3
 #define CANCEL_LEN	6
 #define BYE_LEN		3
 enum { METHOD_OTHER, METHOD_INVITE, METHOD_CANCEL, METHOD_ACK, METHOD_BYE };
 
 #define IFISMETHOD(methodname,firstchar)                                  \
 if (  (*tmp==(firstchar) || *tmp==((firstchar) | 32)) &&                  \
         strncasecmp( tmp+1, #methodname +1, methodname##_LEN-1)==0 &&     \
         *(tmp+methodname##_LEN)==' ') {                                   \
                 fl->type=SIP_REQUEST;                                     \
                 fl->u.request.method.len=methodname##_LEN;                \
                 fl->u.request.method_value=METHOD_##methodname;           \
                 tmp=buffer+methodname##_LEN;                              \
 }
f8d46776
 
512dcd98
 
 #define VIA_PARSE_OK	1
 #define VIA_PARSE_ERROR -1
e4067ffb
 #define PARSE_ERROR -1
 #define PARSE_OK 1
512dcd98
 
 #define SIP_VERSION	"SIP/2.0"
f8d46776
 #define SIP_VERSION_LEN 7
512dcd98
 
 
 struct msg_start{
 	int type;
 	union {
 		struct {
f8d46776
 			str method;
 			str uri;
 			str version;
47642fd2
 			int method_value;
512dcd98
 		}request;
 		struct {
f8d46776
 			str version;
 			str status;
 			str reason;
47642fd2
 			unsigned int /* statusclass,*/ statuscode;
512dcd98
 		}reply;
 	}u;
 };
 
 struct hdr_field{   /* format: name':' body */
 	int type;
f8d46776
 	str name;
 	str body;
 	void* parsed;
e72b5b50
 	struct hdr_field* next;
512dcd98
 };
 
89e74c57
 
 
 struct via_param{
 	int type;
 	str name;
 	str value;
 	int size; /* total size*/
 	struct via_param* next;
 };
 
512dcd98
 struct via_body{  /* format: name/version/transport host:port;params comment */
 	int error;
f8d46776
 	str hdr;   /* contains "Via" or "v" */
 	str name;
 	str version;
 	str transport;
 	str host;
512dcd98
 	int port;
f8d46776
 	str port_str;
 	str params;
 	str comment;
7f74d1b4
 	int bsize;    /* body size, not including hdr */
89e74c57
 	struct via_param* param_lst; /* list of parameters*/
 	struct via_param* last_param; /*last via parameter, internal use*/
7f74d1b4
 	/* shortcuts to "important" params*/
 	struct via_param* branch;
0fcc2741
 
e72b5b50
 	struct via_body* next; /* pointer to next via body string if
0fcc2741
          compact via or null */
512dcd98
 };
 
e4067ffb
 
 
0fcc2741
 struct to_param{
 	int type;
 	str name;
 	str value;
 	struct to_param* next;
 };
 
 struct to_body{
 	int error;
 	str body;
 	str tag_value;
 	struct to_param *param_lst;
 	struct to_param *last_param;
 };
89e74c57
 
 
e4067ffb
 struct cseq_body{
 	int error;
 	str number;
 	str method;
 };
 
 
 
888ca09d
 struct sip_msg{
e72b5b50
 	unsigned int id; /* message id, unique/process*/
888ca09d
 	struct msg_start first_line;
e72b5b50
 	struct via_body* via1;
 	struct via_body* via2;
 	struct hdr_field* headers; /* all the parsed headers*/
 	struct hdr_field* last_header; /* pointer to the last parsed header*/
 	int parsed_flag;
 	/* via, to, cseq, call-id, from, end of header*/
8350de45
 	/* first occurance of it; subsequent occurances saved in 'headers' */
e72b5b50
 	struct hdr_field* h_via1;
 	struct hdr_field* h_via2;
 	struct hdr_field* callid;
 	struct hdr_field* to;
 	struct hdr_field* cseq;
 	struct hdr_field* from;
 	struct hdr_field* contact;
10febf05
 	struct hdr_field* maxforwards;
 	struct hdr_field* route;
f2278164
 	struct hdr_field* record_route;
e72b5b50
 	char* eoh; /* pointer to the end of header (if found) or null */
 	char* unparsed; /* here we stopped parsing*/
4ac74c03
 
a15c363f
 	unsigned int src_ip;
 	unsigned int dst_ip;
4ac74c03
 	char* orig; /* original message copy */
 	char* buf;  /* scratch pad, holds a modfied message,
 				   via, etc. point into it */
 				   
 	unsigned int len; /* message len (orig) */
7268726e
 
 	/* modifications */
f8d46776
 	str new_uri; /* changed first line uri*/
831faabf
 
 	struct lump* add_rm;      /* used for all the forwarded messages */
 	struct lump* repl_add_rm; /* only for localy generated replies !!!*/
0498ceb9
 	struct lump_rpl *reply_lump;
676eb608
 
b4690c76
 	/* str add_to_branch; */ /* whatever whoever want to append to branch comes here */
0a6afa42
 	char add_to_branch_s[MAX_BRANCH_PARAM_LEN];
416db8cd
 	int add_to_branch_len;
0a6afa42
 
d3b31abd
 	/* index to TM hash table; stored in core to avoid unnecessary calcs */
 	unsigned int  hash_index;
 
4ac74c03
 	
888ca09d
 };
 
512dcd98
 
7268726e
 struct sip_uri{
f8d46776
 	str user;
 	str passwd;
 	str host;
 	str port;
 	str params;
 	str headers;
7268726e
 };
 
 
b6f4c1df
 char* parse_fline(char* buffer, char* end, struct msg_start* fl);
512dcd98
 char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl);
f8d46776
 char* parse_hostport(char* buf, str* host, short int* port);
 
888ca09d
 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg);
7268726e
 int parse_uri(char *buf, int len, struct sip_uri* uri);
e4067ffb
 int parse_headers(struct sip_msg* msg, int flags);
 
5ada8f8a
 void free_uri(struct sip_uri* u);
512dcd98
 
 
f8d46776
 char* parse_hname(char* buf, char* end, struct hdr_field* hdr);
 char* parse_via(char* buffer, char* end, struct via_body *vb);
0fcc2741
 char* parse_to(char* buffer, char* end, struct to_body *to_b);
e4067ffb
 char* parse_cseq(char* buffer, char* end, struct cseq_body *cb);
f8d46776
 
7f74d1b4
 void free_via_param_list(struct via_param *vp);
e72b5b50
 void free_via_list(struct via_body *vb);
 void clean_hdr_field(struct hdr_field* hf);
 void free_hdr_field_lst(struct hdr_field* hf);
22d4aa5d
 void free_sip_msg(struct sip_msg* msg);
e72b5b50
 
21f03122
 /* make sure all HFs needed for transaction identification have been
    parsed; return 0 if those HFs can't be found
  */
f0631398
 
21f03122
 #define check_transaction_quadruple(msg ) \
ac79e819
 	(parse_headers((msg), HDR_FROM|HDR_TO|HDR_CALLID|HDR_CSEQ)!=-1 && \
 	(msg)->from && (msg)->to && (msg)->callid && (msg)->cseq)
f0631398
 
 /* restored to the original double-check and put macro params
    in parenthesses  -jiri */
ac79e819
 /* re-reverted to the shorter version -andrei 
f0631398
 #define check_transaction_quadruple(msg ) \
    ( ((msg)->from || (parse_headers( (msg), HDR_FROM)!=-1 && (msg)->from)) && 	\
    ((msg)->to|| (parse_headers( (msg), HDR_TO)!=-1 && (msg)->to)) &&		\
    ((msg)->callid|| (parse_headers( (msg), HDR_CALLID)!=-1 && (msg)->callid)) &&\
68a3fc65
    ((msg)->cseq|| (parse_headers( (msg), HDR_CSEQ)!=-1 && (msg)->cseq)) && \
    ((msg)->via1|| (parse_headers( (msg), HDR_VIA)!=-1 && (msg)->via1)) ) 
ac79e819
 */
 	
512dcd98
 #endif