version 1.1.1.2, 2012/05/29 12:55:57
|
version 1.1.1.3, 2013/07/22 00:32:35
|
Line 1
|
Line 1
|
/* $Id$ */ |
/* $Id$ */ |
/* MiniUPnP project |
/* MiniUPnP project |
* (c) 2007-2010 Thomas Bernard | * (c) 2007-2012 Thomas Bernard |
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ |
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ |
* This software is subject to the conditions detailed |
* This software is subject to the conditions detailed |
* in the LICENCE file provided within the distribution */ |
* in the LICENCE file provided within the distribution */ |
Line 8
|
Line 8
|
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
#include <syslog.h> |
#include <syslog.h> |
|
#include <errno.h> |
#include <time.h> |
#include <time.h> |
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/socket.h> |
#include <sys/socket.h> |
#include <netinet/in.h> |
#include <netinet/in.h> |
#include <arpa/inet.h> |
#include <arpa/inet.h> |
|
|
|
#include "macros.h" |
#include "config.h" |
#include "config.h" |
#include "natpmp.h" |
#include "natpmp.h" |
#include "upnpglobalvars.h" |
#include "upnpglobalvars.h" |
#include "getifaddr.h" |
#include "getifaddr.h" |
#include "upnpredirect.h" |
#include "upnpredirect.h" |
#include "commonrdr.h" |
#include "commonrdr.h" |
|
#include "upnputils.h" |
|
|
#ifdef ENABLE_NATPMP |
#ifdef ENABLE_NATPMP |
|
|
int OpenAndConfNATPMPSocket(in_addr_t addr) |
int OpenAndConfNATPMPSocket(in_addr_t addr) |
{ |
{ |
int snatpmp; |
int snatpmp; |
|
int i = 1; |
snatpmp = socket(PF_INET, SOCK_DGRAM, 0/*IPPROTO_UDP*/); |
snatpmp = socket(PF_INET, SOCK_DGRAM, 0/*IPPROTO_UDP*/); |
if(snatpmp<0) |
if(snatpmp<0) |
{ |
{ |
syslog(LOG_ERR, "socket(natpmp): %m"); | syslog(LOG_ERR, "%s: socket(natpmp): %m", |
| "OpenAndConfNATPMPSocket"); |
return -1; |
return -1; |
} |
} |
else | if(setsockopt(snatpmp, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0) |
{ |
{ |
|
syslog(LOG_WARNING, "%s: setsockopt(natpmp, SO_REUSEADDR): %m", |
|
"OpenAndConfNATPMPSocket"); |
|
} |
|
if(!set_non_blocking(snatpmp)) |
|
{ |
|
syslog(LOG_WARNING, "%s: set_non_blocking(): %m", |
|
"OpenAndConfNATPMPSocket"); |
|
} |
|
{ |
struct sockaddr_in natpmp_addr; |
struct sockaddr_in natpmp_addr; |
memset(&natpmp_addr, 0, sizeof(natpmp_addr)); |
memset(&natpmp_addr, 0, sizeof(natpmp_addr)); |
natpmp_addr.sin_family = AF_INET; |
natpmp_addr.sin_family = AF_INET; |
natpmp_addr.sin_port = htons(NATPMP_PORT); |
natpmp_addr.sin_port = htons(NATPMP_PORT); |
//natpmp_addr.sin_addr.s_addr = INADDR_ANY; | /*natpmp_addr.sin_addr.s_addr = INADDR_ANY; */ |
natpmp_addr.sin_addr.s_addr = addr; |
natpmp_addr.sin_addr.s_addr = addr; |
if(bind(snatpmp, (struct sockaddr *)&natpmp_addr, sizeof(natpmp_addr)) < 0) |
if(bind(snatpmp, (struct sockaddr *)&natpmp_addr, sizeof(natpmp_addr)) < 0) |
{ |
{ |
Line 73 static void FillPublicAddressResponse(unsigned char *
|
Line 88 static void FillPublicAddressResponse(unsigned char *
|
{ |
{ |
#ifndef MULTIPLE_EXTERNAL_IP |
#ifndef MULTIPLE_EXTERNAL_IP |
char tmp[16]; |
char tmp[16]; |
|
UNUSED(senderaddr); |
|
|
if(use_ext_ip_addr) { |
if(use_ext_ip_addr) { |
inet_pton(AF_INET, use_ext_ip_addr, resp+8); |
inet_pton(AF_INET, use_ext_ip_addr, resp+8); |
Line 90 static void FillPublicAddressResponse(unsigned char *
|
Line 106 static void FillPublicAddressResponse(unsigned char *
|
} |
} |
#else |
#else |
struct lan_addr_s * lan_addr; |
struct lan_addr_s * lan_addr; |
|
|
for(lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next) { |
for(lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next) { |
if( (senderaddr & lan_addr->mask.s_addr) |
if( (senderaddr & lan_addr->mask.s_addr) |
== (lan_addr->addr.s_addr & lan_addr->mask.s_addr)) { |
== (lan_addr->addr.s_addr & lan_addr->mask.s_addr)) { |
Line 116 void ProcessIncomingNATPMPPacket(int s)
|
Line 133 void ProcessIncomingNATPMPPacket(int s)
|
n = recvfrom(s, req, sizeof(req), 0, |
n = recvfrom(s, req, sizeof(req), 0, |
(struct sockaddr *)&senderaddr, &senderaddrlen); |
(struct sockaddr *)&senderaddr, &senderaddrlen); |
if(n<0) { |
if(n<0) { |
syslog(LOG_ERR, "recvfrom(natpmp): %m"); | /* EAGAIN, EWOULDBLOCK and EINTR : silently ignore (retry next time) |
| * other errors : log to LOG_ERR */ |
| if(errno != EAGAIN && |
| errno != EWOULDBLOCK && |
| errno != EINTR) { |
| syslog(LOG_ERR, "recvfrom(natpmp): %m"); |
| } |
return; |
return; |
} |
} |
if(!inet_ntop(AF_INET, &senderaddr.sin_addr, |
if(!inet_ntop(AF_INET, &senderaddr.sin_addr, |
Line 209 void ProcessIncomingNATPMPPacket(int s)
|
Line 232 void ProcessIncomingNATPMPPacket(int s)
|
} |
} |
} else { |
} else { |
/* To improve the interworking between nat-pmp and |
/* To improve the interworking between nat-pmp and |
* UPnP, we should check that we remove only NAT-PMP | * UPnP, we should check that we remove only NAT-PMP |
* mappings */ |
* mappings */ |
r = _upnp_delete_redir(eport, proto); |
r = _upnp_delete_redir(eport, proto); |
/*syslog(LOG_DEBUG, "%hu %d r=%d", eport, proto, r);*/ |
/*syslog(LOG_DEBUG, "%hu %d r=%d", eport, proto, r);*/ |
Line 337 int CleanExpiredNATPMP()
|
Line 360 int CleanExpiredNATPMP()
|
return ScanNATPMPforExpiration(); |
return ScanNATPMPforExpiration(); |
/* check desc - this is important since we keep expiration time as part |
/* check desc - this is important since we keep expiration time as part |
* of the desc. |
* of the desc. |
* If the rule is renewed, timestamp and nextnatpmptoclean_timestamp | * If the rule is renewed, timestamp and nextnatpmptoclean_timestamp |
* can be different. In that case, the rule must not be removed ! */ |
* can be different. In that case, the rule must not be removed ! */ |
if(sscanf(desc, "NAT-PMP %u", ×tamp) == 1) { |
if(sscanf(desc, "NAT-PMP %u", ×tamp) == 1) { |
if(timestamp > nextnatpmptoclean_timestamp) |
if(timestamp > nextnatpmptoclean_timestamp) |
Line 400 void SendNATPMPPublicAddressChangeNotification(int * s
|
Line 423 void SendNATPMPPublicAddressChangeNotification(int * s
|
n = sendto(sockets[j], notif, 12, 0, |
n = sendto(sockets[j], notif, 12, 0, |
(struct sockaddr *)&sockname, sizeof(struct sockaddr_in)); |
(struct sockaddr *)&sockname, sizeof(struct sockaddr_in)); |
if(n < 0) |
if(n < 0) |
{ | { |
syslog(LOG_ERR, "%s: sendto(s_udp=%d): %m", |
syslog(LOG_ERR, "%s: sendto(s_udp=%d): %m", |
"SendNATPMPPublicAddressChangeNotification", sockets[j]); |
"SendNATPMPPublicAddressChangeNotification", sockets[j]); |
return; |
return; |
Line 410 void SendNATPMPPublicAddressChangeNotification(int * s
|
Line 433 void SendNATPMPPublicAddressChangeNotification(int * s
|
n = sendto(sockets[j], notif, 12, 0, |
n = sendto(sockets[j], notif, 12, 0, |
(struct sockaddr *)&sockname, sizeof(struct sockaddr_in)); |
(struct sockaddr *)&sockname, sizeof(struct sockaddr_in)); |
if(n < 0) |
if(n < 0) |
{ | { |
syslog(LOG_ERR, "%s: sendto(s_udp=%d): %m", |
syslog(LOG_ERR, "%s: sendto(s_udp=%d): %m", |
"SendNATPMPPublicAddressChangeNotification", sockets[j]); |
"SendNATPMPPublicAddressChangeNotification", sockets[j]); |
return; |
return; |