sip.c

Go to the documentation of this file.
00001 
00058 #include "sip.h"
00059 
00060 #include "../../mem/mem.h"
00061 #include "../../data_lump.h"
00062 #include "../../data_lump_rpl.h"
00063 #include "../../parser/parse_to.h"
00064 #include "../../parser/parse_from.h"
00065 #include "../../parser/parse_expires.h"
00066 #include "../../parser/parse_via.h"
00067 #include "../../parser/parse_content.h"
00068 #include "../../parser/parse_nameaddr.h"
00069 #include "../../parser/contact/contact.h"
00070 #include "../../parser/contact/parse_contact.h"
00071 
00072 #include "../tm/tm_load.h"
00073 
00074 #include "mod.h"
00075 #include "auth_api.h"
00076 
00077 #define strtotime(src,dest) \
00078 {\
00079     int i;\
00080     (dest)=0;\
00081     for(i=0;i<(src).len;i++)\
00082         if ((src).s[i]>='0' && (src).s[i]<='9')\
00083             (dest) = (dest)*10 + (src).s[i] -'0';\
00084 }
00085 
00086 
00087 #define get_qparam(src,name,dst) \
00088 {\
00089     int i,j;\
00090     (dst).s=0;(dst).len=0;\
00091     for(i=0;i<(src).len-(name).len;i++)\
00092         if (strncasecmp((src).s+i,(name).s,(name).len)==0){\
00093             j=i+(name).len;\
00094             (dst).s = (src).s+j;\
00095             (dst).len = 0;\
00096             while(j<(src).len && (src).s[j]!='\"') \
00097                 j++;            \
00098             (dst).len = j-i-(name).len;\
00099             break;\
00100         }       \
00101 }
00102 
00103 #define get_param(src,name,dst) \
00104 {\
00105     int i,j;\
00106     (dst).s=0;(dst).len=0;\
00107     for(i=0;i<(src).len-(name).len;i++)\
00108         if (strncasecmp((src).s+i,(name).s,(name).len)==0 &&\
00109             ((src).s[i-1]==' ' ||(src).s[i-1]==';'||(src).s[i-1]=='\t')){\
00110             j=i+(name).len;\
00111             (dst).s = (src).s+j;\
00112             (dst).len = 0;\
00113             while(j<(src).len && (src).s[j]!=','&& (src).s[j]!=' '&& (src).s[j]!='\t'&& (src).s[j]!=';') \
00114                 j++;            \
00115             (dst).len = j-i-(name).len;\
00116             break;\
00117         }       \
00118 }
00119 
00120 extern struct tm_binds tmb;            
00128 int cscf_add_header_first(struct sip_msg *msg, str *hdr,int type)
00129 {
00130     struct hdr_field *first;
00131     struct lump* anchor,*l;
00132 
00133     first = msg->headers;
00134     anchor = anchor_lump(msg, first->name.s - msg->buf, 0 , 0 );
00135 
00136     if (anchor == NULL) {
00137         LOG(L_ERR, "ERR:"M_NAME":cscf_add_header_first: anchor_lump failed\n");
00138         return 0;
00139     }
00140 
00141     if (!(l=insert_new_lump_before(anchor, hdr->s,hdr->len,type))){
00142         LOG(L_ERR, "ERR:"M_NAME":cscf_add_header_first: error creating lump for header\n" );
00143         return 0;
00144     }   
00145     return 1;
00146 }
00147 
00154 int cscf_add_header(struct sip_msg *msg, str *hdr,int type)
00155 {
00156     struct hdr_field *last;
00157     struct lump* anchor;
00158     last = msg->headers;
00159     while(last->next) 
00160         last = last->next;
00161     anchor = anchor_lump(msg, last->name.s + last->len - msg->buf, 0 , 0);
00162     if (anchor == NULL) {
00163         LOG(L_ERR, "ERR:"M_NAME":cscf_add_header_first: anchor_lump failed\n");
00164         return 0;
00165     }
00166 
00167     if (!insert_new_lump_after(anchor, hdr->s,hdr->len,type)){
00168         LOG(L_ERR, "ERR:"M_NAME":cscf_add_header_first: error creting lump for header\n" );
00169         return 0;
00170     }   
00171     return 1;
00172 }
00173 
00180 int cscf_add_header_rpl(struct sip_msg *msg, str *hdr)
00181 {
00182     if (add_lump_rpl( msg, hdr->s, hdr->len, LUMP_RPL_HDR)==0) {
00183         LOG(L_ERR, "ERR:"M_NAME":cscf_add_header_rpl: Can't add header <%.*s>\n",
00184             hdr->len,hdr->s);
00185         return 0;
00186     }
00187     return 1;
00188 }
00189 
00190 
00191 
00200 str cscf_get_private_identity(struct sip_msg *msg, str realm)
00201 {
00202     str pi={0,0};
00203     struct hdr_field* h=0;
00204     int ret,i;
00205 
00206     if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00207         LOG(L_ERR,"ERR:"M_NAME":cscf_get_private_identity: Error parsing until header Authorization: \n");
00208         return pi;
00209     }
00210 
00211     if (!msg->authorization){
00212         LOG(L_ERR, "ERR:"M_NAME":cscf_get_private_identity: Message does not contain Authorization header.\n");
00213         goto fallback;
00214     }
00215 
00216     ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00217     if (ret < 0) {
00218         LOG(L_ERR, "ERR:"M_NAME":cscf_get_private_identity: Error while looking for credentials.\n");
00219         goto fallback;
00220     } else 
00221         if (ret > 0) {
00222             LOG(L_ERR, "ERR:"M_NAME":cscf_get_private_identity: No credentials for this realm found.\n");
00223             goto fallback;
00224         }
00225     
00226     if (h) pi=((auth_body_t*)h->parsed)->digest.username.whole;
00227 
00228     goto done;
00229         
00230 fallback:
00231     LOG(L_INFO,"INF:"M_NAME":cscf_get_private_identity: Falling back to private_id=stripped(public_id)\n"
00232         "-> Message did not contain a valid Authorization Header!!! This fallback is deprecated outside Early-IMS or NASS-Bundled!\n"); 
00233     pi = cscf_get_public_identity(msg);
00234     if (pi.len>4&&strncasecmp(pi.s,"sip:",4)==0) {pi.s+=4;pi.len-=4;}
00235     for(i=0;i<pi.len;i++)
00236         if (pi.s[i]==';') {
00237             pi.len=i;
00238             break;
00239         }
00240 done:   
00241     LOG(L_DBG,"DBG:"M_NAME":cscf_get_private_identity: <%.*s> \n",
00242         pi.len,pi.s);
00243     return pi;  
00244 }
00245 
00251 str cscf_get_public_identity(struct sip_msg *msg)
00252 {
00253     str pu={0,0};
00254     struct to_body *to;
00255     int i;
00256     
00257     if (parse_headers(msg,HDR_TO_F,0)!=0) {
00258         LOG(L_ERR,"ERR:"M_NAME":cscf_get_public_identity: Error parsing until header To: \n");
00259         return pu;
00260     }
00261     
00262     if ( get_to(msg) == NULL ) {
00263         to = (struct to_body*) pkg_malloc(sizeof(struct to_body));
00264         parse_to( msg->to->body.s, msg->to->body.s + msg->to->body.len, to );
00265         msg->to->parsed = to;
00266     }
00267     else to=(struct to_body *) msg->to->parsed;
00268 
00269     pu = to->uri;
00270     
00271     /* truncate to sip:username@host or tel:number */
00272     for(i=4;i<pu.len;i++)
00273         if (pu.s[i]==';' || pu.s[i]=='?' ||pu.s[i]==':'){
00274             pu.len = i;
00275         }
00276     
00277     LOG(L_DBG,"DBG:"M_NAME":cscf_get_public_identity: <%.*s> \n",
00278         pu.len,pu.s);   
00279     return pu;
00280 }
00281 
00282 
00283     
00290 int cscf_get_expires_hdr(struct sip_msg *msg)
00291 {
00292     exp_body_t *exp;
00293     int expires;
00294     if (!msg) return -1;
00295     /*first search in Expires header */
00296     if (parse_headers(msg,HDR_EXPIRES_F,0)!=0) {
00297         LOG(L_ERR,"ERR:"M_NAME":cscf_get_expires_hdr: Error parsing until header EXPIRES: \n");
00298         return -1;
00299     }
00300     if (msg->expires){      
00301         if (!msg->expires->parsed) {
00302             parse_expires(msg->expires);
00303         }
00304         if (msg->expires->parsed) {
00305             exp = (exp_body_t*) msg->expires->parsed;
00306             if (exp->valid) {
00307                 expires = exp->val;
00308                 LOG(L_DBG,"DBG:"M_NAME":cscf_get_expires_hdr: <%d> \n",expires);
00309                 return expires;
00310             }
00311         }
00312     }
00313     
00314     return -1;
00315 }
00316 
00324 int cscf_get_max_expires(struct sip_msg *msg)
00325 {
00326     unsigned int exp;
00327     int max_expires = -1;
00328     struct hdr_field *h;
00329     contact_t *c;
00330     /*first search in Expires header */
00331     max_expires = cscf_get_expires_hdr(msg);
00332     
00333     cscf_parse_contacts(msg);
00334     for(h=msg->contact;h;h=h->next){
00335         if (h->type==HDR_CONTACT_T && h->parsed) {
00336             for(c=((contact_body_t *) h->parsed)->contacts;c;c=c->next){
00337                 if(c->expires){
00338                     if (!str2int(&(c->expires->body), (unsigned int*)&exp) && (int)exp>max_expires) max_expires = exp;
00339                 }
00340             }
00341         }   
00342     }
00343     LOG(L_DBG,"DBG:"M_NAME":cscf_get_max_expires: <%d> \n",max_expires);
00344     return max_expires;
00345 }
00346 
00352 str cscf_get_public_identity_from_requri(struct sip_msg *msg)
00353 {
00354     str pu={0,0};
00355     
00356     if (msg->first_line.type!=SIP_REQUEST) {
00357         LOG(L_ERR,"INF:"M_NAME":cscf_get_public_identity_from_requri: This ain't a request \n");    
00358         return pu;
00359     }
00360     if (parse_sip_msg_uri(msg)<0){
00361         LOG(L_ERR,"INF:"M_NAME":cscf_get_public_identity_from_requri: Error parsing requesturi \n");    
00362         return pu;
00363     }
00364     
00365     if(msg->parsed_uri.type==TEL_URI_T){
00366         pu.len = 4 + msg->parsed_uri.user.len ;
00367         pu.s = shm_malloc(pu.len+1);
00368         sprintf(pu.s,"tel:%.*s",
00369             msg->parsed_uri.user.len,
00370             msg->parsed_uri.user.s);
00371     }else{
00372         pu.len = 4 + msg->parsed_uri.user.len + 1 + msg->parsed_uri.host.len;
00373         pu.s = shm_malloc(pu.len+1);
00374         sprintf(pu.s,"sip:%.*s@%.*s",
00375             msg->parsed_uri.user.len,   
00376             msg->parsed_uri.user.s, 
00377             msg->parsed_uri.host.len,   
00378             msg->parsed_uri.host.s);
00379     }   
00380     
00381     LOG(L_DBG,"DBG:"M_NAME":cscf_get_public_identity_from_requri: <%.*s> \n",
00382         pu.len,pu.s);   
00383     return pu;
00384 }
00385 
00392 struct sip_msg *cscf_get_request(unsigned int hash,unsigned int label)
00393 {
00394     struct cell *c;
00395     if (tmb.t_lookup_ident(&c,hash,label)<0){
00396         LOG(L_INFO,"INF:"M_NAME":Cx_UAA_timeout: No transaction found for %u %u\n",
00397             hash,label);
00398         return 0;
00399     }
00400     return c->uas.request;
00401 }
00402 
00403 static str s_ip={"integrity-protected",19};
00414 int cscf_get_integrity_protected(struct sip_msg *msg,str realm)
00415 {
00416     struct hdr_field* h=0;
00417     int ret,i,j;
00418 
00419     if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00420         LOG(L_ERR,"ERR:"M_NAME":cscf_get_integrity_protected: Error parsing until header Authorization: \n");
00421         return 0;
00422     }
00423 
00424     if (!msg->authorization){
00425         LOG(L_ERR, "ERR:"M_NAME":cscf_get_integrity_protected: Message does not contain Authorization header.\n");
00426         return 0;
00427     }
00428 
00429     ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00430     if (ret < 0) {
00431         LOG(L_ERR, "ERR:"M_NAME":cscf_get_integrity_protected: Error while looking for credentials.\n");
00432         return 0;
00433     } else 
00434         if (ret > 0) {
00435             LOG(L_ERR, "ERR:"M_NAME":cscf_get_integrity_protected: No credentials for this realm found.\n");
00436             return 0;
00437         }
00438     
00439     if (h) {
00440         for(i=0;i<h->body.len-s_ip.len;i++)
00441             if (strncasecmp(h->body.s+i,s_ip.s,s_ip.len)==0)
00442                 for(j=i+s_ip.len;j<h->body.len;j++){
00443                     if (h->body.s[j]=='y' || h->body.s[j]=='Y') return 1;
00444                     if (h->body.s[j]==' ') return 0;
00445                 }           
00446     }
00447     
00448     return 0;
00449 }
00450 
00451 
00461 int cscf_get_transaction(struct sip_msg *msg, unsigned int *hash,unsigned int *label)
00462 {
00463     
00464     if (tmb.t_get_trans_ident(msg,hash,label)<0){   
00465         LOG(L_DBG,"DBG:"M_NAME":cscf_get_transaction: SIP message without transaction. OK - first request\n");
00466         if (tmb.t_newtran(msg)<0) 
00467             LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: Failed creating SIP transaction\n");
00468         if (tmb.t_get_trans_ident(msg,hash,label)<0){   
00469             LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: SIP message still without transaction\n");
00470             return -1;
00471         }else {
00472             LOG(L_DBG,"DBG:"M_NAME":cscf_get_transaction: New SIP message transaction %u %u\n",
00473                 *hash,*label);
00474             return 1;
00475         }                       
00476     }else {
00477         LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: Transaction %u %u exists."
00478         "Retransmission?\n",*hash,*label);
00479         return 0;
00480     }
00481 }
00482 
00490 int cscf_reply_transactional(struct sip_msg *msg, int code, char *text)
00491 {
00492     unsigned int hash,label;
00493     if (tmb.t_get_trans_ident(msg,&hash,&label)<0){ 
00494     
00495         if (tmb.t_newtran(msg)<0) 
00496             LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: Failed creating SIP transaction\n");
00497     }
00498     return tmb.t_reply(msg,code,text);
00499 }
00500 
00507 str cscf_get_auts(struct sip_msg *msg, str realm)
00508 {
00509     str name={"auts=\"",6};
00510     struct hdr_field* h=0;
00511     int i,ret;
00512     str auts={0,0};
00513 
00514     if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00515         LOG(L_ERR,"ERR:"M_NAME":cscf_get_auts: Error parsing until header Authorization: \n");
00516         return auts;
00517     }
00518 
00519     if (!msg->authorization){
00520         LOG(L_ERR, "ERR:"M_NAME":cscf_get_auts: Message does not contain Authorization header.\n");
00521         return auts;
00522     }
00523 
00524     ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00525     if (ret < 0) {
00526         LOG(L_ERR, "ERR:"M_NAME":cscf_get_auts: Error while looking for credentials.\n");
00527         return auts;
00528     } else 
00529         if (ret > 0) {
00530             LOG(L_ERR, "ERR:"M_NAME":cscf_get_auts: No credentials for this realm found.\n");
00531             return auts;
00532         }
00533     
00534     if (h) {
00535         for(i=0;i<h->body.len-name.len;i++)
00536             if (strncasecmp(h->body.s+i,name.s,name.len)==0){
00537                 auts.s = h->body.s+i+name.len;
00538                 while(i+auts.len<h->body.len && auts.s[auts.len]!='\"')
00539                     auts.len++;
00540             }
00541     }
00542     
00543     return auts;    
00544 }
00545 
00552 str cscf_get_nonce(struct sip_msg *msg, str realm)
00553 {
00554     struct hdr_field* h=0;
00555     int ret;
00556     str nonce={0,0};
00557 
00558     if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00559         LOG(L_ERR,"ERR:"M_NAME":cscf_get_nonce: Error parsing until header Authorization: \n");
00560         return nonce;
00561     }
00562 
00563     if (!msg->authorization){
00564         LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: Message does not contain Authorization header.\n");
00565         return nonce;
00566     }
00567 
00568     ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00569     if (ret < 0) {
00570         LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: Error while looking for credentials.\n");
00571         return nonce;
00572     } else 
00573         if (ret > 0) {
00574             LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: No credentials for this realm found.\n");
00575             return nonce;
00576         }
00577     
00578     if (h&&h->parsed) {
00579         nonce = ((auth_body_t*)h->parsed)->digest.nonce;
00580     }
00581     
00582     return nonce;   
00583 }
00584 
00591 str cscf_get_algorithm(struct sip_msg *msg, str realm)
00592 {
00593     struct hdr_field* h=0;
00594     int ret;
00595     str alg={0,0};
00596 
00597     if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00598         LOG(L_ERR,"ERR:"M_NAME":cscf_get_algorithm: Error parsing until header Authorization: \n");
00599         return alg;
00600     }
00601 
00602     if (!msg->authorization){
00603         LOG(L_ERR, "ERR:"M_NAME":cscf_get_algorithm: Message does not contain Authorization header.\n");
00604         return alg;
00605     }
00606 
00607     ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00608     if (ret < 0) {
00609         LOG(L_ERR, "ERR:"M_NAME":cscf_get_algorithm: Error while looking for credentials.\n");
00610         return alg;
00611     } else 
00612         if (ret > 0) {
00613             LOG(L_ERR, "ERR:"M_NAME":cscf_get_algorithm: No credentials for this realm found.\n");
00614             return alg;
00615         }
00616     
00617     if (h&&h->parsed) {
00618         alg = ((auth_body_t*)h->parsed)->digest.alg.alg_str;
00619     }
00620     return alg; 
00621 }
00622 
00629 str cscf_get_digest_uri(struct sip_msg *msg, str realm)
00630 {
00631     struct hdr_field* h=0;
00632     int ret;
00633     str uri={0,0};
00634 
00635     if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00636         LOG(L_ERR,"ERR:"M_NAME":cscf_get_digest_uri: Error parsing until header Authorization: \n");
00637         return uri;
00638     }
00639 
00640     if (!msg->authorization){
00641         LOG(L_ERR, "ERR:"M_NAME":cscf_get_digest_uri: Message does not contain Authorization header.\n");
00642         return uri;
00643     }
00644 
00645     ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00646     if (ret < 0) {
00647         LOG(L_ERR, "ERR:"M_NAME":cscf_get_digest_uri: Error while looking for credentials.\n");
00648         return uri;
00649     } else 
00650         if (ret > 0) {
00651             LOG(L_ERR, "ERR:"M_NAME":cscf_get_digest_uri: No credentials for this realm found.\n");
00652             return uri;
00653         }
00654     
00655     if (h&&h->parsed) {
00656         uri = ((auth_body_t*)h->parsed)->digest.uri;
00657     }
00658     return uri; 
00659 }
00660 
00669 int cscf_get_nonce_response(struct sip_msg *msg, str realm,str *nonce,str *response,
00670     enum qop_type *qop,str *qop_str,str *nc,str *cnonce,str *uri)
00671 {
00672     struct hdr_field* h=0;
00673     int ret;
00674 
00675     if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00676         LOG(L_ERR,"ERR:"M_NAME":cscf_get_nonce: Error parsing until header Authorization: \n");
00677         return 0;
00678     }
00679 
00680     if (!msg->authorization){
00681         LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: Message does not contain Authorization header.\n");
00682         return 0;
00683     }
00684 
00685     ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00686     if (ret < 0) {
00687         LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: Error while looking for credentials.\n");
00688         return 0;
00689     } else 
00690         if (ret > 0) {
00691             LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: No credentials for this realm found.\n");
00692             return 0;
00693         }
00694     
00695     if (h&&h->parsed) {
00696         if (nonce) *nonce = ((auth_body_t*)h->parsed)->digest.nonce;
00697         if (response) *response = ((auth_body_t*)h->parsed)->digest.response;
00698         if (qop) *qop = ((auth_body_t*)h->parsed)->digest.qop.qop_parsed;
00699         if (qop_str) *qop_str = ((auth_body_t*)h->parsed)->digest.qop.qop_str;
00700         if (nc) *nc = ((auth_body_t*)h->parsed)->digest.nc;
00701         if (cnonce) *cnonce = ((auth_body_t*)h->parsed)->digest.cnonce;
00702         if (uri) *uri = ((auth_body_t*)h->parsed)->digest.uri;
00703     }
00704     
00705     return 1;   
00706 }
00707 
00708 
00709 str ua_dummy={"Unknown UA",10};
00710 str ua_nomsg={"No Message",10};
00716 str cscf_get_user_agent(struct sip_msg *msg)
00717 {
00718     str ua;
00719     if (!msg) return ua_nomsg;
00720     ua.len = 0;
00721     if (parse_headers(msg, HDR_USERAGENT_F, 0) != -1 && msg->user_agent &&
00722         msg->user_agent->body.len > 0) 
00723     {
00724         ua.len = msg->user_agent->body.len;
00725         ua.s = msg->user_agent->body.s;
00726     }
00727     if (ua.len == 0) ua=ua_dummy;
00728     return ua;
00729 }
00730 
00736 contact_body_t *cscf_parse_contacts(struct sip_msg *msg)
00737 {
00738     struct hdr_field* ptr;
00739     if (!msg) return 0;
00740     if (parse_headers(msg, HDR_EOH_F, 0)<0){
00741         LOG(L_ERR,"ERR:"M_NAME":cscf_parse_contacts: Error parsing headers \n");
00742         return 0;
00743     }
00744     if (msg->contact) {
00745         ptr = msg->contact;
00746         while(ptr) {
00747             if (ptr->type == HDR_CONTACT_T) {
00748                 if (ptr->parsed==0){
00749                     if (parse_contact(ptr)<0){
00750                             LOG(L_ERR,"ERR:"M_NAME":cscf_parse_contacts: error parsing contacts [%.*s]\n",
00751                                 ptr->body.len,ptr->body.s);                         
00752                     }
00753                 }
00754             }                   
00755             ptr = ptr->next;
00756         }
00757     }
00758     if (!msg->contact) return 0;
00759     return msg->contact->parsed;
00760 }
00761 
00767 str cscf_get_path(struct sip_msg *msg)
00768 {
00769     str path={0,0};
00770     struct hdr_field *h;
00771     if (!msg) return path;
00772     if (parse_headers(msg, HDR_EOH_F, 0)<0){
00773         LOG(L_ERR,"ERR:"M_NAME":cscf_get_path: error parsing headers\n");
00774         return path;
00775     }
00776     h = msg->headers;
00777     while(h){
00778         if (h->name.len==4 &&
00779             strncasecmp(h->name.s,"Path",4)==0){
00780                 path.len+=h->body.len+1;
00781             }
00782         h = h->next;
00783     }
00784     path.s = pkg_malloc(path.len);
00785     if (!path.s){
00786         LOG(L_ERR,"ERR:"M_NAME":cscf_get_path: error allocating %d bytes\n",
00787             path.len);
00788         path.len=0;
00789         return path;
00790     }
00791     h = msg->headers;
00792     path.len=0;
00793     while(h){
00794         if (h->name.len==4 &&
00795             strncasecmp(h->name.s,"Path",4)==0){
00796                 if (path.len) path.s[path.len++]=',';
00797                 memcpy(path.s+path.len,h->body.s,h->body.len);
00798                 path.len+=h->body.len;
00799             }
00800         h = h->next;
00801     }
00802 
00803     return path;
00804 }
00805 
00811 str cscf_get_event(struct sip_msg *msg)
00812 {
00813     str e={0,0};
00814     if (!msg) return e;
00815     if (parse_headers(msg, HDR_EVENT_F, 0) != -1 && msg->event &&
00816         msg->event->body.len > 0) 
00817     {
00818         e.len = msg->event->body.len;
00819         e.s = msg->event->body.s;
00820     }
00821     return e;
00822 }
00823 
00824 
00825 str s_asserted_identity={"P-Asserted-Identity",19};
00831 str cscf_get_asserted_identity(struct sip_msg *msg)
00832 {
00833     name_addr_t id;
00834     struct hdr_field *h;
00835     rr_t *r;
00836     memset(&id,0,sizeof(name_addr_t));
00837     if (!msg) return id.uri;
00838     if (parse_headers(msg, HDR_EOH_F, 0)<0) {
00839         return id.uri;
00840     }
00841     h = msg->headers;
00842     while(h)
00843     {
00844         if (h->name.len == s_asserted_identity.len  &&
00845             strncasecmp(h->name.s,s_asserted_identity.s,s_asserted_identity.len)==0)
00846         {
00847             if (parse_rr(h)<0){
00848                 //This might be an old client
00849                 LOG(L_CRIT,"WARN:"M_NAME":cscf_get_asserted_identity: P-Asserted-Identity header must contain a Nameaddr!!! Fix the client!\n");
00850                 id.name.s = h->body.s;
00851                 id.name.len = 0;
00852                 id.len = h->body.len;
00853                 id.uri = h->body;
00854                 while(id.uri.len && (id.uri.s[0]==' ' || id.uri.s[0]=='\t' || id.uri.s[0]=='<')){
00855                     id.uri.s = id.uri.s+1;
00856                     id.uri.len --;
00857                 }
00858                 while(id.uri.len && (id.uri.s[id.uri.len-1]==' ' || id.uri.s[id.uri.len-1]=='\t' || id.uri.s[id.uri.len-1]=='>')){
00859                     id.uri.len--;
00860                 }
00861                 return id.uri;  
00862             }
00863             r = (rr_t*) h->parsed;
00864             id = r->nameaddr; 
00865             free_rr(&r);
00866             h->parsed=r;
00867             //LOG(L_CRIT,"%.*s",id.uri.len,id.uri.s);
00868             return id.uri;
00869         }
00870         h = h->next;
00871     }
00872     return id.uri;
00873 }
00874 
00880 str cscf_get_asserted_identity_domain(struct sip_msg *msg)
00881 {
00882     struct sip_uri puri;
00883     str uri = cscf_get_asserted_identity(msg);
00884     if (!uri.len) return uri;
00885     
00886     if (parse_uri(uri.s,uri.len,&puri)<0){
00887         LOG(L_ERR,"ERR:"M_NAME":cscf_get_asserted_identity_domain: error parsing uri <%.*s>\n",
00888             uri.len,uri.s);
00889         uri.len=0;uri.s=0;
00890         return uri;         
00891     }
00892     return puri.host;
00893 }
00894 
00900 str cscf_get_contact(struct sip_msg *msg)
00901 {
00902     str id={0,0};
00903     struct hdr_field *h;
00904     struct contact_body *cb;
00905     
00906     if (!msg) return id;
00907     if (parse_headers(msg, HDR_CONTACT_F, 0)<0) {
00908         LOG(L_ERR,"ERR:"M_NAME":cscf_get_contact: Error parsing headers until Contact.\n");
00909         return id;
00910     }
00911 
00912     h = msg->contact;
00913     if (!h) {
00914         LOG(L_ERR,"ERR:"M_NAME":cscf_get_contact: Contact header not found.\n");
00915         return id;
00916     }
00917     if (h->parsed==0 &&
00918         parse_contact(h)<0){
00919         LOG(L_ERR,"ERR:"M_NAME":cscf_get_contact: Error parsing contacts.\n");
00920         return id;
00921     }
00922     
00923     cb = (struct contact_body *)h->parsed;
00924     if (!cb || !cb->contacts){
00925         LOG(L_ERR,"ERR:"M_NAME":cscf_get_contact: No contacts in header.\n");
00926         return id;
00927     }
00928     id = cb->contacts->uri;
00929     
00930     return id;
00931 }
00932 
00933 
00940 str cscf_get_first_route(struct sip_msg *msg,struct hdr_field **hr)
00941 {
00942     struct hdr_field *h;
00943     rr_t *r;
00944     str route={0,0};
00945     if (hr) *hr = 0;    
00946     if (!msg) return route;
00947     if (parse_headers(msg, HDR_ROUTE_F, 0)<0){
00948         LOG(L_ERR,"ERR:"M_NAME":cscf_get_first_route: error parsing headers\n");
00949         return route;
00950     }
00951     h = msg->route;
00952     if (!h){
00953         LOG(L_DBG,"DBG:"M_NAME":cscf_get_first_route: Header Route not found\n");
00954         return route;
00955     }
00956     if (hr) *hr = h;
00957     if (parse_rr(h)<0){
00958         LOG(L_ERR,"ERR:"M_NAME":cscf_get_first_route: Error parsing as Route header\n");
00959         return route;
00960     }
00961     r = (rr_t*)h->parsed;
00962     route = r->nameaddr.uri;
00963     
00964     return route;
00965 }
00966 
00967 static str route_hdr_s={"Route: ",7};
00968 static str route_hdr_e={"\r\n",2};
00976 int cscf_remove_first_route(struct sip_msg *msg,str value)
00977 {
00978     struct hdr_field *h;
00979     str route={0,0},x;
00980     int i;
00981         
00982     route = cscf_get_first_route(msg,&h);
00983     if (!h||!route.len) return 0;
00984     
00985     if ((route.len == value.len || (route.len>value.len && route.s[value.len]==';')) &&
00986         strncasecmp(route.s,value.s,value.len)==0)
00987     {
00988         cscf_del_header(msg,h);
00989         route = h->body;
00990         i=0;
00991         while(i<route.len && route.s[i]!=',')
00992             i++;
00993         i++;
00994         if (i<route.len){
00995             route.s+=i;
00996             route.len-=i;
00997             x.s = pkg_malloc(route_hdr_s.len + route.len +route_hdr_e.len);
00998             if (!x.s){
00999                 LOG(L_ERR, "ERR"M_NAME":cscf_remove_first_route: Error allocating %d bytes\n",
01000                     route.len);
01001                 x.len=0;
01002             }else{
01003                 x.len = 0;
01004                 STR_APPEND(x,route_hdr_s);
01005                 STR_APPEND(x,route);
01006                 STR_APPEND(x,route_hdr_e);              
01007                 if (!cscf_add_header_first(msg,&x,HDR_ROUTE_T))
01008                     pkg_free(x.s);
01009             }
01010         }
01011     }
01012     
01013     return 1;
01014 }
01015 
01016 
01017 
01023 inline int cscf_is_myself(str uri)
01024 {
01025     int ret;
01026     struct sip_uri puri;
01027     
01028     if (parse_uri(uri.s,uri.len,&puri)<0){
01029         LOG(L_ERR,"ERR:"M_NAME":cscf_is_myself: error parsing uri <%.*s>\n",
01030             uri.len,uri.s);
01031         return 0;           
01032     }
01033     
01034     ret = check_self(&(puri.host), puri.port_no ? puri.port_no : SIP_PORT, 0);
01035     if (ret < 0) return 0;
01036     
01037     return ret;
01038 }
01039 
01047 int cscf_remove_own_route(struct sip_msg *msg,struct hdr_field **h)
01048 {
01049     str route={0,0},x;
01050     int i;
01051         
01052     route = cscf_get_first_route(msg,h);
01053     if (!h||!route.len) return 0;
01054     
01055     LOG(L_DBG,"DBG:"M_NAME":cscf_remove_own_route: <%.*s>\n",
01056         route.len,route.s);
01057     if (cscf_is_myself(route))
01058     {
01059         cscf_del_header(msg,*h);
01060         route = (*h)->body;
01061         i=0;
01062         while(i<route.len && route.s[i]!=',')
01063             i++;
01064         i++;
01065         if (i<route.len){
01066             route.s+=i;
01067             route.len-=i;
01068             x.s = pkg_malloc(route_hdr_s.len + route.len +route_hdr_e.len);
01069             if (!x.s){
01070                 LOG(L_ERR, "ERR"M_NAME":cscf_remove_own_route: Error allocating %d bytes\n",
01071                     route.len);
01072                 x.len=0;
01073             }else{
01074                 x.len = 0;
01075                 STR_APPEND(x,route_hdr_s);
01076                 STR_APPEND(x,route);
01077                 STR_APPEND(x,route_hdr_e);              
01078                 if (!cscf_add_header_first(msg,&x,HDR_ROUTE_T))
01079                     pkg_free(x.s);
01080             }
01081         }
01082     }
01083     
01084     return 1;
01085 }
01086 
01087 
01088 static str s_record_route={"Record-route",12};
01094 str cscf_get_record_routes(struct sip_msg *msg)
01095 {
01096     struct hdr_field *h;
01097     str route={0,0};
01098     
01099     if (!msg) return route;
01100     
01101     if (parse_headers(msg, HDR_EOH_F, 0)<0){
01102         LOG(L_ERR,"ERR:"M_NAME":cscf_get_record_routes: error parsing headers\n");
01103         return route;
01104     }
01105     h = msg->record_route;
01106     while (h){
01107         if (h->name.len == s_record_route.len &&
01108             strncasecmp(h->name.s,s_record_route.s,s_record_route.len)==0)
01109         {
01110             LOG(L_DBG,"DBG:"M_NAME":cscf_get_record_routes: RR %.*s\n",h->body.len,h->body.s);
01111             if (route.s){
01112                 route.s = pkg_realloc(route.s,route.len+1+h->body.len);
01113                 route.s[route.len++]=',';
01114             }else{
01115                 route.s = pkg_malloc(h->body.len);          
01116             }
01117             memcpy(route.s+route.len,h->body.s,h->body.len);
01118             route.len+=h->body.len;
01119         }
01120         h = h->next;
01121     }   
01122     return route;
01123 }
01124 
01131 struct hdr_field* cscf_get_next_record_route(struct sip_msg *msg,struct hdr_field *start)
01132 {
01133     struct hdr_field *h;
01134     
01135     if (!msg) return 0;
01136     
01137     
01138     if (parse_headers(msg, HDR_EOH_F, 0)<0){
01139         LOG(L_ERR,"ERR:"M_NAME":cscf_get_next_record_routes: error parsing headers\n");
01140         return 0;
01141     }
01142     if (start) h = start->next;
01143     else h = msg->record_route;
01144     while (h){
01145         if (h->type == HDR_RECORDROUTE_T)
01146         {
01147             LOG(L_DBG,"DBG:"M_NAME":cscf_get_next_record_routes: RR %.*s\n",h->body.len,h->body.s);
01148             if (!h->parsed){
01149                 if (parse_rr(h)<0){
01150                     LOG(L_ERR,"ERR:"M_NAME":cscf_get_next_record_routes: Error parsing as Route header\n");
01151                     return 0;
01152                 }               
01153             }
01154             return h;
01155         }
01156         h = h->next;
01157     }   
01158     return 0;
01159 }
01160 
01167 struct hdr_field* cscf_get_next_via_hdr(struct sip_msg *msg,struct hdr_field *start)
01168 {
01169     struct hdr_field *h;
01170     
01171     if (!msg) return 0;
01172     
01173     if (parse_headers(msg, HDR_EOH_F, 0)<0){
01174         LOG(L_ERR,"ERR:"M_NAME":cscf_get_next_via: error parsing headers\n");
01175         return 0;
01176     }
01177     if (start) h = start->next;
01178     else h = msg->headers;
01179     while (h){
01180         if (h->type == HDR_VIA_T)
01181             return h;
01182         h = h->next;
01183     }   
01184     return 0;
01185 }
01186 
01191 static int str_trim(str *s)
01192 {
01193     int i;
01194     for (i = 0;i < s->len; i++)
01195     {
01196         if (s->s[i] != '\r' && s->s[i] != '\t' && s->s[i] != ' ')
01197         {
01198             break;
01199         }
01200     }
01201     s->s = s->s + i;    
01202     s->len -= i;
01203 
01204     for (i = s->len;i >=0; i--)
01205     {
01206         if (s->s[i] == '\r' && s->s[i] == '\t' && s->s[i] == ' ')
01207         {
01208             s->len--;
01209         }
01210         else
01211         {
01212             break;
01213         }
01214     }
01215     return 1;
01216 }
01217 
01229 str cscf_get_next_via_str(struct sip_msg *msg, struct hdr_field * h, int pos, struct hdr_field **h_out, int *pos_out)
01230 {
01231     char *viab;
01232     int i, viab_start;
01233     str via_str={0,0};
01234     if (!h_out || !pos_out)
01235         return via_str; 
01236     
01237     if (!h)
01238     {
01239         h = cscf_get_next_via_hdr(msg,0);
01240         pos = 0;
01241     }
01242 
01243     viab = h->body.s;
01244     i = viab_start = pos;
01245 
01246     while (i < h->body.len)
01247     {
01248         if (viab[i] == ',')
01249         {
01250             via_str.s = viab + viab_start;
01251             via_str.len = i - viab_start;
01252             str_trim(&via_str);
01253             viab_start = i+1;
01254             *h_out = h;
01255             *pos_out = viab_start;
01256             return via_str;
01257         }
01258         i++;
01259     }
01260     via_str.s = viab + viab_start;
01261     via_str.len = i - viab_start;
01262     str_trim(&via_str);
01263     *h_out = cscf_get_next_via_hdr(msg,h);
01264     *pos_out = 0;   
01265     return via_str;
01266 }
01267 
01274 int cscf_via_matching( struct via_body *req_via, struct via_body *rpl_via )
01275 {
01276     if ((!req_via->branch && rpl_via->branch) || (req_via->branch && !rpl_via->branch))
01277     {
01278         LOG(L_INFO,"DBG:"M_NAME":cscf_via_matching: branch param missing\n");
01279         return 0;;
01280     }
01281     if (req_via->branch && rpl_via->branch)
01282     {
01283         if (req_via->branch->value.len != rpl_via->branch->value.len ||
01284             strncasecmp(req_via->branch->value.s, rpl_via->branch->value.s,rpl_via->branch->value.len)!=0)
01285         {
01286             LOG(L_INFO,"DBG:"M_NAME":cscf_via_matching: different branch param\n");
01287             return 0;
01288         }
01289     }
01290     if (req_via->host.len!=rpl_via->host.len||
01291         strncasecmp(req_via->host.s, rpl_via->host.s,rpl_via->host.len)!=0)
01292     {
01293         LOG(L_INFO,"DBG:"M_NAME":cscf_via_matching: different host \n");
01294         return 0;
01295     }
01296     if (req_via->port!=rpl_via->port)
01297     {
01298         LOG(L_INFO,"DBG:"M_NAME":cscf_via_matching: different port \n");
01299         return 0;
01300     }
01301     
01302     if (req_via->transport.len!=rpl_via->transport.len||
01303         strncasecmp(req_via->transport.s, rpl_via->transport.s,rpl_via->transport.len)!=0)
01304     {
01305         LOG(L_INFO,"DBG:"M_NAME":cscf_via_matching: transport host \n");
01306         return 0;
01307     }
01308     /* everything matched -- we found it */
01309     return 1;
01310 }
01311 
01312 
01313 
01314 
01315 
01316 static inline void free_via_param_list(struct via_param* vp)
01317 {
01318     struct via_param* foo;
01319     while(vp){
01320         foo=vp;
01321         vp=vp->next;
01322         pkg_free(foo);
01323     }
01324 }
01325 
01326 static str via_hdr_term={"\r\n.",3};
01334 int cscf_str_via_matching(str *sreq_via, str *srpl_via)
01335 {   
01336     struct via_body req_via, rpl_via;
01337     str hdr1={0,0}, hdr2={0,0};
01338     int result = 0;
01339     
01340     memset(&req_via, 0, sizeof(struct via_body));
01341     memset(&rpl_via, 0, sizeof(struct via_body));
01342 
01343     if (sreq_via->s[sreq_via->len+1] !='\r' || sreq_via->s[sreq_via->len+2] != '\n') //check for CRLF 
01344     {
01345         hdr1.len = sreq_via->len + via_hdr_term.len;
01346         hdr1.s = pkg_malloc(hdr1.len);
01347         if (!hdr1.s)
01348         {
01349             LOG(L_ERR, "ERR:"M_NAME":cscf_str_via_matching: cannot alloc bytes : %d", hdr1.len);
01350             return 0;
01351         }
01352         hdr1.len=0;
01353         STR_APPEND(hdr1, *sreq_via);
01354         STR_APPEND(hdr1, via_hdr_term);
01355         parse_via(hdr1.s,hdr1.s+hdr1.len,&req_via);
01356     }
01357     else
01358         parse_via(sreq_via->s,sreq_via->s+sreq_via->len, &req_via);
01359     
01360     
01361     if (srpl_via->s[srpl_via->len+1] !='\r' || srpl_via->s[srpl_via->len+2] != '\n') //check for CRLF 
01362     {
01363         hdr2.len = srpl_via->len + via_hdr_term.len;
01364         hdr2.s = pkg_malloc(hdr2.len);
01365         if (!hdr2.s)
01366         {
01367             LOG(L_ERR, "ERR:"M_NAME":cscf_str_via_matching: cannot alloc bytes : %d", hdr2.len);
01368             goto done;
01369         }
01370         hdr2.len=0;
01371         STR_APPEND(hdr2, *srpl_via);
01372         STR_APPEND(hdr2, via_hdr_term);
01373         parse_via(hdr2.s,hdr2.s+hdr2.len,&rpl_via);
01374     }
01375     else
01376         parse_via(srpl_via->s, srpl_via->s+srpl_via->len, &rpl_via);
01377         
01378     result = cscf_via_matching(&req_via, &rpl_via);
01379     
01380 done:   
01381     if (hdr1.s) pkg_free(hdr1.s);
01382     if (hdr1.s) pkg_free(hdr2.s);
01383     if (req_via.param_lst) free_via_param_list(req_via.param_lst);
01384     if (rpl_via.param_lst) free_via_param_list(rpl_via.param_lst);
01385     return result;
01386 }
01387 
01388 
01389 
01395 str cscf_get_realm_from_ruri(struct sip_msg *msg)
01396 {
01397     str realm={0,0};
01398     if (!msg || msg->first_line.type!=SIP_REQUEST){
01399         LOG(L_ERR,"ERR:"M_NAME":cscf_get_realm_from_ruri: This is not a request!!!\n");
01400         return realm;
01401     }
01402     if (!msg->parsed_orig_ruri_ok)
01403         if (parse_orig_ruri(msg) < 0) 
01404             return realm;
01405     
01406     realm = msg->parsed_orig_ruri.host;
01407     return realm;   
01408 }
01409 
01415 str cscf_get_identity_from_ruri(struct sip_msg *msg)
01416 {
01417     str aor={0,0};
01418     if (!msg || msg->first_line.type!=SIP_REQUEST){
01419         LOG(L_ERR,"ERR:"M_NAME":cscf_get_identity_from_ruri: This is not a request!!!\n");
01420         return aor;
01421     }
01422     aor.s = msg->first_line.u.request.uri.s;
01423     aor.len = 0;
01424     while(aor.s[aor.len]!=' '&&aor.s[aor.len]!='\t'&&
01425           aor.s[aor.len]!=';'&&aor.s[aor.len]!='&'&&
01426           aor.s[aor.len]!='\r'&&aor.s[aor.len]!='\n')
01427         aor.len++;
01428 //  if (!msg->parsed_orig_ruri_ok)
01429 //      if (parse_orig_ruri(msg) < 0) 
01430 //          return aor;
01431 //          
01432 //  aor = msg->parsed_orig_ruri.host;
01433 //  if (msg->parsed_orig_ruri.user.len){
01434 //      aor.s = msg->parsed_orig_ruri.;
01435 //      aor.len = msg->parsed_orig_ruri.user.len+msg->parsed_orig_ruri.passwd.len+1+
01436 //          msg->parsed_orig_ruri.host.len;
01437 //  }
01438     return aor; 
01439 }
01440 
01441 
01448 str cscf_get_call_id(struct sip_msg *msg,struct hdr_field **hr)
01449 {
01450     struct hdr_field *h;
01451     str call_id={0,0};
01452     if (hr) *hr = 0;    
01453     if (!msg) return call_id;
01454     if (parse_headers(msg, HDR_CALLID_F, 0)<0){
01455         LOG(L_ERR,"ERR:"M_NAME":cscf_get_call_id: error parsing headers\n");
01456         return call_id;
01457     }
01458     h = msg->callid;
01459     if (!h){
01460         LOG(L_ERR,"ERR:"M_NAME":cscf_get_call_id: Header Call-ID not found\n");
01461         return call_id;
01462     }
01463     if (hr) *hr = h;
01464     call_id = h->body;  
01465     return call_id;
01466 }
01467 
01468 
01475 int cscf_get_cseq(struct sip_msg *msg,struct hdr_field **hr)
01476 {
01477     struct hdr_field *h;
01478     struct cseq_body *cseq;
01479     int nr = 0,i;
01480     
01481     if (hr) *hr = 0;    
01482     if (!msg) return 0;
01483     if (parse_headers(msg, HDR_CSEQ_F, 0)<0){
01484         LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: error parsing headers\n");
01485         return 0;
01486     }
01487     h = msg->cseq;
01488     if (!h){
01489         LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
01490         return 0;
01491     }
01492     if (hr) *hr = h;
01493     if (!h->parsed){
01494         cseq = pkg_malloc(sizeof(struct cseq_body));
01495         if (!cseq){
01496             LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
01497             return 0;
01498         }
01499         parse_cseq(h->body.s,h->body.s+h->body.len,cseq);
01500         h->parsed = cseq;
01501     }else
01502         cseq = (struct cseq_body*) h->parsed;       
01503     for(i=0;i<cseq->number.len;i++)
01504         nr = (nr*10)+(cseq->number.s[i]-'0');
01505     return nr;
01506 }
01507 
01514 str cscf_get_cseq_method(struct sip_msg *msg,struct hdr_field **hr)
01515 {
01516     struct hdr_field *h;
01517     struct cseq_body *cseq;
01518     str method = {0,0};
01519     
01520     if (hr) *hr = 0;    
01521     if (!msg) return method;
01522     if (parse_headers(msg, HDR_CSEQ_F, 0)<0){
01523         LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: error parsing headers\n");
01524         return method;
01525     }
01526     h = msg->cseq;
01527     if (!h){
01528         LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
01529         return method;
01530     }
01531     if (hr) *hr = h;
01532     if (!h->parsed){
01533         cseq = pkg_malloc(sizeof(struct cseq_body));
01534         if (!cseq){
01535             LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
01536             return method;
01537         }
01538         parse_cseq(h->body.s,h->body.s+h->body.len,cseq);
01539         h->parsed = cseq;
01540     }else
01541         cseq = (struct cseq_body*) h->parsed;       
01542     return cseq->method;
01543 }
01544 
01550 struct sip_msg* cscf_get_request_from_reply(struct sip_msg *reply)
01551 {
01552     struct cell *t;
01553     t = tmb.t_gett();
01554     if (!t || t==(void*) -1){
01555         LOG(L_ERR,"ERR:"M_NAME":cscf_get_request_from_reply: Reply without transaction\n");
01556         return 0;
01557     }
01558     if (t) return t->uas.request;
01559     else return 0;
01560 }
01561 
01562 
01563 static str s_called_party_id={"P-Called-Party-ID",17};
01570 str cscf_get_called_party_id(struct sip_msg *msg,struct hdr_field **hr)
01571 {
01572     str id={0,0};
01573     struct hdr_field *h;
01574     if (hr) *hr=0;
01575     if (!msg) return id;
01576     if (parse_headers(msg, HDR_EOH_F, 0)<0) {
01577         return id;
01578     }
01579     h = msg->headers;
01580     while(h)
01581     {
01582         if (h->name.len == s_called_party_id.len  &&
01583             strncasecmp(h->name.s,s_called_party_id.s,s_called_party_id.len)==0)
01584         {
01585             id = h->body;
01586             while(id.len && (id.s[0]==' ' || id.s[0]=='\t' || id.s[0]=='<')){
01587                 id.s = id.s+1;
01588                 id.len --;
01589             }
01590             while(id.len &&am