sip.c

Go to the documentation of this file.
00001 
00055 #include <stdio.h>
00056 #include <string.h>
00057 #include <ctype.h>
00058 
00059 #include "../../str.h"
00060 #include "../../parser/parse_expires.h"
00061 #include "../../dprint.h"
00062 #include "../../mem/mem.h"
00063 #include "../scscf/scscf_load.h"
00064 #include "../tm/tm_load.h"
00065 
00066 
00067 #include "sip.h"
00068 #include "mod.h"
00069 #include "mark.h"
00070 
00071 extern struct tm_binds isc_tmb;            
00072 extern struct scscf_binds isc_scscfb;            
00080 int str2cmp(str x, str y) {
00081     if (x.len < y.len) return -1;
00082     if (x.len > y.len) return +1;
00083     return strncmp(x.s, y.s, x.len);
00084 }
00085 
00092 int str2icmp(str x, str y) {
00093     if (x.len < y.len) return -1;
00094     if (x.len > y.len) return +1;
00095     return strncasecmp(x.s, y.s, x.len);
00096 }
00097 
00098 
00099 static str bye_s={"BYE",3};
00100 static str ack_s={"ACK",3};
00101 static str prack_s={"PRACK",5};
00102 static str update_s={"UPDATE",6};
00103 static str notify_s={"NOTIFY",6};
00110 int isc_is_initial_request(struct sip_msg *msg)
00111 {
00112     if (msg->first_line.type != SIP_REQUEST ) return 0;
00113     if (strncasecmp(msg->first_line.u.request.method.s,bye_s.s,bye_s.len)==0) return 0;
00114     if (strncasecmp(msg->first_line.u.request.method.s,ack_s.s,ack_s.len)==0) return 0;
00115     if (strncasecmp(msg->first_line.u.request.method.s,prack_s.s,prack_s.len)==0) return 0;
00116     if (strncasecmp(msg->first_line.u.request.method.s,update_s.s,update_s.len)==0) return 0;
00117     if (strncasecmp(msg->first_line.u.request.method.s,notify_s.s,notify_s.len)==0) return 0;
00118     return 1;
00119 }
00120 
00121 
00122 static str register_s={"REGISTER",8};
00128 int isc_is_register(struct sip_msg *msg)
00129 {
00130     if (msg->first_line.type != SIP_REQUEST ) return 0;
00131     if (strncasecmp(msg->first_line.u.request.method.s,register_s.s,register_s.len)==0) return 1;           
00132     return 0;
00133 }
00134 
00135 
00140 static inline void isc_strip_uri(str *uri)
00141 {
00142     int i;
00143     /* Strip the ending */
00144     i=0;
00145     while(i<uri->len&&uri->s[i]!='@')
00146         i++;
00147     while(i<uri->len&&
00148             uri->s[i]!=':'&&
00149             uri->s[i]!='/'&&
00150             uri->s[i]!='&')
00151         i++;
00152     uri->len=i;
00153 }
00154 
00155 
00156 str s_asserted_identity={"P-Asserted-Identity",19};
00162 str cscf_get_asserted_identity(struct sip_msg *msg)
00163 {
00164     name_addr_t id;
00165     struct hdr_field *h;
00166     rr_t *r;
00167     memset(&id,0,sizeof(name_addr_t));
00168     if (!msg) return id.uri;
00169     if (parse_headers(msg, HDR_EOH_F, 0)<0) {
00170         return id.uri;
00171     }
00172     h = msg->headers;
00173     while(h)
00174     {
00175         if (h->name.len == s_asserted_identity.len  &&
00176             strncasecmp(h->name.s,s_asserted_identity.s,s_asserted_identity.len)==0)
00177         {
00178             if (parse_rr(h)<0){
00179                 //This might be an old client
00180                 LOG(L_CRIT,"WARN:"M_NAME":cscf_get_asserted_identity: P-Asserted-Identity header must contain a Nameaddr!!! Fix the client!\n");
00181                 id.name.s = h->body.s;
00182                 id.name.len = 0;
00183                 id.len = h->body.len;
00184                 id.uri = h->body;
00185                 while(id.uri.len && (id.uri.s[0]==' ' || id.uri.s[0]=='\t' || id.uri.s[0]=='<')){
00186                     id.uri.s = id.uri.s+1;
00187                     id.uri.len --;
00188                 }
00189                 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]=='>')){
00190                     id.uri.len--;
00191                 }
00192                 return id.uri;  
00193             }
00194             r = (rr_t*) h->parsed;
00195             id = r->nameaddr;           
00196             free_rr(&r);
00197             h->parsed=r;
00198             //LOG(L_RIT,"%.*s",id.uri.len,id.uri.s);
00199             return id.uri;
00200         }
00201         h = h->next;
00202     }
00203     return id.uri;
00204 }
00211 int isc_get_originating_user( struct sip_msg * msg, isc_mark *mark, str *uri )
00212 {
00213     struct to_body * from;
00214     if (mark && mark->aor.len){
00215         *uri = mark->aor;
00216         return 1;
00217     }
00218     *uri = cscf_get_asserted_identity(msg);
00219     if (!uri->len) {        
00220         /* Fallback to From header */
00221         if ( parse_from_header( msg ) == -1 ) {
00222             LOG(L_ERR,"ERROR:"M_NAME":isc_get_originating_user: unable to extract URI from FROM header\n" );
00223             return 0;
00224         }
00225         if (!msg->from) return 0;
00226         from = (struct to_body*) msg->from->parsed;
00227         *uri = from->uri;
00228         isc_strip_uri(uri);
00229     }
00230     DBG("DEBUG:"M_NAME":isc_get_originating_user: From %.*s\n", uri->len,uri->s );
00231     return 1;
00232 }
00233 
00240 int isc_is_registered(str *uri)
00241 {
00242     int result = 0;
00243     r_public *p;
00244     
00245     p = isc_scscfb.get_r_public(*uri);
00246     
00247     if (p) {
00248         result = p->reg_state;
00249         isc_scscfb.r_unlock(p->hash);
00250     }   
00251     return result;
00252 }
00253 
00260 inline int isc_get_terminating_type(str *uri)
00261 {
00262     if (isc_is_registered(uri)) return IFC_TERMINATING_SESSION;
00263         else return IFC_TERMINATING_UNREGISTERED;
00264 }
00265 
00272 str cscf_get_public_identity_from_requri(struct sip_msg *msg)
00273 {
00274     str pu={0,0};
00275     int i;
00276     if (msg->first_line.type!=SIP_REQUEST) {
00277         LOG(L_INFO,"ERR:"M_NAME":cscf_get_public_identity_from_requri: This ain't a request \n");   
00278         return pu;
00279     }
00280     if (parse_sip_msg_uri(msg)<0){
00281         LOG(L_ERR,"ERR:"M_NAME":cscf_get_public_identity_from_requri: Error parsing requesturi \n");    
00282         return pu;
00283     }
00284     pu = msg->first_line.u.request.uri;
00285     for(i=0;i<pu.len&& pu.s[i]!=';'&&pu.s[i]!='?';i++);
00286     pu.len = i;
00287     
00288     LOG(L_DBG,"DBG:"M_NAME":cscf_get_public_identity_from_requri: <%.*s> \n",
00289         pu.len,pu.s);   
00290     return pu;
00291 }
00292 
00300 int isc_get_terminating_user( struct sip_msg * msg, isc_mark *mark, str *uri )
00301 {
00302     if (mark && mark->aor.len){
00303         *uri = mark->aor;
00304         return 1;
00305     }   
00306     *uri = cscf_get_public_identity_from_requri(msg);
00307     if (!uri->len) return IMS_USER_NOT_REGISTERED;
00308     /*if ( isc_get_terminating_type( uri ) == IFC_TERMINATING_UNREGISTERED )
00309         DBG("DBG:"M_NAME":isc_get_terminating_type: To UNREGISTERED %.*s\n", uri->len,uri->s);
00310     else
00311         DBG("DBG:"M_NAME":isc_get_terminating_type: To REGISTERED %.*s\n", uri->len,uri->s);    */
00312     return IMS_USER_REGISTERED;
00313 }
00314 
00315 
00321 int isc_get_expires(struct sip_msg *msg)
00322 {   
00323     if (msg->expires) {
00324         if (parse_expires(msg->expires) < 0) {
00325             LOG(L_INFO, "INFO:ifc:ifc_get_expires:Error while parsing Expires header\n");
00326             return -1;
00327         }
00328          return ((exp_body_t*) msg->expires->parsed)->val;
00329     } else {
00330         return -1;
00331     }
00332 }
00333 
00334 
00344 int cscf_get_transaction(struct sip_msg *msg, unsigned int *hash,unsigned int *label)
00345 {
00346     
00347     if (isc_tmb.t_get_trans_ident(msg,hash,label)<0){   
00348         LOG(L_DBG,"DBG:"M_NAME":cscf_get_transaction: SIP message without transaction. OK - first request\n");
00349         if (isc_tmb.t_newtran(msg)<0) 
00350             LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: Failed creating SIP transaction\n");
00351         if (isc_tmb.t_get_trans_ident(msg,hash,label)<0){   
00352             LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: SIP message still without transaction\n");
00353             return -1;
00354         }else {
00355             LOG(L_DBG,"DBG:"M_NAME":cscf_get_transaction: New SIP message transaction %u %u\n",
00356                 *hash,*label);
00357             return 1;
00358         }                       
00359     }else {
00360         LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: Transaction %u %u exists."
00361         "Retransmission?\n",*hash,*label);
00362         return 0;
00363     }
00364 }
00365 
00366 
00372 struct sip_msg* cscf_get_request_from_reply(struct sip_msg *reply)
00373 {
00374     struct cell *t;
00375     t = isc_tmb.t_gett();
00376     if (!t || t==(void*) -1){
00377         LOG(L_ERR,"ERR:"M_NAME":cscf_get_request_from_reply: Reply without transaction\n");
00378         return 0;
00379     }
00380     return t->uas.request;
00381 }
00382 
00389 int cscf_get_expires_hdr(struct sip_msg *msg) {
00390     exp_body_t *exp;
00391     int expires;
00392     if (!msg) return -1;
00393     /*first search in Expires header */         
00394     if (parse_headers(msg,HDR_EXPIRES_F,0)!=0) {
00395         LOG(L_ERR,"ERR:"M_NAME":cscf_get_expires_hdr: Error parsing until header EXPIRES: \n");
00396         return -1;
00397     }
00398     if (msg->expires){
00399         if (!msg->expires->parsed) {
00400                 parse_expires(msg->expires);
00401         }
00402         if (msg->expires->parsed) {
00403                 exp = (exp_body_t*) msg->expires->parsed;
00404                 if (exp->valid) {
00405                         expires = exp->val;
00406                         LOG(L_DBG,"DBG:"M_NAME":cscf_get_expires_hdr: <%d> \n",expires);
00407                         return expires;
00408                 }
00409         }
00410     }
00411     
00412     return -1;
00413 }
00421 int cscf_get_max_expires(struct sip_msg *msg)
00422 {
00423     unsigned int exp;
00424     int max_expires = -1;
00425     struct hdr_field *h;
00426     contact_t *c;
00427     /*first search in Expires header */
00428     max_expires = cscf_get_expires_hdr(msg);
00429     
00430     cscf_parse_contacts(msg);
00431     for(h=msg->contact;h;h=h->next){
00432         if (h->type==HDR_CONTACT_T && h->parsed) {
00433             for(c=((contact_body_t *) h->parsed)->contacts;c;c=c->next){
00434                 if(c->expires){
00435                     if (!str2int(&(c->expires->body), (unsigned int*)&exp) && (int)exp>max_expires) max_expires = exp;
00436                 }
00437             }
00438         }   
00439     }
00440     LOG(L_DBG,"DBG:"M_NAME":cscf_get_max_expires: <%d> \n",max_expires);
00441     return max_expires;
00442 }
00443 
00449 contact_body_t *cscf_parse_contacts(struct sip_msg *msg)
00450 {
00451     struct hdr_field* ptr;
00452     if (!msg) return 0;
00453     
00454     if (parse_headers(msg, HDR_EOH_F, 0)<0){
00455         LOG(L_ERR,"ERR:"M_NAME":cscf_parse_contacts: Error parsing headers \n");
00456         return 0;
00457     }
00458     if (msg->contact) {
00459         ptr = msg->contact;
00460         while(ptr) {
00461             if (ptr->type == HDR_CONTACT_T) {
00462                 if (msg->contact->parsed==0){                   
00463                     if (parse_contact(ptr)<0){
00464                         LOG(L_ERR,"ERR:"M_NAME":cscf_parse_contacts: error parsing contacts [%.*s]\n",
00465                             ptr->body.len,ptr->body.s); 
00466                     }
00467                 }
00468             }
00469             ptr = ptr->next;
00470         }
00471     }
00472     if (!msg->contact) return 0;
00473     return msg->contact->parsed;
00474 }
00475 
00482 int cscf_get_first_p_associated_uri(struct sip_msg *msg,str *public_id)
00483 {
00484     struct hdr_field *h;
00485     rr_t *r;
00486     public_id->s=0;public_id->len=0;
00487     
00488     if (!msg) return 0;
00489     if (parse_headers(msg, HDR_EOH_F, 0)<0){
00490         LOG(L_ERR,"ERR:"M_NAME":cscf_get_p_associated_uri: error parsing headers\n");
00491         return 0;
00492     }
00493     h = msg->headers;
00494     while(h){
00495         if (h->name.len==16 && strncasecmp(h->name.s,"P-Associated-URI",16)==0)
00496             break;
00497         h = h->next;
00498     }
00499     if (!h){
00500         LOG(L_DBG,"DBG:"M_NAME":cscf_get_p_associated_uri: Header P-Associated-URI not found\n");
00501         return 0;
00502     }
00503     if (parse_rr(h)<0){
00504         LOG(L_ERR,"ERR:"M_NAME":cscf_get_p_associated_uri: Error parsing as Route header\n");
00505         return 0;
00506     }
00507     r = (rr_t*)h->parsed;
00508     h->type = HDR_ROUTE_T;
00509     
00510     if (r) {
00511         *public_id=r->nameaddr.uri;
00512         return 1;
00513     }
00514     else
00515         return 0;
00516 }
00517 
00523 str cscf_get_public_identity(struct sip_msg *msg)
00524 {
00525     str pu={0,0};
00526     struct to_body *to;
00527     
00528     if (parse_headers(msg,HDR_TO_F,0)!=0) {
00529         LOG(L_ERR,"ERR:"M_NAME":cscf_get_public_identity: Error parsing until header To: \n");
00530         return pu;
00531     }
00532     
00533     if ( get_to(msg) == NULL ) {
00534         to = (struct to_body*) pkg_malloc(sizeof(struct to_body));
00535         parse_to( msg->to->body.s, msg->to->body.s + msg->to->body.len, to );
00536         msg->to->parsed = to;
00537     }
00538         else to=(struct to_body *) msg->to->parsed;
00539     
00540     pu = to->uri;
00541     
00542     LOG(L_DBG,"DBG:"M_NAME":cscf_get_public_identity: <%.*s> \n",
00543         pu.len,pu.s);
00544     return pu;
00545 }
00546 
00547 str cscf_p_access_network_info={"P-Access-Network-Info",21};
00548 
00555 str cscf_get_access_network_info(struct sip_msg *msg, struct hdr_field **h)
00556 {
00557     str ani={0,0};
00558     struct hdr_field *hdr;
00559     
00560     *h=0;
00561     if (parse_headers(msg,HDR_EOH_F,0)!=0) {
00562         LOG(L_DBG,"DBG:"M_NAME":cscf_get_access_network_info: Error parsing until header EOH: \n");
00563         return ani;
00564     }
00565     hdr = msg->headers;
00566     while(hdr){
00567         if (hdr->name.len==cscf_p_access_network_info.len &&
00568             strncasecmp(hdr->name.s,cscf_p_access_network_info.s,hdr->name.len)==0)
00569         {
00570             *h = hdr;
00571             ani = hdr->body;
00572             goto done;
00573         }                 
00574         hdr = hdr->next;
00575     }
00576     LOG(L_DBG,"DBG:"M_NAME":cscf_get_access_network_info: P-Access-Network-Info header not found \n");
00577     
00578 done:
00579     LOG(L_DBG,"DBG:"M_NAME":cscf_get_access_network_info: <%.*s> \n",
00580         ani.len,ani.s);
00581     return ani;
00582 }
00583 
00584 str cscf_p_visited_network_id={"P-Visited-Network-ID",20};
00585 
00592 str cscf_get_visited_network_id(struct sip_msg *msg, struct hdr_field **h)
00593 {
00594     str vnid={0,0};
00595     struct hdr_field *hdr;
00596     
00597     *h=0;
00598     if (parse_headers(msg,HDR_EOH_F,0)!=0) {
00599         LOG(L_DBG,"DBG:"M_NAME":cscf_get_public_identity: Error parsing until header EOH: \n");
00600         return vnid;
00601     }
00602     hdr = msg->headers;
00603     while(hdr){
00604         if (hdr->name.len==cscf_p_visited_network_id.len &&
00605             strncasecmp(hdr->name.s,cscf_p_visited_network_id.s,hdr->name.len)==0)
00606         {
00607             *h = hdr;
00608             vnid = hdr->body;
00609             goto done;
00610         }
00611         hdr = hdr->next;
00612     }
00613     LOG(L_DBG,"DBG:"M_NAME":cscf_get_visited_network_id: P-Visited-Network-ID header not found \n");
00614 
00615 done:
00616     LOG(L_DBG,"DBG:"M_NAME":cscf_get_visited_network_id: <%.*s> \n",
00617         vnid.len,vnid.s);
00618     return vnid;
00619 }
00620 
00621 str cscf_p_charging_vector={"P-Charging-Vector",17};
00622 
00629 str cscf_get_charging_vector(struct sip_msg *msg, struct hdr_field **h)
00630 {
00631     str cv={0,0};
00632     struct hdr_field *hdr;
00633     
00634     *h=0;
00635     if (parse_headers(msg,HDR_EOH_F,0)!=0) {
00636         LOG(L_DBG,"DBG:"M_NAME":cscf_get_charging_vector: Error parsing until header EOH: \n");
00637         return cv;
00638     }
00639     hdr = msg->headers;
00640     while(hdr){
00641         if (hdr->name.len==cscf_p_charging_vector.len &&
00642             strncasecmp(hdr->name.s,cscf_p_charging_vector.s,hdr->name.len)==0)
00643         {
00644             *h = hdr;
00645             cv = hdr->body;
00646             goto done;
00647         }
00648         hdr = hdr->next;
00649     }
00650     LOG(L_DBG,"DBG:"M_NAME":cscf_get_charging_vector: P-Charging-Vector header not found \n");
00651 
00652 done:
00653     LOG(L_DBG,"DBG:"M_NAME":cscf_get_charging_vector: <%.*s> \n",
00654         cv.len,cv.s);
00655     return cv;
00656 }
00657 
00664 str cscf_get_call_id(struct sip_msg *msg,struct hdr_field **hr)
00665 {
00666     struct hdr_field *h;
00667     str call_id={0,0};
00668     if (hr) *hr = 0;    
00669     if (!msg) return call_id;
00670     if (parse_headers(msg, HDR_CALLID_F, 0)<0){
00671         LOG(L_ERR,"ERR:"M_NAME":cscf_get_call_id: error parsing headers\n");
00672         return call_id;
00673     }
00674     h = msg->callid;
00675     if (!h){
00676         LOG(L_ERR,"ERR:"M_NAME":cscf_get_call_id: Header Call-ID not found\n");
00677         return call_id;
00678     }
00679     if (hr) *hr = h;
00680     call_id = h->body;  
00681     return call_id;
00682 }
00683 
00684 
00691 int cscf_get_cseq(struct sip_msg *msg,struct hdr_field **hr)
00692 {
00693     struct hdr_field *h;
00694     struct cseq_body *cseq;
00695     int nr = 0,i;
00696     
00697     if (hr) *hr = 0;    
00698     if (!msg) return 0;
00699     if (parse_headers(msg, HDR_CSEQ_F, 0)<0){
00700         LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: error parsing headers\n");
00701         return 0;
00702     }
00703     h = msg->cseq;
00704     if (!h){
00705         LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
00706         return 0;
00707     }
00708     if (hr) *hr = h;
00709     if (!h->parsed){
00710         cseq = pkg_malloc(sizeof(struct cseq_body));
00711         if (!cseq){
00712             LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
00713             return 0;
00714         }
00715         parse_cseq(h->body.s,h->body.s+h->body.len,cseq);
00716         h->parsed = cseq;
00717     }else
00718         cseq = (struct cseq_body*) h->parsed;       
00719     for(i=0;i<cseq->number.len;i++)
00720         nr = (nr*10)+(cseq->number.s[i]-'0');
00721     return nr;
00722 }

Generated on Thu Oct 23 04:14:38 2008 for Open IMS Core CSCFs by  doxygen 1.5.2