msg_translator.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. /*
  2. * $Id$
  3. *
  4. *
  5. * Copyright (C) 2001-2003 Fhg Fokus
  6. *
  7. * This file is part of ser, a free SIP server.
  8. *
  9. * ser is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version
  13. *
  14. * For a license to use the ser software under conditions
  15. * other than those described here, or to purchase support for this
  16. * software, please contact iptel.org by e-mail at the following addresses:
  17. * [email protected]
  18. *
  19. * ser is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27. */
  28. #include <sys/types.h>
  29. #include <sys/socket.h>
  30. #include <netdb.h>
  31. #include <string.h>
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include "msg_translator.h"
  35. #include "globals.h"
  36. #include "error.h"
  37. #include "mem/mem.h"
  38. #include "dprint.h"
  39. #include "config.h"
  40. #include "md5utils.h"
  41. #include "data_lump_rpl.h"
  42. #include "ip_addr.h"
  43. #include "resolve.h"
  44. #include "ut.h"
  45. #include "pt.h"
  46. #define append_str(_dest,_src,_len,_msg) \
  47. do{\
  48. memcpy( (_dest) , (_src) , (_len) );\
  49. (_dest) += (_len) ;\
  50. }while(0);
  51. #define append_str_trans(_dest,_src,_len,_msg) \
  52. do{\
  53. memcpy( (_dest) , (_msg)->orig+((_src)-(_msg)->buf) , (_len) );\
  54. (_dest) += (_len) ;\
  55. }while(0);
  56. extern char version[];
  57. extern int version_len;
  58. /* checks if ip is in host(name) and ?host(ip)=name?
  59. * ip must be in network byte order!
  60. * resolver = DO_DNS | DO_REV_DNS; if 0 no dns check is made
  61. * return 0 if equal */
  62. int check_address(struct ip_addr* ip, char *name, int resolver)
  63. {
  64. struct hostent* he;
  65. int i;
  66. char* s;
  67. /* maybe we are lucky and name it's an ip */
  68. s=ip_addr2a(ip);
  69. if (s){
  70. DBG("check_address(%s, %s, %d)\n", s, name, resolver);
  71. #ifdef USE_IPV6
  72. if ((ip->af==AF_INET6) && (strcasecmp(name, s)==0))
  73. return 0;
  74. else
  75. #endif
  76. if (strcmp(name, s)==0)
  77. return 0;
  78. }else{
  79. LOG(L_CRIT, "check_address: BUG: could not convert ip address\n");
  80. return -1;
  81. }
  82. if (resolver&DO_DNS){
  83. DBG("check_address: doing dns lookup\n");
  84. /* try all names ips */
  85. he=resolvehost(name);
  86. if (he && ip->af==he->h_addrtype){
  87. for(i=0;he && he->h_addr_list[i];i++){
  88. if ( memcmp(&he->h_addr_list[i], ip->u.addr, ip->len)==0)
  89. return 0;
  90. }
  91. }
  92. }
  93. if (resolver&DO_REV_DNS){
  94. DBG("check_address: doing rev. dns lookup\n");
  95. /* try reverse dns */
  96. he=rev_resolvehost(ip);
  97. if (he && (strcmp(he->h_name, name)==0))
  98. return 0;
  99. for (i=0; he && he->h_aliases[i];i++){
  100. if (strcmp(he->h_aliases[i],name)==0)
  101. return 0;
  102. }
  103. }
  104. return -1;
  105. }
  106. char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
  107. {
  108. static char buf[MAX_WARNING_LEN];
  109. static unsigned int fix_len=0;
  110. str *foo;
  111. int print_len;
  112. if (!fix_len)
  113. {
  114. memcpy(buf+fix_len,"Warning: 392 ",13);
  115. fix_len +=13;
  116. memcpy(buf+fix_len, bind_address->name.s,bind_address->name.len);
  117. fix_len += bind_address->name.len;
  118. //*(buf+fix_len++) = ':';
  119. memcpy(buf+fix_len,bind_address->port_no_str.s,
  120. bind_address->port_no_str.len);
  121. fix_len += bind_address->port_no_str.len;
  122. memcpy(buf+fix_len, " \"Noisy feedback tells: ",24);
  123. fix_len += 24;
  124. }
  125. /*adding out_uri*/
  126. if (msg->new_uri.s)
  127. foo=&(msg->new_uri);
  128. else
  129. foo=&(msg->first_line.u.request.uri);
  130. print_len=snprintf(buf+fix_len, MAX_WARNING_LEN-fix_len,
  131. "pid=%d req_src_ip=%s in_uri=%.*s out_uri=%.*s via_cnt%c=%d\"",
  132. my_pid(),
  133. ip_addr2a(&msg->rcv.src_ip),
  134. msg->first_line.u.request.uri.len, msg->first_line.u.request.uri.s,
  135. foo->len, foo->s,
  136. msg->parsed_flag & HDR_EOH ? '=' : '>', /* should be = */
  137. via_cnt );
  138. if (print_len==-1) {
  139. *returned_len=0;
  140. return 0;
  141. } else {
  142. *returned_len=fix_len+print_len;
  143. return buf;
  144. }
  145. }
  146. char* received_builder(struct sip_msg *msg, unsigned int *received_len)
  147. {
  148. char *buf;
  149. int len;
  150. struct ip_addr *source_ip;
  151. char *tmp;
  152. int tmp_len;
  153. int extra_len;
  154. extra_len = 0;
  155. source_ip=&msg->rcv.src_ip;
  156. buf = 0;
  157. buf=pkg_malloc(sizeof(char)*MAX_RECEIVED_SIZE);
  158. if (buf==0){
  159. ser_error=E_OUT_OF_MEM;
  160. LOG(L_ERR, "ERROR: received_builder: out of memory\n");
  161. return 0;
  162. }
  163. /*
  164. received_len=snprintf(buf, MAX_RECEIVED_SIZE,
  165. ";received=%s",
  166. inet_ntoa(*(struct in_addr *)&source_ip));
  167. */
  168. memcpy(buf, RECEIVED, RECEIVED_LEN);
  169. if ( (tmp=ip_addr2a(source_ip))==0)
  170. return 0; /* error*/
  171. tmp_len=strlen(tmp);
  172. len=RECEIVED_LEN+tmp_len;
  173. if(source_ip->af==AF_INET6){
  174. len+=2;
  175. buf[RECEIVED_LEN]='[';
  176. buf[RECEIVED_LEN+tmp_len+1]=']';
  177. extra_len=1;
  178. }
  179. memcpy(buf+RECEIVED_LEN+extra_len, tmp, tmp_len);
  180. buf[len]=0; /*null terminate it */
  181. *received_len = len;
  182. return buf;
  183. }
  184. /* computes the "unpacked" len of a lump list,
  185. code moved from build_req_from_req */
  186. static inline int lumps_len(struct lump* l)
  187. {
  188. int s_offset;
  189. int new_len;
  190. struct lump* t;
  191. struct lump* r;
  192. s_offset=0;
  193. new_len=0;
  194. for(t=l;t;t=t->next){
  195. for(r=t->before;r;r=r->before){
  196. switch(r->op){
  197. case LUMP_ADD:
  198. new_len+=r->len;
  199. break;
  200. default:
  201. /* only ADD allowed for before/after */
  202. LOG(L_CRIT, "BUG: lumps_len: invalid op "
  203. "for data lump (%x)\n", r->op);
  204. }
  205. }
  206. switch(t->op){
  207. case LUMP_ADD:
  208. new_len+=t->len;
  209. break;
  210. case LUMP_DEL:
  211. /* fix overlapping deleted zones */
  212. if (t->u.offset < s_offset){
  213. /* change len */
  214. if (t->len>s_offset-t->u.offset)
  215. t->len-=s_offset-t->u.offset;
  216. else t->len=0;
  217. t->u.offset=s_offset;
  218. }
  219. s_offset=t->u.offset+t->len;
  220. new_len-=t->len;
  221. break;
  222. case LUMP_NOP:
  223. /* fix offset if overlapping on a deleted zone */
  224. if (t->u.offset < s_offset){
  225. t->u.offset=s_offset;
  226. }else
  227. s_offset=t->u.offset;
  228. /* do nothing */
  229. break;
  230. default:
  231. LOG(L_CRIT,"BUG:lumps_len: invalid"
  232. " op for data lump (%x)\n", r->op);
  233. }
  234. for (r=t->after;r;r=r->after){
  235. switch(r->op){
  236. case LUMP_ADD:
  237. new_len+=r->len;
  238. break;
  239. default:
  240. /* only ADD allowed for before/after */
  241. LOG(L_CRIT, "BUG:lumps_len: invalid"
  242. " op for data lump (%x)\n", r->op);
  243. }
  244. }
  245. }
  246. return new_len;
  247. }
  248. /* another helper functions, adds/Removes the lump,
  249. code moved form build_req_from_req */
  250. static inline void process_lumps( struct lump* l, char* new_buf,
  251. unsigned int* new_buf_offs, char* orig,
  252. unsigned int* orig_offs)
  253. {
  254. struct lump *t;
  255. struct lump *r;
  256. int size;
  257. int offset;
  258. int s_offset;
  259. offset=*new_buf_offs;
  260. s_offset=*orig_offs;
  261. for (t=l;t;t=t->next){
  262. switch(t->op){
  263. case LUMP_ADD:
  264. /* just add it here! */
  265. /* process before */
  266. for(r=t->before;r;r=r->before){
  267. switch (r->op){
  268. case LUMP_ADD:
  269. /*just add it here*/
  270. memcpy(new_buf+offset, r->u.value, r->len);
  271. offset+=r->len;
  272. break;
  273. default:
  274. /* only ADD allowed for before/after */
  275. LOG(L_CRIT, "BUG:process_lumps: "
  276. "invalid op for data lump (%x)\n", r->op);
  277. }
  278. }
  279. /* copy "main" part */
  280. memcpy(new_buf+offset, t->u.value, t->len);
  281. offset+=t->len;
  282. /* process after */
  283. for(r=t->after;r;r=r->after){
  284. switch (r->op){
  285. case LUMP_ADD:
  286. /*just add it here*/
  287. memcpy(new_buf+offset, r->u.value, r->len);
  288. offset+=r->len;
  289. break;
  290. default:
  291. /* only ADD allowed for before/after */
  292. LOG(L_CRIT, "BUG:process_lumps: "
  293. "invalid op for data lump (%x)\n", r->op);
  294. }
  295. }
  296. break;
  297. case LUMP_NOP:
  298. case LUMP_DEL:
  299. /* copy till offset */
  300. if (s_offset>t->u.offset){
  301. DBG("Warning: (%d) overlapped lumps offsets,"
  302. " ignoring(%x, %x)\n", t->op, s_offset,t->u.offset);
  303. /* this should've been fixed above (when computing len) */
  304. /* just ignore it*/
  305. break;
  306. }
  307. size=t->u.offset-s_offset;
  308. if (size){
  309. memcpy(new_buf+offset, orig+s_offset,size);
  310. offset+=size;
  311. s_offset+=size;
  312. }
  313. /* process before */
  314. for(r=t->before;r;r=r->before){
  315. switch (r->op){
  316. case LUMP_ADD:
  317. /*just add it here*/
  318. memcpy(new_buf+offset, r->u.value, r->len);
  319. offset+=r->len;
  320. break;
  321. default:
  322. /* only ADD allowed for before/after */
  323. LOG(L_CRIT, "BUG:process_lumps: "
  324. "invalid op for data lump (%x)\n",r->op);
  325. }
  326. }
  327. /* process main (del only) */
  328. if (t->op==LUMP_DEL){
  329. /* skip len bytes from orig msg */
  330. s_offset+=t->len;
  331. }
  332. /* process after */
  333. for(r=t->after;r;r=r->after){
  334. switch (r->op){
  335. case LUMP_ADD:
  336. /*just add it here*/
  337. memcpy(new_buf+offset, r->u.value, r->len);
  338. offset+=r->len;
  339. break;
  340. default:
  341. /* only ADD allowed for before/after */
  342. LOG(L_CRIT, "BUG:process_lumps: "
  343. "invalid op for data lump (%x)\n", r->op);
  344. }
  345. }
  346. break;
  347. default:
  348. LOG(L_CRIT, "BUG: process_lumps: "
  349. "unknown op (%x)\n", t->op);
  350. }
  351. }
  352. *new_buf_offs=offset;
  353. *orig_offs=s_offset;
  354. }
  355. char * build_req_buf_from_sip_req( struct sip_msg* msg,
  356. unsigned int *returned_len,
  357. struct socket_info* send_sock, int proto)
  358. {
  359. unsigned int len, new_len, received_len, uri_len, via_len;
  360. char* line_buf;
  361. char* received_buf;
  362. char* new_buf;
  363. char* orig;
  364. char* buf;
  365. char backup;
  366. unsigned int offset, s_offset, size;
  367. struct lump* anchor;
  368. int r;
  369. uri_len=0;
  370. orig=msg->orig;
  371. buf=msg->buf;
  372. len=msg->len;
  373. received_len=0;
  374. new_buf=0;
  375. received_buf=0;
  376. line_buf = via_builder( &via_len, send_sock,
  377. msg->add_to_branch_s, msg->add_to_branch_len, proto);
  378. if (!line_buf){
  379. LOG(L_ERR,"ERROR: build_req_buf_from_sip_req: no via received!\n");
  380. goto error00;
  381. }
  382. /* check if received needs to be added */
  383. backup = msg->via1->host.s[msg->via1->host.len];
  384. msg->via1->host.s[msg->via1->host.len] = 0;
  385. r=check_address(&msg->rcv.src_ip, msg->via1->host.s, received_dns);
  386. msg->via1->host.s[msg->via1->host.len] = backup;
  387. if (r!=0){
  388. if ((received_buf=received_builder(msg,&received_len))==0)
  389. goto error01; /* free also line_buf */
  390. }
  391. /* add via header to the list */
  392. /* try to add it before msg. 1st via */
  393. /* add first via, as an anchor for second via*/
  394. anchor=anchor_lump(&(msg->add_rm), msg->via1->hdr.s-buf, 0, HDR_VIA);
  395. if (anchor==0) goto error01;
  396. if (insert_new_lump_before(anchor, line_buf, via_len, HDR_VIA)==0)
  397. goto error01;
  398. /* if received needs to be added, add anchor after host and add it */
  399. if (received_len){
  400. if (msg->via1->params.s){
  401. size= msg->via1->params.s-msg->via1->hdr.s-1; /*compensate
  402. for ';' */
  403. }else{
  404. size= msg->via1->host.s-msg->via1->hdr.s+msg->via1->host.len;
  405. if (msg->via1->port!=0){
  406. /*size+=strlen(msg->via1->hdr.s+size+1)+1;*/
  407. size += msg->via1->port_str.len + 1; /* +1 for ':'*/
  408. }
  409. #ifdef USE_IPV6
  410. if(send_sock->address.af==AF_INET6) size+=1; /* +1 for ']'*/
  411. #endif
  412. }
  413. anchor=anchor_lump(&(msg->add_rm),msg->via1->hdr.s-buf+size,0,
  414. HDR_VIA);
  415. if (anchor==0) goto error02; /* free also line_buf */
  416. if (insert_new_lump_after(anchor, received_buf, received_len, HDR_VIA)
  417. ==0 ) goto error02; /* free also line_buf */
  418. }
  419. /* compute new msg len and fix overlapping zones*/
  420. new_len=len+lumps_len(msg->add_rm);
  421. if (msg->new_uri.s){
  422. uri_len=msg->new_uri.len;
  423. new_len=new_len-msg->first_line.u.request.uri.len+uri_len;
  424. }
  425. new_buf=(char*)pkg_malloc(new_len+1);
  426. if (new_buf==0){
  427. ser_error=E_OUT_OF_MEM;
  428. LOG(L_ERR, "ERROR: build_req_buf_from_sip_req: out of memory\n");
  429. goto error00;
  430. }
  431. offset=s_offset=0;
  432. if (msg->new_uri.s){
  433. /* copy message up to uri */
  434. size=msg->first_line.u.request.uri.s-buf;
  435. memcpy(new_buf, orig, size);
  436. offset+=size;
  437. s_offset+=size;
  438. /* add our uri */
  439. memcpy(new_buf+offset, msg->new_uri.s, uri_len);
  440. offset+=uri_len;
  441. s_offset+=msg->first_line.u.request.uri.len; /* skip original uri */
  442. }
  443. new_buf[new_len]=0;
  444. /* copy msg adding/removing lumps */
  445. process_lumps(msg->add_rm, new_buf, &offset, orig, &s_offset);
  446. /* copy the rest of the message */
  447. memcpy(new_buf+offset, orig+s_offset, len-s_offset);
  448. new_buf[new_len]=0;
  449. #ifdef DBG_MSG_QA
  450. if (new_buf[new_len-1]==0) {
  451. LOG(L_ERR, "ERROR: build_req_buf_from_sip_req: 0 in the end\n");
  452. abort();
  453. }
  454. #endif
  455. *returned_len=new_len;
  456. return new_buf;
  457. error01:
  458. pkg_free(line_buf);
  459. error02:
  460. if (received_buf) pkg_free(received_buf);
  461. error00:
  462. *returned_len=0;
  463. return 0;
  464. }
  465. char * build_res_buf_from_sip_res( struct sip_msg* msg,
  466. unsigned int *returned_len)
  467. {
  468. unsigned int new_len, via_len;
  469. char* new_buf;
  470. unsigned offset, s_offset, via_offset;
  471. char* orig;
  472. char* buf;
  473. unsigned int len;
  474. orig=msg->orig;
  475. buf=msg->buf;
  476. len=msg->len;
  477. new_buf=0;
  478. /* we must remove the first via */
  479. via_len=msg->via1->bsize;
  480. via_offset=msg->via1->hdr.s-buf;
  481. DBG("via len: %d, initial via offset: %d\n", via_len, via_offset);
  482. if (msg->via1->next){
  483. /* add hdr size*/
  484. via_offset+=msg->via1->hdr.len+1;
  485. DBG(" adjusted via len: %d, initial offset: %d\n",
  486. via_len, via_offset);
  487. }else{
  488. /* add hdr size ("Via:")*/
  489. via_len+=msg->via1->hdr.len+1;
  490. }
  491. /* remove the first via*/
  492. if (del_lump( &(msg->repl_add_rm), via_offset, via_len, HDR_VIA)==0){
  493. LOG(L_ERR, "build_res_buf_from_sip_res: error trying to remove first"
  494. "via\n");
  495. goto error;
  496. }
  497. new_len=len+lumps_len(msg->repl_add_rm);
  498. DBG(" old size: %d, new size: %d\n", len, new_len);
  499. new_buf=(char*)pkg_malloc(new_len+1); /* +1 is for debugging
  500. (\0 to print it )*/
  501. if (new_buf==0){
  502. LOG(L_ERR, "ERROR: build_res_buf_from_sip_res: out of mem\n");
  503. goto error;
  504. }
  505. new_buf[new_len]=0; /* debug: print the message */
  506. offset=s_offset=0;
  507. process_lumps(msg->repl_add_rm, new_buf, &offset, orig, &s_offset);
  508. /* copy the rest of the message */
  509. memcpy(new_buf+offset,orig+s_offset, len-s_offset);
  510. /* send it! */
  511. DBG(" copied size: orig:%d, new: %d, rest: %d\n",
  512. s_offset, offset,
  513. len-s_offset );
  514. *returned_len=new_len;
  515. return new_buf;
  516. error:
  517. *returned_len=0;
  518. return 0;
  519. }
  520. char * build_res_buf_from_sip_req( unsigned int code, char *text,
  521. char *new_tag, unsigned int new_tag_len,
  522. struct sip_msg* msg, unsigned int *returned_len)
  523. {
  524. char *buf, *p;
  525. unsigned int len,foo;
  526. struct hdr_field *hdr;
  527. struct lump_rpl *lump;
  528. int i;
  529. char backup;
  530. char *received_buf;
  531. unsigned int received_len;
  532. char *warning;
  533. unsigned int warning_len;
  534. int r;
  535. str to_tag;
  536. received_buf=0;
  537. received_len=0;
  538. buf=0;
  539. /* make -Wall happy */
  540. warning=0;
  541. /* force parsing all headers -- we want to return all
  542. Via's in the reply and they may be scattered down to the
  543. end of header (non-block Vias are a really poor property
  544. of SIP :( ) */
  545. if (parse_headers( msg, HDR_EOH, 0 )==-1) {
  546. LOG(L_ERR, "ERROR: build_res_buf_from_sip_req: "
  547. "alas, parse_headers failed\n");
  548. goto error00;
  549. }
  550. /* check if received needs to be added */
  551. backup = msg->via1->host.s[msg->via1->host.len];
  552. msg->via1->host.s[msg->via1->host.len] = 0;
  553. r=check_address(&msg->rcv.src_ip, msg->via1->host.s, received_dns);
  554. msg->via1->host.s[msg->via1->host.len] = backup;
  555. if (r!=0) {
  556. if ((received_buf=received_builder(msg,&received_len))==0) {
  557. LOG(L_ERR, "ERROR: build_res_buf_from_sip_req: "
  558. "alas, received_builder failed\n");
  559. goto error00;
  560. }
  561. }
  562. /*computes the lenght of the new response buffer*/
  563. len = 0;
  564. /* first line */
  565. len += SIP_VERSION_LEN + 1/*space*/ + 3/*code*/ + 1/*space*/ +
  566. strlen(text) + CRLF_LEN/*new line*/;
  567. /*headers that will be copied (TO, FROM, CSEQ,CALLID,VIA)*/
  568. for ( hdr=msg->headers ; hdr ; hdr=hdr->next ) {
  569. if (hdr->type==HDR_TO) {
  570. if (new_tag)
  571. {
  572. to_tag=get_to(msg)->tag_value;
  573. if (to_tag.s )
  574. len+=new_tag_len-to_tag.len;
  575. else
  576. len+=new_tag_len+TOTAG_TOKEN_LEN/*";tag="*/;
  577. }
  578. } else if (hdr->type==HDR_VIA) {
  579. if (hdr==msg->h_via1) len += received_len;
  580. } else if (hdr->type==HDR_RECORDROUTE) {
  581. /* RR only for 1xx and 2xx replies */
  582. if (code<180 || code>=300) continue;
  583. } else if (!(hdr->type==HDR_FROM
  584. || hdr->type==HDR_CALLID
  585. || hdr->type==HDR_CSEQ)) {
  586. continue;
  587. }
  588. len += ((hdr->body.s+hdr->body.len )-hdr->name.s )+CRLF_LEN;
  589. }
  590. /*lumps length*/
  591. for(lump=msg->reply_lump;lump;lump=lump->next)
  592. len += lump->text.len;
  593. if (server_signature) {
  594. /*server header*/
  595. len += SERVER_HDR_LEN + CRLF_LEN;
  596. /*content length header*/
  597. len +=CONTENT_LENGTH_LEN+1 + CRLF_LEN;
  598. }
  599. if (sip_warning) {
  600. warning = warning_builder(msg,&warning_len);
  601. if (warning==0) {
  602. LOG(L_ERR, "ERROR: warning too big\n");
  603. goto error01;
  604. }
  605. len += warning_len + CRLF_LEN;
  606. }
  607. /* end of message */
  608. len += CRLF_LEN; /*new line*/
  609. /*allocating mem*/
  610. buf = (char*) pkg_malloc( len+1 );
  611. if (!buf)
  612. {
  613. LOG(L_ERR, "ERROR: build_res_buf_from_sip_req: out of memory "
  614. " ; needs %d\n",len);
  615. goto error01;
  616. }
  617. /* filling the buffer*/
  618. p=buf;
  619. /* first line */
  620. memcpy( p , SIP_VERSION , SIP_VERSION_LEN );
  621. p += SIP_VERSION_LEN;
  622. *(p++) = ' ' ;
  623. /*code*/
  624. for ( i=2 , foo = code ; i>=0 ; i-- , foo=foo/10 )
  625. *(p+i) = '0' + foo - ( foo/10 )*10;
  626. p += 3;
  627. *(p++) = ' ' ;
  628. memcpy( p , text , strlen(text) );
  629. p += strlen(text);
  630. memcpy( p, CRLF, CRLF_LEN );
  631. p+=CRLF_LEN;
  632. /* headers*/
  633. for ( hdr=msg->headers ; hdr ; hdr=hdr->next )
  634. switch (hdr->type)
  635. {
  636. case HDR_TO:
  637. if (new_tag){
  638. if (to_tag.s ) {
  639. append_str_trans( p, hdr->name.s ,
  640. to_tag.s-hdr->name.s,msg);
  641. append_str( p, new_tag,new_tag_len,msg);
  642. append_str_trans( p,to_tag.s+to_tag.len,
  643. ((hdr->body.s+hdr->body.len )-
  644. (to_tag.s+to_tag.len)),msg);
  645. append_str( p, CRLF,CRLF_LEN,msg);
  646. }else{
  647. append_str_trans( p, hdr->name.s ,
  648. ((hdr->body.s+hdr->body.len )-hdr->name.s ),
  649. msg);
  650. append_str( p, TOTAG_TOKEN,TOTAG_TOKEN_LEN,msg);
  651. append_str( p, new_tag,new_tag_len,msg);
  652. append_str( p, CRLF,CRLF_LEN,msg);
  653. }
  654. break;
  655. }
  656. case HDR_VIA:
  657. append_str_trans( p, hdr->name.s ,
  658. ((hdr->body.s+hdr->body.len )-hdr->name.s ),msg);
  659. if (hdr==msg->h_via1 && received_buf)
  660. append_str( p, received_buf, received_len, msg);
  661. append_str( p, CRLF,CRLF_LEN,msg);
  662. break;
  663. case HDR_RECORDROUTE:
  664. /* RR only for 1xx and 2xx replies */
  665. if (code<180 || code>=300) break;
  666. case HDR_FROM:
  667. case HDR_CALLID:
  668. case HDR_CSEQ:
  669. append_str_trans( p, hdr->name.s ,
  670. ((hdr->body.s+hdr->body.len )-hdr->name.s ),msg);
  671. append_str( p, CRLF,CRLF_LEN,msg);
  672. } /* for switch */
  673. /*lumps*/
  674. for(lump=msg->reply_lump;lump;lump=lump->next)
  675. {
  676. memcpy(p,lump->text.s,lump->text.len);
  677. p += lump->text.len;
  678. }
  679. if (server_signature) {
  680. /*server header*/
  681. memcpy( p, SERVER_HDR , SERVER_HDR_LEN );
  682. p+=SERVER_HDR_LEN;
  683. memcpy( p, CRLF, CRLF_LEN );
  684. p+=CRLF_LEN;
  685. /* content length header*/
  686. memcpy( p, CONTENT_LENGTH "0" , CONTENT_LENGTH_LEN+1 );
  687. p+=CONTENT_LENGTH_LEN+1;
  688. memcpy( p, CRLF, CRLF_LEN );
  689. p+=CRLF_LEN;
  690. }
  691. if (sip_warning) {
  692. memcpy( p, warning, warning_len);
  693. p+=warning_len;
  694. memcpy( p, CRLF, CRLF_LEN);
  695. p+=CRLF_LEN;
  696. }
  697. /*end of message*/
  698. memcpy( p, CRLF, CRLF_LEN );
  699. p+=CRLF_LEN;
  700. *(p) = 0;
  701. *returned_len = len;
  702. /* in req2reply, received_buf is not introduced to lumps and
  703. needs to be deleted here
  704. */
  705. if (received_buf) pkg_free(received_buf);
  706. return buf;
  707. error01:
  708. if (received_buf) pkg_free(received_buf);
  709. error00:
  710. *returned_len=0;
  711. return 0;
  712. }
  713. /* return number of chars printed or 0 if space exceeded;
  714. assumes buffer sace of at least MAX_BRANCH_PARAM_LEN
  715. */
  716. int branch_builder( unsigned int hash_index,
  717. /* only either parameter useful */
  718. unsigned int label, char * char_v,
  719. int branch,
  720. char *branch_str, int *len )
  721. {
  722. char *begin;
  723. int size;
  724. #ifdef _OBSOLETED
  725. /* no hash_id --- whoever called me wants to have
  726. very simple branch_id
  727. */
  728. if (hash_index==0) {
  729. *branch_str='0';
  730. *len=1;
  731. return *len;
  732. }
  733. #endif
  734. /* hash id provided ... start with it */
  735. size=MAX_BRANCH_PARAM_LEN;
  736. begin=branch_str;
  737. *len=0;
  738. memcpy(begin, MCOOKIE, MCOOKIE_LEN );
  739. size-=MCOOKIE_LEN;begin+=MCOOKIE_LEN;
  740. if (int2reverse_hex( &begin, &size, hash_index)==-1)
  741. return 0;
  742. if (size) {
  743. *begin=BRANCH_SEPARATOR;
  744. begin++; size--;
  745. } else return 0;
  746. /* string with request's characteristic value ... use it ... */
  747. if (char_v) {
  748. if (memcpy(begin,char_v,MD5_LEN)) {
  749. begin+=MD5_LEN; size-=MD5_LEN;
  750. } else return 0;
  751. } else { /* ... use the "label" value otherwise */
  752. if (int2reverse_hex( &begin, &size, label )==-1)
  753. return 0;
  754. }
  755. if (size) {
  756. *begin=BRANCH_SEPARATOR;
  757. begin++; size--;
  758. } else return 0;
  759. if (int2reverse_hex( &begin, &size, branch)==-1)
  760. return 0;
  761. *len=MAX_BRANCH_PARAM_LEN-size;
  762. return size;
  763. }
  764. char* via_builder( unsigned int *len,
  765. struct socket_info* send_sock,
  766. char *branch, int branch_len, int proto )
  767. {
  768. unsigned int via_len, extra_len;
  769. char *line_buf;
  770. int max_len;
  771. max_len=MY_VIA_LEN+send_sock->address_str.len /* space in MY_VIA */
  772. +2 /* just in case it it a v6 address ... [ ] */
  773. +send_sock->port_no_str.len
  774. +MY_BRANCH_LEN+branch_len+CRLF_LEN+1;
  775. line_buf=pkg_malloc( max_len );
  776. if (line_buf==0){
  777. ser_error=E_OUT_OF_MEM;
  778. LOG(L_ERR, "ERROR: via_builder: out of memory\n");
  779. return 0;
  780. }
  781. extra_len=0;
  782. via_len=MY_VIA_LEN+send_sock->address_str.len; /*space included in MY_VIA*/
  783. memcpy(line_buf, MY_VIA, MY_VIA_LEN-4); /* without "UPD " */
  784. if (proto==PROTO_UDP)
  785. memcpy(line_buf+MY_VIA_LEN-4, "UDP ", 4);
  786. else if (proto==PROTO_TCP)
  787. memcpy(line_buf+MY_VIA_LEN-4, "TCP ", 4);
  788. else{
  789. LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", proto);
  790. return 0;
  791. }
  792. # ifdef USE_IPV6
  793. if (send_sock->address.af==AF_INET6) {
  794. line_buf[MY_VIA_LEN]='[';
  795. line_buf[MY_VIA_LEN+1+send_sock->address_str.len]=']';
  796. extra_len=1;
  797. via_len+=2; /* [ ]*/
  798. }
  799. # endif
  800. memcpy(line_buf+MY_VIA_LEN+extra_len, send_sock->address_str.s,
  801. send_sock->address_str.len);
  802. if (send_sock->port_no!=SIP_PORT){
  803. memcpy(line_buf+via_len, send_sock->port_no_str.s,
  804. send_sock->port_no_str.len);
  805. via_len+=send_sock->port_no_str.len;
  806. }
  807. /* branch parameter */
  808. memcpy(line_buf+via_len, MY_BRANCH, MY_BRANCH_LEN );
  809. via_len+=MY_BRANCH_LEN;
  810. memcpy(line_buf+via_len, branch, branch_len );
  811. via_len+=branch_len;
  812. memcpy(line_buf+via_len, CRLF, CRLF_LEN);
  813. via_len+=CRLF_LEN;
  814. line_buf[via_len]=0; /* null terminate the string*/
  815. *len = via_len;
  816. return line_buf;
  817. }