miniupnpd: start work to enable IPv6 PCP operations
This commit is contained in:
parent
f70484f27f
commit
ad88cc0819
|
@ -1,4 +1,7 @@
|
|||
$Id: Changelog.txt,v 1.365 2014/03/14 21:26:34 nanard Exp $
|
||||
$Id: Changelog.txt,v 1.366 2014/03/24 11:03:50 nanard Exp $
|
||||
|
||||
2014/03/24:
|
||||
start work to enable IPv6 PCP operations
|
||||
|
||||
2014/03/14:
|
||||
reject renewal of subscribtion that already timeouted
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile.linux,v 1.81 2014/01/27 10:06:58 nanard Exp $
|
||||
# $Id: Makefile.linux,v 1.84 2014/03/24 10:43:25 nanard Exp $
|
||||
# MiniUPnP project
|
||||
# (c) 2006-2014 Thomas Bernard
|
||||
# http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
|
@ -253,9 +253,10 @@ minissdp.o: upnputils.h getroute.h asyncsendto.h codelength.h
|
|||
natpmp.o: macros.h config.h natpmp.h upnpglobalvars.h upnppermissions.h
|
||||
natpmp.o: miniupnpdtypes.h getifaddr.h upnpredirect.h commonrdr.h upnputils.h
|
||||
natpmp.o: asyncsendto.h
|
||||
pcpserver.o: config.h pcpserver.h macros.h upnpglobalvars.h upnppermissions.h
|
||||
pcpserver.o: miniupnpdtypes.h pcplearndscp.h upnpredirect.h commonrdr.h
|
||||
pcpserver.o: getifaddr.h asyncsendto.h pcp_msg_struct.h
|
||||
pcpserver.o: config.h pcpserver.h natpmp.h macros.h upnpglobalvars.h
|
||||
pcpserver.o: upnppermissions.h miniupnpdtypes.h pcplearndscp.h upnpredirect.h
|
||||
pcpserver.o: commonrdr.h getifaddr.h asyncsendto.h upnputils.h
|
||||
pcpserver.o: pcp_msg_struct.h netfilter/iptcrdr.h commonrdr.h
|
||||
upnpevents.o: config.h upnpevents.h miniupnpdpath.h upnpglobalvars.h
|
||||
upnpevents.o: upnppermissions.h miniupnpdtypes.h upnpdescgen.h upnputils.h
|
||||
upnputils.o: config.h upnputils.h upnpglobalvars.h upnppermissions.h
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: miniupnpd.c,v 1.189 2014/03/10 11:04:52 nanard Exp $ */
|
||||
/* $Id: miniupnpd.c,v 1.190 2014/03/24 10:49:44 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006-2014 Thomas Bernard
|
||||
|
@ -1460,6 +1460,9 @@ main(int argc, char * * argv)
|
|||
#ifdef ENABLE_NATPMP
|
||||
int * snatpmp = NULL; /* also used for PCP */
|
||||
#endif
|
||||
#if defined(ENABLE_IPV6) && defined(ENABLE_PCP)
|
||||
int spcp_v6 = -1;
|
||||
#endif
|
||||
#ifdef ENABLE_NFQUEUE
|
||||
int nfqh = -1;
|
||||
#endif
|
||||
|
@ -1648,6 +1651,10 @@ main(int argc, char * * argv)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_IPV6) && defined(ENABLE_PCP)
|
||||
spcp_v6 = OpenAndConfPCPv6Socket();
|
||||
#endif
|
||||
|
||||
/* for miniupnpdctl */
|
||||
#ifdef USE_MINIUPNPDCTL
|
||||
sctl = OpenAndConfCtlUnixSocket("/var/run/miniupnpd.ctl");
|
||||
|
@ -1842,6 +1849,12 @@ main(int argc, char * * argv)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(ENABLE_IPV6) && defined(ENABLE_PCP)
|
||||
if(spcp_v6 >= 0) {
|
||||
FD_SET(spcp_v6, &readset);
|
||||
max_fd = MAX(max_fd, spcp_v6);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_MINIUPNPDCTL
|
||||
if(sctl >= 0) {
|
||||
FD_SET(sctl, &readset);
|
||||
|
@ -1978,19 +1991,23 @@ main(int argc, char * * argv)
|
|||
{
|
||||
unsigned char msg_buff[PCP_MAX_LEN];
|
||||
struct sockaddr_in senderaddr;
|
||||
socklen_t senderaddrlen;
|
||||
int len;
|
||||
memset(msg_buff, 0, PCP_MAX_LEN);
|
||||
len = ReceiveNATPMPOrPCPPacket(snatpmp[i], &senderaddr,
|
||||
msg_buff, sizeof(msg_buff));
|
||||
senderaddrlen = sizeof(senderaddr);
|
||||
len = ReceiveNATPMPOrPCPPacket(snatpmp[i],
|
||||
(struct sockaddr *)&senderaddr,
|
||||
&senderaddrlen,
|
||||
msg_buff, sizeof(msg_buff));
|
||||
if (len < 1)
|
||||
continue;
|
||||
#ifdef ENABLE_PCP
|
||||
if (msg_buff[0]==0) { /* version equals to 0 -> means NAT-PMP */
|
||||
ProcessIncomingNATPMPPacket(snatpmp[i], msg_buff, len,
|
||||
&senderaddr);
|
||||
&senderaddr);
|
||||
} else { /* everything else can be PCP */
|
||||
ProcessIncomingPCPPacket(snatpmp[i], msg_buff, len,
|
||||
&senderaddr);
|
||||
(struct sockaddr *)&senderaddr);
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -1998,6 +2015,25 @@ main(int argc, char * * argv)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(ENABLE_IPV6) && defined(ENABLE_PCP)
|
||||
/* in IPv6, only PCP is supported, not NAT-PMP */
|
||||
if(spcp_v6 >= 0 && FD_ISSET(spcp_v6, &readset))
|
||||
{
|
||||
unsigned char msg_buff[PCP_MAX_LEN];
|
||||
struct sockaddr_in6 senderaddr;
|
||||
socklen_t senderaddrlen;
|
||||
int len;
|
||||
memset(msg_buff, 0, PCP_MAX_LEN);
|
||||
senderaddrlen = sizeof(senderaddr);
|
||||
len = ReceiveNATPMPOrPCPPacket(spcp_v6,
|
||||
(struct sockaddr *)&senderaddr,
|
||||
&senderaddrlen,
|
||||
msg_buff, sizeof(msg_buff));
|
||||
if(len >= 1)
|
||||
ProcessIncomingPCPPacket(spcp_v6, msg_buff, len,
|
||||
(struct sockaddr *)&senderaddr);
|
||||
}
|
||||
#endif
|
||||
/* process SSDP packets */
|
||||
if(sudp >= 0 && FD_ISSET(sudp, &readset))
|
||||
|
@ -2119,6 +2155,13 @@ shutdown:
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(ENABLE_IPV6) && defined(ENABLE_PCP)
|
||||
if(spcp_v6 >= 0)
|
||||
{
|
||||
close(spcp_v6);
|
||||
spcp_v6 = -1;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_MINIUPNPDCTL
|
||||
if(sctl>=0)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: natpmp.c,v 1.39 2014/03/07 10:43:30 nanard Exp $ */
|
||||
/* $Id: natpmp.c,v 1.43 2014/03/24 10:49:45 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* (c) 2007-2014 Thomas Bernard
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
|
@ -34,13 +34,13 @@ int OpenAndConfNATPMPSocket(in_addr_t addr)
|
|||
snatpmp = socket(PF_INET, SOCK_DGRAM, 0/*IPPROTO_UDP*/);
|
||||
if(snatpmp<0)
|
||||
{
|
||||
syslog(LOG_ERR, "%s: socket(natpmp): %m",
|
||||
syslog(LOG_ERR, "%s: socket(): %m",
|
||||
"OpenAndConfNATPMPSocket");
|
||||
return -1;
|
||||
}
|
||||
if(setsockopt(snatpmp, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
|
||||
{
|
||||
syslog(LOG_WARNING, "%s: setsockopt(natpmp, SO_REUSEADDR): %m",
|
||||
syslog(LOG_WARNING, "%s: setsockopt(SO_REUSEADDR): %m",
|
||||
"OpenAndConfNATPMPSocket");
|
||||
}
|
||||
if(!set_non_blocking(snatpmp))
|
||||
|
@ -57,7 +57,8 @@ int OpenAndConfNATPMPSocket(in_addr_t addr)
|
|||
natpmp_addr.sin_addr.s_addr = addr;
|
||||
if(bind(snatpmp, (struct sockaddr *)&natpmp_addr, sizeof(natpmp_addr)) < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "bind(natpmp): %m");
|
||||
syslog(LOG_ERR, "%s: bind(): %m",
|
||||
"OpenAndConfNATPMPSocket");
|
||||
close(snatpmp);
|
||||
return -1;
|
||||
}
|
||||
|
@ -67,22 +68,25 @@ int OpenAndConfNATPMPSocket(in_addr_t addr)
|
|||
|
||||
int OpenAndConfNATPMPSockets(int * sockets)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
struct lan_addr_s * lan_addr;
|
||||
for(i = 0, lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next, i++)
|
||||
for(i = 0, lan_addr = lan_addrs.lh_first;
|
||||
lan_addr != NULL;
|
||||
lan_addr = lan_addr->list.le_next)
|
||||
{
|
||||
sockets[i] = OpenAndConfNATPMPSocket(lan_addr->addr.s_addr);
|
||||
if(sockets[i] < 0)
|
||||
{
|
||||
for(j=0; j<i; j++)
|
||||
{
|
||||
close(sockets[j]);
|
||||
sockets[j] = -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
goto error;
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
while(--i >= 0)
|
||||
{
|
||||
close(sockets[i]);
|
||||
sockets[i] = -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void FillPublicAddressResponse(unsigned char * resp, in_addr_t senderaddr)
|
||||
|
@ -124,15 +128,15 @@ static void FillPublicAddressResponse(unsigned char * resp, in_addr_t senderaddr
|
|||
* The sender information is stored in senderaddr.
|
||||
* Returns number of bytes recevied, even if number is negative.
|
||||
*/
|
||||
int ReceiveNATPMPOrPCPPacket(int s, struct sockaddr_in* senderaddr,
|
||||
unsigned char *msg_buff, size_t msg_buff_size)
|
||||
int ReceiveNATPMPOrPCPPacket(int s, struct sockaddr * senderaddr,
|
||||
socklen_t * senderaddrlen,
|
||||
unsigned char * msg_buff, size_t msg_buff_size)
|
||||
{
|
||||
|
||||
socklen_t senderaddrlen = sizeof(*senderaddr);
|
||||
int n;
|
||||
|
||||
n = recvfrom(s, msg_buff, msg_buff_size, 0,
|
||||
(struct sockaddr *)senderaddr, &senderaddrlen);
|
||||
senderaddr, senderaddrlen);
|
||||
|
||||
if(n<0) {
|
||||
/* EAGAIN, EWOULDBLOCK and EINTR : silently ignore (retry next time)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: natpmp.h,v 1.11 2014/02/01 17:17:35 nanard Exp $ */
|
||||
/* $Id: natpmp.h,v 1.12 2014/03/24 10:49:46 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* author : Thomas Bernard
|
||||
* website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
|
@ -20,11 +20,12 @@
|
|||
|
||||
int OpenAndConfNATPMPSockets(int * sockets);
|
||||
|
||||
int ReceiveNATPMPOrPCPPacket(int s, struct sockaddr_in* senderaddr,
|
||||
unsigned char *msg_buff, size_t msg_buff_size);
|
||||
int ReceiveNATPMPOrPCPPacket(int s, struct sockaddr * senderaddr,
|
||||
socklen_t * senderaddrlen,
|
||||
unsigned char * msg_buff, size_t msg_buff_size);
|
||||
|
||||
void ProcessIncomingNATPMPPacket(int s, unsigned char *msg_buff, int len,
|
||||
struct sockaddr_in *senderaddr);
|
||||
void ProcessIncomingNATPMPPacket(int s, unsigned char * msg_buff, int len,
|
||||
struct sockaddr_in * senderaddr);
|
||||
|
||||
void SendNATPMPPublicAddressChangeNotification(int * sockets, int n_sockets);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: pcpserver.c,v 1.20 2014/03/22 12:06:15 nanard Exp $ */
|
||||
/* $Id: pcpserver.c,v 1.24 2014/03/24 11:03:52 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* Website : http://miniupnp.free.fr/
|
||||
* Author : Peter Tatrai
|
||||
|
@ -53,6 +53,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <syslog.h>
|
||||
|
||||
#include "pcpserver.h"
|
||||
#include "natpmp.h"
|
||||
#include "macros.h"
|
||||
#include "upnpglobalvars.h"
|
||||
#include "pcplearndscp.h"
|
||||
|
@ -60,6 +61,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "commonrdr.h"
|
||||
#include "getifaddr.h"
|
||||
#include "asyncsendto.h"
|
||||
#include "upnputils.h"
|
||||
#include "pcp_msg_struct.h"
|
||||
|
||||
#ifdef PCP_PEER
|
||||
|
@ -117,7 +119,7 @@ typedef struct pcp_info {
|
|||
uint8_t is_peer_op;
|
||||
int thirdp_present; /* indicate presence of the options */
|
||||
int pfailure_present;
|
||||
char senderaddrstr[INET_ADDRSTRLEN];
|
||||
char senderaddrstr[INET_ADDRSTRLEN]; /* only if IPv4 sender */
|
||||
|
||||
} pcp_info_t;
|
||||
|
||||
|
@ -1385,19 +1387,29 @@ static void createPCPResponse(unsigned char *response, pcp_info_t *pcp_msg_info)
|
|||
}
|
||||
|
||||
int ProcessIncomingPCPPacket(int s, unsigned char *buff, int len,
|
||||
struct sockaddr_in *senderaddr)
|
||||
const struct sockaddr * senderaddr)
|
||||
{
|
||||
pcp_info_t pcp_msg_info;
|
||||
#ifdef DEBUG
|
||||
char addr_str[64];
|
||||
#endif
|
||||
|
||||
memset(&pcp_msg_info, 0, sizeof(pcp_info_t));
|
||||
|
||||
if(!inet_ntop(AF_INET, &senderaddr->sin_addr,
|
||||
pcp_msg_info.senderaddrstr,
|
||||
sizeof(pcp_msg_info.senderaddrstr))) {
|
||||
syslog(LOG_ERR, "inet_ntop(pcpserver): %m");
|
||||
if(senderaddr->sa_family == AF_INET) {
|
||||
const struct sockaddr_in * senderaddr_v4;
|
||||
senderaddr_v4 = (const struct sockaddr_in *)senderaddr;
|
||||
if(!inet_ntop(AF_INET, &senderaddr_v4->sin_addr,
|
||||
pcp_msg_info.senderaddrstr,
|
||||
sizeof(pcp_msg_info.senderaddrstr))) {
|
||||
syslog(LOG_ERR, "inet_ntop(pcpserver): %m");
|
||||
}
|
||||
}
|
||||
syslog(LOG_DEBUG, "PCP request received from %s:%hu %dbytes",
|
||||
pcp_msg_info.senderaddrstr, ntohs(senderaddr->sin_port), len);
|
||||
#ifdef DEBUG
|
||||
if(sockaddr_to_string(senderaddr, addr_str, sizeof(addr_str)))
|
||||
syslog(LOG_DEBUG, "PCP request received from %s %dbytes",
|
||||
addr_str, len);
|
||||
#endif
|
||||
|
||||
if(buff[1] & 128) {
|
||||
/* discarding PCP responses silently */
|
||||
|
@ -1421,4 +1433,44 @@ int ProcessIncomingPCPPacket(int s, unsigned char *buff, int len,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
int OpenAndConfPCPv6Socket(void)
|
||||
{
|
||||
int s;
|
||||
int i = 1;
|
||||
struct sockaddr_in6 addr;
|
||||
s = socket(PF_INET6, SOCK_DGRAM, 0/*IPPROTO_UDP*/);
|
||||
if(s < 0) {
|
||||
syslog(LOG_ERR, "%s: socket(): %m", "OpenAndConfPCPv6Socket");
|
||||
return -1;
|
||||
}
|
||||
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0) {
|
||||
syslog(LOG_WARNING, "%s: setsockopt(SO_REUSEADDR): %m",
|
||||
"OpenAndConfPCPv6Socket");
|
||||
}
|
||||
#ifdef IPV6_V6ONLY
|
||||
/* force IPV6 only for IPV6 socket.
|
||||
* see http://www.ietf.org/rfc/rfc3493.txt section 5.3 */
|
||||
if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &i, sizeof(i)) < 0) {
|
||||
syslog(LOG_WARNING, "%s: setsockopt(IPV6_V6ONLY): %m",
|
||||
"OpenAndConfPCPv6Socket");
|
||||
}
|
||||
#endif
|
||||
if(!set_non_blocking(s)) {
|
||||
syslog(LOG_WARNING, "%s: set_non_blocking(): %m",
|
||||
"OpenAndConfPCPv6Socket");
|
||||
}
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin6_family = AF_INET6;
|
||||
addr.sin6_port = htons(NATPMP_PORT);
|
||||
addr.sin6_addr = in6addr_any;
|
||||
if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
syslog(LOG_ERR, "%s: bind(): %m", "OpenAndConfPCPv6Socket");
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
#endif /*ENABLE_IPV6*/
|
||||
#endif /*ENABLE_PCP*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: pcpserver.h,v 1.2 2013/12/13 15:48:39 nanard Exp $ */
|
||||
/* $Id: pcpserver.h,v 1.3 2014/03/24 10:49:46 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* Website : http://miniupnp.free.fr/
|
||||
* Author : Peter Tatrai
|
||||
|
@ -36,12 +36,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define PCP_MIN_LEN 24
|
||||
#define PCP_MAX_LEN 1100
|
||||
|
||||
struct sockaddr_in;
|
||||
struct sockaddr;
|
||||
|
||||
/*
|
||||
* returns 0 upon success 1 otherwise
|
||||
*/
|
||||
int ProcessIncomingPCPPacket(int s, unsigned char *msg_buff, int len,
|
||||
struct sockaddr_in *senderaddr);
|
||||
const struct sockaddr *senderaddr);
|
||||
|
||||
/*
|
||||
* returns the socket
|
||||
*/
|
||||
int OpenAndConfPCPv6Socket(void);
|
||||
|
||||
#endif /* PCPSERVER_H_INCLUDED */
|
||||
|
|
Loading…
Reference in New Issue