- ipv6 support (-DUSE_IPV6)
[sip-router] / parser / msg_parser.h
1 /*
2  * $Id$
3  */
4
5 #ifndef msg_parser_h
6 #define msg_parser_h
7
8 #include "../str.h"
9 #include "../data_lump.h"
10 #include "../flags.h"
11 #include "../ip_addr.h"
12
13 #define SIP_REQUEST 1
14 #define SIP_REPLY   2
15 #define SIP_INVALID 0
16
17
18
19 /*header types and flags*/
20 #define HDR_EOH             -1
21 #define HDR_ERROR            0
22 #define HDR_VIA              1
23 #define HDR_VIA1             1
24 #define HDR_VIA2             2  /*only used as flag*/
25 #define HDR_TO               4
26 #define HDR_FROM             8
27 #define HDR_CSEQ            16
28 #define HDR_CALLID          32
29 #define HDR_CONTACT         64
30 #define HDR_MAXFORWARDS    128
31 #define HDR_ROUTE          256
32 #define HDR_RECORDROUTE    512
33 #define HDR_CONTENTTYPE   1024
34 #define HDR_CONTENTLENGTH 2048
35 #define HDR_OTHER        65536 /*unknown header type*/
36
37
38 /* maximum length of values appended to Via-branch parameter */
39 #ifdef USE_SYNONIM
40 #define MAX_BRANCH_PARAM_LEN  22
41 #else
42 #define MAX_BRANCH_PARAM_LEN  48
43 #endif
44 /* via param types
45  * WARNING: keep in sync w/ FIN_*, GEN_PARAM and PARAM_ERROR from via_parse.c*/
46 enum{
47                 PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, PARAM_MADDR, PARAM_RECEIVED,
48                 GEN_PARAM,
49                 PARAM_ERROR
50 };
51
52 enum{
53                 TAG_PARAM=400, GENERAL_PARAM
54 };
55
56 /* casting macro for accessing CSEQ body */
57 #define get_cseq( p_msg)  ((struct cseq_body*)(p_msg)->cseq->parsed)
58 #define get_to( p_msg)      ((struct to_body*)(p_msg)->to->parsed)
59
60 #ifdef NEW_HNAME
61 #       define parse_hname(_b,_e,_h) parse_hname2((_b),(_e),(_h))
62         void init_htable(void);
63 #else
64 #       define parse_hname(_b,_e,_h) parse_hname1((_b),(_e),(_h))
65 #endif
66
67
68 #define INVITE_LEN      6
69 #define ACK_LEN         3
70 #define CANCEL_LEN      6
71 #define BYE_LEN         3
72
73 #define CANCEL  "CANCEL"
74 #define ACK             "ACK"
75 #define INVITE "INVITE"
76
77 /* convenience short-cut macros */
78 #define REQ_METHOD first_line.u.request.method_value
79 #define REPLY_STATUS first_line.u.reply.statuscode
80 #define REPLY_CLASS(_reply) ((_reply)->REPLY_STATUS/100)
81
82 enum { METHOD_OTHER, METHOD_INVITE, METHOD_CANCEL, METHOD_ACK, METHOD_BYE };
83
84 #define IFISMETHOD(methodname,firstchar)                                  \
85 if (  (*tmp==(firstchar) || *tmp==((firstchar) | 32)) &&                  \
86         strncasecmp( tmp+1, #methodname +1, methodname##_LEN-1)==0 &&     \
87         *(tmp+methodname##_LEN)==' ') {                                   \
88                 fl->type=SIP_REQUEST;                                     \
89                 fl->u.request.method.len=methodname##_LEN;                \
90                 fl->u.request.method_value=METHOD_##methodname;           \
91                 tmp=buffer+methodname##_LEN;                              \
92 }
93
94
95 #define VIA_PARSE_OK    1
96 #define VIA_PARSE_ERROR -1
97 #define PARSE_ERROR -1
98 #define PARSE_OK 1
99
100 #define SIP_VERSION     "SIP/2.0"
101 #define SIP_VERSION_LEN 7
102
103
104 struct msg_start{
105         int type;
106         union {
107                 struct {
108                         str method;
109                         str uri;
110                         str version;
111                         int method_value;
112                 }request;
113                 struct {
114                         str version;
115                         str status;
116                         str reason;
117                         unsigned int /* statusclass,*/ statuscode;
118                 }reply;
119         }u;
120 };
121
122 struct hdr_field{   /* format: name':' body */
123         int type;
124         str name;
125         str body;
126         void* parsed;
127         struct hdr_field* next;
128 };
129
130
131
132 struct via_param{
133         int type;
134         str name;
135         str value;
136         int size; /* total size*/
137         struct via_param* next;
138 };
139
140 struct via_body{  /* format: name/version/transport host:port;params comment */
141         int error;
142         str hdr;   /* contains "Via" or "v" */
143         str name;
144         str version;
145         str transport;
146         str host;
147         int port;
148         str port_str;
149         str params;
150         str comment;
151         int bsize;    /* body size, not including hdr */
152         struct via_param* param_lst; /* list of parameters*/
153         struct via_param* last_param; /*last via parameter, internal use*/
154         /* shortcuts to "important" params*/
155         struct via_param* branch;
156
157         struct via_body* next; /* pointer to next via body string if
158          compact via or null */
159 };
160
161
162
163 struct to_param{
164         int type;
165         str name;
166         str value;
167         struct to_param* next;
168 };
169
170 struct to_body{
171         int error;
172         str body;
173         str uri;
174         str tag_value;
175         struct to_param *param_lst;
176         struct to_param *last_param;
177 };
178
179
180 struct cseq_body{
181         int error;
182         str number;
183         str method;
184 };
185
186
187
188 struct sip_msg{
189         unsigned int id; /* message id, unique/process*/
190         struct msg_start first_line;
191         struct via_body* via1;
192         struct via_body* via2;
193         struct hdr_field* headers; /* all the parsed headers*/
194         struct hdr_field* last_header; /* pointer to the last parsed header*/
195         int parsed_flag;
196         /* via, to, cseq, call-id, from, end of header*/
197         /* first occurance of it; subsequent occurances saved in 'headers' */
198         struct hdr_field* h_via1;
199         struct hdr_field* h_via2;
200         struct hdr_field* callid;
201         struct hdr_field* to;
202         struct hdr_field* cseq;
203         struct hdr_field* from;
204         struct hdr_field* contact;
205         struct hdr_field* maxforwards;
206         struct hdr_field* route;
207         struct hdr_field* record_route;
208         struct hdr_field* content_type;
209         struct hdr_field* content_length;
210         char* eoh; /* pointer to the end of header (if found) or null */
211         char* unparsed; /* here we stopped parsing*/
212
213         struct ip_addr src_ip;
214         struct ip_addr dst_ip;
215         char* orig; /* original message copy */
216         char* buf;  /* scratch pad, holds a modfied message,
217                                    via, etc. point into it */
218                                    
219         unsigned int len; /* message len (orig) */
220
221         /* modifications */
222         str new_uri; /* changed first line uri*/
223
224         struct lump* add_rm;      /* used for all the forwarded messages */
225         struct lump* repl_add_rm; /* only for localy generated replies !!!*/
226         struct lump_rpl *reply_lump;
227
228         /* str add_to_branch; */ /* whatever whoever want to append to branch comes here */
229         char add_to_branch_s[MAX_BRANCH_PARAM_LEN];
230         int add_to_branch_len;
231
232         /* index to TM hash table; stored in core to avoid unnecessary calcs */
233         unsigned int  hash_index;
234
235         /* allows to set various flags on the message; may be used for 
236            simple inter-module communication or remembering processing state
237            reached */
238         flag_t flags;
239
240         
241 };
242
243
244 struct sip_uri{
245         str user;
246         str passwd;
247         str host;
248         str port;
249         str params;
250         str headers;
251 };
252
253
254 char* parse_fline(char* buffer, char* end, struct msg_start* fl);
255 char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl);
256 char* parse_hostport(char* buf, str* host, short int* port);
257
258 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg);
259 int parse_uri(char *buf, int len, struct sip_uri* uri);
260 int parse_headers(struct sip_msg* msg, int flags);
261
262 void free_uri(struct sip_uri* u);
263
264
265 /* char* parse_hname(char* buf, char* end, struct hdr_field* hdr); */
266 char* parse_hname1(char* buf, char* end, struct hdr_field* hdr);
267 char* parse_hname2(char* buf, char* end, struct hdr_field* hdr);
268
269 char* parse_via(char* buffer, char* end, struct via_body *vb);
270 char* parse_to(char* buffer, char* end, struct to_body *to_b);
271 char* parse_cseq(char* buffer, char* end, struct cseq_body *cb);
272
273 void free_via_param_list(struct via_param *vp);
274 void free_via_list(struct via_body *vb);
275 void clean_hdr_field(struct hdr_field* hf);
276 void free_hdr_field_lst(struct hdr_field* hf);
277 void free_sip_msg(struct sip_msg* msg);
278
279 /* make sure all HFs needed for transaction identification have been
280    parsed; return 0 if those HFs can't be found
281  */
282
283 #define check_transaction_quadruple(msg ) \
284         (parse_headers((msg), HDR_FROM|HDR_TO|HDR_CALLID|HDR_CSEQ)!=-1 && \
285         (msg)->from && (msg)->to && (msg)->callid && (msg)->cseq)
286
287 /* restored to the original double-check and put macro params
288    in parenthesses  -jiri */
289 /* re-reverted to the shorter version -andrei 
290 #define check_transaction_quadruple(msg ) \
291    ( ((msg)->from || (parse_headers( (msg), HDR_FROM)!=-1 && (msg)->from)) &&   \
292    ((msg)->to|| (parse_headers( (msg), HDR_TO)!=-1 && (msg)->to)) &&            \
293    ((msg)->callid|| (parse_headers( (msg), HDR_CALLID)!=-1 && (msg)->callid)) &&\
294    ((msg)->cseq|| (parse_headers( (msg), HDR_CSEQ)!=-1 && (msg)->cseq)) && \
295    ((msg)->via1|| (parse_headers( (msg), HDR_VIA)!=-1 && (msg)->via1)) ) 
296 */
297         
298 #endif