parse_methods.c
Go to the documentation of this file.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 #include <strings.h>
00036 #include "../dprint.h"
00037 #include "../trim.h"
00038 #include "../core_stats.h"
00039 #include "parse_methods.h"
00040 #include "msg_parser.h"
00041
00042
00043
00044
00045
00046 static inline int method_char(char _c)
00047 {
00048 return (_c >= 65 && _c <= 90)
00049 || (_c >= 97 && _c <= 122)
00050 || (_c >= 48 && _c <= 57)
00051 || (_c == '-') || (_c == '.') || (_c == '%') || (_c == '*')
00052 || (_c == '_') || (_c == '+') || (_c == '~') || (_c == '+');
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062 char* parse_method(char* start, char* end, unsigned int* method)
00063 {
00064 int len=0;
00065 int max=0;
00066
00067 if (!start || !method) {
00068 LM_ERR("invalid parameter value\n");
00069 return NULL;
00070 }
00071
00072 if(end)
00073 max = end - start;
00074 *method = METHOD_UNDEF;
00075
00076 switch (start[0]) {
00077 case 'A':
00078 case 'a':
00079 if(end && max<3)
00080 goto unknown;
00081
00082 if ((start[1]=='c' || start[1]=='C')
00083 && (start[2]=='k' || start[2]=='K'))
00084 {
00085 *method = METHOD_ACK;
00086 len = 3;
00087 goto done;
00088 }
00089 goto unknown;
00090
00091 case 'B':
00092 case 'b':
00093 if(end && max<3)
00094 goto unknown;
00095
00096 if ((start[1]=='y' || start[1]=='Y')
00097 && (start[2]=='e' || start[2]=='E'))
00098 {
00099 *method = METHOD_BYE;
00100 len = 3;
00101 goto done;
00102 }
00103 goto unknown;
00104
00105 case 'C':
00106 case 'c':
00107 if(end && max<6)
00108 goto unknown;
00109 if ((start[1]=='a' || start[1]=='A')
00110 && (start[2]=='n' || start[2]=='N')
00111 && (start[3]=='c' || start[3]=='C')
00112 && (start[4]=='e' || start[4]=='E')
00113 && (start[5]=='l' || start[5]=='L'))
00114 {
00115 *method = METHOD_CANCEL;
00116 len = 6;
00117 goto done;
00118 }
00119 goto unknown;
00120
00121 case 'I':
00122 case 'i':
00123 if(end && max<4)
00124 goto unknown;
00125 if(start[1]=='n' && start[1]=='N')
00126 goto unknown;
00127
00128 if ((start[2]=='f' || start[2]=='F')
00129 && (start[3]=='o' || start[3]=='O'))
00130 {
00131 *method = METHOD_INFO;
00132 len = 4;
00133 goto done;
00134 }
00135
00136 if(end && max<6)
00137 goto unknown;
00138 if ((start[2]=='v' || start[2]=='V')
00139 && (start[3]=='i' || start[3]=='I')
00140 && (start[4]=='t' || start[4]=='T')
00141 && (start[5]=='e' || start[5]=='E'))
00142 {
00143 *method = METHOD_INVITE;
00144 len = 6;
00145 goto done;
00146 }
00147 goto unknown;
00148
00149 case 'M':
00150 case 'm':
00151 if(end && max<7)
00152 goto unknown;
00153 if ((start[1]=='e' || start[1]=='E')
00154 && (start[2]=='s' || start[2]=='S')
00155 && (start[3]=='s' || start[3]=='S')
00156 && (start[4]=='a' || start[4]=='A')
00157 && (start[5]=='g' || start[5]=='G')
00158 && (start[6]=='e' || start[6]=='E')) {
00159 *method = METHOD_MESSAGE;
00160 len = 7;
00161 goto done;
00162 }
00163 goto unknown;
00164
00165 case 'N':
00166 case 'n':
00167 if(end && max<6)
00168 goto unknown;
00169 if ((start[1]=='o' || start[1]=='O')
00170 && (start[2]=='t' || start[2]=='T')
00171 && (start[3]=='i' || start[3]=='I')
00172 && (start[4]=='f' || start[4]=='F')
00173 && (start[5]=='y' || start[5]=='Y'))
00174 {
00175 *method = METHOD_NOTIFY;
00176 len = 6;
00177 goto done;
00178 }
00179 goto unknown;
00180
00181 case 'O':
00182 case 'o':
00183 if(end && max<7)
00184 goto unknown;
00185 if((start[1]=='p' || start[1]=='P')
00186 && (start[2]=='t' || start[2]=='T')
00187 && (start[3]=='i' || start[3]=='I')
00188 && (start[4]=='o' || start[4]=='O')
00189 && (start[5]=='n' || start[5]=='N')
00190 && (start[6]=='s' || start[6]=='S'))
00191 {
00192 *method = METHOD_OPTIONS;
00193 len = 7;
00194 goto done;
00195 }
00196 goto unknown;
00197
00198 case 'P':
00199 case 'p':
00200 if(end && max<5)
00201 goto unknown;
00202 if((start[1]=='r' || start[1]=='R')
00203 && (start[2]=='a' || start[2]=='A')
00204 && (start[3]=='c' || start[3]=='C')
00205 && (start[4]=='k' || start[4]=='K'))
00206 {
00207 *method = METHOD_PRACK;
00208 len = 5;
00209 goto done;
00210 }
00211
00212 if(end && max<7)
00213 goto unknown;
00214
00215 if ((start[1]=='u' || start[1]=='U')
00216 && (start[2]=='b' || start[2]=='B')
00217 && (start[3]=='l' || start[3]=='L')
00218 && (start[4]=='i' || start[4]=='I')
00219 && (start[5]=='s' || start[5]=='S')
00220 && (start[6]=='h' || start[6]=='H'))
00221 {
00222 *method = METHOD_PUBLISH;
00223 len = 7;
00224 goto done;
00225 }
00226 goto unknown;
00227
00228 case 'R':
00229 case 'r':
00230 if(end && max<5)
00231 goto unknown;
00232 if(start[1]!='e' && start[1]!='E')
00233 goto unknown;
00234
00235 if((start[2]=='f' || start[2]=='F')
00236 && (start[3]=='e' || start[3]=='E')
00237 && (start[4]=='R' || start[4]=='R'))
00238 {
00239 *method = METHOD_REFER;
00240 len = 5;
00241 goto done;
00242 }
00243
00244 if(end && max<8)
00245 goto unknown;
00246
00247 if ((start[2]=='g' || start[2]=='G')
00248 && (start[3]=='i' || start[3]=='I')
00249 && (start[4]=='s' || start[4]=='S')
00250 && (start[5]=='t' || start[5]=='T')
00251 && (start[6]=='e' || start[6]=='E')
00252 && (start[7]=='r' || start[7]=='R'))
00253 {
00254 *method = METHOD_REGISTER;
00255 len = 8;
00256 goto done;
00257 }
00258 goto unknown;
00259
00260 case 'S':
00261 case 's':
00262 if(end && max<9)
00263 goto unknown;
00264 if ((start[1]=='u' || start[1]=='U')
00265 && (start[2]=='b' || start[2]=='B')
00266 && (start[3]=='s' || start[3]=='S')
00267 && (start[4]=='c' || start[4]=='C')
00268 && (start[5]=='r' || start[5]=='R')
00269 && (start[6]=='i' || start[6]=='I')
00270 && (start[7]=='b' || start[7]=='B')
00271 && (start[8]=='e' || start[8]=='E'))
00272 {
00273 *method = METHOD_SUBSCRIBE;
00274 len = 9;
00275 goto done;
00276 }
00277 goto unknown;
00278
00279 case 'U':
00280 case 'u':
00281 if(end && max<6)
00282 goto unknown;
00283 if ((start[1]=='p' || start[1]=='P')
00284 && (start[2]=='d' || start[2]=='D')
00285 && (start[3]=='a' || start[3]=='A')
00286 && (start[4]=='t' || start[4]=='T')
00287 && (start[5]=='e' || start[5]=='E')) {
00288 *method = METHOD_UPDATE;
00289 len = 6;
00290 goto done;
00291 }
00292 goto unknown;
00293
00294 default:
00295 goto unknown;
00296 }
00297
00298 done:
00299 if(!end || (end && len < max))
00300 {
00301 if(start[len]!='\0' && start[len]!=',' && start[len]!=' '
00302 && start[len]!='\t' && start[len]!='\r' && start[len]!='\n')
00303 goto unknown;
00304 }
00305
00306 return (start+len);
00307
00308 unknown:
00309 update_stat(unsupported_methods, 1);
00310 *method = METHOD_OTHER;
00311 if(end)
00312 {
00313 while(len < max)
00314 {
00315 if((start[len]=='\0' || start[len]==',' || start[len]==' '
00316 || start[len]=='\t' || start[len]=='\r'
00317 || start[len]=='\n'))
00318 return (start+len);
00319
00320 if(!method_char(start[len]))
00321 {
00322 LM_ERR("invalid character %c\n", start[len]);
00323 return NULL;
00324 }
00325
00326 len++;
00327 }
00328 return end;
00329 }
00330
00331 while(start[len]!='\0' && start[len]!=',' && start[len]!=' '
00332 && start[len]!='\t' && start[len]!='\r' && start[len]!='\n')
00333 {
00334 if(!method_char(start[len]))
00335 {
00336 LM_ERR("invalid character %c!\n", start[len]);
00337 return NULL;
00338 }
00339 len++;
00340 }
00341
00342 return (start+len);
00343 }
00344
00345
00346
00347
00348
00349
00350
00351 int parse_methods(str* _body, unsigned int* _methods)
00352 {
00353 str next;
00354 char *p;
00355 char *p0;
00356 unsigned int method;
00357
00358 if (!_body || !_methods) {
00359 LM_ERR("invalid parameter value\n");
00360 return -1;
00361 }
00362
00363 next.len = _body->len;
00364 next.s = _body->s;
00365
00366 trim_leading(&next);
00367
00368 *_methods = 0;
00369 if (next.len == 0) {
00370 goto done;
00371 }
00372
00373 method = 0;
00374 p = next.s;
00375
00376 while (p<next.s+next.len) {
00377 if((p0=parse_method(p, next.s+next.len, &method))!=NULL) {
00378 *_methods |= method;
00379 p = p0;
00380 } else {
00381 LM_ERR("invalid method [%.*s]\n", next.len, next.s);
00382 return -1;
00383 }
00384
00385 while(p<next.s+next.len && (*p==' ' || *p=='\t'
00386 || *p=='\r' || *p=='\n'))
00387 p++;
00388 if(p>=next.s+next.len || *p == '\0')
00389 goto done;
00390
00391
00392 if (*p == ',')
00393 {
00394 p++;
00395 while(p<next.s+next.len && (*p==' ' || *p=='\t'
00396 || *p=='\r' || *p=='\n'))
00397 p++;
00398 if(p>=next.s+next.len)
00399 goto done;
00400 } else {
00401 LM_ERR("comma expected\n");
00402 return -1;
00403 }
00404 }
00405
00406 done:
00407 LM_DBG("methods 0x%X\n", *_methods);
00408 return 0;
00409 }