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