miniupnpd: Allow to use two different network interfaces for IPv4 and IPv6 internet

-i / -I
ext_ifname= / ext_ifname6=

see :
df906367be/
thanks to "sfstudio"
This commit is contained in:
Thomas Bernard 2019-05-21 10:42:40 +02:00
parent f89d01d06a
commit a1ceec3dba
No known key found for this signature in database
GPG Key ID: 0FF11B67A5C0863C
10 changed files with 93 additions and 21 deletions

View File

@ -1,4 +1,7 @@
$Id: Changelog.txt,v 1.446 2019/04/09 20:04:32 nanard Exp $ $Id: Changelog.txt,v 1.448 2019/05/21 08:39:42 nanard Exp $
2019/05/21:
Allow to use two different network interfaces for IPv4 and IPv6 internet
2019/05/02: 2019/05/02:
Fix ssdp notify on unrelated interfaces Fix ssdp notify on unrelated interfaces

View File

@ -152,6 +152,10 @@ UPNP requests forwarding is not implemented.
It is however possible to use STUN. See the ext_perform_stun / ext_stun_host It is however possible to use STUN. See the ext_perform_stun / ext_stun_host
/ ext_stun_port options. / ext_stun_port options.
it is also possible to set a different interface for IPv6 WAN
ext_ifname=eth0
ext_ifname6=sit0
miniupnpd supports some kind of security check for allowing or disallowing miniupnpd supports some kind of security check for allowing or disallowing
redirection to be made. The UPnP permission rules are read from the redirection to be made. The UPnP permission rules are read from the
miniupnpd.conf configuration file. miniupnpd.conf configuration file.

View File

@ -1,4 +1,4 @@
/* $Id: miniupnpd.c,v 1.232 2018/07/06 12:35:26 nanard Exp $ */ /* $Id: miniupnpd.c,v 1.235 2019/05/21 08:39:43 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project * MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
@ -1178,6 +1178,11 @@ init(int argc, char * * argv, struct runtime_vars * v)
case UPNPEXT_IFNAME: case UPNPEXT_IFNAME:
ext_if_name = ary_options[i].value; ext_if_name = ary_options[i].value;
break; break;
#ifdef ENABLE_IPV6
case UPNPEXT_IFNAME6:
ext_if_name6 = ary_options[i].value;
break;
#endif
case UPNPEXT_IP: case UPNPEXT_IP:
use_ext_ip_addr = ary_options[i].value; use_ext_ip_addr = ary_options[i].value;
break; break;
@ -1501,6 +1506,14 @@ init(int argc, char * * argv, struct runtime_vars * v)
else else
fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]); fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
break; break;
#ifdef ENABLE_IPV6
case 'I':
if(i+1 < argc)
ext_if_name6 = argv[++i];
else
fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
break;
#endif
#ifdef USE_PF #ifdef USE_PF
case 'q': case 'q':
if(i+1 < argc) if(i+1 < argc)
@ -1672,12 +1685,17 @@ init(int argc, char * * argv, struct runtime_vars * v)
fprintf(stderr, "Unknown option: %s\n", argv[i]); fprintf(stderr, "Unknown option: %s\n", argv[i]);
} }
} }
if(!ext_if_name || !lan_addrs.lh_first) if(!ext_if_name || !lan_addrs.lh_first) {
{
/* bad configuration */ /* bad configuration */
goto print_usage; goto print_usage;
} }
/* IPv6 ifname is defaulted to same as IPv4 */
#ifdef ENABLE_IPV6
if(!ext_if_name6)
ext_if_name6 = ext_if_name;
#endif
if (use_ext_ip_addr && GETFLAG(PERFORMSTUNMASK)) { if (use_ext_ip_addr && GETFLAG(PERFORMSTUNMASK)) {
fprintf(stderr, "Error: options ext_ip= and ext_perform_stun=yes cannot be specified together\n"); fprintf(stderr, "Error: options ext_ip= and ext_perform_stun=yes cannot be specified together\n");
return 1; return 1;
@ -1825,7 +1843,11 @@ print_usage:
#ifndef DISABLE_CONFIG_FILE #ifndef DISABLE_CONFIG_FILE
"[-f config_file] " "[-f config_file] "
#endif #endif
"[-i ext_ifname] [-o ext_ip]\n" "[-i ext_ifname] "
#ifdef ENABLE_IPV6
"[-I ext_ifname6] "
#endif
"[-o ext_ip]\n"
#ifndef MULTIPLE_EXTERNAL_IP #ifndef MULTIPLE_EXTERNAL_IP
"\t\t[-a listening_ip]" "\t\t[-a listening_ip]"
#else #else
@ -2011,6 +2033,11 @@ main(int argc, char * * argv)
#endif #endif
GETFLAG(ENABLEUPNPMASK) ? "UPnP-IGD " : "", GETFLAG(ENABLEUPNPMASK) ? "UPnP-IGD " : "",
ext_if_name, upnp_bootid); ext_if_name, upnp_bootid);
#ifdef ENABLE_IPV6
if (ext_if_name6 != ext_if_name) {
syslog(LOG_INFO, "specific IPv6 ext if %s", ext_if_name6);
}
#endif
if(GETFLAG(PERFORMSTUNMASK)) if(GETFLAG(PERFORMSTUNMASK))
{ {

View File

@ -1,6 +1,9 @@
# WAN network interface # WAN network interface
#ext_ifname=eth1 #ext_ifname=eth1
#ext_ifname=xl1 #ext_ifname=xl1
# if the WAN network interface for IPv6 is different than for IPv4,
# set ext_ifname6
#ext_ifname6=eth2
# If the WAN interface has several IP addresses, you # If the WAN interface has several IP addresses, you
# can specify the one to use below # can specify the one to use below
#ext_ip= #ext_ip=

View File

@ -1,9 +1,9 @@
/* $Id: options.c,v 1.36 2018/07/06 12:05:48 nanard Exp $ */ /* $Id: options.c,v 1.37 2019/05/21 08:39:44 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project * MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* author: Ryan Wagoner * author: Ryan Wagoner
* (c) 2006-2018 Thomas Bernard * (c) 2006-2019 Thomas Bernard
* 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 */
@ -30,6 +30,9 @@ static const struct {
const char * name; const char * name;
} optionids[] = { } optionids[] = {
{ UPNPEXT_IFNAME, "ext_ifname" }, { UPNPEXT_IFNAME, "ext_ifname" },
#ifdef ENABLE_IPV6
{ UPNPEXT_IFNAME6, "ext_ifname6" },
#endif
{ UPNPEXT_IP, "ext_ip" }, { UPNPEXT_IP, "ext_ip" },
{ UPNPEXT_PERFORM_STUN, "ext_perform_stun" }, { UPNPEXT_PERFORM_STUN, "ext_perform_stun" },
{ UPNPEXT_STUN_HOST, "ext_stun_host" }, { UPNPEXT_STUN_HOST, "ext_stun_host" },

View File

@ -1,9 +1,9 @@
/* $Id: options.h,v 1.29 2018/07/06 12:05:48 nanard Exp $ */ /* $Id: options.h,v 1.30 2019/05/21 08:39:44 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project * MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* author: Ryan Wagoner * author: Ryan Wagoner
* (c) 2006-2018 Thomas Bernard * (c) 2006-2019 Thomas Bernard
* 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 */
@ -17,6 +17,9 @@
enum upnpconfigoptions { enum upnpconfigoptions {
UPNP_INVALID = 0, UPNP_INVALID = 0,
UPNPEXT_IFNAME = 1, /* ext_ifname */ UPNPEXT_IFNAME = 1, /* ext_ifname */
#ifdef ENABLE_IPV6
UPNPEXT_IFNAME6, /* ext_ifname6 */
#endif
UPNPEXT_IP, /* ext_ip */ UPNPEXT_IP, /* ext_ip */
UPNPEXT_PERFORM_STUN, /* ext_perform_stun */ UPNPEXT_PERFORM_STUN, /* ext_perform_stun */
UPNPEXT_STUN_HOST, /* ext_stun_host */ UPNPEXT_STUN_HOST, /* ext_stun_host */

View File

@ -1,5 +1,6 @@
/* $Id: pcpserver.c,v 1.47 2018/03/13 10:21:19 nanard Exp $ */ /* $Id: pcpserver.c,v 1.51 2019/05/21 08:39:44 nanard Exp $ */
/* MiniUPnP project /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project
* Website : http://miniupnp.free.fr/ * Website : http://miniupnp.free.fr/
* Author : Peter Tatrai * Author : Peter Tatrai
@ -590,6 +591,17 @@ static int CheckExternalAddress(pcp_info_t* pcp_msg_info)
pcp_msg_info->result_code = PCP_ERR_NETWORK_FAILURE; pcp_msg_info->result_code = PCP_ERR_NETWORK_FAILURE;
return -1; return -1;
} }
#ifdef ENABLE_IPV6
} else if ((af == AF_INET6) && (ext_if_name6 != ext_if_name)) {
if(!ext_if_name6 || ext_if_name6[0]=='\0') {
pcp_msg_info->result_code = PCP_ERR_NETWORK_FAILURE;
return -1;
}
if(getifaddr_in6(ext_if_name6, af, &external_addr) < 0) {
pcp_msg_info->result_code = PCP_ERR_NETWORK_FAILURE;
return -1;
}
#endif
} else { } else {
if(!ext_if_name || ext_if_name[0]=='\0') { if(!ext_if_name || ext_if_name[0]=='\0') {
pcp_msg_info->result_code = PCP_ERR_NETWORK_FAILURE; pcp_msg_info->result_code = PCP_ERR_NETWORK_FAILURE;
@ -686,6 +698,7 @@ static int CreatePCPPeer_NAT(pcp_info_t *pcp_msg_info)
char peerip_s[INET6_ADDRSTRLEN], extip_s[INET6_ADDRSTRLEN]; char peerip_s[INET6_ADDRSTRLEN], extip_s[INET6_ADDRSTRLEN];
time_t timestamp = upnp_time() + pcp_msg_info->lifetime; time_t timestamp = upnp_time() + pcp_msg_info->lifetime;
int r; int r;
const char * ext_if = ext_if_name;
FillSA((struct sockaddr*)&intip, pcp_msg_info->mapped_ip, FillSA((struct sockaddr*)&intip, pcp_msg_info->mapped_ip,
pcp_msg_info->int_port); pcp_msg_info->int_port);
@ -718,9 +731,14 @@ static int CreatePCPPeer_NAT(pcp_info_t *pcp_msg_info)
eport = pcp_msg_info->int_port; eport = pcp_msg_info->int_port;
} }
#ifdef ENABLE_IPV6
if (ret_extip.ss_family == AF_INET6) {
ext_if = ext_if_name6;
}
#endif
#ifdef PCP_FLOWP #ifdef PCP_FLOWP
if (pcp_msg_info->flowp_present && pcp_msg_info->dscp_up) { if (pcp_msg_info->flowp_present && pcp_msg_info->dscp_up) {
if (add_peer_dscp_rule2(ext_if_name, peerip_s, if (add_peer_dscp_rule2(ext_if, peerip_s,
pcp_msg_info->peer_port, pcp_msg_info->dscp_up, pcp_msg_info->peer_port, pcp_msg_info->dscp_up,
pcp_msg_info->mapped_str, pcp_msg_info->int_port, pcp_msg_info->mapped_str, pcp_msg_info->int_port,
proto, pcp_msg_info->desc, timestamp) < 0 ) { proto, pcp_msg_info->desc, timestamp) < 0 ) {
@ -735,7 +753,7 @@ static int CreatePCPPeer_NAT(pcp_info_t *pcp_msg_info)
} }
if (pcp_msg_info->flowp_present && pcp_msg_info->dscp_down) { if (pcp_msg_info->flowp_present && pcp_msg_info->dscp_down) {
if (add_peer_dscp_rule2(ext_if_name, pcp_msg_info->mapped_str, if (add_peer_dscp_rule2(ext_if, pcp_msg_info->mapped_str,
pcp_msg_info->int_port, pcp_msg_info->dscp_down, pcp_msg_info->int_port, pcp_msg_info->dscp_down,
peerip_s, pcp_msg_info->peer_port, proto, pcp_msg_info->desc, timestamp) peerip_s, pcp_msg_info->peer_port, proto, pcp_msg_info->desc, timestamp)
< 0 ) { < 0 ) {
@ -751,7 +769,7 @@ static int CreatePCPPeer_NAT(pcp_info_t *pcp_msg_info)
} }
#endif #endif
r = add_peer_redirect_rule2(ext_if_name, r = add_peer_redirect_rule2(ext_if,
peerip_s, peerip_s,
pcp_msg_info->peer_port, pcp_msg_info->peer_port,
extip_s, extip_s,

View File

@ -1,4 +1,4 @@
/* $Id: upnpglobalvars.c,v 1.43 2018/07/06 12:05:48 nanard Exp $ */ /* $Id: upnpglobalvars.c,v 1.44 2019/05/21 08:39:45 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project * MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
@ -16,6 +16,11 @@
/* network interface for internet */ /* network interface for internet */
const char * ext_if_name = 0; const char * ext_if_name = 0;
#ifdef ENABLE_IPV6
/* network interface for internet - IPv6 */
const char * ext_if_name6 = 0;
#endif
/* stun host/port configuration */ /* stun host/port configuration */
const char * ext_stun_host = 0; const char * ext_stun_host = 0;
uint16_t ext_stun_port = 0; uint16_t ext_stun_port = 0;

View File

@ -1,8 +1,8 @@
/* $Id: upnpglobalvars.h,v 1.47 2018/07/06 12:05:48 nanard Exp $ */ /* $Id: upnpglobalvars.h,v 1.48 2019/05/21 08:39:45 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project * MiniUPnP project
* http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
* (c) 2006-2018 Thomas Bernard * (c) 2006-2019 Thomas Bernard
* 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 */
@ -17,6 +17,11 @@
/* name of the network interface used to access internet */ /* name of the network interface used to access internet */
extern const char * ext_if_name; extern const char * ext_if_name;
#ifdef ENABLE_IPV6
/* name of the network interface used to access internet - for IPv6*/
extern const char * ext_if_name6;
#endif
/* stun host/port configuration */ /* stun host/port configuration */
extern const char * ext_stun_host; extern const char * ext_stun_host;
extern uint16_t ext_stun_port; extern uint16_t ext_stun_port;

View File

@ -1,7 +1,8 @@
/* $Id: upnppinhole.c,v 1.13 2018/03/13 10:49:13 nanard Exp $ */ /* $Id: upnppinhole.c,v 1.14 2019/05/21 08:39:45 nanard Exp $ */
/* MiniUPnP project /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2018 Thomas Bernard * (c) 2006-2019 Thomas Bernard
* 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 */
@ -142,7 +143,7 @@ upnp_add_inboundpinhole(const char * raddr,
return (r >= 0) ? 1 : r; return (r >= 0) ? 1 : r;
} }
#if defined(USE_PF) || defined(USE_NETFILTER) #if defined(USE_PF) || defined(USE_NETFILTER)
*uid = add_pinhole (ext_if_name, raddr, rport, *uid = add_pinhole (ext_if_name6, raddr, rport,
iaddr, iport, proto, desc, timestamp); iaddr, iport, proto, desc, timestamp);
return *uid >= 0 ? 1 : -1; return *uid >= 0 ? 1 : -1;
#else #else