1 /*
2  * $Id: parse_common.h 1486 2009-08-29 14:40:38Z rco $
3  *
4  * Copyright (C) 2007 Raphael Coeffic
5  *
6  * This file is part of SEMS, a free SIP media server.
7  *
8  * SEMS is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version. This program is released under
12  * the GPL with the additional exemption that compiling, linking,
13  * and/or using OpenSSL is allowed.
14  *
15  * For a license to use the SEMS software under conditions
16  * other than those described here, or to purchase support for this
17  * software, please contact iptel.org by e-mail at the following addresses:
18  *    info@iptel.org
19  *
20  * SEMS is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29 
30 #ifndef _parse_common_h
31 #define _parse_common_h
32 
33 #include "cstring.h"
34 
35 #include <list>
36 using std::list;
37 
38 //
39 // Constants
40 //
41 
42 #define UNDEFINED_ERR      -1
43 #define UNEXPECTED_EOT     -2
44 #define UNEXPECTED_EOL     -3
45 #define MALFORMED_SIP_MSG  -4
46 #define INCOMPLETE_SIP_MSG -5
47 #define MALFORMED_URI      -6
48 #define MALFORMED_FLINE    -7
49 
50 #define IS_IN(c,l,r) (((c)>=(l))&&((c)<=(r)))
51 
52 #define CR        (0x0d) // '\r'
53 #define LF        (0x0a) // '\n'
54 #define SP        (0x20) // ' '
55 #define HTAB      (0x09) // '\t'
56 #define IS_WSP(c) (SP==(c) || HTAB==(c))
57 
58 #define HCOLON    (':')
59 #define SEMICOLON (';')
60 #define COMMA     (',')
61 #define DQUOTE    ('"')
62 #define SLASH     ('/')
63 #define BACKSLASH ('\\')
64 #define HYPHEN    ('-')
65 
66 #define IS_ALPHA(c) (IS_IN(c,0x41,0x5a) || IS_IN(c,0x61,0x7a))
67 #define IS_DIGIT(c) IS_IN(c,0x30,0x39)
68 #define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_DIGIT(c))
69 
70 //#define IS_UPPER(c) IS_IN(c,0x41,0x5a)
71 //#define LOWER_B(c) (IS_UPPER(c) ? ((c)+0x20) : (c))
72 #define IS_UPPER(c) (c & 0x20 == 0)
73 #define LOWER_B(c)  (c | 0x20)
74 
75 // TODO: wouldn't a switch work quicker?
76 #define IS_TOKEN(c) \
77    (IS_ALPHANUM(c) || \
78     ((c)=='-') || ((c)=='.') || ((c)=='!') || ((c)=='%') || \
79     ((c)=='*') || ((c)=='_') || ((c)=='+') || ((c)=='`') || \
80     ((c)=='\'') || ((c)=='~') )
81 
82 #define IS_MARK(c) \
83    (((c)=='-') || ((c)=='_') || ((c)=='.') || ((c)=='!') || \
84     ((c)=='~') || ((c)=='*') || ((c)=='\'') || ((c)=='(') || \
85     ((c)==')') )
86 
87 #define IS_UNRESERVED(c) \
88    (IS_ALPHANUM(c) || IS_MARK(c))
89 
90 #define IS_USER_UNRESERVED(c) \
91    (((c)=='&') || ((c)=='=') || ((c)=='+') || ((c)=='$') || \
92     ((c)==',') || ((c)==';') || ((c)=='?') || ((c)=='/'))
93 
94 #define IS_USER(c) \
95    (IS_UNRESERVED(c) || IS_USER_UNRESERVED(c)) // Escaped chars missing
96 
97 //
98 // SIP version constants
99 //
100 
101 #define SIP_str    "SIP"
102 #define SUP_SIPVER "/2.0"
103 
104 #define SIP_len        (sizeof(SIP_str)-/*0-term*/1)
105 #define SUP_SIPVER_len (sizeof(SUP_SIPVER)-/*0-term*/1)
106 
107 #define SIPVER_len (SIP_len+SUP_SIPVER_len)
108 
109 //
110 // Common states: (>100)
111 //
112 
113 enum {
114     ST_CR=100,
115     ST_LF,
116     ST_CRLF
117 };
118 
119 #define case_CR_LF \
120 	    case CR:\
121 		saved_st = st;\
122 		st = ST_CR;\
123 		break;\
124 	    case LF:\
125 		saved_st = st;\
126 		st = ST_LF;\
127 		break
128 
129 #define case_ST_CR(c) \
130 	    case ST_CR:\
131 	        if((c) == LF){\
132 	    	    st = ST_CRLF;\
133 	        }\
134 	        else {\
135  		    DBG("CR without LF\n");\
136  		    return MALFORMED_SIP_MSG;\
137 	        }\
138 	        break
139 
140 //
141 // Structs
142 //
143 
144 struct sip_avp
145 {
146     cstring name;
147     cstring value;
148 
sip_avpsip_avp149     sip_avp()
150 	: name(), value()
151     {}
152 
sip_avpsip_avp153     sip_avp(const cstring& n,
154 	    const cstring& v)
155 	: name(n),value(v)
156     {}
157 };
158 
159 
160 //
161 // Functions
162 //
163 
lower_cmp(const char * l,const char * r,int len)164 inline int lower_cmp(const char* l, const char* r, int len)
165 {
166     const char* end = l+len;
167 
168     while(l!=end){
169 	if( LOWER_B(*l) == LOWER_B(*r) ){
170 	    l++; r++;
171 	    continue;
172 	}
173 	else if(LOWER_B(*l) < LOWER_B(*r)) {
174 	    return -1;
175 	}
176 	else {
177 	    return 1;
178 	}
179     }
180 
181     return 0;
182 }
183 
lower_cmp_n(const char * l,int llen,const char * r,int rlen)184 inline int lower_cmp_n(const char* l, int llen, const char* r, int rlen)
185 {
186     if(llen == rlen)
187 	return lower_cmp(l,r,rlen);
188     else if(llen < rlen)
189 	return -1;
190 
191     return 1;
192 }
193 
lower_cmp_n(const cstring & l,const cstring & r)194 inline int lower_cmp_n(const cstring& l, const cstring& r)
195 {
196     return lower_cmp_n(l.s,l.len,r.s,r.len);
197 }
198 
199 int parse_sip_version(const char* beg, int len);
200 
201 /**
202  * Parse a list of Attribute-Value pairs beginning with
203  * and separated by semi-colons until stop_char or the
204  * end of the string is reached.
205  */
206 int parse_gen_params_sc(list<sip_avp*>* params, const char** c,
207 			int len, char stop_char);
208 
209 /**
210  * Parse a list of Attribute-Value pairs separated
211  * by semi-colons until stop_char or the end of
212  * the string is reached.
213  */
214 int parse_gen_params(list<sip_avp*>* params, const char** c, int len, char stop_char);
215 
216 /** Free the parameters in the list (NOT the list itself) */
217 void free_gen_params(list<sip_avp*>* params);
218 
219 #endif
220 
221 /** EMACS **
222  * Local variables:
223  * mode: c++
224  * c-basic-offset: 4
225  * End:
226  */
227