parse_fline.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305
  1. /*
  2. * $Id$
  3. *
  4. * sip first line parsing automaton
  5. *
  6. *
  7. * Copyright (C) 2001-2003 Fhg Fokus
  8. *
  9. * This file is part of ser, a free SIP server.
  10. *
  11. * ser is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version
  15. *
  16. * For a license to use the ser software under conditions
  17. * other than those described here, or to purchase support for this
  18. * software, please contact iptel.org by e-mail at the following addresses:
  19. * [email protected]
  20. *
  21. * ser is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU General Public License
  27. * along with this program; if not, write to the Free Software
  28. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  29. */
  30. #include "../dprint.h"
  31. #include "msg_parser.h"
  32. #include "parser_f.h"
  33. #include "../mem/mem.h"
  34. /* grammar:
  35. request = method SP uri SP version CRLF
  36. response = version SP status SP reason CRLF
  37. (version = "SIP/2.0")
  38. */
  39. /*known methods: INVITE, ACK, CANCEL, BYE*/
  40. enum { START,
  41. INVITE1, INVITE2, INVITE3, INVITE4, INVITE5,
  42. ACK1, ACK2,
  43. CANCEL1, CANCEL2, CANCEL3, CANCEL4, CANCEL5,
  44. BYE1, BYE2,
  45. SIP1, SIP2, SIP3, SIP4, SIP5, SIP6,
  46. FIN_INVITE = 100, FIN_ACK, FIN_CANCEL, FIN_BYE, FIN_SIP,
  47. P_METHOD = 200, L_URI, P_URI, L_VER,
  48. VER1, VER2, VER3, VER4, VER5, VER6, FIN_VER,
  49. L_STATUS, P_STATUS, L_REASON, P_REASON,
  50. L_LF, F_CR, F_LF
  51. };
  52. char* parse_fline(char* buffer, char* end, struct msg_start* fl)
  53. {
  54. char* tmp;
  55. register int state;
  56. unsigned short stat;
  57. stat=0;
  58. fl->type=SIP_REQUEST;
  59. state=START;
  60. for(tmp=buffer;tmp<end;tmp++){
  61. switch(*tmp){
  62. case ' ':
  63. case '\t':
  64. switch(state){
  65. case START: /*allow space at the beginnig, althoug not
  66. legal*/
  67. break;
  68. case L_URI:
  69. case L_VER:
  70. case L_STATUS:
  71. case L_REASON:
  72. case L_LF:
  73. /*eat space*/
  74. break;
  75. case FIN_INVITE:
  76. *tmp=0;
  77. fl->u.request.method.len=tmp-fl->u.request.method.s;
  78. fl->u.request.method_value=METHOD_INVITE;
  79. state=L_URI;
  80. break;
  81. case FIN_ACK:
  82. *tmp=0;
  83. fl->u.request.method.len=tmp-fl->u.request.method.s;
  84. fl->u.request.method_value=METHOD_ACK;
  85. state=L_URI;
  86. break;
  87. case FIN_CANCEL:
  88. *tmp=0;
  89. fl->u.request.method.len=tmp-fl->u.request.method.s;
  90. fl->u.request.method_value=METHOD_CANCEL;
  91. state=L_URI;
  92. break;
  93. case FIN_BYE:
  94. *tmp=0;
  95. fl->u.request.method.len=tmp-fl->u.request.method.s;
  96. fl->u.request.method_value=METHOD_BYE;
  97. state=L_URI;
  98. break;
  99. case FIN_SIP:
  100. *tmp=0;
  101. fl->u.reply.version.len=tmp-fl->u.reply.version.s;
  102. state=L_STATUS;
  103. fl->type=SIP_REPLY;
  104. break;
  105. case P_URI:
  106. *tmp=0;
  107. fl->u.request.uri.len=tmp-fl->u.request.uri.s;
  108. state=L_VER;
  109. break;
  110. case FIN_VER:
  111. *tmp=0;
  112. fl->u.request.version.len=tmp-fl->u.request.version.s;
  113. state=L_LF;
  114. break;
  115. case P_STATUS:
  116. *tmp=0;
  117. fl->u.reply.status.len=tmp-fl->u.reply.status.s;
  118. state=L_REASON;
  119. break;
  120. case P_REASON:
  121. /* *tmp=0;
  122. fl->u.reply.reason.len=tmp-fl->u.reply.reason.s;
  123. */
  124. break;
  125. case VER1:
  126. case VER2:
  127. case VER3:
  128. case VER4:
  129. case VER5:
  130. case VER6:
  131. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  132. " in request\n");
  133. goto error;
  134. case P_METHOD:
  135. default:
  136. *tmp=0;
  137. fl->u.request.method.len=tmp-fl->u.request.method.s;
  138. fl->u.request.method_value=METHOD_OTHER;
  139. state=L_URI;
  140. }
  141. break;
  142. case 's':
  143. case 'S':
  144. switch(state){
  145. case START:
  146. state=SIP1;
  147. fl->u.reply.version.s=tmp;
  148. break;
  149. case P_URI:
  150. case P_REASON:
  151. case P_METHOD:
  152. break;
  153. case L_REASON:
  154. fl->u.reply.reason.s=tmp;
  155. state=P_REASON;
  156. break;
  157. case P_STATUS:
  158. case L_STATUS:
  159. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  160. "character <%c> in request status\n", *tmp);
  161. goto error;
  162. case L_LF:
  163. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  164. "character <%c> in request\n", *tmp);
  165. goto error;
  166. case L_URI:
  167. fl->u.request.uri.s=tmp;
  168. state=P_URI;
  169. break;
  170. case L_VER:
  171. fl->u.request.version.s=tmp;
  172. state=VER1;
  173. break;
  174. case VER1:
  175. case VER2:
  176. case VER3:
  177. case VER4:
  178. case VER5:
  179. case VER6:
  180. case FIN_VER:
  181. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  182. " in request\n");
  183. goto error;
  184. default:
  185. state=P_METHOD;
  186. }
  187. break;
  188. case 'i':
  189. case 'I':
  190. switch(state){
  191. case START:
  192. state=INVITE1;
  193. fl->u.request.method.s=tmp;
  194. break;
  195. case INVITE3:
  196. state=INVITE4;
  197. break;
  198. case SIP1:
  199. state=SIP2;
  200. break;
  201. case P_URI:
  202. case P_REASON:
  203. case P_METHOD:
  204. break;
  205. case L_REASON:
  206. fl->u.reply.reason.s=tmp;
  207. state=P_REASON;
  208. break;
  209. case P_STATUS:
  210. case L_STATUS:
  211. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  212. "character <%c> in request status\n", *tmp);
  213. goto error;
  214. case L_LF:
  215. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  216. "character <%c> in request\n", *tmp);
  217. goto error;
  218. case L_URI:
  219. fl->u.request.uri.s=tmp;
  220. state=P_URI;
  221. break;
  222. case VER1:
  223. state=VER2;
  224. break;
  225. case L_VER:
  226. case VER2:
  227. case VER3:
  228. case VER4:
  229. case VER5:
  230. case VER6:
  231. case FIN_VER:
  232. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  233. " in request\n");
  234. goto error;
  235. default:
  236. state=P_METHOD;
  237. }
  238. break;
  239. case 'p':
  240. case 'P':
  241. switch(state){
  242. case START:
  243. state=P_METHOD;
  244. fl->u.request.method.s=tmp;
  245. break;
  246. case SIP2:
  247. state=SIP3;
  248. break;
  249. case P_URI:
  250. case P_REASON:
  251. case P_METHOD:
  252. break;
  253. case L_REASON:
  254. fl->u.reply.reason.s=tmp;
  255. state=P_REASON;
  256. break;
  257. case P_STATUS:
  258. case L_STATUS:
  259. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  260. "character <%c> in request status\n", *tmp);
  261. goto error;
  262. case L_LF:
  263. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  264. "character <%c> in request\n", *tmp);
  265. goto error;
  266. case L_URI:
  267. fl->u.request.uri.s=tmp;
  268. state=P_URI;
  269. break;
  270. case VER2:
  271. state=VER3;
  272. break;
  273. case L_VER:
  274. case VER1:
  275. case VER3:
  276. case VER4:
  277. case VER5:
  278. case VER6:
  279. case FIN_VER:
  280. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  281. " in request\n");
  282. goto error;
  283. default:
  284. state=P_METHOD;
  285. }
  286. break;
  287. case '/':
  288. switch(state){
  289. case START:
  290. state=P_METHOD;
  291. fl->u.request.method.s=tmp;
  292. break;
  293. case SIP3:
  294. state=SIP4;
  295. break;
  296. case P_URI:
  297. case P_REASON:
  298. case P_METHOD:
  299. break;
  300. case L_REASON:
  301. fl->u.reply.reason.s=tmp;
  302. state=P_REASON;
  303. break;
  304. case P_STATUS:
  305. case L_STATUS:
  306. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  307. "character <%c> in request status\n", *tmp);
  308. goto error;
  309. case L_LF:
  310. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  311. "character <%c> in request\n", *tmp);
  312. goto error;
  313. case L_URI:
  314. fl->u.request.uri.s=tmp;
  315. state=P_URI;
  316. break;
  317. case VER3:
  318. state=VER4;
  319. break;
  320. case L_VER:
  321. case VER1:
  322. case VER2:
  323. case VER4:
  324. case VER5:
  325. case VER6:
  326. case FIN_VER:
  327. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  328. " in request\n");
  329. goto error;
  330. default:
  331. state=P_METHOD;
  332. }
  333. break;
  334. case '2':
  335. switch(state){
  336. case START:
  337. state=P_METHOD;
  338. fl->u.request.method.s=tmp;
  339. break;
  340. case SIP4:
  341. state=SIP5;
  342. break;
  343. case P_URI:
  344. case P_REASON:
  345. case P_METHOD:
  346. break;
  347. case L_REASON:
  348. fl->u.reply.reason.s=tmp;
  349. state=P_REASON;
  350. break;
  351. case P_STATUS:
  352. stat=stat*10+*tmp-'0';
  353. break;
  354. case L_STATUS:
  355. stat=*tmp-'0';
  356. fl->u.reply.status.s=tmp;
  357. break;
  358. case L_LF:
  359. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  360. "character <%c> in request\n", *tmp);
  361. goto error;
  362. case L_URI:
  363. fl->u.request.uri.s=tmp;
  364. state=P_URI;
  365. break;
  366. case VER4:
  367. state=VER5;
  368. break;
  369. case L_VER:
  370. case VER1:
  371. case VER2:
  372. case VER3:
  373. case VER5:
  374. case VER6:
  375. case FIN_VER:
  376. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  377. " in request\n");
  378. goto error;
  379. default:
  380. state=P_METHOD;
  381. }
  382. break;
  383. case '.':
  384. switch(state){
  385. case START:
  386. state=P_METHOD;
  387. fl->u.request.method.s=tmp;
  388. break;
  389. case SIP5:
  390. state=SIP6;
  391. break;
  392. case P_URI:
  393. case P_REASON:
  394. case P_METHOD:
  395. break;
  396. case L_REASON:
  397. fl->u.reply.reason.s=tmp;
  398. state=P_REASON;
  399. break;
  400. case P_STATUS:
  401. case L_STATUS:
  402. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  403. "character <%c> in request status\n", *tmp);
  404. goto error;
  405. case L_LF:
  406. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  407. "character <%c> in request\n", *tmp);
  408. goto error;
  409. case L_URI:
  410. fl->u.request.uri.s=tmp;
  411. state=P_URI;
  412. break;
  413. case VER5:
  414. state=VER6;
  415. break;
  416. case L_VER:
  417. case VER1:
  418. case VER2:
  419. case VER3:
  420. case VER4:
  421. case VER6:
  422. case FIN_VER:
  423. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  424. " in request\n");
  425. goto error;
  426. default:
  427. state=P_METHOD;
  428. }
  429. break;
  430. case '0':
  431. switch(state){
  432. case START:
  433. state=P_METHOD;
  434. fl->u.request.method.s=tmp;
  435. break;
  436. case SIP6:
  437. state=FIN_SIP;
  438. break;
  439. case P_URI:
  440. case P_REASON:
  441. case P_METHOD:
  442. break;
  443. case L_REASON:
  444. fl->u.reply.reason.s=tmp;
  445. state=P_REASON;
  446. break;
  447. case P_STATUS:
  448. stat=stat*10;
  449. break;
  450. case L_STATUS:
  451. stat=0;
  452. fl->u.reply.status.s=tmp;
  453. break;
  454. case L_LF:
  455. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  456. "character <%c> in request\n", *tmp);
  457. goto error;
  458. case L_URI:
  459. fl->u.request.uri.s=tmp;
  460. state=P_URI;
  461. break;
  462. case VER6:
  463. state=FIN_VER;
  464. break;
  465. case L_VER:
  466. case VER1:
  467. case VER2:
  468. case VER3:
  469. case VER4:
  470. case VER5:
  471. case FIN_VER:
  472. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  473. " in request\n");
  474. goto error;
  475. default:
  476. state=P_METHOD;
  477. }
  478. break;
  479. case 'n':
  480. case 'N':
  481. switch(state){
  482. case START:
  483. state=P_METHOD;
  484. fl->u.request.method.s=tmp;
  485. break;
  486. case INVITE1:
  487. state=INVITE2;
  488. break;
  489. case CANCEL2:
  490. state=CANCEL3;
  491. break;
  492. case P_URI:
  493. case P_REASON:
  494. case P_METHOD:
  495. break;
  496. case L_REASON:
  497. fl->u.reply.reason.s=tmp;
  498. state=P_REASON;
  499. break;
  500. case P_STATUS:
  501. case L_STATUS:
  502. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  503. "character <%c> in request status\n", *tmp);
  504. goto error;
  505. case L_LF:
  506. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  507. "character <%c> in request\n", *tmp);
  508. goto error;
  509. case L_URI:
  510. fl->u.request.uri.s=tmp;
  511. state=P_URI;
  512. break;
  513. case L_VER:
  514. case VER1:
  515. case VER2:
  516. case VER3:
  517. case VER4:
  518. case VER5:
  519. case VER6:
  520. case FIN_VER:
  521. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  522. " in request\n");
  523. goto error;
  524. default:
  525. state=P_METHOD;
  526. }
  527. break;
  528. case 'v':
  529. case 'V':
  530. switch(state){
  531. case START:
  532. state=P_METHOD;
  533. fl->u.request.method.s=tmp;
  534. break;
  535. case INVITE2:
  536. state=INVITE3;
  537. break;
  538. case P_URI:
  539. case P_REASON:
  540. case P_METHOD:
  541. break;
  542. case L_REASON:
  543. fl->u.reply.reason.s=tmp;
  544. state=P_REASON;
  545. break;
  546. case P_STATUS:
  547. case L_STATUS:
  548. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  549. "character <%c> in request status\n", *tmp);
  550. goto error;
  551. case L_LF:
  552. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  553. "character <%c> in request\n", *tmp);
  554. goto error;
  555. case L_URI:
  556. fl->u.request.uri.s=tmp;
  557. state=P_URI;
  558. break;
  559. case L_VER:
  560. case VER1:
  561. case VER2:
  562. case VER3:
  563. case VER4:
  564. case VER5:
  565. case VER6:
  566. case FIN_VER:
  567. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  568. " in request\n");
  569. goto error;
  570. default:
  571. state=P_METHOD;
  572. }
  573. break;
  574. case 't':
  575. case 'T':
  576. switch(state){
  577. case START:
  578. state=P_METHOD;
  579. fl->u.request.method.s=tmp;
  580. break;
  581. case INVITE4:
  582. state=INVITE5;
  583. break;
  584. case P_URI:
  585. case P_REASON:
  586. case P_METHOD:
  587. break;
  588. case L_REASON:
  589. fl->u.reply.reason.s=tmp;
  590. state=P_REASON;
  591. break;
  592. case P_STATUS:
  593. case L_STATUS:
  594. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  595. "character <%c> in request status\n", *tmp);
  596. goto error;
  597. case L_LF:
  598. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  599. "character <%c> in request\n", *tmp);
  600. goto error;
  601. case L_URI:
  602. fl->u.request.uri.s=tmp;
  603. state=P_URI;
  604. break;
  605. case L_VER:
  606. case VER1:
  607. case VER2:
  608. case VER3:
  609. case VER4:
  610. case VER5:
  611. case VER6:
  612. case FIN_VER:
  613. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  614. " in request\n");
  615. goto error;
  616. default:
  617. state=P_METHOD;
  618. }
  619. break;
  620. case 'e':
  621. case 'E':
  622. switch(state){
  623. case START:
  624. state=P_METHOD;
  625. fl->u.request.method.s=tmp;
  626. break;
  627. case INVITE5:
  628. state=FIN_INVITE;
  629. break;
  630. case CANCEL4:
  631. state=CANCEL5;
  632. break;
  633. case BYE2:
  634. state=FIN_BYE;
  635. break;
  636. case P_URI:
  637. case P_REASON:
  638. case P_METHOD:
  639. break;
  640. case L_REASON:
  641. fl->u.reply.reason.s=tmp;
  642. state=P_REASON;
  643. break;
  644. case P_STATUS:
  645. case L_STATUS:
  646. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  647. "character <%c> in request status\n", *tmp);
  648. goto error;
  649. case L_LF:
  650. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  651. "character <%c> in request\n", *tmp);
  652. goto error;
  653. case L_URI:
  654. fl->u.request.uri.s=tmp;
  655. state=P_URI;
  656. break;
  657. case L_VER:
  658. case VER1:
  659. case VER2:
  660. case VER3:
  661. case VER4:
  662. case VER5:
  663. case VER6:
  664. case FIN_VER:
  665. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  666. " in request\n");
  667. goto error;
  668. default:
  669. state=P_METHOD;
  670. }
  671. break;
  672. case 'a':
  673. case 'A':
  674. switch(state){
  675. case START:
  676. state=ACK1;
  677. fl->u.request.method.s=tmp;
  678. break;
  679. case CANCEL1:
  680. state=CANCEL2;
  681. break;
  682. case BYE2:
  683. state=FIN_BYE;
  684. break;
  685. case P_URI:
  686. case P_REASON:
  687. case P_METHOD:
  688. break;
  689. case L_REASON:
  690. fl->u.reply.reason.s=tmp;
  691. state=P_REASON;
  692. break;
  693. case P_STATUS:
  694. case L_STATUS:
  695. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  696. "character <%c> in request status\n", *tmp);
  697. goto error;
  698. case L_LF:
  699. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  700. "character <%c> in request\n", *tmp);
  701. goto error;
  702. case L_URI:
  703. fl->u.request.uri.s=tmp;
  704. state=P_URI;
  705. break;
  706. case L_VER:
  707. case VER1:
  708. case VER2:
  709. case VER3:
  710. case VER4:
  711. case VER5:
  712. case VER6:
  713. case FIN_VER:
  714. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  715. " in request\n");
  716. goto error;
  717. default:
  718. state=P_METHOD;
  719. }
  720. break;
  721. case 'c':
  722. case 'C':
  723. switch(state){
  724. case START:
  725. state=CANCEL1;
  726. fl->u.request.method.s=tmp;
  727. break;
  728. case CANCEL3:
  729. state=CANCEL4;
  730. break;
  731. case ACK1:
  732. state=ACK2;
  733. break;
  734. case P_URI:
  735. case P_REASON:
  736. case P_METHOD:
  737. break;
  738. case L_REASON:
  739. fl->u.reply.reason.s=tmp;
  740. state=P_REASON;
  741. break;
  742. case P_STATUS:
  743. case L_STATUS:
  744. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  745. "character <%c> in request status\n", *tmp);
  746. goto error;
  747. case L_LF:
  748. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  749. "character <%c> in request\n", *tmp);
  750. goto error;
  751. case L_URI:
  752. fl->u.request.uri.s=tmp;
  753. state=P_URI;
  754. break;
  755. case L_VER:
  756. case VER1:
  757. case VER2:
  758. case VER3:
  759. case VER4:
  760. case VER5:
  761. case VER6:
  762. case FIN_VER:
  763. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  764. " in request\n");
  765. goto error;
  766. default:
  767. state=P_METHOD;
  768. }
  769. break;
  770. case 'k':
  771. case 'K':
  772. switch(state){
  773. case START:
  774. state=P_METHOD;
  775. fl->u.request.method.s=tmp;
  776. break;
  777. case ACK2:
  778. state=FIN_ACK;
  779. break;
  780. case P_URI:
  781. case P_REASON:
  782. case P_METHOD:
  783. break;
  784. case L_REASON:
  785. fl->u.reply.reason.s=tmp;
  786. state=P_REASON;
  787. break;
  788. case P_STATUS:
  789. case L_STATUS:
  790. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  791. "character <%c> in request status\n", *tmp);
  792. goto error;
  793. case L_LF:
  794. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  795. "character <%c> in request\n", *tmp);
  796. goto error;
  797. case L_URI:
  798. fl->u.request.uri.s=tmp;
  799. state=P_URI;
  800. break;
  801. case L_VER:
  802. case VER1:
  803. case VER2:
  804. case VER3:
  805. case VER4:
  806. case VER5:
  807. case VER6:
  808. case FIN_VER:
  809. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  810. " in request\n");
  811. goto error;
  812. default:
  813. state=P_METHOD;
  814. }
  815. break;
  816. case 'l':
  817. case 'L':
  818. switch(state){
  819. case START:
  820. state=P_METHOD;
  821. fl->u.request.method.s=tmp;
  822. break;
  823. case CANCEL5:
  824. state=FIN_CANCEL;
  825. break;
  826. case P_URI:
  827. case P_REASON:
  828. case P_METHOD:
  829. break;
  830. case L_REASON:
  831. fl->u.reply.reason.s=tmp;
  832. state=P_REASON;
  833. break;
  834. case P_STATUS:
  835. case L_STATUS:
  836. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  837. "character <%c> in request status\n", *tmp);
  838. goto error;
  839. case L_LF:
  840. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  841. "character <%c> in request\n", *tmp);
  842. goto error;
  843. case L_URI:
  844. fl->u.request.uri.s=tmp;
  845. state=P_URI;
  846. break;
  847. case L_VER:
  848. case VER1:
  849. case VER2:
  850. case VER3:
  851. case VER4:
  852. case VER5:
  853. case VER6:
  854. case FIN_VER:
  855. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  856. " in request\n");
  857. goto error;
  858. default:
  859. state=P_METHOD;
  860. }
  861. break;
  862. case 'b':
  863. case 'B':
  864. switch(state){
  865. case START:
  866. state=BYE1;
  867. fl->u.request.method.s=tmp;
  868. break;
  869. case P_URI:
  870. case P_REASON:
  871. case P_METHOD:
  872. break;
  873. case L_REASON:
  874. fl->u.reply.reason.s=tmp;
  875. state=P_REASON;
  876. break;
  877. case P_STATUS:
  878. case L_STATUS:
  879. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  880. "character <%c> in request status\n", *tmp);
  881. goto error;
  882. case L_LF:
  883. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  884. "character <%c> in request\n", *tmp);
  885. goto error;
  886. case L_URI:
  887. fl->u.request.uri.s=tmp;
  888. state=P_URI;
  889. break;
  890. case L_VER:
  891. case VER1:
  892. case VER2:
  893. case VER3:
  894. case VER4:
  895. case VER5:
  896. case VER6:
  897. case FIN_VER:
  898. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  899. " in request\n");
  900. goto error;
  901. default:
  902. state=P_METHOD;
  903. }
  904. break;
  905. case 'y':
  906. case 'Y':
  907. switch(state){
  908. case START:
  909. state=P_METHOD;
  910. fl->u.request.method.s=tmp;
  911. break;
  912. case BYE1:
  913. state=BYE2;
  914. break;
  915. case P_URI:
  916. case P_REASON:
  917. case P_METHOD:
  918. break;
  919. case L_REASON:
  920. fl->u.reply.reason.s=tmp;
  921. state=P_REASON;
  922. break;
  923. case P_STATUS:
  924. case L_STATUS:
  925. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  926. "character <%c> in request status\n", *tmp);
  927. goto error;
  928. case L_LF:
  929. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  930. "character <%c> in request\n", *tmp);
  931. goto error;
  932. case L_URI:
  933. fl->u.request.uri.s=tmp;
  934. state=P_URI;
  935. break;
  936. case L_VER:
  937. case VER1:
  938. case VER2:
  939. case VER3:
  940. case VER4:
  941. case VER5:
  942. case VER6:
  943. case FIN_VER:
  944. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  945. " in request\n");
  946. goto error;
  947. default:
  948. state=P_METHOD;
  949. }
  950. break;
  951. case '\r':
  952. switch(state){
  953. case P_REASON:
  954. *tmp=0;
  955. fl->u.reply.reason.len=tmp-fl->u.reply.reason.s;
  956. state=F_CR;
  957. break;
  958. case L_LF:
  959. state=F_CR;
  960. break;
  961. case FIN_VER:
  962. *tmp=0;
  963. fl->u.request.version.len=tmp-fl->u.request.version.s;
  964. state=F_CR;
  965. break;
  966. case L_REASON:
  967. state=F_CR;
  968. break;
  969. default:
  970. LOG(L_ERR, "ERROR: parse_first_line: invalid"
  971. "message\n");
  972. goto error;
  973. }
  974. break;
  975. case '\n':
  976. switch(state){
  977. case P_REASON:
  978. *tmp=0;
  979. fl->u.reply.reason.len=tmp-fl->u.reply.reason.s;
  980. state=F_LF;
  981. goto skip;
  982. case FIN_VER:
  983. *tmp=0;
  984. fl->u.request.version.len=tmp-fl->u.request.version.s;
  985. state=F_LF;
  986. goto skip;
  987. case L_REASON:
  988. case L_LF:
  989. case F_CR:
  990. state=F_LF;
  991. goto skip;
  992. default:
  993. LOG(L_ERR, "ERROR: parse_first_line: invalid"
  994. " message\n");
  995. goto error;
  996. }
  997. break;
  998. case '1':
  999. case '3':
  1000. case '4':
  1001. case '5':
  1002. case '6':
  1003. case '7':
  1004. case '8':
  1005. case '9':
  1006. switch(state){
  1007. case START:
  1008. state=P_METHOD;
  1009. fl->u.request.method.s=tmp;
  1010. break;
  1011. case P_URI:
  1012. case P_REASON:
  1013. case P_METHOD:
  1014. break;
  1015. case L_REASON:
  1016. fl->u.reply.reason.s=tmp;
  1017. state=P_REASON;
  1018. break;
  1019. case P_STATUS:
  1020. stat=stat*10+*tmp-'0';
  1021. break;
  1022. case L_STATUS:
  1023. stat=*tmp-'0';
  1024. state=P_STATUS;
  1025. fl->u.reply.status.s=tmp;
  1026. break;
  1027. case L_LF:
  1028. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  1029. "character <%c> in request\n", *tmp);
  1030. goto error;
  1031. case L_URI:
  1032. fl->u.request.uri.s=tmp;
  1033. state=P_URI;
  1034. break;
  1035. case L_VER:
  1036. case VER1:
  1037. case VER2:
  1038. case VER3:
  1039. case VER4:
  1040. case VER5:
  1041. case VER6:
  1042. case FIN_VER:
  1043. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  1044. " in request\n");
  1045. goto error;
  1046. default:
  1047. state=P_METHOD;
  1048. }
  1049. default:
  1050. switch(state){
  1051. case START:
  1052. state=P_METHOD;
  1053. fl->u.request.method.s=tmp;
  1054. break;
  1055. case P_URI:
  1056. case P_REASON:
  1057. case P_METHOD:
  1058. break;
  1059. case L_REASON:
  1060. fl->u.reply.reason.s=tmp;
  1061. state=P_REASON;
  1062. break;
  1063. case P_STATUS:
  1064. case L_STATUS:
  1065. LOG(L_ERR, "ERROR: parse_first_line: non-number "
  1066. "character <%c> in request status\n", *tmp);
  1067. goto error;
  1068. case L_LF:
  1069. LOG(L_ERR, "ERROR: parse_first_line: invalid "
  1070. "character <%c> in request\n", *tmp);
  1071. goto error;
  1072. case L_URI:
  1073. fl->u.request.uri.s=tmp;
  1074. state=P_URI;
  1075. break;
  1076. case L_VER:
  1077. case VER1:
  1078. case VER2:
  1079. case VER3:
  1080. case VER4:
  1081. case VER5:
  1082. case VER6:
  1083. case FIN_VER:
  1084. LOG(L_ERR, "ERROR: parse_first_line: invalid version "
  1085. " in request\n");
  1086. goto error;
  1087. default:
  1088. state=P_METHOD;
  1089. }
  1090. }
  1091. }
  1092. skip:
  1093. if (fl->type==SIP_REPLY){
  1094. fl->u.reply.statuscode=stat;
  1095. /* fl->u.reply.statusclass=stat/100; */
  1096. }
  1097. return tmp;
  1098. error:
  1099. LOG(L_ERR, "ERROR: while parsing first line (state=%d)\n", state);
  1100. fl->type=SIP_INVALID;
  1101. return tmp;
  1102. }
  1103. /* parses the first line, returns pointer to next line & fills fl;
  1104. also modifies buffer (to avoid extra copy ops) */
  1105. char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl)
  1106. {
  1107. char *tmp;
  1108. char* second;
  1109. char* third;
  1110. char* nl;
  1111. int offset;
  1112. /* int l; */
  1113. char* end;
  1114. char s1,s2,s3;
  1115. char *prn;
  1116. unsigned int t;
  1117. /* grammar:
  1118. request = method SP uri SP version CRLF
  1119. response = version SP status SP reason CRLF
  1120. (version = "SIP/2.0")
  1121. */
  1122. end=buffer+len;
  1123. /* see if it's a reply (status) */
  1124. /* jku -- parse well-known methods */
  1125. /* drop messages which are so short they are for sure useless;
  1126. utilize knowledge of minimum size in parsing the first
  1127. token
  1128. */
  1129. if (len <=16 ) {
  1130. LOG(L_INFO, "ERROR: parse_first_line: message too short: %d\n", len);
  1131. goto error1;
  1132. }
  1133. tmp=buffer;
  1134. /* is it perhaps a reply, ie does it start with "SIP...." ? */
  1135. if ( (*tmp=='S' || *tmp=='s') &&
  1136. strncasecmp( tmp+1, SIP_VERSION+1, SIP_VERSION_LEN-1)==0 &&
  1137. (*(tmp+SIP_VERSION_LEN)==' ')) {
  1138. fl->type=SIP_REPLY;
  1139. fl->u.reply.version.len=SIP_VERSION_LEN;
  1140. tmp=buffer+SIP_VERSION_LEN;
  1141. } else IFISMETHOD( INVITE, 'I' )
  1142. else IFISMETHOD( CANCEL, 'C')
  1143. else IFISMETHOD( ACK, 'A' )
  1144. else IFISMETHOD( BYE, 'B' )
  1145. /* if you want to add another method XXX, include METHOD_XXX in
  1146. H-file (this is the value which you will take later in
  1147. processing and define XXX_LEN as length of method name;
  1148. then just call IFISMETHOD( XXX, 'X' ) ... 'X' is the first
  1149. latter; everything must be capitals
  1150. */
  1151. else {
  1152. /* neither reply, nor any of known method requests,
  1153. let's believe it is an unknown method request
  1154. */
  1155. tmp=eat_token_end(buffer,buffer+len);
  1156. if ((tmp==buffer)||(tmp>=end)){
  1157. LOG(L_INFO, "ERROR:parse_first_line: empty or bad first line\n");
  1158. goto error1;
  1159. }
  1160. if (*tmp!=' ') {
  1161. LOG(L_INFO, "ERROR:parse_first_line: method not followed by SP\n");
  1162. goto error1;
  1163. }
  1164. fl->type=SIP_REQUEST;
  1165. fl->u.request.method_value=METHOD_OTHER;
  1166. fl->u.request.method.len=tmp-buffer;
  1167. }
  1168. /* identifying type of message over now;
  1169. tmp points at space after; go ahead */
  1170. fl->u.request.method.s=buffer; /* store ptr to first token */
  1171. (*tmp)=0; /* mark the 1st token end */
  1172. second=tmp+1; /* jump to second token */
  1173. offset=second-buffer;
  1174. /* EoJku */
  1175. /* next element */
  1176. tmp=eat_token_end(second, second+len-offset);
  1177. if (tmp>=end){
  1178. goto error;
  1179. }
  1180. offset+=tmp-second;
  1181. third=eat_space_end(tmp, tmp+len-offset);
  1182. offset+=third-tmp;
  1183. if ((third==tmp)||(tmp>=end)){
  1184. goto error;
  1185. }
  1186. *tmp=0; /* mark the end of the token */
  1187. fl->u.request.uri.s=second;
  1188. fl->u.request.uri.len=tmp-second;
  1189. /* jku: parse status code */
  1190. if (fl->type==SIP_REPLY) {
  1191. if (fl->u.request.uri.len!=3) {
  1192. LOG(L_INFO, "ERROR:parse_first_line: len(status code)!=3: %s\n",
  1193. second );
  1194. goto error;
  1195. }
  1196. s1=*second; s2=*(second+1);s3=*(second+2);
  1197. if (s1>='0' && s1<='9' &&
  1198. s2>='0' && s2<='9' &&
  1199. s3>='0' && s3<='9' ) {
  1200. fl->u.reply.statuscode=(s1-'0')*100+10*(s2-'0')+(s3-'0');
  1201. } else {
  1202. LOG(L_INFO, "ERROR:parse_first_line: status_code non-numerical: %s\n",
  1203. second );
  1204. goto error;
  1205. }
  1206. }
  1207. /* EoJku */
  1208. /* last part: for a request it must be the version, for a reply
  1209. * it can contain almost anything, including spaces, so we don't care
  1210. * about it*/
  1211. if (fl->type==SIP_REQUEST){
  1212. tmp=eat_token_end(third,third+len-offset);
  1213. offset+=tmp-third;
  1214. if ((tmp==third)||(tmp>=end)){
  1215. goto error;
  1216. }
  1217. if (! is_empty_end(tmp, tmp+len-offset)){
  1218. goto error;
  1219. }
  1220. }else{
  1221. tmp=eat_token2_end(third,third+len-offset,'\r'); /* find end of line
  1222. ('\n' or '\r') */
  1223. if (tmp>=end){ /* no crlf in packet => invalid */
  1224. goto error;
  1225. }
  1226. offset+=tmp-third;
  1227. }
  1228. nl=eat_line(tmp,len-offset);
  1229. if (nl>=end){ /* no crlf in packet or only 1 line > invalid */
  1230. goto error;
  1231. }
  1232. *tmp=0;
  1233. fl->u.request.version.s=third;
  1234. fl->u.request.version.len=tmp-third;
  1235. return nl;
  1236. error:
  1237. LOG(L_INFO, "ERROR:parse_first_line: bad %s first line\n",
  1238. (fl->type==SIP_REPLY)?"reply(status)":"request");
  1239. LOG(L_INFO, "ERROR: at line 0 char %d: \n", offset );
  1240. prn=pkg_malloc( offset );
  1241. if (prn) {
  1242. for (t=0; t<offset; t++)
  1243. if (*(buffer+t)) *(prn+t)=*(buffer+t);
  1244. else *(prn+t)='°';
  1245. LOG(L_INFO, "ERROR: parsed so far: %.*s\n", offset, prn );
  1246. pkg_free( prn );
  1247. };
  1248. error1:
  1249. fl->type=SIP_INVALID;
  1250. LOG(L_INFO, "ERROR:parse_first_line: bad message\n");
  1251. /* skip line */
  1252. nl=eat_line(buffer,len);
  1253. return nl;
  1254. }