00001
00041 #include "sip_tool.h"
00042
00043
00045
00046
00052 void set_sip_contents(tList* lp, Buffer sdp)
00053 {
00054 char num[LEN_INT];
00055
00056 set_protocol_contents(lp, sdp);
00057
00058
00059 snprintf(num, LEN_INT, "%d", sdp.vldsz);
00060 num[LEN_INT-1] = '\0';
00061 set_protocol_header(lp, (char*)"Content-Length", num, 1, ON);
00062
00063 return;
00064 }
00065
00066
00067
00069
00070
00071
00072
00074
00075
00083 Buffer get_sip_via_address(tList* lp, int no)
00084 {
00085 char* pp;
00086 Buffer buf = init_Buffer();
00087
00088 if (lp==NULL) return buf;
00089 if (no<=0) no = 1;
00090
00091 buf = search_protocol_header_item(lp, (char*)"Via", no, ' ', 2);
00092 if (buf.buf!=NULL) {
00093
00094 Buffer wrk = dup_Buffer(buf);
00095 pp = strstrcase((char*)wrk.buf, "received=");
00096 if (pp!=NULL) {
00097 char* pa = pp = pp + 9;
00098 while (*pp!=';' && *pp!='\0') pp++;
00099 if (*pp==';') *pp = '\0';
00100
00101 pp = strstrcase((char*)buf.buf, "rport=");
00102 if (pp!=NULL) {
00103 char* pt = pp = pp + 6;
00104 while (*pp!=';' && *pp!='\0') pp++;
00105 if (*pp==';') *pp = '\0';
00106
00107 Buffer hostport = comp_hostport(pa, (unsigned short)atoi(pt));
00108 free_Buffer(&buf);
00109 free_Buffer(&wrk);
00110 return hostport;
00111 }
00112 }
00113 free_Buffer(&wrk);
00114
00115
00116 pp = (char*)buf.buf;
00117 while (*pp!=';' && *pp!='\0') pp++;
00118 if (*pp==';') *pp = '\0';
00119 }
00120
00121 return buf;
00122 }
00123
00124
00130 void insert_sip_via(tList* lp, char* host, unsigned short port, char* branch, int add_mode)
00131 {
00132 char sipver[] = "SIP/2.0/UDP ";
00133 char hostport[LBUF];
00134 Buffer buf;
00135 tList* pm;
00136
00137 if (lp==NULL || host==NULL) return;
00138
00139 pm = strncasecmp_tList(lp, (char*)"Via", 0, 1);
00140 if (pm==NULL) {
00141 if (add_mode) pm = strncmp_tList(lp, (char*)HDLIST_FIRST_LINE_KEY, 0, 1);
00142 if (pm==NULL) return;
00143 }
00144 else if (pm->prev!=NULL) pm = pm->prev;
00145 else return;
00146
00147 buf = make_Buffer(LBUF);
00148 if (port!=0) snprintf(hostport, LBUF, "%s:%d", host, port);
00149 else snprintf(hostport, LBUF, "%s", host);
00150 hostport[LBUF-1] = '\0';
00151
00152 copy_s2Buffer(sipver, &buf);
00153 cat_s2Buffer (hostport, &buf);
00154 if (branch!=NULL) {
00155 cat_s2Buffer(";branch=z9hG4bK", &buf);
00156 cat_s2Buffer(branch, &buf);
00157 }
00158
00159 add_tList_node_str(pm, "Via", (char*)buf.buf);
00160 free_Buffer(&buf);
00161
00162 return;
00163 }
00164
00165
00171 void del_sip_via(tList* lp, char* host, unsigned short port)
00172 {
00173 char hostport[LBUF];
00174
00175 if (lp==NULL || host==NULL) return;
00176
00177 if (port!=0) snprintf(hostport, LBUF, "%s:%d", host, port);
00178 else snprintf(hostport, LBUF, "%s", host);
00179 hostport[LBUF-1] = '\0';
00180
00181 while (lp!=NULL) {
00182 if (lp->ldat.key.buf!=NULL && !strcasecmp((char*)lp->ldat.key.buf, "Via")) {
00183 Buffer via_hostport = cawk_Buffer(lp->ldat.val, ' ', 2);
00184 if (!strncmp(hostport, (char*)via_hostport.buf, strlen(hostport))) {
00185 lp = del_tList_node(&lp);
00186 }
00187 else lp = lp->next;
00188 free_Buffer(&via_hostport);
00189 }
00190 else lp = lp->next;
00191 }
00192
00193 return;
00194 }
00195
00196
00198
00199
00205 void insert_sip_record_route(tList* lp, char* host, unsigned short port, int add_mode)
00206 {
00207 char ftag[LBUF];
00208 char sipuri[LBUF];
00209 tList* pm;
00210
00211 if (lp==NULL || host==NULL) return;
00212
00213 ftag[0] = '\0';
00214
00215 pm = strncasecmp_tList(lp, (char*)"Record-Route", 0, 1);
00216 if (pm==NULL) {
00217 if (add_mode) pm = strncmp_tList(lp, (char*)HDLIST_FIRST_LINE_KEY, 0, 1);
00218 if (pm==NULL) return;
00219 }
00220 else if (pm->prev!=NULL) {
00221 char* pp = strstrcase((char*)pm->ldat.val.buf, "ftag=");
00222 if (pp!=NULL) {
00223 pp = pp + 5;
00224 int i = 0;
00225 while (pp[i]!='\0' && pp[i]!=';' && pp[i]!='>' && i<LBUF) {
00226 ftag[i] = pp[i];
00227 i++;
00228 }
00229 ftag[i] = '\0';
00230 }
00231 pm = pm->prev;
00232 }
00233 else return;
00234
00235 if (port!=0) {
00236 if (ftag[0]!='\0') snprintf(sipuri, LBUF, "<sip:%s:%d;ftag=%s;lr=on>", host, port, ftag);
00237 else snprintf(sipuri, LBUF, "<sip:%s:%d;lr=on>", host, port);
00238 }
00239 else {
00240 if (ftag[0]!='\0') snprintf(sipuri, LBUF, "<sip:%s;ftag=%s;lr=on>", host, ftag);
00241 else snprintf(sipuri, LBUF, "<sip:%s;lr=on>", host);
00242 }
00243 sipuri[LBUF-1] = '\0';
00244
00245 add_tList_node_str(pm, "Record-Route", sipuri);
00246
00247 return;
00248 }
00249
00250
00256 void del_sip_record_route(tList* lp, char* host, unsigned short port)
00257 {
00258 char sipuri[LBUF];
00259
00260 if (lp==NULL || host==NULL) return;
00261
00262 if (port!=0) snprintf(sipuri, LBUF, "sip:%s:%d", host, port);
00263 else snprintf(sipuri, LBUF, "sip:%s", host);
00264 sipuri[LBUF-1] = '\0';
00265
00266 while (lp!=NULL) {
00267 if (lp->ldat.key.buf!=NULL && !strcasecmp((char*)lp->ldat.key.buf, "Record-Route")) {
00268 char* rrt = (char*)lp->ldat.val.buf;
00269 if (rrt[0]=='<') rrt++;
00270
00271 if (!strncmp(sipuri, rrt, strlen(sipuri))) {
00272 lp = del_tList_node(&lp);
00273 }
00274 else lp = lp->next;
00275 }
00276 else lp = lp->next;
00277 }
00278
00279 return;
00280 }
00281
00282
00288 void del_sip_record_route_all(tList* lp)
00289 {
00290 while (lp!=NULL) {
00291 if (lp->ldat.key.buf!=NULL && !strcasecmp((char*)lp->ldat.key.buf, "Record-Route")) {
00292 lp = del_tList_node(&lp);
00293 }
00294 else lp = lp->next;
00295 }
00296 }
00297
00298
00299
00301
00302
00308 void replace_sip_contact(tList* lp, char* host, unsigned short port)
00309 {
00310 char contct[LBUF];
00311 char hostport[LBUF];
00312
00313 if (lp==NULL || host==NULL) return;
00314
00315 tList* lc = strncasecmp_tList(lp, (char*)"Contact", 0, 1);
00316 if (lc==NULL || lc->ldat.val.buf==NULL) return;
00317
00318 char* pa = (char*)lc->ldat.val.buf;
00319 char* ps = strstrcase(pa, "sip:");
00320
00321 while (ps!=NULL) {
00322 char* pp = strstr(ps, "@");
00323 if (pp==NULL) pp = ps + 3;
00324
00325 pp++;
00326
00327 int i;
00328 for (i=0; i<LBUF-1; i++) {
00329
00330 if (*pp=='\0' || *pp=='>' || *pp==' ' || *pp==';') break;
00331 contct[i] = *pp;
00332 pp++;
00333 }
00334 contct[i] = '\0';
00335
00336 if (i<LBUF-1) {
00337
00338
00339 if (port!=0) snprintf(hostport, LBUF, "%s:%d", host, port);
00340 else snprintf(hostport, LBUF, "%s", host);
00341 hostport[LBUF-1] = '\0';
00342
00343 Buffer buf = replace_sBuffer(lc->ldat.val, contct, hostport);
00344 free_Buffer(&lc->ldat.val);
00345 lc->ldat.val = buf;
00346 }
00347
00348 ps = strstrcase(pp, "sip:");
00349 }
00350
00351 return;
00352 }
00353
00354
00365 Buffer get_sip_contact_uri(tList* lp)
00366 {
00367 Buffer cturi = init_Buffer();
00368 Buffer cntct = search_protocol_header(lp, (char*)"Contact", 1);
00369
00370 if (cntct.buf!=NULL) {
00371 int i = 0;
00372 while (cntct.buf[i]!='\0' && cntct.buf[i]!=';' && cntct.buf[i]!=',' && cntct.buf[i]!=CHAR_LF && cntct.buf[i]!=CHAR_CR) i++;
00373 cntct.buf[i] = '\0';
00374
00375 cturi = cntct;
00376 }
00377
00378 return cturi;
00379 }
00380
00381
00392 Buffer get_sip_domain(Buffer sipuri)
00393 {
00394 Buffer sipdmn = init_Buffer();
00395 Buffer siptmp = dup_Buffer(sipuri);
00396
00397 if (siptmp.buf!=NULL) {
00398 int i = 0;
00399 char* pp = NULL;
00400 while (siptmp.buf[i]!='\0' && siptmp.buf[i]!='>' && siptmp.buf[i]!=';' &&
00401 siptmp.buf[i]!=',' && siptmp.buf[i]!=CHAR_LF && siptmp.buf[i]!=CHAR_CR) {
00402 if (siptmp.buf[i]=='@') pp = (char*)&siptmp.buf[i+1];
00403 i++;
00404 }
00405 siptmp.buf[i] = '\0';
00406
00407 if (pp!=NULL) sipdmn = make_Buffer_bystr(pp);
00408 free_Buffer(&siptmp);
00409 }
00410
00411 return sipdmn;
00412 }
00413
00414
00415
00417
00418
00424 int get_max_forwards(tList* lp)
00425 {
00426 int mxfd = SIP_NOMAXFORWARDS;
00427
00428 if (lp==NULL) return mxfd;
00429
00430 tList* lt = strncasecmp_tList(lp, (char*)"Max-Forwards", 0, 1);
00431 if (lt!=NULL) {
00432 mxfd = atoi((char*)lt->ldat.val.buf);
00433 }
00434
00435 return mxfd;
00436 }
00437
00438
00444 void set_max_forwards(tList* lp, int nm)
00445 {
00446 char mxfd[LEN_INT];
00447
00448 if (lp==NULL) return;
00449
00450 tList* lt = strncasecmp_tList(lp, (char*)"Max-Forwards", 0, 1);
00451 if (lt!=NULL) {
00452 snprintf(mxfd, LEN_INT, "%d", nm);
00453 mxfd[LEN_INT-1] = '\0';
00454 free_Buffer(<->ldat.val);
00455 lt->ldat.val = make_Buffer_bystr(mxfd);
00456 }
00457
00458 return;
00459 }
00460
00461
00462
00464
00465
00466
00473 tList* get_sdp_body_list(tList* lp)
00474 {
00475 Buffer cnt = restore_protocol_contents(lp);
00476 tList* ls = get_protocol_header_list(cnt, '=', FALSE, FALSE);
00477
00478 free_Buffer(&cnt);
00479 return ls;
00480 }
00481
00482
00488 Buffer restore_sdp_body(tList* ls)
00489 {
00490 Buffer buf = init_Buffer();
00491
00492 if (ls==NULL) return buf;
00493
00494 buf = restore_protocol_header(ls, (char*)"=", OFF, NULL);
00495 if (buf.buf!=NULL) {
00496 buf.vldsz = buf.vldsz - 2;
00497 buf.buf[buf.vldsz] = '\0';
00498 }
00499
00500 return buf;
00501 }
00502
00503
00515 int replace_sdp_invite_addr(tList*lp, tList* ls, char* host, unsigned short port, int del_candi)
00516 {
00517 tList* lsdp;
00518 Buffer num, sdp;
00519
00520 if (lp==NULL || host==NULL || port==0) return FALSE;
00521
00522 num = make_Buffer(LEN_INT);
00523 copy_i2Buffer((int)port, &num);
00524
00525 if (ls==NULL) lsdp = get_sdp_body_list(lp);
00526 else lsdp = ls;
00527
00528 if (del_candi) {
00529 tList* pm = lsdp;
00530 while (pm!=NULL) {
00531 if (pm->ldat.key.buf!=NULL && !strcasecmp("a", (char*)pm->ldat.key.buf)) {
00532 if (pm->ldat.val.buf!=NULL && !strncasecmp("candidate ", (char*)pm->ldat.val.buf, 10)) {
00533 pm = del_tList_node(&pm);
00534 }
00535 else pm = pm->next;
00536 }
00537 else pm = pm->next;
00538 }
00539 }
00540
00541 set_protocol_header_item(lsdp, (char*)"o", 1, ' ', 6, host);
00542 set_protocol_header_item(lsdp, (char*)"c", 1, ' ', 3, host);
00543 set_protocol_header_item(lsdp, (char*)"m", 1, ' ', 2, (char*)num.buf);
00544
00545 sdp = restore_sdp_body(lsdp);
00546 set_sip_contents(lp, sdp);
00547
00548 if (ls==NULL) del_tList(&lsdp);
00549 free_Buffer(&sdp);
00550 free_Buffer(&num);
00551
00552 return TRUE;
00553 }
00554
00555
00556
00558
00559
00560
00573 unsigned short get_valid_rtp_pair_sockets(int min, int max, int* rtp, int* rtcp)
00574 {
00575 int i = 1;
00576 int range, sock1, sock2, port;
00577
00578 max = max - 1;
00579 min = min + 1;
00580
00581 range = max - min + 1;
00582 port = ((rand()%range + min)/2)*2;
00583
00584 sock1 = udp_server_socket(port, NULL);
00585 sock2 = udp_server_socket(port+1, NULL);
00586 if (sock1<=0 || sock2<=0) {
00587 if (sock1>0) socket_close(sock1);
00588 if (sock2>0) socket_close(sock2);
00589 sock1 = sock2 = 0;
00590 }
00591
00592 while(sock1==0 && i<range) {
00593 port = port + 2;
00594 if (port>max) port = ((port%max + min - 1)/2)*2;
00595
00596 sock1 = udp_server_socket(port, NULL);
00597 sock2 = udp_server_socket(port+1, NULL);
00598 if (sock1<=0 || sock2<=0) {
00599 if (sock1>0) socket_close(sock1);
00600 if (sock2>0) socket_close(sock2);
00601 sock1 = sock2 = 0;
00602 }
00603 i = i + 2;
00604 }
00605
00606 if (sock1==0) {
00607 port = 0;
00608 *rtp = *rtcp =0;
00609 }
00610 else {
00611 *rtp = sock1;
00612 *rtcp = sock2;
00613 }
00614
00615 return (unsigned short)port;
00616 }
00617
00618
00619
00621
00622
00630 Buffer replace_sip_via(tList* lp, char* host, unsigned short port, int no)
00631 {
00632 Buffer buf = init_Buffer();
00633
00634 if (lp==NULL || host==NULL || port==0) return buf;
00635 if (no<=0) no = 1;
00636
00637 buf = search_protocol_header_item(lp, (char*)"Via", no, ' ', 2);
00638 if (buf.buf!=NULL) {
00639 int i = 0;
00640 char hostport[LBUF];
00641
00642 while (buf.buf[i]!=';' && buf.buf[i]!='\0') i++;
00643 if (buf.buf[i]!='\0') buf.buf[i] = '\0';
00644
00645 snprintf(hostport, LBUF, "%s:%d", host, port);
00646 hostport[LBUF-1] = '\0';
00647
00648 replace_protocol_header(lp, (char*)"Via", 1, (char*)buf.buf, hostport);
00649 }
00650
00651 return buf;
00652 }
00653
00654
00658 int replace_sip_contact_dstipport(tList* lp, char* ipaddr, unsigned short port)
00659 {
00660 int i;
00661 char dstip[] = "dstip=";
00662 char dstport[] = "dstport=";
00663 char* ip = NULL;
00664 char* pt = NULL;
00665
00666 Buffer frip, frpt;
00667 Buffer toip, topt;
00668
00669 if (lp==NULL || ipaddr==NULL || port==0) return FALSE;
00670
00671 tList* lc = strncasecmp_tList(lp, (char*)"Contact", 0, 1);
00672 if (lc==NULL || lc->ldat.val.buf==NULL) return FALSE;
00673
00674 frip = search_protocol_header_partvalue(lp, (char*)"Contact", dstip, 1);
00675 frpt = search_protocol_header_partvalue(lp, (char*)"Contact", dstport, 1);
00676 if (frip.buf==NULL || frpt.buf==NULL) {
00677 free_Buffer(&frip);
00678 free_Buffer(&frpt);
00679 return FALSE;
00680 }
00681
00682 i = 0;
00683 ip = strstr((char*)frip.buf, dstip);
00684 while (ip[i]!='\0' && ip[i]!=';' && ip[i]!='"') i++;
00685 ip[i] = '\0';
00686
00687 i = 0;
00688 pt = strstr((char*)frpt.buf, dstport);
00689 while (pt[i]!='\0' && pt[i]!=';' && pt[i]!='"') i++;
00690 pt[i] = '\0';
00691
00692 toip = make_Buffer(LBUF);
00693 topt = make_Buffer(LBUF);
00694
00695 copy_s2Buffer(dstip, &toip);
00696 cat_s2Buffer (ipaddr, &toip);
00697 copy_s2Buffer(dstport, &topt);
00698 cat_i2Buffer (port, &topt);
00699
00700 Buffer buftemp = replace_sBuffer(lc->ldat.val, ip, (char*)toip.buf);
00701 Buffer nwcntct = replace_sBuffer(buftemp, pt, (char*)topt.buf);
00702
00703 free_Buffer(&lc->ldat.val);
00704 lc->ldat.val = nwcntct;
00705
00706 free_Buffer(&frip);
00707 free_Buffer(&frpt);
00708 free_Buffer(&toip);
00709 free_Buffer(&topt);
00710 free_Buffer(&buftemp);
00711
00712 return TRUE;
00713 }
00714
00715