Definition in file registration.h.
#include "../../sr_module.h"
Go to the source code of this file.
Defines | |
| #define | MSG_200_OK_NOTIFY "OK Notification received by P-CSCF" |
| < response to NOTIFY for reg event | |
Functions | |
| int | P_add_path (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the Path header. | |
| int | P_add_require (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the Require header. | |
| int | P_add_p_charging_vector (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the P-Charging-Vector header P-Charging-Vector:. | |
| int | P_add_integrity_protected (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the integrity protected parameter into the Authorization header. | |
| int | P_add_p_visited_network_id (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the P-Visited-Network-ID header or a field inside if it exists. | |
| int | P_remove_ck_ik (struct sip_msg *msg, char *str1, char *str2) |
| Removes the CK and IK keys from the WWW-Authenticate header. | |
| int | P_is_integrity_protected (struct sip_msg *msg, char *str1, char *str2) |
| Finds out if the message was received over a protected IPSec channel. | |
| int | P_is_registered (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the message comes from a registered UE at this P-CSCF. | |
| int | P_assert_identity (struct sip_msg *msg, char *str1, char *str2) |
| Asserts the P-Preferred-Identity if registered and inserts the P-Asserted-Identity. | |
| int | P_assert_called_identity (struct sip_msg *msg, char *str1, char *str2) |
| Asserts the P-Called-Identity. | |
| int | P_process_notification (struct sip_msg *msg, char *str1, char *str2) |
| Process an incoming NOTIFY for the reg event. | |
| int | P_mobile_terminating (struct sip_msg *msg, char *str1, char *str2) |
| Determines if this is the Mobile Terminating case. | |
| int | P_remove_route (struct sip_msg *msg, char *str1, char *str2) |
| int | P_NAT_relay (struct sip_msg *msg, char *str1, char *str2) |
| Forward a message through the NAT pinhole. | |
| int | P_security_relay (struct sip_msg *msg, char *str1, char *str2) |
| Forward a response through the IPSec SA. | |
| int | P_follows_service_routes (struct sip_msg *msg, char *str1, char *str2) |
| Checks if the message follows Service-Route imposed at registration. | |
| int | P_enforce_service_routes (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the Route header containing the Service-Route to be enforced. | |
| int | P_access_network_info (struct sip_msg *req, char *str1, char *str2) |
| Asserts the P-Access-Network-Info. | |
| #define MSG_200_OK_NOTIFY "OK Notification received by P-CSCF" |
| int P_add_path | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Inserts the Path header.
Path: <sip:term@pcscf.name.com;lr>
| msg | - the SIP message to add to | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 104 of file registration.c.
References cscf_add_header(), CSCF_RETURN_ERROR, CSCF_RETURN_TRUE, pcscf_path_hdr_str, and STR_PKG_DUP.
00105 { 00106 str x={0,0}; 00107 00108 STR_PKG_DUP(x,pcscf_path_hdr_str,"pkg"); 00109 if (!x.s) return CSCF_RETURN_ERROR; 00110 if (cscf_add_header(msg,&x,HDR_OTHER_T)) return CSCF_RETURN_TRUE; 00111 else { 00112 pkg_free(x.s); 00113 return CSCF_RETURN_ERROR; 00114 } 00115 out_of_memory: 00116 return CSCF_RETURN_ERROR; 00117 }
| int P_add_require | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Inserts the Require header.
Require: path
| msg | - the SIP message to add to | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 129 of file registration.c.
References cscf_add_header(), CSCF_RETURN_ERROR, CSCF_RETURN_TRUE, require_hdr, and STR_PKG_DUP.
00130 { 00131 str x={0,0}; 00132 00133 STR_PKG_DUP(x,require_hdr,"pkg"); 00134 if (!x.s) return CSCF_RETURN_ERROR; 00135 if (cscf_add_header(msg,&x,HDR_OTHER_T)) return CSCF_RETURN_TRUE; 00136 else { 00137 pkg_free(x.s); 00138 return CSCF_RETURN_ERROR; 00139 } 00140 out_of_memory: 00141 return CSCF_RETURN_ERROR; 00142 }
| int P_add_p_charging_vector | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Inserts the P-Charging-Vector header P-Charging-Vector:.
| msg | - the SIP message to add to | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 153 of file registration.c.
References cscf_add_p_charging_vector().
00154 { 00155 return cscf_add_p_charging_vector(msg); 00156 }
| int P_add_integrity_protected | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Inserts the integrity protected parameter into the Authorization header.
| msg | - the SIP message to add to | |
| str1 | - the value to insert into integrity protected: ["yes","no"] | |
| str2 | - not used |
Definition at line 207 of file registration.c.
References cscf_get_authorization(), CSCF_RETURN_FALSE, if, integrity_protected_s, and M_NAME.
00208 { 00209 int r = CSCF_RETURN_FALSE; 00210 str x={0,0}; 00211 str v={0,0}; 00212 str auth; 00213 int i; 00214 int s=0,e=0; 00215 struct hdr_field *hdr; 00216 00217 v.s = str1; 00218 v.len = strlen(str1); 00219 00220 auth = cscf_get_authorization(msg,&hdr); 00221 if (!auth.len){ 00222 LOG(L_INFO,"INF:"M_NAME":P_add_integrity_protected: No authorization header found.\n"); 00223 goto done; 00224 } 00225 00226 s=auth.len;e=auth.len; 00227 /* first we look for it */ 00228 for(i=0;i<auth.len-integrity_protected_s.len;i++) 00229 if (strncasecmp(auth.s+i,integrity_protected_s.s,integrity_protected_s.len)==0){ 00230 s = i; 00231 e = i+integrity_protected_s.len; 00232 while(e<auth.len && auth.s[e]!='\"') 00233 e++; 00234 if (e<auth.len) e++; 00235 break; 00236 } 00237 x.len = authorization_s.len+ 00238 auth.len - (e-s)+ 00239 integrity_protected_s.len+v.len+integrity_protected_e.len+ 00240 authorization_e.len; 00241 x.s = pkg_malloc(x.len); 00242 if (!x.s){ 00243 LOG(L_ERR, "ERR"M_NAME":P_add_integrity_protected: Error allocating %d bytes\n", 00244 x.len); 00245 x.len=0; 00246 goto error; 00247 } 00248 x.len=0; 00249 00250 STR_APPEND(x,authorization_s); 00251 memcpy(x.s+x.len,auth.s,s); 00252 x.len += s; 00253 STR_APPEND(x,integrity_protected_s); 00254 STR_APPEND(x,v); 00255 STR_APPEND(x,integrity_protected_e); 00256 memcpy(x.s+x.len,auth.s+e,auth.len-e); 00257 x.len += auth.len-e; 00258 STR_APPEND(x,authorization_e); 00259 00260 if (cscf_add_header(msg,&x,HDR_OTHER_T)) r = CSCF_RETURN_TRUE; 00261 else goto error; 00262 00263 00264 if (!cscf_del_header(msg,hdr)){ 00265 LOG(L_INFO,"INF:"M_NAME":P_add_integrity_protected: Error dropping old authorization header.\n"); 00266 goto error; 00267 } 00268 00269 done: 00270 return r; 00271 error: 00272 r = CSCF_RETURN_ERROR; 00273 if (x.s) pkg_free(x.s); 00274 return r; 00275 }
| int P_add_p_visited_network_id | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Inserts the P-Visited-Network-ID header or a field inside if it exists.
| msg | - the SIP message to add to | |
| str1 | - the value to insert - !!! quoted if needed | |
| str2 | - not used |
Definition at line 289 of file registration.c.
References cscf_add_header(), cscf_del_header(), cscf_get_visited_network_id(), CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, and require_hdr.
00290 { 00291 int r = CSCF_RETURN_FALSE; 00292 str x={0,0}; 00293 str v={0,0}; 00294 str old={0,0}; 00295 struct hdr_field *hdr; 00296 00297 v.s = str1; 00298 v.len = strlen(str1); 00299 00300 old = cscf_get_visited_network_id(msg,&hdr); 00301 00302 x.len = p_visited_network_id_s.len + old.len + v.len + p_visited_network_id_e.len; 00303 if (old.len) x.len+=p_visited_network_id_1.len; 00304 00305 x.s = pkg_malloc(x.len); 00306 if (!x.s){ 00307 LOG(L_ERR, "ERR"M_NAME":P_add_p_visited_network_id: Error allocating %d bytes\n", 00308 require_hdr.len); 00309 x.len=0; 00310 goto error; 00311 } 00312 x.len=0; 00313 memcpy(x.s+x.len,p_visited_network_id_s.s,p_visited_network_id_s.len); 00314 x.len += p_visited_network_id_s.len; 00315 00316 if (old.len) { 00317 memcpy(x.s+x.len,old.s,old.len); 00318 x.len += old.len; 00319 00320 memcpy(x.s+x.len,p_visited_network_id_1.s,p_visited_network_id_1.len); 00321 x.len += p_visited_network_id_1.len; 00322 } 00323 00324 memcpy(x.s+x.len,v.s,v.len); 00325 x.len += v.len; 00326 00327 memcpy(x.s+x.len,p_visited_network_id_e.s,p_visited_network_id_e.len); 00328 x.len += p_visited_network_id_e.len; 00329 00330 00331 if (cscf_add_header(msg,&x,HDR_OTHER_T)) r = CSCF_RETURN_TRUE; 00332 else goto error; 00333 00334 if (!cscf_del_header(msg,hdr)){ 00335 LOG(L_INFO,"INF:"M_NAME":P_add_p_visited_network_id: Error dropping old header.\n"); 00336 goto error; 00337 } 00338 00339 return r; 00340 error: 00341 r = CSCF_RETURN_ERROR; 00342 if (x.s) pkg_free(x.s); 00343 return r; 00344 }
| int P_remove_ck_ik | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Removes the CK and IK keys from the WWW-Authenticate header.
| msg | - the SIP reply message to remove from | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 358 of file registration.c.
References cscf_add_header(), cscf_del_header(), cscf_get_authenticate(), CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, and STR_APPEND.
00359 { 00360 int r = CSCF_RETURN_FALSE; 00361 str auth,x={0,0}; 00362 struct hdr_field *hdr; 00363 int inString = 0; 00364 int mlen,i; 00365 auth = cscf_get_authenticate(msg,&hdr); 00366 if (!auth.len){ 00367 LOG(L_INFO,"INF:"M_NAME":P_remove_ck_ik: No WWW-Authenticate header found.\n"); 00368 goto done; 00369 } 00370 00371 LOG(L_DBG,"DBG:"M_NAME":P_remove_ck_ik: Original: <%.*s>\n", 00372 auth.len,auth.s); 00373 00374 x.s = pkg_malloc(authenticate_s.len+auth.len+authenticate_e.len); 00375 if (!x.s){ 00376 LOG(L_ERR, "ERR"M_NAME":P_remove_ck_ik: Error allocating %d bytes\n", 00377 x.len); 00378 x.len=0; 00379 goto error; 00380 } 00381 x.len=0; 00382 00383 if (ck.len>ik.len) mlen = auth.len - ck.len; 00384 else mlen = auth.len - ik.len; 00385 00386 STR_APPEND(x,authenticate_s); 00387 i=0; 00388 while(i<auth.len){ 00389 if ((auth.s[i] == '\"') &&(i==0||auth.s[i-1]!='\\')) 00390 inString = !inString; 00391 00392 if (!inString && i<mlen && strncasecmp(auth.s+i,ck.s,ck.len)==0){ 00393 i+=ck.len; 00394 while(i<auth.len && auth.s[i]!='\"') 00395 i++; 00396 i++; 00397 while(i<auth.len &&(auth.s[i]==' '||auth.s[i]==','||auth.s[i]=='\t')) 00398 i++; 00399 continue; 00400 } 00401 if (!inString && i<mlen && strncasecmp(auth.s+i,ik.s,ik.len)==0){ 00402 i+=ik.len; 00403 while(i<auth.len && auth.s[i]!='\"') 00404 i++; 00405 i++; 00406 while(i<auth.len &&(auth.s[i]==' '||auth.s[i]==','||auth.s[i]=='\t')) 00407 i++; 00408 continue; 00409 } 00410 x.s[x.len++]=auth.s[i++]; 00411 } 00412 while(x.len>0 && (x.s[x.len-1]==' '||x.s[x.len-1]==','||x.s[x.len-1]=='\t')) 00413 x.len--; 00414 STR_APPEND(x,authenticate_e); 00415 00416 LOG(L_DBG,"DBG:"M_NAME":P_remove_ck_ik: Changed: <%.*s>\n", 00417 x.len,x.s); 00418 00419 if (!cscf_del_header(msg,hdr)){ 00420 LOG(L_INFO,"INF:"M_NAME":P_remove_ck_ik: Error dropping old authorization header.\n"); 00421 goto error; 00422 } 00423 00424 if (cscf_add_header(msg,&x,HDR_OTHER_T)) r = CSCF_RETURN_TRUE; 00425 else goto error; 00426 00427 LOG(L_DBG,"DBG::"M_NAME":P_remove_ck_ik: Final : <%.*s>\n", 00428 x.len,x.s); 00429 00430 done: 00431 return r; 00432 error: 00433 r = CSCF_RETURN_ERROR; 00434 if (x.s) pkg_free(x.s); 00435 return r; 00436 }
| int P_is_integrity_protected | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Finds out if the message was received over a protected IPSec channel.
| msg | - the SIP to check | |
| str1 | - the realm to look into | |
| str2 | - not used |
Definition at line 166 of file registration.c.
References cscf_get_ue_via(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, get_tls_session_hash, M_NAME, pcscf_tls_port, pcscf_use_tls, and r_is_integrity_protected().
00167 { 00168 int ret=CSCF_RETURN_FALSE; 00169 struct via_body *vb; 00170 unsigned long s_hash = 0; 00171 00172 00173 LOG(L_DBG,"DBG:"M_NAME":P_is_integrity_protected: Looking if registered\n"); 00174 // print_r(L_INFO); 00175 00176 vb = cscf_get_ue_via(msg); 00177 00178 LOG(L_DBG,"DBG:"M_NAME":P_is_integrity_protected: Looking for <%d://%.*s:%d,%d>\n", 00179 vb->proto,vb->host.len,vb->host.s,vb->port,msg->rcv.src_port); 00180 if (pcscf_use_tls && msg->rcv.dst_port == pcscf_tls_port){ 00181 s_hash = get_tls_session_hash(msg); 00182 if (!s_hash){ 00183 LOG(L_ERR,"ERR:"M_NAME":P_is_integrity_protected: Session Hash could not be obtained !\n"); 00184 return CSCF_RETURN_FALSE; 00185 } 00186 } 00187 if (r_is_integrity_protected(vb->host,vb->port,msg->rcv.src_port,vb->proto, s_hash)) 00188 ret = CSCF_RETURN_TRUE; 00189 else 00190 ret = CSCF_RETURN_FALSE; 00191 00192 return ret; 00193 }
| int P_is_registered | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Finds if the message comes from a registered UE at this P-CSCF.
| msg | - the SIP message | |
| str1 | - the realm to look into | |
| str2 | - not used |
Definition at line 448 of file registration.c.
References cscf_get_ue_via(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, and r_is_registered().
00449 { 00450 int ret=CSCF_RETURN_FALSE; 00451 struct via_body *vb; 00452 00453 LOG(L_INFO,"DBG:"M_NAME":P_is_registered: Looking if registered\n"); 00454 // print_r(L_INFO); 00455 00456 vb = cscf_get_ue_via(msg); 00457 00458 00459 if (vb->port==0) vb->port=5060; 00460 LOG(L_INFO,"DBG:"M_NAME":P_is_registered: Looking for <%d://%.*s:%d>\n", 00461 vb->proto,vb->host.len,vb->host.s,vb->port); 00462 00463 if (r_is_registered(vb->host,vb->port,vb->proto)) 00464 ret = CSCF_RETURN_TRUE; 00465 else 00466 ret = CSCF_RETURN_FALSE; 00467 00468 return ret; 00469 }
| int P_assert_identity | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Asserts the P-Preferred-Identity if registered and inserts the P-Asserted-Identity.
| msg | - the SIP message | |
| str1 | - the realm to look into | |
| str2 | - not used |
Definition at line 482 of file registration.c.
References cscf_add_header(), cscf_del_header(), cscf_get_preferred_identity(), cscf_get_ue_via(), CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, r_assert_identity(), require_hdr, and STR_APPEND.
00483 { 00484 int ret=CSCF_RETURN_FALSE; 00485 struct via_body *vb; 00486 struct hdr_field *h=0; 00487 name_addr_t preferred,asserted; 00488 str x={0,0}; 00489 00490 LOG(L_INFO,"INF:"M_NAME":P_assert_identity: Asserting Identity\n"); 00491 // print_r(L_INFO); 00492 00493 vb = cscf_get_ue_via(msg); 00494 00495 preferred = cscf_get_preferred_identity(msg,&h); 00496 00497 LOG(L_INFO,"DBG:"M_NAME":P_assert_identity: Looking for <%d://%.*s:%d> Pref: %.*s\n", 00498 vb->proto,vb->host.len,vb->host.s,vb->port, 00499 preferred.len,preferred.name.s); 00500 00501 asserted = r_assert_identity(vb->host,vb->port,vb->proto,preferred); 00502 if (!asserted.uri.len){ 00503 ret = CSCF_RETURN_FALSE; 00504 }else{ 00505 cscf_del_header(msg,h); 00506 x.len = p_asserted_identity_s.len+asserted.name.len+p_asserted_identity_m.len + 00507 asserted.uri.len+p_asserted_identity_e.len; 00508 x.s = pkg_malloc(x.len); 00509 if (!x.s){ 00510 LOG(L_ERR, "ERR"M_NAME":P_assert_identity: Error allocating %d bytes\n", 00511 require_hdr.len); 00512 x.len=0; 00513 goto error; 00514 } 00515 x.len=0; 00516 STR_APPEND(x,p_asserted_identity_s); 00517 STR_APPEND(x,asserted.name); 00518 STR_APPEND(x,p_asserted_identity_m); 00519 STR_APPEND(x,asserted.uri); 00520 STR_APPEND(x,p_asserted_identity_e); 00521 00522 if (cscf_add_header(msg,&x,HDR_OTHER_T)) 00523 ret = CSCF_RETURN_TRUE; 00524 else 00525 ret = CSCF_RETURN_FALSE; 00526 } 00527 00528 00529 return ret; 00530 error: 00531 ret=CSCF_RETURN_ERROR; 00532 return ret; 00533 }
| int P_assert_called_identity | ( | struct sip_msg * | rpl, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Asserts the P-Called-Identity.
| rpl | - the SIP response message | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 542 of file registration.c.
References cscf_add_header(), cscf_del_header(), cscf_get_called_party_id(), cscf_get_preferred_identity(), cscf_get_request_from_reply(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, require_hdr, and STR_APPEND.
00543 { 00544 int ret=CSCF_RETURN_FALSE; 00545 struct hdr_field *h=0; 00546 str called={0,0},x={0,0}; 00547 struct sip_msg *req = cscf_get_request_from_reply(rpl); 00548 00549 LOG(L_INFO,"INF:"M_NAME":P_assert_called_identity: Asserting Identity\n"); 00550 00551 cscf_get_preferred_identity(rpl,&h); 00552 cscf_del_header(rpl,h); 00553 00554 if (!req){ 00555 LOG(L_INFO,"INF:"M_NAME":P_assert_called_identity: Error finding correspondent request.\n"); 00556 goto error; 00557 } 00558 00559 called = cscf_get_called_party_id(req,&h); 00560 if (!called.len){ 00561 ret = CSCF_RETURN_FALSE; 00562 }else{ 00563 x.len = p_asserted_identity_s.len+p_asserted_identity_m.len+called.len+p_asserted_identity_e.len; 00564 x.s = pkg_malloc(x.len); 00565 if (!x.s){ 00566 LOG(L_ERR, "ERR"M_NAME":P_assert_called_identity: Error allocating %d bytes\n", 00567 require_hdr.len); 00568 x.len=0; 00569 goto error; 00570 } 00571 x.len=0; 00572 STR_APPEND(x,p_asserted_identity_s); 00573 STR_APPEND(x,p_asserted_identity_m); 00574 STR_APPEND(x,called); 00575 STR_APPEND(x,p_asserted_identity_e); 00576 00577 if (cscf_add_header(rpl,&x,HDR_OTHER_T)) 00578 ret = CSCF_RETURN_TRUE; 00579 else 00580 ret = CSCF_RETURN_FALSE; 00581 } 00582 00583 return ret; 00584 error: 00585 ret=CSCF_RETURN_FALSE; 00586 return ret; 00587 }
| int P_process_notification | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Process an incoming NOTIFY for the reg event.
To be Called when a NOTIFY comes in - checks if for itself. if the NOTIFY is destined for this node, generate an event and respond with 200 OK, and return TRUE. else return FALSE
| msg | - the SIP message | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 601 of file registration.c.
References cscf_get_call_id(), cscf_get_content_len(), cscf_get_content_type(), cscf_get_cseq(), cscf_get_subscription_state(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, r_notification_free(), r_notification_parse(), and r_notification_process().
00602 { 00603 int ret=CSCF_RETURN_FALSE; 00604 str content_type,body; 00605 r_notification *n=0; 00606 int expires; 00607 LOG(L_DBG,"DBG:"M_NAME":P_NOTIFY: Checking NOTIFY\n"); 00608 00609 // print_r(L_INFO); 00610 00611 /* check if we received what we should */ 00612 if (msg->first_line.type!=SIP_REQUEST) { 00613 LOG(L_ERR,"ERR:"M_NAME":P_NOTIFY: The message is not a request\n"); 00614 goto error; 00615 } 00616 if (msg->first_line.u.request.method.len!=6|| 00617 memcmp(msg->first_line.u.request.method.s,"NOTIFY",6)!=0) 00618 { 00619 LOG(L_ERR,"ERR:"M_NAME":P_NOTIFY: The method is not a NOTIFY\n"); 00620 goto error; 00621 } 00622 00623 /* update the subscription state */ 00624 expires = cscf_get_subscription_state(msg); 00625 /* treat event */ 00626 content_type = cscf_get_content_type(msg); 00627 if (content_type.len==reginfo.len && 00628 strncasecmp(content_type.s,reginfo.s,reginfo.len)==0) 00629 { 00630 body.s = get_body(msg); 00631 if (!body.s){ 00632 LOG(L_ERR,"ERR:"M_NAME":P_NOTIFY: No body extracted\n"); 00633 goto error; 00634 }else{ 00635 body.len = cscf_get_content_len(msg); 00636 LOG(L_DBG,"DBG:"M_NAME":P_NOTIFY: Found body: %.*s\n", 00637 body.len,body.s); 00638 n = r_notification_parse(body); 00639 if (!n){ 00640 LOG(L_DBG,"DBG:"M_NAME":P_NOTIFY: Error parsing XML\n"); 00641 }else { 00642 #ifdef WITH_IMS_PM 00643 ims_pm_notify_reg(n,cscf_get_call_id(msg,0),cscf_get_cseq(msg,0)); 00644 #endif 00645 if (r_notification_process(n,expires)) 00646 ret = CSCF_RETURN_TRUE; 00647 r_notification_free(n); 00648 } 00649 } 00650 }else{ 00651 LOG(L_ERR,"ERR:"M_NAME":P_NOTIFY: The content should be %.*s but it is %.*s\n", 00652 reginfo.len,reginfo.s,content_type.len,content_type.s); 00653 goto error; 00654 } 00655 00656 00657 return ret; 00658 error: 00659 ret=CSCF_RETURN_FALSE; 00660 return ret; 00661 }
| int P_mobile_terminating | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Determines if this is the Mobile Terminating case.
uses the indication in the first Route header
| msg | - the SIP message | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 672 of file registration.c.
References cscf_get_first_route(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, and pcscf_path_str.
00673 { 00674 int ret=CSCF_RETURN_FALSE; 00675 str route={0,0}; 00676 int i; 00677 00678 route = cscf_get_first_route(msg,0); 00679 if (!route.len){ 00680 LOG(L_DBG,"DBG:"M_NAME":P_mobile_terminating: No Route header.\n"); 00681 goto done; 00682 } 00683 i=0; 00684 while(i<route.len && (route.s[i]==' ' ||route.s[i]=='\t'||route.s[i]=='<')) 00685 i++; 00686 route.s += i; 00687 route.len -= i; 00688 i=0; 00689 while(route.s[i]!=';' && route.s[i]!='>' && i<route.len) 00690 i++; 00691 route.len = i; 00692 00693 if (route.len == pcscf_path_str.len && 00694 strncasecmp(route.s,pcscf_path_str.s,pcscf_path_str.len)==0) 00695 { 00696 LOG(L_DBG,"DBG:"M_NAME":P_mobile_terminating: Term indication found.\n"); 00697 ret = CSCF_RETURN_TRUE; 00698 goto done; 00699 }else{ 00700 LOG(L_DBG,"DBG:"M_NAME":P_mobile_terminating: Term indication not found in <%.*s> as <%.*s>.\n", 00701 route.len,route.s,pcscf_path_str.len,pcscf_path_str.s); 00702 } 00703 00704 00705 done: 00706 return ret; 00707 }
| int P_remove_route | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
| msg | - the SIP message | |
| str1 | - if not empty, will look and remove this value instead | |
| str2 | - not used |
Definition at line 718 of file registration.c.
References cscf_remove_first_route(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, pcscf_name_str, and pcscf_path_str.
00719 { 00720 int ret=CSCF_RETURN_FALSE; 00721 str x; 00722 00723 if (str1 && strlen(str1)){ 00724 x.s = str1; 00725 x.len =strlen(str1); 00726 if (cscf_remove_first_route(msg,x)) 00727 ret = CSCF_RETURN_TRUE; 00728 else 00729 ret = CSCF_RETURN_FALSE; 00730 }else{ 00731 if (cscf_remove_first_route(msg,pcscf_path_str)+cscf_remove_first_route(msg,pcscf_name_str)) 00732 ret = CSCF_RETURN_TRUE; 00733 else 00734 ret = CSCF_RETURN_FALSE; 00735 } 00736 00737 return ret; 00738 }
| int P_NAT_relay | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Forward a message through the NAT pinhole.
| msg | - the SIP message to forward | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 910 of file registration.c.
References cscf_get_request_from_reply(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, get_r_contact(), _r_contact::hash, M_NAME, _r_nat_dest::nat_addr, _r_nat_dest::nat_port, NULL, pcscf_nat_enable, _r_contact::pinhole, r_unlock(), and tmb.
00911 { 00912 str dst={0,0}; 00913 int len; 00914 struct ip_addr ip; 00915 unsigned short int port; 00916 r_contact *c=0; 00917 struct dest_info dst_info; 00918 struct cell *t=0; 00919 00920 if (!pcscf_nat_enable) return CSCF_RETURN_FALSE; 00921 00922 if(msg -> first_line.type == SIP_REQUEST) { 00923 /* on request get the destination from the Request-URI */ 00924 struct sip_uri uri; 00925 str req_uri = msg -> first_line.u.request.uri; 00926 00927 parse_uri(req_uri.s, req_uri.len, &uri); 00928 if(uri.port_no == 0) 00929 uri.port_no=5060; 00930 00931 c = get_r_contact(uri.host, uri.port_no, uri.proto); 00932 00933 if(c==NULL || c->pinhole == NULL) { 00934 LOG(L_DBG, "ERR:"M_NAME":P_NAT_relay: we cannot find the pinhole for contact %.*s. Sorry\n", req_uri.len, req_uri.s); 00935 if (c) r_unlock(c->hash); 00936 return CSCF_RETURN_FALSE; 00937 } 00938 ip = c->pinhole->nat_addr; 00939 port = c->pinhole->nat_port; 00940 } else { 00941 /* on response get the destination from the received addr for the corresponding request */ 00942 struct sip_msg *req; 00943 req = cscf_get_request_from_reply(msg); 00944 if(req == NULL) { 00945 LOG(L_ERR, "ERR:"M_NAME":P_NAT_relay: Cannot get request for the transaction\n"); 00946 if (c) r_unlock(c->hash); 00947 return CSCF_RETURN_FALSE; 00948 } 00949 ip = req->rcv.src_ip; 00950 port = req->rcv.src_port; 00951 } 00952 00953 switch(ip.af){ 00954 case AF_INET: 00955 if (ip.len<4) break; 00956 len = 4 /* sip: */ + 4 * ip.len /* ip address */ + 1 /* : */ + 6 /* port */; 00957 dst.s = pkg_malloc(len); 00958 if (!dst.s){ 00959 LOG(L_ERR, "ERR:"M_NAME":P_NAT_relay: Error allocating %d bytes\n", len); 00960 if (c) r_unlock(c->hash); 00961 return CSCF_RETURN_FALSE; 00962 } 00963 dst.len = sprintf(dst.s, "sip:%d.%d.%d.%d:%d", ip.u.addr[0],ip.u.addr[1],ip.u.addr[2],ip.u.addr[3],port); 00964 break; 00965 case AF_INET6: 00966 if (ip.len<16) break; 00967 len = 5 /* sip:[ */ + 2 * ip.len /* ip address */ + 7/*:*/ + 2/* ]: */ + 6 /* port */; 00968 dst.s = pkg_malloc(len); 00969 if (!dst.s){ 00970 LOG(L_ERR, "ERR:"M_NAME":P_NAT_relay: Error allocating %d bytes\n", len); 00971 if (c) r_unlock(c->hash); 00972 return CSCF_RETURN_FALSE; 00973 } 00974 dst.len = sprintf(dst.s, "sip:[%.02x%.02x:%.02x%.02x:%.02x%.02x:%.02x%.02x:%.02x%.02x:%.02x%.02x:%.02x%.02x:%.02x%.02x]:%d", 00975 ip.u.addr[0], 00976 ip.u.addr[1], 00977 ip.u.addr[2], 00978 ip.u.addr[3], 00979 ip.u.addr[4], 00980 ip.u.addr[5], 00981 ip.u.addr[6], 00982 ip.u.addr[7], 00983 ip.u.addr[8], 00984 ip.u.addr[9], 00985 ip.u.addr[10], 00986 ip.u.addr[11], 00987 ip.u.addr[12], 00988 ip.u.addr[13], 00989 ip.u.addr[14], 00990 ip.u.addr[15], 00991 port); 00992 break; 00993 } 00994 00995 00996 if (c) r_unlock(c->hash); 00997 00998 if (msg->dst_uri.s) pkg_free(msg->dst_uri.s); 00999 msg -> dst_uri = dst; 01000 01001 if (msg -> first_line.type == SIP_REPLY) { 01002 /* on reply we have to modify the t->uas->response->dst.to.sin.sin_port/sin_addr */ 01003 t = tmb.t_gett(); 01004 if (!t){ 01005 LOG(L_INFO, "INFO:"M_NAME":P_NAT_relay: Can't relay non-transactional responses\n"); 01006 return CSCF_RETURN_FALSE; /* error */ 01007 } 01008 #ifdef USE_DNS_FAILOVER 01009 if (!uri2dst(0,&dst_info, msg, &msg->dst_uri, PROTO_NONE)) { 01010 #else 01011 if (!uri2dst(&dst_info, msg, &msg->dst_uri, PROTO_NONE)) { 01012 #endif 01013 LOG(L_INFO, "INFO:"M_NAME":P_NAT_relay: Error setting uri as dst <%.*s>\n", msg -> dst_uri.len, msg -> dst_uri.s); 01014 return CSCF_RETURN_FALSE; /* error */ 01015 } 01016 t->uas.response.dst = dst_info; 01017 } 01018 01019 LOG(L_INFO, "INFO:"M_NAME":P_NAT_relay: <%.*s>\n", msg -> dst_uri.len, msg -> dst_uri.s); 01020 return CSCF_RETURN_TRUE; 01021 }
| int P_security_relay | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Forward a response through the IPSec SA.
| msg | - the SIP message to forward | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 1033 of file registration.c.
References cscf_get_request_from_reply(), cscf_get_ue_via(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, _r_security::data, get_r_contact(), _r_contact::hash, _r_security::ipsec, M_NAME, NULL, pcscf_tls_port, pcscf_use_ipsec, pcscf_use_tls, _r_tls::port_tls, _r_ipsec::port_us, r_unlock(), SEC_IPSEC, SEC_NONE, SEC_TLS, _r_contact::security, STR_APPEND, _r_security::tls, tmb, and _r_security::type.
01034 { 01035 str dst={0,0}; 01036 int len; 01037 r_contact *c=0; 01038 int proto, port; 01039 str host; 01040 struct dest_info dst_info; 01041 struct cell *t=0; 01042 struct sip_msg *req = 0; 01043 01044 if (!pcscf_use_ipsec && !pcscf_use_tls) return CSCF_RETURN_FALSE; 01045 01046 if(msg -> first_line.type == SIP_REQUEST) { 01047 /* on request, get the destination from the Request-URI */ 01048 struct sip_uri uri; 01049 str req_uri = msg->first_line.u.request.uri; 01050 if (parse_uri(req_uri.s,req_uri.len,&uri)<0){ 01051 LOG(L_ERR, "ERR:"M_NAME":P_security_relay: Error parsing Request-URI: <%.*s>\n",req_uri.len,req_uri.s); 01052 return CSCF_RETURN_FALSE; 01053 } 01054 if (uri.port_no==0) uri.port_no =5060; 01055 proto = uri.proto; 01056 host = uri.host; 01057 port = uri.port_no; 01058 } else { 01059 /* On response get the source from the first via in the corresponding request */ 01060 struct via_body *vb; 01061 req = cscf_get_request_from_reply(msg); 01062 if(req == NULL) { 01063 LOG(L_ERR, "ERR:"M_NAME":P_security_relay: Cannot get request for the transaction\n"); 01064 return CSCF_RETURN_FALSE; 01065 } 01066 vb = cscf_get_ue_via(req); 01067 if (vb->port==0) vb->port=5060; 01068 proto = vb->proto; 01069 host = vb->host; 01070 port = vb->port; 01071 } 01072 01073 len =