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
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
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
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
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
00309
00310
00311
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
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
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 }