2
0

via_parse.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589
  1. /* test program -> via parse */
  2. /*
  3. *
  4. * Copyright (C) 2001-2003 Fhg Fokus
  5. *
  6. * This file is part of ser, a free SIP server.
  7. *
  8. * ser 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
  12. *
  13. * For a license to use the ser software under conditions
  14. * other than those described here, or to purchase support for this
  15. * software, please contact iptel.org by e-mail at the following addresses:
  16. * [email protected]
  17. *
  18. * ser is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  26. */
  27. /* parsing: compact form:
  28. */
  29. /*
  30. * still TODO/test:
  31. * - parse next via
  32. * - return a list of header structs
  33. * - '[' ']' ipv6 parsing!
  34. * - return list of params
  35. * - test ^\s...'
  36. * - add support for parsing via front (SIP/2.0/UDP)
  37. */
  38. #include <stdio.h>
  39. /* main via states (uri:port ...) */
  40. enum{ F_HOST, P_HOST,
  41. L_PORT, F_PORT, P_PORT,
  42. L_PARAM, F_PARAM, P_PARAM,
  43. L_VIA, F_VIA,
  44. F_COMMENT, P_COMMENT,
  45. F_IP6HOST, P_IP6HOST,
  46. F_CRLF,
  47. F_LF,
  48. F_CR,
  49. END_OF_HEADER
  50. };
  51. /* first via part state */
  52. enum{ F_SIP=100,
  53. SIP1, SIP2, FIN_SIP,
  54. L_VER, F_VER,
  55. VER1, VER2, FIN_VER,
  56. L_PROTO, F_PROTO, P_PROTO
  57. };
  58. /* param realated states */
  59. enum{ L_VALUE=200, F_VALUE, P_VALUE, P_STRING,
  60. HIDDEN1, HIDDEN2, HIDDEN3, HIDDEN4, HIDDEN5,
  61. TTL1, TTL2,
  62. BRANCH1, BRANCH2, BRANCH3, BRANCH4, BRANCH5,
  63. MADDR1, MADDR2, MADDR3, MADDR4,
  64. RECEIVED1, RECEIVED2, RECEIVED3, RECEIVED4, RECEIVED5, RECEIVED6,
  65. RECEIVED7,
  66. /* fin states (227-...)*/
  67. FIN_HIDDEN, FIN_TTL, FIN_BRANCH, FIN_MADDR, FIN_RECEIVED,
  68. GEN_PARAM
  69. };
  70. #define LOG(lev, fmt, args...) fprintf(stderr, fmt, ## args)
  71. /* entry state must be F_PARAM, or saved_state=F_PARAM and
  72. * state=F_{LF,CR,CRLF}!
  73. * output state = L_PARAM or F_PARAM or END_OF_HEADER
  74. * (and saved_state= last state); everything else => error */
  75. __inline char* parse_via_param(char* p, int* pstate, int* psaved_state)
  76. {
  77. char* tmp;
  78. register int state;
  79. int saved_state;
  80. int param_type;
  81. char* param_name;
  82. char* param_value;
  83. state=*pstate;
  84. saved_state=*psaved_state;
  85. param_name=param_value=0;
  86. param_type=0;
  87. for (tmp=p;*tmp;tmp++){
  88. switch(*tmp){
  89. case ' ':
  90. case '\t':
  91. switch(state){
  92. case FIN_HIDDEN:
  93. *tmp=0;
  94. param_type=state;
  95. state=L_PARAM;
  96. goto endofparam;
  97. case FIN_BRANCH:
  98. case FIN_TTL:
  99. case FIN_MADDR:
  100. case FIN_RECEIVED:
  101. *tmp=0;
  102. param_type=state;
  103. state=L_VALUE;
  104. goto find_value;
  105. case F_PARAM:
  106. break;
  107. case F_LF:
  108. case F_CR:
  109. case F_CRLF:
  110. state=saved_state;
  111. break;
  112. case GEN_PARAM:
  113. default:
  114. *tmp=0;
  115. param_type=GEN_PARAM;
  116. state=L_VALUE;
  117. goto find_value;
  118. }
  119. break;
  120. /* \n and \r*/
  121. case '\n':
  122. switch(state){
  123. case FIN_HIDDEN:
  124. *tmp=0;
  125. param_type=state;
  126. saved_state=L_PARAM;
  127. state=F_LF;
  128. goto endofparam;
  129. case FIN_BRANCH:
  130. case FIN_TTL:
  131. case FIN_MADDR:
  132. case FIN_RECEIVED:
  133. *tmp=0;
  134. param_type=state;
  135. saved_state=L_VALUE;
  136. state=F_LF;
  137. goto find_value;
  138. case F_PARAM:
  139. saved_state=state;
  140. state=F_LF;
  141. break;
  142. case F_LF:
  143. case F_CRLF:
  144. state=END_OF_HEADER;
  145. goto end;
  146. case F_CR:
  147. state=F_CRLF;
  148. break;
  149. case GEN_PARAM:
  150. default:
  151. *tmp=0;
  152. param_type=GEN_PARAM;
  153. saved_state=L_VALUE;
  154. state=F_LF;
  155. goto find_value;
  156. }
  157. break;
  158. case '\r':
  159. switch(state){
  160. case FIN_HIDDEN:
  161. *tmp=0;
  162. param_type=state;
  163. saved_state=L_PARAM;
  164. state=F_CR;
  165. goto endofparam;
  166. case FIN_BRANCH:
  167. case FIN_TTL:
  168. case FIN_MADDR:
  169. case FIN_RECEIVED:
  170. *tmp=0;
  171. param_type=state;
  172. saved_state=L_VALUE;
  173. state=F_CR;
  174. goto find_value;
  175. case F_PARAM:
  176. saved_state=state;
  177. state=F_CR;
  178. break;
  179. case F_CR:
  180. case F_CRLF:
  181. state=END_OF_HEADER;
  182. goto end;
  183. case GEN_PARAM:
  184. default:
  185. *tmp=0;
  186. param_type=GEN_PARAM;
  187. saved_state=L_VALUE;
  188. state=F_CR;
  189. goto find_value;
  190. }
  191. break;
  192. case '=':
  193. switch(state){
  194. case FIN_BRANCH:
  195. case FIN_TTL:
  196. case FIN_MADDR:
  197. case FIN_RECEIVED:
  198. *tmp=0;
  199. param_type=state;
  200. state=F_VALUE;
  201. goto find_value;
  202. case F_PARAM:
  203. case FIN_HIDDEN:
  204. LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
  205. " state %d\n");
  206. goto error;
  207. case F_CR:
  208. case F_LF:
  209. case F_CRLF:
  210. state=END_OF_HEADER;
  211. goto end;
  212. case GEN_PARAM:
  213. default:
  214. *tmp=0;
  215. param_type=GEN_PARAM;
  216. state=F_VALUE;
  217. goto find_value;
  218. }
  219. break;
  220. case ';':
  221. switch(state){
  222. case FIN_HIDDEN:
  223. *tmp=0;
  224. param_type=state;
  225. state=F_PARAM;
  226. goto endofparam;
  227. case FIN_BRANCH:
  228. case FIN_MADDR:
  229. case FIN_TTL:
  230. case FIN_RECEIVED:
  231. LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
  232. " state %d\n");
  233. goto error;
  234. case F_CR:
  235. case F_LF:
  236. case F_CRLF:
  237. state=END_OF_HEADER;
  238. goto end;
  239. case GEN_PARAM:
  240. default:
  241. *tmp=0;
  242. param_type=GEN_PARAM;
  243. state=F_PARAM;
  244. goto endofparam;
  245. }
  246. break;
  247. /* param names */
  248. case 'h':
  249. case 'H':
  250. switch(state){
  251. case F_PARAM:
  252. state=HIDDEN1;
  253. param_name=tmp;
  254. break;
  255. case GEN_PARAM:
  256. break;
  257. case F_CR:
  258. case F_LF:
  259. case F_CRLF:
  260. state=END_OF_HEADER;
  261. goto end;
  262. default:
  263. state=GEN_PARAM;
  264. }
  265. break;
  266. case 'i':
  267. case 'I':
  268. switch(state){
  269. case HIDDEN1:
  270. state=HIDDEN2;
  271. break;
  272. case RECEIVED4:
  273. state=RECEIVED5;
  274. break;
  275. case GEN_PARAM:
  276. break;
  277. case F_CR:
  278. case F_LF:
  279. case F_CRLF:
  280. state=END_OF_HEADER;
  281. goto end;
  282. default:
  283. state=GEN_PARAM;
  284. }
  285. break;
  286. case 'd':
  287. case 'D':
  288. switch(state){
  289. case HIDDEN2:
  290. state=HIDDEN3;
  291. break;
  292. case HIDDEN3:
  293. state=HIDDEN4;
  294. break;
  295. case MADDR2:
  296. state=MADDR3;
  297. break;
  298. case MADDR3:
  299. state=MADDR4;
  300. break;
  301. case RECEIVED7:
  302. state=FIN_RECEIVED;
  303. break;
  304. case GEN_PARAM:
  305. break;
  306. case F_CR:
  307. case F_LF:
  308. case F_CRLF:
  309. state=END_OF_HEADER;
  310. goto end;
  311. default:
  312. state=GEN_PARAM;
  313. }
  314. break;
  315. case 'e':
  316. case 'E':
  317. switch(state){
  318. case HIDDEN4:
  319. state=HIDDEN5;
  320. break;
  321. case RECEIVED1:
  322. state=RECEIVED2;
  323. break;
  324. case RECEIVED3:
  325. state=RECEIVED4;
  326. break;
  327. case RECEIVED6:
  328. state=RECEIVED7;
  329. break;
  330. case GEN_PARAM:
  331. break;
  332. case F_CR:
  333. case F_LF:
  334. case F_CRLF:
  335. state=END_OF_HEADER;
  336. goto end;
  337. default:
  338. state=GEN_PARAM;
  339. }
  340. break;
  341. case 'n':
  342. case 'N':
  343. switch(state){
  344. case HIDDEN5:
  345. state=FIN_HIDDEN;
  346. break;
  347. case BRANCH3:
  348. state=BRANCH4;
  349. break;
  350. case GEN_PARAM:
  351. break;
  352. case F_CR:
  353. case F_LF:
  354. case F_CRLF:
  355. state=END_OF_HEADER;
  356. goto end;
  357. default:
  358. state=GEN_PARAM;
  359. }
  360. break;
  361. case 't':
  362. case 'T':
  363. switch(state){
  364. case F_PARAM:
  365. state=TTL1;
  366. param_name=tmp;
  367. break;
  368. case TTL1:
  369. state=TTL2;
  370. break;
  371. case GEN_PARAM:
  372. break;
  373. case F_CR:
  374. case F_LF:
  375. case F_CRLF:
  376. state=END_OF_HEADER;
  377. goto end;
  378. default:
  379. state=GEN_PARAM;
  380. }
  381. break;
  382. case 'l':
  383. case 'L':
  384. switch(state){
  385. case TTL2:
  386. state=FIN_TTL;
  387. break;
  388. case GEN_PARAM:
  389. break;
  390. case F_CR:
  391. case F_LF:
  392. case F_CRLF:
  393. state=END_OF_HEADER;
  394. goto end;
  395. default:
  396. state=GEN_PARAM;
  397. }
  398. break;
  399. case 'm':
  400. case 'M':
  401. switch(state){
  402. case F_PARAM:
  403. state=MADDR1;
  404. param_name=tmp;
  405. break;
  406. case GEN_PARAM:
  407. break;
  408. case F_CR:
  409. case F_LF:
  410. case F_CRLF:
  411. state=END_OF_HEADER;
  412. goto end;
  413. default:
  414. state=GEN_PARAM;
  415. }
  416. break;
  417. case 'a':
  418. case 'A':
  419. switch(state){
  420. case MADDR1:
  421. state=MADDR2;
  422. break;
  423. case BRANCH2:
  424. state=BRANCH3;
  425. break;
  426. case GEN_PARAM:
  427. break;
  428. case F_CR:
  429. case F_LF:
  430. case F_CRLF:
  431. state=END_OF_HEADER;
  432. goto end;
  433. default:
  434. state=GEN_PARAM;
  435. }
  436. break;
  437. case 'r':
  438. case 'R':
  439. switch(state){
  440. case MADDR4:
  441. state=FIN_MADDR;
  442. break;
  443. case F_PARAM:
  444. state=RECEIVED1;
  445. param_name=tmp;
  446. break;
  447. case BRANCH1:
  448. state=BRANCH2;
  449. break;
  450. case GEN_PARAM:
  451. break;
  452. case F_CR:
  453. case F_LF:
  454. case F_CRLF:
  455. state=END_OF_HEADER;
  456. goto end;
  457. default:
  458. state=GEN_PARAM;
  459. }
  460. break;
  461. case 'c':
  462. case 'C':
  463. switch(state){
  464. case RECEIVED2:
  465. state=RECEIVED3;
  466. break;
  467. case BRANCH4:
  468. state=BRANCH5;
  469. break;
  470. case GEN_PARAM:
  471. break;
  472. case F_CR:
  473. case F_LF:
  474. case F_CRLF:
  475. state=END_OF_HEADER;
  476. goto end;
  477. default:
  478. state=GEN_PARAM;
  479. }
  480. break;
  481. case 'v':
  482. case 'V':
  483. switch(state){
  484. case RECEIVED5:
  485. state=RECEIVED6;
  486. break;
  487. case GEN_PARAM:
  488. break;
  489. case F_CR:
  490. case F_LF:
  491. case F_CRLF:
  492. state=END_OF_HEADER;
  493. goto end;
  494. default:
  495. state=GEN_PARAM;
  496. }
  497. break;
  498. case 'b':
  499. case 'B':
  500. switch(state){
  501. case F_PARAM:
  502. state=BRANCH1;
  503. param_name=tmp;
  504. break;
  505. case GEN_PARAM:
  506. break;
  507. case F_CR:
  508. case F_LF:
  509. case F_CRLF:
  510. state=END_OF_HEADER;
  511. goto end;
  512. default:
  513. state=GEN_PARAM;
  514. }
  515. break;
  516. default:
  517. switch(state){
  518. case F_PARAM:
  519. state=GEN_PARAM;
  520. param_name=tmp;
  521. break;
  522. case GEN_PARAM:
  523. break;
  524. case F_CR:
  525. case F_LF:
  526. case F_CRLF:
  527. state=END_OF_HEADER;
  528. goto end;
  529. default:
  530. state=GEN_PARAM;
  531. }
  532. }
  533. }/* for tmp*/
  534. /* end of packet?*/
  535. saved_state=state;
  536. param_type=state;
  537. state=END_OF_HEADER;
  538. goto end;
  539. find_value:
  540. tmp++;
  541. for(tmp;*tmp;tmp++){
  542. switch(*tmp){
  543. case ' ':
  544. case '\t':
  545. switch(state){
  546. case L_VALUE:
  547. case F_VALUE: /*eat space*/
  548. break;
  549. case P_VALUE:
  550. *tmp=0;
  551. state=L_PARAM;
  552. goto endofvalue;
  553. case P_STRING:
  554. break;
  555. case F_CR:
  556. case F_LF:
  557. case F_CRLF:
  558. state=saved_state;
  559. break;
  560. default:
  561. LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
  562. " in state %d\n", state);
  563. goto error;
  564. }
  565. break;
  566. case '\n':
  567. switch(state){
  568. case L_VALUE:
  569. case F_VALUE: /*eat space*/
  570. case P_STRING:
  571. saved_state=state;
  572. state=F_LF;
  573. break;
  574. case P_VALUE:
  575. *tmp=0;
  576. saved_state=L_PARAM;
  577. state=F_LF;
  578. goto endofvalue;
  579. case F_LF:
  580. case F_CRLF:
  581. state=END_OF_HEADER;
  582. goto end;
  583. case F_CR:
  584. state=F_CRLF;
  585. break;
  586. default:
  587. LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
  588. " in state %d\n", state);
  589. goto error;
  590. }
  591. break;
  592. case '\r':
  593. switch(state){
  594. case L_VALUE:
  595. case F_VALUE: /*eat space*/
  596. case P_STRING:
  597. saved_state=state;
  598. state=F_CR;
  599. break;
  600. case P_VALUE:
  601. *tmp=0;
  602. saved_state=L_PARAM;
  603. state=F_CR;
  604. goto endofvalue;
  605. case F_LF:
  606. case F_CR:
  607. case F_CRLF:
  608. state=END_OF_HEADER;
  609. goto end;
  610. default:
  611. LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
  612. " in state %d\n", state);
  613. goto error;
  614. }
  615. break;
  616. case '=':
  617. switch(state){
  618. case L_VALUE:
  619. state=F_VALUE;
  620. break;
  621. case P_STRING:
  622. break;
  623. case F_LF:
  624. case F_CR:
  625. case F_CRLF:
  626. state=END_OF_HEADER;
  627. goto end;
  628. default:
  629. LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
  630. " in state %d\n", state);
  631. goto error;
  632. }
  633. break;
  634. case ';':
  635. switch(state){
  636. case P_VALUE:
  637. *tmp=0;
  638. state=F_PARAM;
  639. goto endofvalue;
  640. case P_STRING:
  641. break; /* what to do? */
  642. case F_LF:
  643. case F_CR:
  644. case F_CRLF:
  645. state=END_OF_HEADER;
  646. goto end;
  647. default:
  648. LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
  649. " in state %d\n", state);
  650. goto error;
  651. }
  652. break;
  653. case '"':
  654. switch(state){
  655. case F_VALUE:
  656. state=P_STRING;
  657. param_value=tmp+1;
  658. break;
  659. case P_STRING:
  660. *tmp=0;
  661. state=L_PARAM;
  662. goto endofvalue;
  663. case F_LF:
  664. case F_CR:
  665. case F_CRLF:
  666. state=END_OF_HEADER;
  667. goto end;
  668. default:
  669. LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
  670. " in state %d\n", state);
  671. goto error;
  672. }
  673. break;
  674. default:
  675. switch(state){
  676. case F_VALUE:
  677. state=P_VALUE;
  678. param_value=tmp;
  679. break;
  680. case P_VALUE:
  681. case P_STRING:
  682. break;
  683. case F_LF:
  684. case F_CR:
  685. case F_CRLF:
  686. state=END_OF_HEADER;
  687. goto end;
  688. default:
  689. LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
  690. " in state %d\n", state);
  691. goto error;
  692. }
  693. }
  694. } /* for2 tmp*/
  695. /* if generic_param => it can have no value */
  696. if ((state==L_VALUE)&&(param_type==GEN_PARAM)) state=L_PARAM;
  697. saved_state=state;
  698. state=END_OF_HEADER;
  699. goto end;
  700. endofparam:
  701. endofvalue:
  702. printf("end, tmp=%x, <%c>\n", tmp, *tmp);
  703. //tmp++;
  704. end:
  705. *pstate=state;
  706. *psaved_state=saved_state;
  707. printf("Found param type %d, <%s> = <%s>\n", param_type, param_name,
  708. param_value);
  709. return tmp;
  710. error:
  711. fprintf(stderr,"error: via_parse_param\n");
  712. *pstate=state;
  713. *psaved_state=saved_state;
  714. return tmp;
  715. }
  716. int main(int argc, char** argv)
  717. {
  718. char* tmp;
  719. int state;
  720. int saved_state;
  721. int c_nest;
  722. int i;
  723. int port;
  724. char* host;
  725. char* port_str;
  726. char* param;
  727. char* comment;
  728. char* next_via;
  729. char *proto; /* in fact transport*/
  730. host=port_str=param=comment=next_via=proto=0;
  731. printf(" %s (%d)\n", argv[0], argc);
  732. if (argc<2){
  733. fprintf(stderr, " no parameters\n");
  734. exit(-1);
  735. }
  736. /* parse start of via ( SIP/2.0/UDP )*/
  737. state=F_SIP;
  738. for(tmp=argv[1];*tmp;tmp++){
  739. switch(*tmp){
  740. case ' ':
  741. case'\t':
  742. switch(state){
  743. case L_VER: /* eat space */
  744. case L_PROTO:
  745. case F_SIP:
  746. case F_VER:
  747. case F_PROTO:
  748. break;
  749. case P_PROTO:
  750. *tmp=0; /* finished proto parsing */
  751. state=F_HOST; /* start looking for host*/
  752. goto main_via;
  753. case FIN_SIP:
  754. *tmp=0;
  755. state=L_VER;
  756. break;
  757. case FIN_VER:
  758. *tmp=0;
  759. state=L_PROTO;
  760. break;
  761. case F_LF:
  762. case F_CRLF:
  763. case F_CR: /* header continues on this line */
  764. state=saved_state;
  765. break;
  766. default:
  767. LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
  768. " state %d\n", *tmp, state);
  769. goto error;
  770. }
  771. break;
  772. case '\n':
  773. switch(state){
  774. case L_VER:
  775. case F_SIP:
  776. case F_VER:
  777. case F_PROTO:
  778. case L_PROTO:
  779. saved_state=state;
  780. state=F_LF;
  781. break;
  782. case P_PROTO:
  783. *tmp=0;
  784. state=F_LF;
  785. saved_state=F_HOST; /* start looking for host*/
  786. goto main_via;
  787. case FIN_SIP:
  788. *tmp=0;
  789. state=F_LF;
  790. saved_state=L_VER;
  791. break;
  792. case FIN_VER:
  793. *tmp=0;
  794. state=F_LF;
  795. saved_state=L_PROTO;
  796. break;
  797. case F_CR:
  798. state=F_CRLF;
  799. break;
  800. case F_LF:
  801. case F_CRLF:
  802. state=saved_state;
  803. goto endofheader;
  804. default:
  805. LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
  806. " state %d\n", *tmp, state);
  807. goto error;
  808. }
  809. break;
  810. case '\r':
  811. switch(state){
  812. case L_VER:
  813. case F_SIP:
  814. case F_VER:
  815. case F_PROTO:
  816. case L_PROTO:
  817. saved_state=state;
  818. state=F_CR;
  819. break;
  820. case P_PROTO:
  821. *tmp=0;
  822. state=F_CR;
  823. saved_state=F_HOST;
  824. goto main_via;
  825. case FIN_SIP:
  826. *tmp=0;
  827. state=F_CR;
  828. saved_state=L_VER;
  829. break;
  830. case FIN_VER:
  831. *tmp=0;
  832. state=F_CR;
  833. saved_state=L_PROTO;
  834. break;
  835. case F_LF: /*end of line ?next header?*/
  836. case F_CR:
  837. case F_CRLF:
  838. state=saved_state;
  839. goto endofheader;
  840. default:
  841. LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
  842. " state %d\n", *tmp, state);
  843. goto error;
  844. }
  845. break;
  846. case '/':
  847. switch(state){
  848. case FIN_SIP:
  849. *tmp=0;
  850. state=F_VER;
  851. break;
  852. case FIN_VER:
  853. *tmp=0;
  854. state=F_PROTO;
  855. break;
  856. case L_VER:
  857. state=F_VER;
  858. break;
  859. case L_PROTO:
  860. state=F_PROTO;
  861. break;
  862. default:
  863. LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
  864. " state %d\n", *tmp, state);
  865. goto error;
  866. }
  867. break;
  868. /* match SIP*/
  869. case 'S':
  870. case 's':
  871. switch(state){
  872. case F_SIP:
  873. state=SIP1;
  874. break;
  875. /* allow S in PROTO */
  876. case F_PROTO:
  877. proto=tmp;
  878. state=P_PROTO;
  879. break;
  880. case P_PROTO:
  881. break;
  882. default:
  883. LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
  884. " state %d\n", *tmp, state);
  885. goto error;
  886. }
  887. break;
  888. case 'I':
  889. case 'i':
  890. switch(state){
  891. case SIP1:
  892. state=SIP2;
  893. break;
  894. /* allow i in PROTO */
  895. case F_PROTO:
  896. proto=tmp;
  897. state=P_PROTO;
  898. break;
  899. case P_PROTO:
  900. break;
  901. default:
  902. LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
  903. " state %d\n", *tmp, state);
  904. goto error;
  905. }
  906. break;
  907. case 'p':
  908. case 'P':
  909. switch(state){
  910. case SIP2:
  911. state=FIN_SIP;
  912. break;
  913. /* allow p in PROTO */
  914. case F_PROTO:
  915. proto=tmp;
  916. state=P_PROTO;
  917. break;
  918. case P_PROTO:
  919. break;
  920. default:
  921. LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
  922. " state %d\n", *tmp, state);
  923. goto error;
  924. }
  925. break;
  926. /*match 2.0*/
  927. case '2':
  928. switch(state){
  929. case F_VER:
  930. state=VER1;
  931. break;
  932. /* allow 2 in PROTO*/
  933. case F_PROTO:
  934. proto=tmp;
  935. state=P_PROTO;
  936. break;
  937. case P_PROTO:
  938. break;
  939. default:
  940. LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
  941. " state %d\n", *tmp, state);
  942. goto error;
  943. }
  944. break;
  945. case '.':
  946. switch(state){
  947. case VER1:
  948. state=VER2;
  949. break;
  950. /* allow . in PROTO */
  951. case F_PROTO:
  952. proto=tmp;
  953. state=P_PROTO;
  954. break;
  955. case P_PROTO:
  956. break;
  957. default:
  958. LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
  959. " state %d\n", *tmp, state);
  960. goto error;
  961. }
  962. break;
  963. case '0':
  964. switch(state){
  965. case VER2:
  966. state=FIN_VER;
  967. break;
  968. /* allow 0 in PROTO*/
  969. case F_PROTO:
  970. proto=tmp;
  971. state=P_PROTO;
  972. break;
  973. case P_PROTO:
  974. break;
  975. default:
  976. LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
  977. " state %d\n", *tmp, state);
  978. goto error;
  979. }
  980. break;
  981. default:
  982. switch(state){
  983. case F_PROTO:
  984. proto=tmp;
  985. state=P_PROTO;
  986. break;
  987. case P_PROTO:
  988. break;
  989. default:
  990. LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
  991. " state %d\n", *tmp, state);
  992. goto error;
  993. }
  994. break;
  995. }
  996. } /* for tmp*/
  997. /* we should not be here! if everything is ok > main_via*/
  998. LOG(L_ERR, "ERROR: parse_via: bad via: end of packet on state=%d\n",
  999. state);
  1000. goto error;
  1001. main_via:
  1002. /* inc tmp to point to the next char*/
  1003. tmp++;
  1004. c_nest=0;
  1005. /*state should always be F_HOST here*/;
  1006. for(;*tmp;tmp++){
  1007. switch(*tmp){
  1008. case ' ':
  1009. case '\t':
  1010. switch(state){
  1011. case F_HOST:/*eat the spaces*/
  1012. break;
  1013. case P_HOST:
  1014. *tmp=0;/*mark end of host*/
  1015. state=L_PORT;
  1016. break;
  1017. case L_PORT: /*eat the spaces*/
  1018. case F_PORT:
  1019. break;
  1020. case P_PORT:
  1021. *tmp=0; /*end of port */
  1022. state=L_PARAM;
  1023. break;
  1024. case L_PARAM: /* eat the space */
  1025. case F_PARAM:
  1026. break;
  1027. case P_PARAM:
  1028. /* *tmp=0;*/ /*!?end of param*/
  1029. state=L_PARAM;
  1030. break;
  1031. case L_VIA:
  1032. case F_VIA: /* eat the space */
  1033. break;
  1034. case F_COMMENT:
  1035. case P_COMMENT:
  1036. break;
  1037. case F_IP6HOST: /*eat the spaces*/
  1038. break;
  1039. case P_IP6HOST:
  1040. *tmp=0; /*mark end of host*/
  1041. state=L_PORT;
  1042. break;
  1043. case F_CRLF:
  1044. case F_LF:
  1045. case F_CR:
  1046. /*previous=crlf and now =' '*/
  1047. state=saved_state;
  1048. break;
  1049. default:
  1050. LOG(L_CRIT,"BUG: parse_via"
  1051. " on <%c>, state=%d\n",*tmp, state);
  1052. goto error;
  1053. }
  1054. break;
  1055. case '\n':
  1056. switch(state){
  1057. case F_HOST:/*eat the spaces*/
  1058. case L_PORT: /*eat the spaces*/
  1059. case F_PORT:
  1060. case L_PARAM: /* eat the space */
  1061. case F_PARAM:
  1062. case F_VIA: /* eat the space */
  1063. case L_VIA:
  1064. case F_COMMENT:
  1065. case P_COMMENT:
  1066. case F_IP6HOST:
  1067. case P_IP6HOST:
  1068. saved_state=state;
  1069. state=F_LF;
  1070. break;
  1071. case P_HOST:
  1072. *tmp=0;/*mark end of host*/
  1073. saved_state=L_PORT;
  1074. state=F_LF;
  1075. break;
  1076. case P_PORT:
  1077. *tmp=0; /*end of port */
  1078. saved_state=L_PARAM;
  1079. state=F_LF;
  1080. break;
  1081. case P_PARAM:
  1082. /* *tmp=0;*/ /*!?end of param*/
  1083. saved_state=L_PARAM;
  1084. state=F_LF;
  1085. break;
  1086. case F_CR:
  1087. state=F_CRLF;
  1088. break;
  1089. case F_CRLF:
  1090. case F_LF:
  1091. state=saved_state;
  1092. goto endofheader;
  1093. default:
  1094. LOG(L_CRIT,"BUG: parse_via"
  1095. " on <%c>\n",*tmp);
  1096. goto error;
  1097. }
  1098. break;
  1099. case '\r':
  1100. switch(state){
  1101. case F_HOST:/*eat the spaces*/
  1102. case L_PORT: /*eat the spaces*/
  1103. case F_PORT:
  1104. case L_PARAM: /* eat the space */
  1105. case F_PARAM:
  1106. case F_VIA: /* eat the space */
  1107. case L_VIA:
  1108. case F_COMMENT:
  1109. case P_COMMENT:
  1110. case F_IP6HOST:
  1111. case P_IP6HOST:
  1112. saved_state=state;
  1113. state=F_CR;
  1114. break;
  1115. case P_HOST:
  1116. *tmp=0;/*mark end of host*/
  1117. saved_state=L_PORT;
  1118. state=F_CR;
  1119. break;
  1120. case P_PORT:
  1121. *tmp=0; /*end of port */
  1122. saved_state=L_PARAM;
  1123. state=F_CR;
  1124. break;
  1125. case P_PARAM:
  1126. /* *tmp=0;*/ /*!?end of param*/
  1127. saved_state=L_PARAM;
  1128. state=F_CR;
  1129. break;
  1130. case F_CRLF:
  1131. case F_CR:
  1132. case F_LF:
  1133. state=saved_state;
  1134. goto endofheader;
  1135. default:
  1136. LOG(L_CRIT,"BUG: parse_via"
  1137. " on <%c>\n",*tmp);
  1138. goto error;
  1139. }
  1140. break;
  1141. case ':':
  1142. switch(state){
  1143. case F_HOST:
  1144. case F_IP6HOST:
  1145. LOG(L_ERR,"ERROR:parse_via:"
  1146. " no host found\n");
  1147. goto error;
  1148. case P_IP6HOST:
  1149. LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
  1150. goto error;
  1151. case P_HOST:
  1152. *tmp=0; /*mark end of host*/
  1153. state=F_PORT;
  1154. break;
  1155. case L_PORT:
  1156. state=F_PORT;
  1157. break;
  1158. case P_PORT:
  1159. LOG(L_ERR, "ERROR:parse_via:"
  1160. " bad port\n");
  1161. goto error;
  1162. case L_PARAM:
  1163. case F_PARAM:
  1164. case P_PARAM:
  1165. LOG(L_ERR, "ERROR:parse_via:"
  1166. " bad char <%c> in state %d\n",
  1167. *tmp,state);
  1168. goto error;
  1169. case L_VIA:
  1170. case F_VIA:
  1171. LOG(L_ERR, "ERROR:parse_via:"
  1172. " bad char in compact via\n");
  1173. goto error;
  1174. case F_CRLF:
  1175. case F_LF:
  1176. case F_CR:
  1177. /*previous=crlf and now !=' '*/
  1178. goto endofheader;
  1179. case F_COMMENT:/*everything is allowed in a comment*/
  1180. comment=tmp;
  1181. state=P_COMMENT;
  1182. break;
  1183. case P_COMMENT: /*everything is allowed in a comment*/
  1184. break;
  1185. default:
  1186. LOG(L_CRIT,"BUG: parse_via"
  1187. " on <%c> state %d\n",
  1188. *tmp, state);
  1189. goto error;
  1190. }
  1191. break;
  1192. case ';':
  1193. switch(state){
  1194. case F_HOST:
  1195. case F_IP6HOST:
  1196. LOG(L_ERR,"ERROR:parse_via:"
  1197. " no host found\n");
  1198. goto error;
  1199. case P_IP6HOST:
  1200. LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
  1201. goto error;
  1202. case P_HOST:
  1203. case P_PORT:
  1204. *tmp=0; /*mark the end*/
  1205. case L_PORT:
  1206. case L_PARAM:
  1207. state=F_PARAM;
  1208. break;
  1209. case F_PORT:
  1210. LOG(L_ERR, "ERROR:parse_via:"
  1211. " bad char <%c> in state %d\n",
  1212. *tmp,state);
  1213. goto error;
  1214. case F_PARAM:
  1215. LOG(L_ERR, "ERROR:parse_via:"
  1216. " null param?\n");
  1217. goto error;
  1218. case P_PARAM:
  1219. /*hmm next, param?*/
  1220. state=F_PARAM;
  1221. break;
  1222. case L_VIA:
  1223. case F_VIA:
  1224. LOG(L_ERR, "ERROR:parse_via:"
  1225. " bad char <%c> in next via\n",
  1226. *tmp);
  1227. goto error;
  1228. case F_CRLF:
  1229. case F_LF:
  1230. case F_CR:
  1231. /*previous=crlf and now !=' '*/
  1232. goto endofheader;
  1233. case F_COMMENT:/*everything is allowed in a comment*/
  1234. comment=tmp;
  1235. state=P_COMMENT;
  1236. break;
  1237. case P_COMMENT: /*everything is allowed in a comment*/
  1238. break;
  1239. default:
  1240. LOG(L_CRIT,"BUG: parse_via"
  1241. " on <%c> state %d\n",
  1242. *tmp, state);
  1243. goto error;
  1244. }
  1245. break;
  1246. case ',':
  1247. switch(state){
  1248. case F_HOST:
  1249. case F_IP6HOST:
  1250. LOG(L_ERR,"ERROR:parse_via:"
  1251. " no host found\n");
  1252. goto error;
  1253. case P_IP6HOST:
  1254. LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
  1255. goto error;
  1256. case P_HOST:
  1257. case P_PORT:
  1258. *tmp=0; /*mark the end*/
  1259. case L_PORT:
  1260. case L_PARAM:
  1261. case P_PARAM:
  1262. case L_VIA:
  1263. state=F_VIA;
  1264. break;
  1265. case F_PORT:
  1266. case F_PARAM:
  1267. LOG(L_ERR, "ERROR:parse_via:"
  1268. " invalid char <%c> in state"
  1269. " %d\n", *tmp,state);
  1270. goto error;
  1271. case F_VIA:
  1272. /* do nothing, eat ","*/
  1273. break;
  1274. case F_CRLF:
  1275. case F_LF:
  1276. case F_CR:
  1277. /*previous=crlf and now !=' '*/
  1278. goto endofheader;
  1279. case F_COMMENT:/*everything is allowed in a comment*/
  1280. comment=tmp;
  1281. state=P_COMMENT;
  1282. break;
  1283. case P_COMMENT: /*everything is allowed in a comment*/
  1284. break;
  1285. default:
  1286. LOG(L_CRIT,"BUG: parse_via"
  1287. " on <%c> state %d\n",
  1288. *tmp, state);
  1289. goto error;
  1290. }
  1291. break;
  1292. case '(':
  1293. switch(state){
  1294. case F_HOST:
  1295. case F_PORT:
  1296. case F_PARAM:
  1297. case F_VIA:
  1298. case F_IP6HOST:
  1299. case P_IP6HOST: /*must be terminated in ']'*/
  1300. LOG(_ERR,"ERROR:parse_via"
  1301. " on <%c> state %d\n",
  1302. *tmp, state);
  1303. goto error;
  1304. case P_HOST:
  1305. case P_PORT:
  1306. case P_PARAM:
  1307. *tmp=0; /*mark the end*/
  1308. case L_PORT:
  1309. case L_PARAM:
  1310. case L_VIA:
  1311. state=F_COMMENT;
  1312. c_nest++;
  1313. printf("found '(', state=%d, c_nest=%d\n",
  1314. state, c_nest);
  1315. *tmp=0;
  1316. break;
  1317. case P_COMMENT:
  1318. case F_COMMENT:
  1319. c_nest++;
  1320. break;
  1321. case F_CRLF:
  1322. case F_LF:
  1323. case F_CR:
  1324. /*previous=crlf and now !=' '*/
  1325. goto endofheader;
  1326. default:
  1327. LOG(L_CRIT,"BUG: parse_via"
  1328. " on <%c> state %d\n",
  1329. *tmp, state);
  1330. goto error;
  1331. }
  1332. break;
  1333. case ')':
  1334. switch(state){
  1335. case F_COMMENT:
  1336. case P_COMMENT:
  1337. if (c_nest){
  1338. c_nest--;
  1339. if(c_nest==0){
  1340. state=L_VIA;
  1341. *tmp=0;
  1342. printf("out of comment\n");
  1343. break;
  1344. }
  1345. }else{
  1346. LOG(L_ERR,"ERROR:"
  1347. "parse_via: "
  1348. "missing '(' - "
  1349. "nesting = %d\n",
  1350. c_nest);
  1351. goto error;
  1352. }
  1353. break;
  1354. case F_HOST:
  1355. case F_PORT:
  1356. case F_PARAM:
  1357. case F_VIA:
  1358. case P_HOST:
  1359. case P_PORT:
  1360. case P_PARAM:
  1361. case L_PORT:
  1362. case L_PARAM:
  1363. case L_VIA:
  1364. case F_IP6HOST:
  1365. case P_IP6HOST:
  1366. LOG(L_ERR,"ERROR:parse_via"
  1367. " on <%c> state %d\n",
  1368. *tmp, state);
  1369. goto error;
  1370. case F_CRLF:
  1371. case F_LF:
  1372. case F_CR:
  1373. /*previous=crlf and now !=' '*/
  1374. goto endofheader;
  1375. default:
  1376. LOG(L_CRIT,"BUG: parse_via"
  1377. " on <%c> state %d\n",
  1378. *tmp, state);
  1379. goto error;
  1380. }
  1381. break;
  1382. case '[':
  1383. switch(state){
  1384. case F_HOST:
  1385. state=F_IP6HOST;
  1386. break;
  1387. case F_COMMENT:/*everything is allowed in a comment*/
  1388. comment=tmp;
  1389. state=P_COMMENT;
  1390. break;
  1391. case P_COMMENT:
  1392. break;
  1393. case F_CRLF:
  1394. case F_LF:
  1395. case F_CR:
  1396. /*previous=crlf and now !=' '*/
  1397. goto endofheader;
  1398. default:
  1399. LOG(L_ERR,"ERROR:parse_via"
  1400. " on <%c> state %d\n",
  1401. *tmp, state);
  1402. goto error;
  1403. }
  1404. break;
  1405. case ']':
  1406. switch(state){
  1407. case P_IP6HOST:
  1408. *tmp=0; /*mark the end*/
  1409. state=L_PORT;
  1410. break;
  1411. case F_CRLF:
  1412. case F_LF:
  1413. case F_CR:
  1414. /*previous=crlf and now !=' '*/
  1415. goto endofheader;
  1416. case F_COMMENT:/*everything is allowed in a comment*/
  1417. comment=tmp;
  1418. state=P_COMMENT;
  1419. break;
  1420. case P_COMMENT:
  1421. break;
  1422. default:
  1423. LOG(L_ERR,"ERROR:parse_via"
  1424. " on <%c> state %d\n",
  1425. *tmp, state);
  1426. goto error;
  1427. }
  1428. break;
  1429. default:
  1430. switch(state){
  1431. case F_HOST:
  1432. state=P_HOST;
  1433. host=tmp;
  1434. break;
  1435. case P_HOST:
  1436. break;
  1437. case F_PORT:
  1438. state=P_PORT;
  1439. port_str=tmp;
  1440. break;
  1441. case P_PORT:
  1442. /*check if number?*/
  1443. break;
  1444. case F_PARAM:
  1445. /*state=P_PARAM*/;
  1446. param=tmp;
  1447. tmp=parse_via_param(tmp, &state, &saved_state);
  1448. switch(state){
  1449. case L_PARAM:
  1450. case F_PARAM:
  1451. case F_LF:
  1452. case F_CR:
  1453. break;
  1454. case END_OF_HEADER:
  1455. state=saved_state;
  1456. goto endofheader;
  1457. default:
  1458. LOG(L_ERR, "ERROR: parse_via after"
  1459. " parse_via_param: invalid"
  1460. " char <%c> on state %d\n",
  1461. *tmp, state);
  1462. goto error;
  1463. }
  1464. break;
  1465. case P_PARAM:
  1466. break;
  1467. case F_VIA:
  1468. next_via=tmp;
  1469. printf("found new via on <%c>\n", *tmp);
  1470. goto nextvia;
  1471. case L_PORT:
  1472. case L_PARAM:
  1473. case L_VIA:
  1474. LOG(L_ERR,"ERROR:parse_via"
  1475. " on <%c> state %d (default)\n",
  1476. *tmp, state);
  1477. goto error;
  1478. case F_COMMENT:
  1479. printf("starting comment parsing on %c \n",*tmp);
  1480. state=P_COMMENT;
  1481. comment=tmp;
  1482. break;
  1483. case P_COMMENT:
  1484. break;
  1485. case F_IP6HOST:
  1486. state=P_IP6HOST;
  1487. host=tmp;
  1488. break;
  1489. case P_IP6HOST:
  1490. break;
  1491. case F_CRLF:
  1492. case F_LF:
  1493. case F_CR:
  1494. /*previous=crlf and now !=' '*/
  1495. goto endofheader;
  1496. default:
  1497. LOG(L_ERR, "BUG:parse_via:"
  1498. " invalid char <%c>"
  1499. " in state %d\n",
  1500. *tmp, state);
  1501. goto error;
  1502. }
  1503. }
  1504. }
  1505. printf("end of packet reached, state=%d\n", state);
  1506. goto endofpacket; /*end of packet, probably should be goto error*/
  1507. endofheader:
  1508. state=saved_state;
  1509. printf("end of header reached, state=%d\n", state);
  1510. endofpacket:
  1511. /* check if error*/
  1512. switch(state){
  1513. case P_HOST:
  1514. case L_PORT:
  1515. case P_PORT:
  1516. case L_PARAM:
  1517. case P_PARAM:
  1518. case P_VALUE:
  1519. case GEN_PARAM:
  1520. case FIN_HIDDEN:
  1521. case L_VIA:
  1522. break;
  1523. default:
  1524. LOG(L_ERR, "ERROR: parse_via: invalid via - end of header in"
  1525. " state %d\n", state);
  1526. goto error;
  1527. }
  1528. nextvia:
  1529. if (proto) printf("<SIP/2.0/%s>\n", proto);
  1530. if (host) printf("host= <%s>\n", host);
  1531. if (port_str) printf("port= <%s>\n", port_str);
  1532. if (param) printf("params= <%s>\n", param);
  1533. if (comment) printf("comment= <%s>\n", comment);
  1534. if(next_via) printf("next_via= <%s>\n", next_via);
  1535. printf("rest=<%s>\n", tmp);
  1536. exit(0);
  1537. error:
  1538. fprintf(stderr, "via parse error\n");
  1539. exit(-1);
  1540. }