Definition in file nat_helper.c.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "../../parser/msg_parser.h"
#include "../../msg_translator.h"
#include "../../parser/parser_f.h"
#include "../../parser/contact/contact.h"
#include "../../parser/contact/parse_contact.h"
#include "../../parser/parse_uri.h"
#include "../../parser/hf.h"
#include "../../ut.h"
#include "../../forward.h"
#include "mod.h"
#include "registrar_storage.h"
#include "nat_helper.h"
Go to the source code of this file.
Defines | |
| #define | READ(val) (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24)) |
| #define | advance(_ptr, _n, _str, _error) |
| #define | one_of_16(_x, _t) |
| #define | one_of_8(_x, _t) |
Functions | |
| int | is1918addr (str *saddr) |
| Test if IP address pointed to by saddr belongs to RFC1918 networks. | |
| 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 | nat_prepare_1918addr () |
| Fixes the 1918 private networks addresses. | |
| static int | get_contact_uri (struct sip_msg *_m, struct sip_uri *uri, contact_t **_c) |
| Extract URI from the Contact header field. | |
| static int | via_1918 (struct sip_msg *msg) |
| Checks if the first Via in the message is a 1918 address. | |
| int | nat_uac_test (struct sip_msg *msg) |
| Tests if the message was received from behind a NAT. | |
| r_nat_dest * | nat_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. | |
| int | nat_send_ping (r_contact *c) |
| Pings a contact to keep the NAT pinhole alive. | |
Variables | |
| static const char | udp_ping [2] = { 10, 13} |
| message to ping with - CRLF | |
| int | pcscf_nat_enable |
| whether to enable NAT | |
| int | pcscf_nat_ping |
| whether to ping anything | |
| int | pcscf_nat_pingall |
| whether to ping also the UA that don't look like being behind a NAT | |
| int | pcscf_nat_detection_type |
| the NAT detection tests | |
| network_t | nets_1918 [] |
| #define READ | ( | val | ) | (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24)) |
| #define advance | ( | _ptr, | |||
| _n, | |||||
| _str, | |||||
| _error | ) |
Value:
do{\ if ((_ptr)+(_n)>(_str).s+(_str).len)\ goto _error;\ (_ptr) = (_ptr) + (_n);\ }while(0);
Definition at line 250 of file nat_helper.c.
Referenced by check_content_type().
| #define one_of_16 | ( | _x, | |||
| _t | ) |
Value:
(_x==_t[0]||_x==_t[15]||_x==_t[8]||_x==_t[2]||_x==_t[3]||_x==_t[4]\
||_x==_t[5]||_x==_t[6]||_x==_t[7]||_x==_t[1]||_x==_t[9]||_x==_t[10]\
||_x==_t[11]||_x==_t[12]||_x==_t[13]||_x==_t[14])
Definition at line 256 of file nat_helper.c.
Referenced by check_content_type().
| #define one_of_8 | ( | _x, | |||
| _t | ) |
Value:
(_x==_t[0]||_x==_t[7]||_x==_t[1]||_x==_t[2]||_x==_t[3]||_x==_t[4]\
||_x==_t[5]||_x==_t[6])
Definition at line 260 of file nat_helper.c.
Referenced by check_content_type().
| int is1918addr | ( | str * | saddr | ) |
Test if IP address pointed to by saddr belongs to RFC1918 networks.
| saddr | - string with address to check |
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 }
| 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 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 }
| static int get_contact_uri | ( | struct sip_msg * | _m, | |
| struct sip_uri * | uri, | |||
| contact_t ** | _c | |||
| ) | [inline, static] |
Extract URI from the Contact header field.
| _m | - the SIP message | |
| uri | - URI to fill | |
| _c | - contact to fill |
Definition at line 358 of file nat_helper.c.
References NULL.
00359 { 00360 00361 if ((parse_headers(_m, HDR_CONTACT_F, 0) == -1) || !_m->contact) 00362 return -1; 00363 if (!_m->contact->parsed && parse_contact(_m->contact) < 0) { 00364 LOG(L_ERR, "get_contact_uri: Error while parsing Contact body\n"); 00365 return -1; 00366 } 00367 *_c = ((contact_body_t*)_m->contact->parsed)->contacts; 00368 if (*_c == NULL) { 00369 LOG(L_DBG, "get_contact_uri: Error while parsing Contact body or star contact\n"); 00370 return -1; 00371 } 00372 if (parse_uri((*_c)->uri.s, (*_c)->uri.len, uri) < 0 || uri->host.len <= 0) { 00373 LOG(L_ERR, "get_contact_uri: Error while parsing Contact URI\n"); 00374 return -1; 00375 } 00376 return 0; 00377 }
| static int via_1918 | ( | struct sip_msg * | msg | ) | [static] |
Checks if the first Via in the message is a 1918 address.
| msg | - the SIP message |
Definition at line 399 of file nat_helper.c.
References is1918addr().
Referenced by nat_uac_test().
00399 { 00400 return (is1918addr(&(msg->via1->host)) == 1) ? 1 : 0; 00401 }
| int nat_uac_test | ( | struct sip_msg * | msg | ) |
Tests if the message was received from behind a NAT.
| msg | - the SIP message |
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 }
| r_nat_dest* nat_msg_origin | ( | struct sip_msg * | msg | ) |
Retrieves the originating source of a message into a r_nat_dest structure.
| msg | - the SIP message | |
| pinhole | - where to save to |
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.
| msg | - the SIP message |
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 }
| int nat_send_ping | ( | r_contact * | c | ) |
Pings a contact to keep the NAT pinhole alive.
| c | - the r_contact to ping |
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 }
const char udp_ping[2] = { 10, 13} [static] |
message to ping with - CRLF
Definition at line 241 of file nat_helper.c.
Referenced by nat_send_ping().
| int pcscf_nat_enable |
| int pcscf_nat_ping |
Initial value:
{
{"10.0.0.0", 0, 0xffffffffu << 24},
{"172.16.0.0", 0, 0xffffffffu << 20},
{"192.168.0.0", 0, 0xffffffffu << 16},
{NULL, 0, 0}
}
Definition at line 265 of file nat_helper.c.
Referenced by is1918addr(), nat_prepare_1918addr(), and rfc1918address().
1.5.2