nat_helper.h File Reference


Detailed Description

Proxy-CSCF - NAT helper for signalling.

Note:
Taken from SER nathelper module
Author:
adapted for the pcscf module by Marius Corici mco -at- fokus dot fraunhofer dot de

Definition in file nat_helper.h.

#include "registrar_storage.h"

Go to the source code of this file.

Data Structures

struct  network_t
 Network structure. More...

Defines

#define NAT_UAC_TEST_C_1918   0x01
 NAT test for Contact.
#define NAT_UAC_TEST_RCVD   0x02
 NAT test for received from.
#define NAT_UAC_TEST_V_1918   0x04
 NAT test for Via.
#define NAT_UAC_TEST_S_1918   0x08
 NAT test for SDP?
#define NAT_UAC_TEST_RPORT   0x10
 NAT test for rport.

Functions

char * ser_memmem (const void *b1, const void *b2, size_t len1, size_t len2)
 ser_memmem() returns the location of the first occurrence of data pattern b2 of size len2 in memory block b1 of size len1 or NULL if none is found.
int is1918addr (str *saddr)
 Test if IP address pointed to by saddr belongs to RFC1918 networks.
int nat_send_ping (r_contact *c)
 Pings a contact to keep the NAT pinhole alive.
int nat_uac_test (struct sip_msg *msg)
 Tests if the message was received from behind a NAT.
int nat_prepare_1918addr ()
 Fixes the 1918 private networks addresses.
r_nat_destnat_msg_origin (struct sip_msg *msg)
 Retrieves the originating source of a message into a r_nat_dest structure.
int requires_nat (struct sip_msg *msg)
 Finds if a NAT pinhole would be required to reach this user.


Define Documentation

#define NAT_UAC_TEST_C_1918   0x01

NAT test for Contact.

Definition at line 102 of file nat_helper.h.

#define NAT_UAC_TEST_RCVD   0x02

NAT test for received from.

Definition at line 104 of file nat_helper.h.

Referenced by nat_uac_test().

#define NAT_UAC_TEST_V_1918   0x04

NAT test for Via.

Definition at line 106 of file nat_helper.h.

Referenced by nat_uac_test().

#define NAT_UAC_TEST_S_1918   0x08

NAT test for SDP?

Definition at line 108 of file nat_helper.h.

#define NAT_UAC_TEST_RPORT   0x10

NAT test for rport.

Definition at line 110 of file nat_helper.h.

Referenced by nat_uac_test().


Function Documentation

char* ser_memmem ( const void *  b1,
const void *  b2,
size_t  len1,
size_t  len2 
)

ser_memmem() returns the location of the first occurrence of data pattern b2 of size len2 in memory block b1 of size len1 or NULL if none is found.

Obtained from NetBSD.

Definition at line 309 of file nat_helper.c.

References NULL.

Referenced by extract_mediaip(), extract_mediaport(), find_sdp_line(), and force_rtp_proxy2_f().

00310 {
00311     /* Initialize search pointer */
00312     char *sp = (char *) b1;
00313 
00314     /* Initialize pattern pointer */
00315     char *pp = (char *) b2;
00316 
00317     /* Initialize end of search address space pointer */
00318     char *eos = sp + len1 - len2;
00319 
00320     /* Sanity check */
00321     if(!(b1 && b2 && len1 && len2))
00322         return NULL;
00323 
00324     while (sp <= eos) {
00325         if (*sp == *pp)
00326             if (memcmp(sp, pp, len2) == 0)
00327                 return sp;
00328 
00329             sp++;
00330     }
00331 
00332     return NULL;
00333 }

int is1918addr ( str *  saddr  ) 

Test if IP address pointed to by saddr belongs to RFC1918 networks.

Parameters:
saddr - string with address to check
Returns:
if the network is private one

Definition at line 278 of file nat_helper.c.

References network_t::cnetaddr, nets_1918, and NULL.

Referenced by via_1918().

00278                            {
00279     struct in_addr addr;
00280     uint32_t netaddr;
00281     int i, rval;
00282     char backup;
00283 
00284     rval = -1;
00285     backup = saddr->s[saddr->len];
00286     saddr->s[saddr->len] = '\0';
00287     if (inet_aton(saddr->s, &addr) != 1)
00288         goto is1918addr_end;
00289     netaddr = ntohl(addr.s_addr);
00290     for (i = 0; nets_1918[i].cnetaddr != NULL; i++) {
00291         if ((netaddr & nets_1918[i].mask) == nets_1918[i].netaddr) {
00292             rval = 1;
00293             goto is1918addr_end;
00294         }
00295     }
00296     rval = 0;
00297 
00298 is1918addr_end:
00299     saddr->s[saddr->len] = backup;
00300     return rval;
00301 }

int nat_send_ping ( r_contact c  ) 

Pings a contact to keep the NAT pinhole alive.

Parameters:
c - the r_contact to ping
Returns:
1 on success, -1 on failure

Definition at line 469 of file nat_helper.c.

References M_NAME, _r_nat_dest::nat_addr, _r_nat_dest::nat_port, NULL, _r_contact::pinhole, _r_contact::transport, and udp_ping.

00469                                 {
00470     struct dest_info dst;
00471     
00472     if(c->pinhole == NULL)
00473         return 1;
00474     if(c->transport != PROTO_UDP && c->transport != PROTO_NONE)
00475         return 1;
00476     init_dest_info(&dst);
00477     dst.proto = PROTO_UDP;
00478     
00479     memset(&(dst.to), 0, sizeof(union sockaddr_union));
00480     dst.to.s.sa_family=c->pinhole->nat_addr.af;
00481     switch(dst.to.s.sa_family) {
00482         case AF_INET6:
00483             memcpy(&dst.to.sin6.sin6_addr, c->pinhole->nat_addr.u.addr, c->pinhole->nat_addr.len);
00484             //dst.to.sin6.sin6_len=sizeof(struct sockaddr_in6);
00485             dst.to.sin6.sin6_port=htons(c->pinhole->nat_port);
00486             break;
00487         case AF_INET:
00488             memcpy(&dst.to.sin.sin_addr, c->pinhole->nat_addr.u.addr, c->pinhole->nat_addr.len);
00489             //dst.to.sin.sin_len=sizeof(struct sockaddr_in);
00490             dst.to.sin.sin_port=htons(c->pinhole->nat_port);
00491             break;
00492         default:
00493             LOG(L_CRIT,"CRIT:"M_NAME":nat_send_ping: unknown address family %d\n", dst.to.s.sa_family);
00494             return -1;
00495     }
00496     dst.send_sock=get_send_socket(0, &dst.to, PROTO_UDP);
00497     if(dst.send_sock == NULL) {
00498         LOG(L_ERR,"ERR:"M_NAME":nat_send_ping: cannot get sending socket\n");
00499         return -1;
00500     }
00501     udp_send(&dst, (char *)udp_ping, sizeof(udp_ping));
00502     return 1; 
00503 }

int nat_uac_test ( struct sip_msg *  msg  ) 

Tests if the message was received from behind a NAT.

Definition at line 408 of file nat_helper.c.

References NAT_UAC_TEST_RCVD, NAT_UAC_TEST_RPORT, NAT_UAC_TEST_V_1918, pcscf_nat_detection_type, pcscf_nat_pingall, and via_1918().

Referenced by nat_msg_origin(), and requires_nat().

00408                                        {
00409 
00410     if(pcscf_nat_pingall)
00411         return 1;
00412         
00413     if((pcscf_nat_detection_type && NAT_UAC_TEST_RPORT) && 
00414         (msg->rcv.src_port != (msg-> via1->port ? msg->via1->port:SIP_PORT)))
00415         return 1;
00416     
00417     if((pcscf_nat_detection_type & NAT_UAC_TEST_RCVD) && received_test(msg))
00418         return 1;
00419     
00420 //  if((pcscf_nat_detection_type & NAT_UAC_TEST_C_1918) && contact_1918(msg))
00421         //return 1;
00422     
00423 //  if((pcscf_nat_detection_type & NAT_UAC_TEST_S_1918) && sdp_1918(msg))
00424 //      return 1;
00425         
00426     if((pcscf_nat_detection_type & NAT_UAC_TEST_V_1918) && via_1918(msg))
00427         return 1;
00428     
00429     return 0;
00430 }

int nat_prepare_1918addr (  ) 

Fixes the 1918 private networks addresses.

Definition at line 338 of file nat_helper.c.

References network_t::cnetaddr, network_t::mask, network_t::netaddr, nets_1918, and NULL.

Referenced by mod_init().

00338                            {
00339     int i;
00340     struct in_addr addr;
00341     
00342     /* Prepare 1918 networks list */
00343     for (i = 0; nets_1918[i].cnetaddr != NULL; i++) {
00344         if (inet_aton(nets_1918[i].cnetaddr, &addr) != 1)
00345             abort();
00346         nets_1918[i].netaddr = ntohl(addr.s_addr) & nets_1918[i].mask;
00347     }
00348     return 1;
00349 }

r_nat_dest* nat_msg_origin ( struct sip_msg *  msg  ) 

Retrieves the originating source of a message into a r_nat_dest structure.

Parameters:
msg - the SIP message
pinhole - where to save to
Returns:
1 on success, -1 on error

Definition at line 438 of file nat_helper.c.

References M_NAME, _r_nat_dest::nat_addr, nat_uac_test(), NULL, pcscf_nat_enable, and pcscf_nat_pingall.

Referenced by update_contacts().

00438                                                  {
00439     r_nat_dest *pinhole=NULL;
00440     if (!pcscf_nat_enable) return NULL;
00441     if(pcscf_nat_pingall || nat_uac_test(msg)) {
00442         pinhole = shm_malloc(sizeof(r_nat_dest));
00443         if (pinhole == NULL) {
00444             LOG(L_ERR,"ERR:"M_NAME":nat_msg_origin:no memory\n");
00445             return NULL;
00446         }
00447         memcpy(&pinhole->nat_addr, &msg->rcv.src_ip, sizeof(struct ip_addr));
00448         pinhole -> nat_port = msg -> rcv.src_port;
00449     }
00450     return pinhole;
00451 }

int requires_nat ( struct sip_msg *  msg  ) 

Finds if a NAT pinhole would be required to reach this user.

Parameters:
msg - the SIP message
Returns:
1 if yes, 0 if not

Definition at line 458 of file nat_helper.c.

References nat_uac_test(), pcscf_nat_enable, and pcscf_nat_pingall.

Referenced by P_save_location().

00459 {
00460     return pcscf_nat_enable && (pcscf_nat_pingall || nat_uac_test(msg));
00461 }


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