00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00044 #include "../comp_defs.h"
00045 #include "../dprint.h"
00046 #include "msg_parser.h"
00047 #include "parser_f.h"
00048 #include "../mem/mem.h"
00049 #include "../ut.h"
00050
00051 int http_reply_hack = 0;
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl)
00063 {
00064
00065 char *tmp;
00066 char* second;
00067 char* third;
00068 char* nl;
00069 int offset;
00070
00071 char* end;
00072 char s1,s2,s3;
00073 char *prn;
00074 unsigned int t;
00075
00076
00077
00078
00079
00080
00081
00082
00083 end=buffer+len;
00084
00085
00086
00087
00088
00089
00090
00091
00092 if (len <=16 ) {
00093 LOG(L_INFO, "ERROR: parse_first_line: message too short: %d\n", len);
00094 goto error1;
00095 }
00096 tmp=buffer;
00097
00098 if ( (*tmp=='S' || *tmp=='s') &&
00099 strncasecmp( tmp+1, SIP_VERSION+1, SIP_VERSION_LEN-1)==0 &&
00100 (*(tmp+SIP_VERSION_LEN)==' ')) {
00101 fl->type=SIP_REPLY;
00102 fl->u.reply.version.len=SIP_VERSION_LEN;
00103 tmp=buffer+SIP_VERSION_LEN;
00104 } else if (http_reply_hack != 0 &&
00105 (*tmp=='H' || *tmp=='h') &&
00106
00107 strncasecmp( tmp+1, HTTP_VERSION+1, HTTP_VERSION_LEN-1)==0 &&
00108
00109 ((*(tmp+HTTP_VERSION_LEN)=='0') || (*(tmp+HTTP_VERSION_LEN)=='1')) &&
00110 (*(tmp+HTTP_VERSION_LEN+1)==' ') ){
00111
00112
00113
00114
00115 fl->type=SIP_REPLY;
00116 fl->u.reply.version.len=HTTP_VERSION_LEN+1 ;
00117 tmp=buffer+HTTP_VERSION_LEN+1 ;
00118 } else IFISMETHOD( INVITE, 'I' )
00119 else IFISMETHOD( CANCEL, 'C')
00120 else IFISMETHOD( ACK, 'A' )
00121 else IFISMETHOD( BYE, 'B' )
00122 else IFISMETHOD( INFO, 'I' )
00123 else IFISMETHOD( REGISTER, 'R')
00124 else IFISMETHOD( SUBSCRIBE, 'S')
00125 else IFISMETHOD( NOTIFY, 'N')
00126 else IFISMETHOD( MESSAGE, 'M')
00127 else IFISMETHOD( OPTIONS, 'O')
00128 else IFISMETHOD( PRACK, 'P')
00129 else IFISMETHOD( UPDATE, 'U')
00130 else IFISMETHOD( REFER, 'R')
00131 else IFISMETHOD( PUBLISH, 'P')
00132
00133
00134
00135
00136
00137
00138 else {
00139
00140
00141
00142 tmp=eat_token_end(buffer,buffer+len);
00143 if ((tmp==buffer)||(tmp>=end)){
00144 LOG(L_INFO, "ERROR:parse_first_line: empty or bad first line\n");
00145 goto error1;
00146 }
00147 if (*tmp!=' ') {
00148 LOG(L_INFO, "ERROR:parse_first_line: method not followed by SP\n");
00149 goto error1;
00150 }
00151 fl->type=SIP_REQUEST;
00152 fl->u.request.method_value=METHOD_OTHER;
00153 fl->u.request.method.len=tmp-buffer;
00154 }
00155
00156
00157
00158
00159
00160 fl->u.request.method.s=buffer;
00161 second=tmp+1;
00162 offset=second-buffer;
00163
00164
00165
00166
00167 tmp=eat_token_end(second, second+len-offset);
00168 if (tmp>=end){
00169 goto error;
00170 }
00171 offset+=tmp-second;
00172 third=eat_space_end(tmp, tmp+len-offset);
00173 offset+=third-tmp;
00174 if ((third==tmp)||(tmp>=end)){
00175 goto error;
00176 }
00177 fl->u.request.uri.s=second;
00178 fl->u.request.uri.len=tmp-second;
00179
00180
00181 if (fl->type==SIP_REPLY) {
00182 if (fl->u.request.uri.len!=3) {
00183 LOG(L_INFO, "ERROR:parse_first_line: len(status code)!=3: %.*s\n",
00184 fl->u.request.uri.len, ZSW(second) );
00185 goto error;
00186 }
00187 s1=*second; s2=*(second+1);s3=*(second+2);
00188 if (s1>='0' && s1<='9' &&
00189 s2>='0' && s2<='9' &&
00190 s3>='0' && s3<='9' ) {
00191 fl->u.reply.statuscode=(s1-'0')*100+10*(s2-'0')+(s3-'0');
00192 } else {
00193 LOG(L_INFO, "ERROR:parse_first_line: status_code non-numerical: %.*s\n",
00194 fl->u.request.uri.len, ZSW(second) );
00195 goto error;
00196 }
00197 }
00198
00199
00200
00201
00202
00203 if (fl->type==SIP_REQUEST){
00204 tmp=eat_token_end(third,third+len-offset);
00205 offset+=tmp-third;
00206 if ((tmp==third)||(tmp>=end)){
00207 goto error;
00208 }
00209 if (! is_empty_end(tmp, tmp+len-offset)){
00210 goto error;
00211 }
00212 }else{
00213 tmp=eat_token2_end(third,third+len-offset,'\r');
00214
00215 if (tmp>=end){
00216 goto error;
00217 }
00218 offset+=tmp-third;
00219 }
00220 nl=eat_line(tmp,len-offset);
00221 if (nl>=end){
00222 goto error;
00223 }
00224 fl->u.request.version.s=third;
00225 fl->u.request.version.len=tmp-third;
00226 fl->len=nl-buffer;
00227
00228 return nl;
00229
00230 error:
00231 LOG(L_INFO, "ERROR:parse_first_line: bad %s first line\n",
00232 (fl->type==SIP_REPLY)?"reply(status)":"request");
00233
00234 LOG(L_INFO, "ERROR: at line 0 char %d: \n", offset );
00235 prn=pkg_malloc( offset );
00236 if (prn) {
00237 for (t=0; t<offset; t++)
00238 if (*(buffer+t)) *(prn+t)=*(buffer+t);
00239 else *(prn+t)='°';
00240 LOG(L_INFO, "ERROR: parsed so far: %.*s\n", offset, ZSW(prn) );
00241 pkg_free( prn );
00242 };
00243 error1:
00244 fl->type=SIP_INVALID;
00245 LOG(L_INFO, "ERROR:parse_first_line: bad message\n");
00246
00247 nl=eat_line(buffer,len);
00248 return nl;
00249 }