Move IPv6FirewallControl related code from upnpredirect.c to upnppinhole.c

This commit is contained in:
Thomas Bernard 2012-05-01 22:25:30 +02:00
parent 439047cbc4
commit 89212758f2
9 changed files with 613 additions and 548 deletions

View File

@ -1,4 +1,7 @@
$Id: Changelog.txt,v 1.278 2012/04/30 21:21:32 nanard Exp $
$Id: Changelog.txt,v 1.279 2012/05/01 20:08:20 nanard Exp $
2012/05/01:
Move IPv6FirewallControl related code from upnpredirect.c to upnppinhole.c
2012/04/30:
Clean up settings of CFLAGS in Makefile's

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.64 2012/04/30 13:58:31 nanard Exp $
# $Id: Makefile,v 1.65 2012/05/01 20:11:40 nanard Exp $
# MiniUPnP project
# http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
# Author: Thomas Bernard
@ -73,7 +73,8 @@ CFLAGS += -m64 -mcmodel=medlow
STDOBJS = miniupnpd.o upnphttp.o upnpdescgen.o upnpsoap.o \
upnpredirect.o getifaddr.o daemonize.o upnpglobalvars.o \
options.o upnppermissions.o minissdp.o natpmp.o \
upnpevents.o upnputils.o getconnstatus.o
upnpevents.o upnputils.o getconnstatus.o \
upnppinhole.o
BSDOBJS = bsd/getifstats.o bsd/ifacewatcher.o
SUNOSOBJS = solaris/getifstats.o bsd/ifacewatcher.o
MACOBJS = mac/getifstats.o bsd/ifacewatcher.o

View File

@ -1,4 +1,4 @@
# $Id: Makefile.linux,v 1.67 2012/04/30 21:06:28 nanard Exp $
# $Id: Makefile.linux,v 1.69 2012/05/01 20:13:34 nanard Exp $
# MiniUPnP project
# (c) 2006-2012 Thomas Bernard
# http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
@ -41,9 +41,10 @@ ETCINSTALLDIR = $(PREFIX)/etc/miniupnpd
BASEOBJS = miniupnpd.o upnphttp.o upnpdescgen.o upnpsoap.o \
upnpreplyparse.o minixml.o \
upnpredirect.o getifaddr.o daemonize.o upnpglobalvars.o \
upnpredirect.o getifaddr.o daemonize.o upnpglobalvars.o \
options.o upnppermissions.o minissdp.o natpmp.o \
upnpevents.o upnputils.o getconnstatus.o
upnpevents.o upnputils.o getconnstatus.o \
upnppinhole.o
LNXOBJS = linux/getifstats.o linux/ifacewatcher.o
NETFILTEROBJS = netfilter/iptcrdr.o netfilter/iptpinhole.o
@ -174,20 +175,22 @@ depend: config.h
miniupnpd.o: config.h upnpglobalvars.h upnppermissions.h miniupnpdtypes.h
miniupnpd.o: upnphttp.h upnpdescgen.h miniupnpdpath.h getifaddr.h upnpsoap.h
miniupnpd.o: options.h minissdp.h upnpredirect.h daemonize.h upnpevents.h
miniupnpd.o: natpmp.h commonrdr.h upnputils.h ifacewatcher.h
miniupnpd.o: options.h minissdp.h upnpredirect.h upnppinhole.h daemonize.h
miniupnpd.o: upnpevents.h natpmp.h commonrdr.h upnputils.h ifacewatcher.h
upnphttp.o: config.h upnphttp.h upnpdescgen.h miniupnpdpath.h upnpsoap.h
upnphttp.o: upnpevents.h upnputils.h
upnpdescgen.o: config.h getifaddr.h upnpredirect.h upnpdescgen.h
upnpdescgen.o: miniupnpdpath.h upnpglobalvars.h upnppermissions.h
upnpdescgen.o: miniupnpdtypes.h upnpdescstrings.h upnpurns.h getconnstatus.h
upnpsoap.o: config.h upnpglobalvars.h upnppermissions.h miniupnpdtypes.h
upnpsoap.o: upnphttp.h upnpsoap.h upnpreplyparse.h upnpredirect.h getifaddr.h
upnpsoap.o: getifstats.h getconnstatus.h upnpurns.h
upnpsoap.o: macros.h config.h upnpglobalvars.h upnppermissions.h
upnpsoap.o: miniupnpdtypes.h upnphttp.h upnpsoap.h upnpreplyparse.h
upnpsoap.o: upnpredirect.h upnppinhole.h getifaddr.h getifstats.h
upnpsoap.o: getconnstatus.h upnpurns.h
upnpreplyparse.o: upnpreplyparse.h minixml.h
minixml.o: minixml.h
upnpredirect.o: config.h upnpredirect.h upnpglobalvars.h upnppermissions.h
upnpredirect.o: miniupnpdtypes.h upnpevents.h netfilter/iptcrdr.h commonrdr.h
upnpredirect.o: macros.h config.h upnpredirect.h upnpglobalvars.h
upnpredirect.o: upnppermissions.h miniupnpdtypes.h upnpevents.h
upnpredirect.o: netfilter/iptcrdr.h commonrdr.h
getifaddr.o: config.h getifaddr.h
daemonize.o: daemonize.h config.h
upnpglobalvars.o: config.h upnpglobalvars.h upnppermissions.h
@ -198,19 +201,26 @@ upnppermissions.o: config.h upnppermissions.h
minissdp.o: config.h upnpdescstrings.h miniupnpdpath.h upnphttp.h
minissdp.o: upnpglobalvars.h upnppermissions.h miniupnpdtypes.h minissdp.h
minissdp.o: upnputils.h codelength.h
natpmp.o: config.h natpmp.h upnpglobalvars.h upnppermissions.h
natpmp.o: macros.h config.h natpmp.h upnpglobalvars.h upnppermissions.h
natpmp.o: miniupnpdtypes.h getifaddr.h upnpredirect.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
getconnstatus.o: getconnstatus.h getifaddr.h
upnppinhole.o: macros.h config.h upnpredirect.h upnpglobalvars.h
upnppinhole.o: upnppermissions.h miniupnpdtypes.h upnpevents.h
upnppinhole.o: netfilter/iptpinhole.h
linux/getifstats.o: config.h getifstats.h
linux/ifacewatcher.o: config.h ifacewatcher.h config.h minissdp.h
linux/ifacewatcher.o: miniupnpdtypes.h getifaddr.h upnpglobalvars.h
linux/ifacewatcher.o: upnppermissions.h natpmp.h
netfilter/iptcrdr.o: netfilter/iptcrdr.h commonrdr.h config.h
netfilter/iptcrdr.o: upnpglobalvars.h upnppermissions.h miniupnpdtypes.h
testupnpdescgen.o: config.h upnpdescgen.h
netfilter/iptcrdr.o: macros.h config.h netfilter/iptcrdr.h commonrdr.h
netfilter/iptcrdr.o: config.h upnpglobalvars.h upnppermissions.h
netfilter/iptcrdr.o: miniupnpdtypes.h
netfilter/iptpinhole.o: config.h netfilter/iptpinhole.h upnpglobalvars.h
netfilter/iptpinhole.o: upnppermissions.h config.h miniupnpdtypes.h
netfilter/iptpinhole.o: netfilter/tiny_nf_nat.h
testupnpdescgen.o: macros.h config.h upnpdescgen.h
upnpdescgen.o: config.h getifaddr.h upnpredirect.h upnpdescgen.h
upnpdescgen.o: miniupnpdpath.h upnpglobalvars.h upnppermissions.h
upnpdescgen.o: miniupnpdtypes.h upnpdescstrings.h upnpurns.h getconnstatus.h

View File

@ -1,4 +1,4 @@
/* $Id: miniupnpd.c,v 1.154 2012/04/30 13:38:21 nanard Exp $ */
/* $Id: miniupnpd.c,v 1.155 2012/05/01 20:13:35 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard
@ -58,6 +58,7 @@
#include "options.h"
#include "minissdp.h"
#include "upnpredirect.h"
#include "upnppinhole.h"
#include "miniupnpdtypes.h"
#include "daemonize.h"
#include "upnpevents.h"

508
miniupnpd/upnppinhole.c Normal file
View File

@ -0,0 +1,508 @@
/* $Id: upnppinhole.c,v 1.1 2012/05/01 20:08:22 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include "macros.h"
#include "config.h"
#include "upnpredirect.h"
#include "upnpglobalvars.h"
#include "upnpevents.h"
#if defined(USE_NETFILTER)
#include "netfilter/iptpinhole.h"
#endif
#if defined(USE_PF)
#include "pf/pfpinhole.h"
#endif
#if defined(USE_IPF)
#endif
#if defined(USE_IPFW)
#endif
#ifdef ENABLE_6FC_SERVICE
#if 0
int
upnp_check_outbound_pinhole(int proto, int * timeout)
{
int s, tmptimeout, tmptime_out;
switch(proto)
{
case IPPROTO_UDP:
s = retrieve_timeout("udp_timeout", timeout);
return s;
break;
case IPPROTO_UDPLITE:
s = retrieve_timeout("udp_timeout_stream", timeout);
return s;
break;
case IPPROTO_TCP:
s = retrieve_timeout("tcp_timeout_established", timeout);
return s;
break;
case 65535:
s = retrieve_timeout("udp_timeout", timeout);
s = retrieve_timeout("udp_timeout_stream", &tmptimeout);
s = retrieve_timeout("tcp_timeout_established", &tmptime_out);
if(tmptimeout<tmptime_out)
{
if(tmptimeout<*timeout)
*timeout = tmptimeout;
}
else
{
if(tmptime_out<*timeout)
*timeout = tmptimeout;
}
return s;
break;
default:
return -5;
break;
}
return 0;
}
#endif
/* upnp_add_inboundpinhole()
* returns: 0 on success
* -1 failed to add pinhole
* -2 already created
* -3 inbound pinhole disabled
* TODO : return uid on success (positive) or error value (negative)
*/
int
upnp_add_inboundpinhole(const char * raddr,
unsigned short rport,
const char * iaddr,
unsigned short iport,
int proto,
unsigned int leasetime,
int * uid)
{
int r;
time_t current;
unsigned int timestamp;
struct in6_addr address;
if(inet_pton(AF_INET6, iaddr, &address) < 0)
{
syslog(LOG_ERR, "inet_pton(%s) : %m", iaddr);
return 0;
}
current = time(NULL);
timestamp = current + leasetime;
r = 0;
#if 0
if(r == 1 && strcmp(iaddr, iaddr_old)==0 && iport==iport_old)
{
syslog(LOG_INFO, "Pinhole for inbound traffic from [%s]:%hu to [%s]:%hu with protocol %s already done. Updating it.", raddr, rport, iaddr_old, iport_old, protocol);
t = upnp_update_inboundpinhole(idfound, leaseTime);
*uid = atoi(idfound);
return t;
}
else
#endif
{
#if defined(USE_PF) || defined(USE_NETFILTER)
*uid = add_pinhole (0/*ext_if_name*/, raddr, rport,
iaddr, iport, proto, timestamp);
return 1;
#else
return -42; /* not implemented */
#endif
}
}
#if 0
int
upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport,
const char * iaddr, unsigned short iport,
const char * proto, int * uid)
{
int c = 9999;
char cmd[256], cmd_raw[256], cuid[42];
#if 0
static const char cmdval_full_udptcp[] = "ip6tables -I %s %d -p %s -i %s -s %s --sport %hu -d %s --dport %hu -j ACCEPT";
static const char cmdval_udptcp[] = "ip6tables -I %s %d -p %s -i %s --sport %hu -d %s --dport %hu -j ACCEPT";
static const char cmdval_full_udplite[] = "ip6tables -I %s %d -p %s -i %s -s %s -d %s -j ACCEPT";
static const char cmdval_udplite[] = "ip6tables -I %s %d -p %s -i %s -d %s -j ACCEPT";
// raw table command
static const char cmdval_full_udptcp_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s -s %s --sport %hu -d %s --dport %hu -j TRACE";
static const char cmdval_udptcp_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s --sport %hu -d %s --dport %hu -j TRACE";
static const char cmdval_full_udplite_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s -s %s -d %s -j TRACE";
static const char cmdval_udplite_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s -d %s -j TRACE";
#endif
/*printf("%s\n", raddr);*/
if(raddr!=NULL)
{
#ifdef IPPROTO_UDPLITE
if(atoi(proto) == IPPROTO_UDPLITE)
{
/* snprintf(cmd, sizeof(cmd), cmdval_full_udplite, miniupnpd_forward_chain, line_number, proto, ext_if_name, raddr, iaddr);
snprintf(cmd_raw, sizeof(cmd_raw), cmdval_full_udplite_raw, line_number, proto, ext_if_name, raddr, iaddr);*/
}
else
#endif
{
/* snprintf(cmd, sizeof(cmd), cmdval_full_udptcp, miniupnpd_forward_chain, line_number, proto, ext_if_name, raddr, rport, iaddr, iport);
snprintf(cmd_raw, sizeof(cmd_raw), cmdval_full_udptcp_raw, line_number, proto, ext_if_name, raddr, rport, iaddr, iport);*/
}
}
else
{
#ifdef IPPROTO_UDPLITE
if(atoi(proto) == IPPROTO_UDPLITE)
{
/*snprintf(cmd, sizeof(cmd), cmdval_udplite, miniupnpd_forward_chain, line_number, proto, ext_if_name, iaddr);
snprintf(cmd_raw, sizeof(cmd_raw), cmdval_udplite_raw, line_number, proto, ext_if_name, iaddr);*/
}
else
#endif
{
/*snprintf(cmd, sizeof(cmd), cmdval_udptcp, miniupnpd_forward_chain, line_number, proto, ext_if_name, rport, iaddr, iport);
snprintf(cmd_raw, sizeof(cmd_raw), cmdval_udptcp_raw, line_number, proto, ext_if_name, rport, iaddr, iport);
*/
}
}
#ifdef DEBUG
syslog(LOG_INFO, "Adding following ip6tables rule:");
syslog(LOG_INFO, " -> %s", cmd);
syslog(LOG_INFO, " -> %s", cmd_raw);
#endif
/* TODO Add a better checking error.*/
if(system(cmd) < 0 || system(cmd_raw) < 0)
{
return 0;
}
srand(time(NULL));
snprintf(cuid, sizeof(cuid), "%.4d", rand()%c);
*uid = atoi(cuid);
printf("\t_add_ uid: %s\n", cuid);
return 1;
}
#endif
/* upnp_get_pinhole_info()
* return values :
* 0 OK
* -1 Internal error
* -2 NOT FOUND (no such entry)
* ..
* -42 Not implemented
*/
int
upnp_get_pinhole_info(unsigned short uid,
char * raddr, int raddrlen,
unsigned short * rport,
char * iaddr, int iaddrlen,
unsigned short * iport,
int * proto,
unsigned int * leasetime,
unsigned int * packets)
{
/* Call Firewall specific code to get IPv6 pinhole infos */
#ifdef USE_PF
int r;
unsigned int timestamp;
u_int64_t packets_tmp, bytes_tmp;
r = get_pinhole(uid, raddr, raddrlen, rport,
iaddr, iaddrlen, iport, proto, &timestamp,
&packets_tmp, &bytes_tmp);
if(r >= 0) {
if(leasetime) {
time_t current_time;
current_time = time(NULL);
if(timestamp > (unsigned int)current_time)
*leasetime = timestamp - current_time;
else
*leasetime = 0;
}
if(packets)
*packets = (unsigned int)packets_tmp;
}
return r;
#else
UNUSED(uid);
UNUSED(raddr); UNUSED(raddrlen); UNUSED(rport);
UNUSED(iaddr); UNUSED(iaddrlen); UNUSED(iport);
UNUSED(proto); UNUSED(leasetime); UNUSED(packets);
return -42; /* not implemented */
#endif
}
int
upnp_update_inboundpinhole(unsigned short uid, unsigned int leasetime)
{
#ifdef USE_PF
unsigned int timestamp;
timestamp = time(NULL) + leasetime;
return update_pinhole(uid, timestamp);
#else
UNUSED(uid); UNUSED(leasetime);
return -42; /* not implemented */
#endif
}
int
upnp_delete_inboundpinhole(unsigned short uid)
{
#ifdef USE_PF
return delete_pinhole(uid);
#else
UNUSED(uid);
return -1;
#endif
}
#if 0
/*
* Result:
* 1: Found Result
* -4: No result
* -5: Result in another table
* -6: Result in another chain
* -7: Result in a chain not a rule
*/
int
upnp_check_pinhole_working(const char * uid,
char * eaddr,
char * iaddr,
unsigned short * eport,
unsigned short * iport,
char * protocol,
int * rulenum_used)
{
/* TODO : to be implemented */
#if 0
FILE * fd;
time_t expire = time(NULL);
char buf[1024], filename[] = "/var/log/kern.log", expire_time[32]="";
int res = -4, str_len;
str_len = strftime(expire_time, sizeof(expire_time), "%b %d %H:%M:%S", localtime(&expire));
fd = fopen(filename, "r");
if (fd==NULL)
{
syslog(LOG_ERR, "Get_rule: could not open file: %s", filename);
return -1;
}
syslog(LOG_INFO, "Get_rule: Starting getting info in file %s for %s\n", filename, uid);
buf[sizeof(buf)-1] = 0;
while(fgets(buf, sizeof(buf)-1, fd) != NULL && res != 1)
{
//printf("line: %s\n", buf);
char * r, * t, * c, * p;
// looking for something like filter:FORWARD:rule: or filter:MINIUPNPD:rule:
r = strstr(buf, ":rule:");
p = strstr(buf, ":policy:");
t = strstr(buf, "TRACE:"); // table pointeur
t += 7;
c = t + 7; // chain pointeur
if(r)
{
printf("\t** Found %.*s\n", 24 ,t);
char * src, * dst, * sport, * dport, * proto, * line;
char time[15]="", src_addr[40], dst_addr[40], proto_tmp[8];
int proto_int;
strncpy(time, buf, sizeof(time));
/*if(compare_time(time, expire_time)<0)
{
printf("\t\tNot corresponding time\n");
continue;
}*/
line = r + 6;
printf("\trule line = %d\n", atoi(line));
src = strstr(buf, "SRC=");
src += 4;
snprintf(src_addr, sizeof(src_addr), "%.*s", 39, src);
#if 0
del_char(src_addr);
add_char(src_addr);
#endif
dst = strstr(buf, "DST=");
dst += 4;
snprintf(dst_addr, sizeof(dst_addr), "%.*s", 39, dst);
#if 0
del_char(dst_addr);
add_char(dst_addr);
#endif
proto = strstr(buf, "PROTO=");
proto += 6;
proto_int = atoi(protocol);
if(proto_int == IPPROTO_UDP)
strcpy(proto_tmp, "UDP");
else if(proto_int == IPPROTO_TCP)
strcpy(proto_tmp, "TCP");
#ifdef IPPROTO_UDPLITE
else if(proto_int == IPPROTO_UDPLITE)
strcpy(proto_tmp, "UDPLITE");
#endif
else
strcpy(proto_tmp, "UnsupportedProto");
// printf("\tCompare eaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", eaddr, proto_tmp, src_addr, strlen(proto_tmp), proto);
// printf("\tCompare iaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", iaddr, proto_tmp, dst_addr, strlen(proto_tmp), proto);
// TODO Check time
// Check that the paquet found in trace correspond to the one we are looking for
if( /*(strcmp(eaddr, src_addr) == 0) &&*/ (strcmp(iaddr, dst_addr) == 0) && (strncmp(proto_tmp, proto, strlen(proto_tmp))==0))
{
sport = strstr(buf, "SPT=");
sport += 4;
dport = strstr(buf, "DPT=");
dport += 4;
printf("\tCompare eport: %hu\n\t to port: %d\n", *eport, atoi(sport));
printf("\tCompare iport: %hu\n\t to port: %d\n", *iport, atoi(dport));
if(/*eport != atoi(sport) &&*/ *iport != atoi(dport))
{
printf("\t\tPort not corresponding\n");
continue;
}
printf("\ttable found: %.*s\n", 6, t);
printf("\tchain found: %.*s\n", 9, c);
// Check that the table correspond to the filter table
if(strncmp(t, "filter", 6)==0)
{
// Check that the table correspond to the MINIUPNP table
if(strncmp(c, "MINIUPNPD", 9)==0)
{
*rulenum_used = atoi(line);
res = 1;
}
else
{
res = -6;
continue;
}
}
else
{
res = -5;
continue;
}
}
else
{
printf("Packet information not corresponding\n");
continue;
}
}
if(!r && p)
{
printf("\t** Policy case\n");
char * src, * dst, * sport, * dport, * proto, * line;
char time[15], src_addr[40], dst_addr[40], proto_tmp[8];
int proto_int;
strncpy(time, buf, sizeof(time));
/*if(compare_time(time, expire_time)<0)
{
printf("\t\tNot corresponding time\n");
continue;
}*/
line = p + 8;
printf("\trule line = %d\n", atoi(line));
src = strstr(buf, "SRC=");
src += 4;
snprintf(src_addr, sizeof(src_addr), "%.*s", 39, src);
#if 0
del_char(src_addr);
add_char(src_addr);
#endif
dst = strstr(buf, "DST=");
dst += 4;
snprintf(dst_addr, sizeof(dst_addr), "%.*s", 39, dst);
#if 0
del_char(dst_addr);
add_char(dst_addr);
#endif
proto = strstr(buf, "PROTO=");
proto += 6;
proto_int = atoi(protocol);
if(proto_int == IPPROTO_UDP)
strcpy(proto_tmp, "UDP");
else if(proto_int == IPPROTO_TCP)
strcpy(proto_tmp, "TCP");
#ifdef IPPROTO_UDPLITE
else if(proto_int == IPPROTO_UDPLITE)
strcpy(proto_tmp, "UDPLITE");
#endif
else
strcpy(proto_tmp, "UnsupportedProto");
// printf("\tCompare eaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", eaddr, proto_tmp, src_addr, strlen(proto_tmp), proto);
// printf("\tCompare iaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", iaddr, proto_tmp, dst_addr, strlen(proto_tmp), proto);
// Check that the paquet found in trace correspond to the one we are looking for
if( (strcmp(eaddr, src_addr) == 0) && (strcmp(iaddr, dst_addr) == 0) && (strncmp(proto_tmp, proto, 5)==0))
{
sport = strstr(buf, "SPT=");
sport += 4;
dport = strstr(buf, "DPT=");
dport += 4;
printf("\tCompare eport: %hu\n\t to port: %d\n", *eport, atoi(sport));
printf("\tCompare iport: %hu\n\t to port: %d\n", *iport, atoi(dport));
if(*eport != atoi(sport) && *iport != atoi(dport))
{
printf("\t\tPort not corresponding\n");
continue;
}
else
{
printf("Find a corresponding policy trace in the chain: %.*s\n", 10, c);
res = -7;
continue;
}
}
else
continue;
}
}
fclose(fd);
return res;
#else
return -42; /* to be implemented */
#endif
}
#endif
int
upnp_clean_expired_pinholes(unsigned int * next_timestamp)
{
#ifdef USE_PF
return clean_pinhole_list(next_timestamp);
#else
UNUSED(next_timestamp);
return 0; /* nothing to do */
#endif
}
#endif

68
miniupnpd/upnppinhole.h Normal file
View File

@ -0,0 +1,68 @@
/* $Id: upnppinhole.h,v 1.1 2012/05/01 20:08:22 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#ifndef __UPNPPINHOLE_H__
#define __UPNPPINHOLE_H__
#include "config.h"
#ifdef ENABLE_6FC_SERVICE
/* functions to be used by WANIPv6_FirewallControl implementation */
#if 0
/* retrieve outbound pinhole timeout */
int
upnp_check_outbound_pinhole(int proto, int * timeout);
#endif
/* add an inbound pinehole
* return value :
* 1 = success
* -1 = Pinhole space exhausted
* .. = error */
int
upnp_add_inboundpinhole(const char * raddr, unsigned short rport,
const char * iaddr, unsigned short iport,
int proto, unsigned int leasetime, int * uid);
/*
* return values :
* -1 not found
* */
int
upnp_get_pinhole_info(unsigned short uid,
char * raddr, int raddrlen,
unsigned short * rport,
char * iaddr, int iaddrlen,
unsigned short * iport,
int * proto,
unsigned int * leasetime,
unsigned int * packets);
/* update the lease time */
int
upnp_update_inboundpinhole(unsigned short uid, unsigned int leasetime);
/* remove the inbound pinhole */
int
upnp_delete_inboundpinhole(unsigned short uid);
/* ... */
#if 0
int
upnp_check_pinhole_working(const char * uid, char * eaddr, char * iaddr, unsigned short * eport, unsigned short * iport, char * protocol, int * rulenum_used);
#endif
/* ? */
int
upnp_clean_expired_pinholes(unsigned int * next_timestamp);
#endif /* ENABLE_6FC_SERVICE */
#endif

View File

@ -1,4 +1,4 @@
/* $Id: upnpredirect.c,v 1.79 2012/04/30 21:08:00 nanard Exp $ */
/* $Id: upnpredirect.c,v 1.80 2012/05/01 20:08:22 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard
@ -25,11 +25,9 @@
#include "upnpevents.h"
#if defined(USE_NETFILTER)
#include "netfilter/iptcrdr.h"
#include "netfilter/iptpinhole.h"
#endif
#if defined(USE_PF)
#include "pf/obsdrdr.h"
#include "pf/pfpinhole.h"
#endif
#if defined(USE_IPF)
#include "ipf/ipfrdr.h"
@ -583,478 +581,6 @@ upnp_get_portmappings_in_range(unsigned short startport,
return get_portmappings_in_range(startport, endport, proto, number);
}
#ifdef ENABLE_6FC_SERVICE
#if 0
int
upnp_check_outbound_pinhole(int proto, int * timeout)
{
int s, tmptimeout, tmptime_out;
switch(proto)
{
case IPPROTO_UDP:
s = retrieve_timeout("udp_timeout", timeout);
return s;
break;
case IPPROTO_UDPLITE:
s = retrieve_timeout("udp_timeout_stream", timeout);
return s;
break;
case IPPROTO_TCP:
s = retrieve_timeout("tcp_timeout_established", timeout);
return s;
break;
case 65535:
s = retrieve_timeout("udp_timeout", timeout);
s = retrieve_timeout("udp_timeout_stream", &tmptimeout);
s = retrieve_timeout("tcp_timeout_established", &tmptime_out);
if(tmptimeout<tmptime_out)
{
if(tmptimeout<*timeout)
*timeout = tmptimeout;
}
else
{
if(tmptime_out<*timeout)
*timeout = tmptimeout;
}
return s;
break;
default:
return -5;
break;
}
return 0;
}
#endif
/* upnp_add_inboundpinhole()
* returns: 0 on success
* -1 failed to add pinhole
* -2 already created
* -3 inbound pinhole disabled
* TODO : return uid on success (positive) or error value (negative)
*/
int
upnp_add_inboundpinhole(const char * raddr,
unsigned short rport,
const char * iaddr,
unsigned short iport,
int proto,
unsigned int leasetime,
int * uid)
{
int r;
time_t current;
unsigned int timestamp;
struct in6_addr address;
if(inet_pton(AF_INET6, iaddr, &address) < 0)
{
syslog(LOG_ERR, "inet_pton(%s) : %m", iaddr);
return 0;
}
current = time(NULL);
timestamp = current + leasetime;
r = 0;
#if 0
if(r == 1 && strcmp(iaddr, iaddr_old)==0 && iport==iport_old)
{
syslog(LOG_INFO, "Pinhole for inbound traffic from [%s]:%hu to [%s]:%hu with protocol %s already done. Updating it.", raddr, rport, iaddr_old, iport_old, protocol);
t = upnp_update_inboundpinhole(idfound, leaseTime);
*uid = atoi(idfound);
return t;
}
else
#endif
{
#if defined(USE_PF) || defined(USE_NETFILTER)
*uid = add_pinhole (0/*ext_if_name*/, raddr, rport,
iaddr, iport, proto, timestamp);
return 1;
#else
return -42; /* not implemented */
#endif
}
}
#if 0
int
upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport,
const char * iaddr, unsigned short iport,
const char * proto, int * uid)
{
int c = 9999;
char cmd[256], cmd_raw[256], cuid[42];
#if 0
static const char cmdval_full_udptcp[] = "ip6tables -I %s %d -p %s -i %s -s %s --sport %hu -d %s --dport %hu -j ACCEPT";
static const char cmdval_udptcp[] = "ip6tables -I %s %d -p %s -i %s --sport %hu -d %s --dport %hu -j ACCEPT";
static const char cmdval_full_udplite[] = "ip6tables -I %s %d -p %s -i %s -s %s -d %s -j ACCEPT";
static const char cmdval_udplite[] = "ip6tables -I %s %d -p %s -i %s -d %s -j ACCEPT";
// raw table command
static const char cmdval_full_udptcp_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s -s %s --sport %hu -d %s --dport %hu -j TRACE";
static const char cmdval_udptcp_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s --sport %hu -d %s --dport %hu -j TRACE";
static const char cmdval_full_udplite_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s -s %s -d %s -j TRACE";
static const char cmdval_udplite_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s -d %s -j TRACE";
#endif
/*printf("%s\n", raddr);*/
if(raddr!=NULL)
{
#ifdef IPPROTO_UDPLITE
if(atoi(proto) == IPPROTO_UDPLITE)
{
/* snprintf(cmd, sizeof(cmd), cmdval_full_udplite, miniupnpd_forward_chain, line_number, proto, ext_if_name, raddr, iaddr);
snprintf(cmd_raw, sizeof(cmd_raw), cmdval_full_udplite_raw, line_number, proto, ext_if_name, raddr, iaddr);*/
}
else
#endif
{
/* snprintf(cmd, sizeof(cmd), cmdval_full_udptcp, miniupnpd_forward_chain, line_number, proto, ext_if_name, raddr, rport, iaddr, iport);
snprintf(cmd_raw, sizeof(cmd_raw), cmdval_full_udptcp_raw, line_number, proto, ext_if_name, raddr, rport, iaddr, iport);*/
}
}
else
{
#ifdef IPPROTO_UDPLITE
if(atoi(proto) == IPPROTO_UDPLITE)
{
/*snprintf(cmd, sizeof(cmd), cmdval_udplite, miniupnpd_forward_chain, line_number, proto, ext_if_name, iaddr);
snprintf(cmd_raw, sizeof(cmd_raw), cmdval_udplite_raw, line_number, proto, ext_if_name, iaddr);*/
}
else
#endif
{
/*snprintf(cmd, sizeof(cmd), cmdval_udptcp, miniupnpd_forward_chain, line_number, proto, ext_if_name, rport, iaddr, iport);
snprintf(cmd_raw, sizeof(cmd_raw), cmdval_udptcp_raw, line_number, proto, ext_if_name, rport, iaddr, iport);
*/
}
}
#ifdef DEBUG
syslog(LOG_INFO, "Adding following ip6tables rule:");
syslog(LOG_INFO, " -> %s", cmd);
syslog(LOG_INFO, " -> %s", cmd_raw);
#endif
/* TODO Add a better checking error.*/
if(system(cmd) < 0 || system(cmd_raw) < 0)
{
return 0;
}
srand(time(NULL));
snprintf(cuid, sizeof(cuid), "%.4d", rand()%c);
*uid = atoi(cuid);
printf("\t_add_ uid: %s\n", cuid);
return 1;
}
#endif
/* upnp_get_pinhole_info()
* return values :
* 0 OK
* -1 Internal error
* -2 NOT FOUND (no such entry)
* ..
* -42 Not implemented
*/
int
upnp_get_pinhole_info(unsigned short uid,
char * raddr, int raddrlen,
unsigned short * rport,
char * iaddr, int iaddrlen,
unsigned short * iport,
int * proto,
unsigned int * leasetime,
unsigned int * packets)
{
/* Call Firewall specific code to get IPv6 pinhole infos */
#ifdef USE_PF
int r;
unsigned int timestamp;
u_int64_t packets_tmp, bytes_tmp;
r = get_pinhole(uid, raddr, raddrlen, rport,
iaddr, iaddrlen, iport, proto, &timestamp,
&packets_tmp, &bytes_tmp);
if(r >= 0) {
if(leasetime) {
time_t current_time;
current_time = time(NULL);
if(timestamp > (unsigned int)current_time)
*leasetime = timestamp - current_time;
else
*leasetime = 0;
}
if(packets)
*packets = (unsigned int)packets_tmp;
}
return r;
#else
UNUSED(uid);
UNUSED(raddr); UNUSED(raddrlen); UNUSED(rport);
UNUSED(iaddr); UNUSED(iaddrlen); UNUSED(iport);
UNUSED(proto); UNUSED(leasetime); UNUSED(packets);
return -42; /* not implemented */
#endif
}
int
upnp_update_inboundpinhole(unsigned short uid, unsigned int leasetime)
{
#ifdef USE_PF
unsigned int timestamp;
timestamp = time(NULL) + leasetime;
return update_pinhole(uid, timestamp);
#else
UNUSED(uid); UNUSED(leasetime);
return -42; /* not implemented */
#endif
}
int
upnp_delete_inboundpinhole(unsigned short uid)
{
#ifdef USE_PF
return delete_pinhole(uid);
#else
UNUSED(uid);
return -1;
#endif
}
#if 0
/*
* Result:
* 1: Found Result
* -4: No result
* -5: Result in another table
* -6: Result in another chain
* -7: Result in a chain not a rule
*/
int
upnp_check_pinhole_working(const char * uid,
char * eaddr,
char * iaddr,
unsigned short * eport,
unsigned short * iport,
char * protocol,
int * rulenum_used)
{
/* TODO : to be implemented */
#if 0
FILE * fd;
time_t expire = time(NULL);
char buf[1024], filename[] = "/var/log/kern.log", expire_time[32]="";
int res = -4, str_len;
str_len = strftime(expire_time, sizeof(expire_time), "%b %d %H:%M:%S", localtime(&expire));
fd = fopen(filename, "r");
if (fd==NULL)
{
syslog(LOG_ERR, "Get_rule: could not open file: %s", filename);
return -1;
}
syslog(LOG_INFO, "Get_rule: Starting getting info in file %s for %s\n", filename, uid);
buf[sizeof(buf)-1] = 0;
while(fgets(buf, sizeof(buf)-1, fd) != NULL && res != 1)
{
//printf("line: %s\n", buf);
char * r, * t, * c, * p;
// looking for something like filter:FORWARD:rule: or filter:MINIUPNPD:rule:
r = strstr(buf, ":rule:");
p = strstr(buf, ":policy:");
t = strstr(buf, "TRACE:"); // table pointeur
t += 7;
c = t + 7; // chain pointeur
if(r)
{
printf("\t** Found %.*s\n", 24 ,t);
char * src, * dst, * sport, * dport, * proto, * line;
char time[15]="", src_addr[40], dst_addr[40], proto_tmp[8];
int proto_int;
strncpy(time, buf, sizeof(time));
/*if(compare_time(time, expire_time)<0)
{
printf("\t\tNot corresponding time\n");
continue;
}*/
line = r + 6;
printf("\trule line = %d\n", atoi(line));
src = strstr(buf, "SRC=");
src += 4;
snprintf(src_addr, sizeof(src_addr), "%.*s", 39, src);
#if 0
del_char(src_addr);
add_char(src_addr);
#endif
dst = strstr(buf, "DST=");
dst += 4;
snprintf(dst_addr, sizeof(dst_addr), "%.*s", 39, dst);
#if 0
del_char(dst_addr);
add_char(dst_addr);
#endif
proto = strstr(buf, "PROTO=");
proto += 6;
proto_int = atoi(protocol);
if(proto_int == IPPROTO_UDP)
strcpy(proto_tmp, "UDP");
else if(proto_int == IPPROTO_TCP)
strcpy(proto_tmp, "TCP");
#ifdef IPPROTO_UDPLITE
else if(proto_int == IPPROTO_UDPLITE)
strcpy(proto_tmp, "UDPLITE");
#endif
else
strcpy(proto_tmp, "UnsupportedProto");
// printf("\tCompare eaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", eaddr, proto_tmp, src_addr, strlen(proto_tmp), proto);
// printf("\tCompare iaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", iaddr, proto_tmp, dst_addr, strlen(proto_tmp), proto);
// TODO Check time
// Check that the paquet found in trace correspond to the one we are looking for
if( /*(strcmp(eaddr, src_addr) == 0) &&*/ (strcmp(iaddr, dst_addr) == 0) && (strncmp(proto_tmp, proto, strlen(proto_tmp))==0))
{
sport = strstr(buf, "SPT=");
sport += 4;
dport = strstr(buf, "DPT=");
dport += 4;
printf("\tCompare eport: %hu\n\t to port: %d\n", *eport, atoi(sport));
printf("\tCompare iport: %hu\n\t to port: %d\n", *iport, atoi(dport));
if(/*eport != atoi(sport) &&*/ *iport != atoi(dport))
{
printf("\t\tPort not corresponding\n");
continue;
}
printf("\ttable found: %.*s\n", 6, t);
printf("\tchain found: %.*s\n", 9, c);
// Check that the table correspond to the filter table
if(strncmp(t, "filter", 6)==0)
{
// Check that the table correspond to the MINIUPNP table
if(strncmp(c, "MINIUPNPD", 9)==0)
{
*rulenum_used = atoi(line);
res = 1;
}
else
{
res = -6;
continue;
}
}
else
{
res = -5;
continue;
}
}
else
{
printf("Packet information not corresponding\n");
continue;
}
}
if(!r && p)
{
printf("\t** Policy case\n");
char * src, * dst, * sport, * dport, * proto, * line;
char time[15], src_addr[40], dst_addr[40], proto_tmp[8];
int proto_int;
strncpy(time, buf, sizeof(time));
/*if(compare_time(time, expire_time)<0)
{
printf("\t\tNot corresponding time\n");
continue;
}*/
line = p + 8;
printf("\trule line = %d\n", atoi(line));
src = strstr(buf, "SRC=");
src += 4;
snprintf(src_addr, sizeof(src_addr), "%.*s", 39, src);
#if 0
del_char(src_addr);
add_char(src_addr);
#endif
dst = strstr(buf, "DST=");
dst += 4;
snprintf(dst_addr, sizeof(dst_addr), "%.*s", 39, dst);
#if 0
del_char(dst_addr);
add_char(dst_addr);
#endif
proto = strstr(buf, "PROTO=");
proto += 6;
proto_int = atoi(protocol);
if(proto_int == IPPROTO_UDP)
strcpy(proto_tmp, "UDP");
else if(proto_int == IPPROTO_TCP)
strcpy(proto_tmp, "TCP");
#ifdef IPPROTO_UDPLITE
else if(proto_int == IPPROTO_UDPLITE)
strcpy(proto_tmp, "UDPLITE");
#endif
else
strcpy(proto_tmp, "UnsupportedProto");
// printf("\tCompare eaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", eaddr, proto_tmp, src_addr, strlen(proto_tmp), proto);
// printf("\tCompare iaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", iaddr, proto_tmp, dst_addr, strlen(proto_tmp), proto);
// Check that the paquet found in trace correspond to the one we are looking for
if( (strcmp(eaddr, src_addr) == 0) && (strcmp(iaddr, dst_addr) == 0) && (strncmp(proto_tmp, proto, 5)==0))
{
sport = strstr(buf, "SPT=");
sport += 4;
dport = strstr(buf, "DPT=");
dport += 4;
printf("\tCompare eport: %hu\n\t to port: %d\n", *eport, atoi(sport));
printf("\tCompare iport: %hu\n\t to port: %d\n", *iport, atoi(dport));
if(*eport != atoi(sport) && *iport != atoi(dport))
{
printf("\t\tPort not corresponding\n");
continue;
}
else
{
printf("Find a corresponding policy trace in the chain: %.*s\n", 10, c);
res = -7;
continue;
}
}
else
continue;
}
}
fclose(fd);
return res;
#else
return -42; /* to be implemented */
#endif
}
#endif
int
upnp_clean_expired_pinholes(unsigned int * next_timestamp)
{
#ifdef USE_PF
return clean_pinhole_list(next_timestamp);
#else
UNUSED(next_timestamp);
return 0; /* nothing to do */
#endif
}
#endif
/* stuff for miniupnpdctl */
#ifdef USE_MINIUPNPDCTL
void

View File

@ -1,4 +1,4 @@
/* $Id: upnpredirect.h,v 1.33 2012/04/30 13:45:34 nanard Exp $ */
/* $Id: upnpredirect.h,v 1.34 2012/05/01 20:08:23 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard
@ -108,59 +108,6 @@ upnp_get_portmappings_in_range(unsigned short startport,
const char * protocol,
unsigned int * number);
#ifdef ENABLE_6FC_SERVICE
/* functions to be used by WANIPv6_FirewallControl implementation */
#if 0
/* retrieve outbound pinhole timeout */
int
upnp_check_outbound_pinhole(int proto, int * timeout);
#endif
/* add an inbound pinehole
* return value :
* 1 = success
* -1 = Pinhole space exhausted
* .. = error */
int
upnp_add_inboundpinhole(const char * raddr, unsigned short rport,
const char * iaddr, unsigned short iport,
int proto, unsigned int leasetime, int * uid);
/*
* return values :
* -1 not found
* */
int
upnp_get_pinhole_info(unsigned short uid,
char * raddr, int raddrlen,
unsigned short * rport,
char * iaddr, int iaddrlen,
unsigned short * iport,
int * proto,
unsigned int * leasetime,
unsigned int * packets);
/* update the lease time */
int
upnp_update_inboundpinhole(unsigned short uid, unsigned int leasetime);
/* remove the inbound pinhole */
int
upnp_delete_inboundpinhole(unsigned short uid);
/* ... */
#if 0
int
upnp_check_pinhole_working(const char * uid, char * eaddr, char * iaddr, unsigned short * eport, unsigned short * iport, char * protocol, int * rulenum_used);
#endif
/* ? */
int
upnp_clean_expired_pinholes(unsigned int * next_timestamp);
#endif /* ENABLE_6FC_SERVICE */
/* stuff for responding to miniupnpdctl */
#ifdef USE_MINIUPNPDCTL
void

View File

@ -1,4 +1,4 @@
/* $Id: upnpsoap.c,v 1.108 2012/04/30 21:08:01 nanard Exp $ */
/* $Id: upnpsoap.c,v 1.109 2012/05/01 20:08:23 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard
@ -24,6 +24,7 @@
#include "upnpsoap.h"
#include "upnpreplyparse.h"
#include "upnpredirect.h"
#include "upnppinhole.h"
#include "getifaddr.h"
#include "getifstats.h"
#include "getconnstatus.h"