Working on DeletePinhole() and GetPinholePackets()
This commit is contained in:
parent
82355aca40
commit
d27f35ccde
|
@ -1,4 +1,4 @@
|
|||
/* $Id: pfpinhole.c,v 1.12 2012/04/22 00:55:51 nanard Exp $ */
|
||||
/* $Id: pfpinhole.c,v 1.15 2012/04/22 23:36:41 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2012 Thomas Bernard
|
||||
|
@ -199,13 +199,14 @@ int delete_pinhole(unsigned short uid)
|
|||
}
|
||||
}
|
||||
/* not found */
|
||||
return -1;
|
||||
return -2;
|
||||
}
|
||||
|
||||
int get_pinhole(unsigned short uid,
|
||||
char * rem_host, int rem_hostlen, unsigned short * rem_port,
|
||||
char * int_client, int int_clientlen, unsigned short * int_port,
|
||||
int * proto, unsigned int * timestamp)
|
||||
int * proto, unsigned int * timestamp,
|
||||
u_int64_t * packets, u_int64_t * bytes)
|
||||
{
|
||||
int i, n;
|
||||
struct pfioc_rule pr;
|
||||
|
@ -239,23 +240,40 @@ int get_pinhole(unsigned short uid,
|
|||
p = tmp_label;
|
||||
strsep(&p, " ");
|
||||
if(0 == strcmp(tmp_label, label_start)) {
|
||||
if(inet_ntop(AF_INET6, &pr.rule.src.addr.v.a.addr.v6, rem_host, rem_hostlen) == NULL) {
|
||||
return -2;
|
||||
if(rem_host && (inet_ntop(AF_INET6, &pr.rule.src.addr.v.a.addr.v6, rem_host, rem_hostlen) == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
*rem_port = ntohs(pr.rule.src.port[0]);
|
||||
if(inet_ntop(AF_INET6, &pr.rule.dst.addr.v.a.addr.v6, int_client, int_clientlen) == NULL) {
|
||||
return -2;
|
||||
if(rem_port)
|
||||
*rem_port = ntohs(pr.rule.src.port[0]);
|
||||
if(int_client && (inet_ntop(AF_INET6, &pr.rule.dst.addr.v.a.addr.v6, int_client, int_clientlen) == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
*int_port = ntohs(pr.rule.dst.port[0]);
|
||||
*proto = pr.rule.proto;
|
||||
sscanf(p, "ts-%u", timestamp);
|
||||
if(int_port)
|
||||
*int_port = ntohs(pr.rule.dst.port[0]);
|
||||
if(proto)
|
||||
*proto = pr.rule.proto;
|
||||
if(timestamp)
|
||||
sscanf(p, "ts-%u", timestamp);
|
||||
#ifdef PFRULE_INOUT_COUNTS
|
||||
if(packets)
|
||||
*packets = pr.rule.packets[0] + pr.rule.packets[1];
|
||||
if(bytes)
|
||||
*bytes = pr.rule.bytes[0] + pr.rule.bytes[1];
|
||||
#else
|
||||
if(packets)
|
||||
*packets = pr.rule.packets;
|
||||
if(bytes)
|
||||
*bytes = pr.rule.bytes;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* not found */
|
||||
return -1;
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* return the number of rules removed
|
||||
* or a negative integer in case of error */
|
||||
int clean_pinhole_list(unsigned int * next_timestamp)
|
||||
{
|
||||
int i;
|
||||
|
@ -265,6 +283,7 @@ int clean_pinhole_list(unsigned int * next_timestamp)
|
|||
int uid;
|
||||
unsigned int min_ts = UINT_MAX;
|
||||
int min_uid = INT_MAX, max_uid = -1;
|
||||
int n = 0;
|
||||
|
||||
if(dev<0) {
|
||||
syslog(LOG_ERR, "pf device is not open");
|
||||
|
@ -303,6 +322,7 @@ int clean_pinhole_list(unsigned int * next_timestamp)
|
|||
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
|
||||
return -1;
|
||||
}
|
||||
n++;
|
||||
#ifndef PF_NEWSTYLE
|
||||
pr.rule.action = PF_PASS;
|
||||
#endif
|
||||
|
@ -329,7 +349,7 @@ int clean_pinhole_list(unsigned int * next_timestamp)
|
|||
next_uid = 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return n; /* number of rules removed */
|
||||
}
|
||||
|
||||
#endif /* ENABLE_IPV6 */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: pfpinhole.h,v 1.6 2012/04/22 00:55:51 nanard Exp $ */
|
||||
/* $Id: pfpinhole.h,v 1.7 2012/04/22 23:08:51 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2012 Thomas Bernard
|
||||
|
@ -18,7 +18,8 @@ int delete_pinhole(unsigned short uid);
|
|||
int get_pinhole(unsigned short uid,
|
||||
char * rem_host, int rem_hostlen, unsigned short * rem_port,
|
||||
char * int_client, int int_clientlen, unsigned short * int_port,
|
||||
int * proto, unsigned int * timestamp);
|
||||
int * proto, unsigned int * timestamp,
|
||||
u_int64_t * packets, u_int64_t * bytes);
|
||||
|
||||
int clean_pinhole_list(unsigned int * next_timestamp);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: testpfpinhole.c,v 1.9 2012/04/22 00:55:51 nanard Exp $ */
|
||||
/* $Id: testpfpinhole.c,v 1.10 2012/04/22 23:12:51 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2012 Thomas Bernard
|
||||
|
@ -30,17 +30,20 @@ static int print_pinhole(int uid)
|
|||
unsigned short int_port;
|
||||
int proto;
|
||||
unsigned int timestamp;
|
||||
u_int64_t packets, bytes;
|
||||
|
||||
r = get_pinhole((unsigned short)uid,
|
||||
rem_host, sizeof(rem_host), &rem_port,
|
||||
int_client, sizeof(int_client), &int_port,
|
||||
&proto, ×tamp);
|
||||
&proto, ×tamp,
|
||||
&packets, &bytes);
|
||||
if(r < 0) {
|
||||
fprintf(stderr, "get_pinhole(%d) returned %d\n", uid, r);
|
||||
} else {
|
||||
printf("pinhole %d : [%s]:%hu => [%s]:%hu proto=%d ts=%u\n",
|
||||
uid, rem_host, rem_port, int_client, int_port,
|
||||
proto, timestamp);
|
||||
printf(" packets=%llu bytes=%llu\n", packets, bytes);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: upnpredirect.c,v 1.70 2012/04/22 00:55:46 nanard Exp $ */
|
||||
/* $Id: upnpredirect.c,v 1.72 2012/04/22 23:25:22 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006-2012 Thomas Bernard
|
||||
|
@ -763,6 +763,14 @@ upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
|
@ -770,14 +778,17 @@ upnp_get_pinhole_info(unsigned short uid,
|
|||
char * iaddr, int iaddrlen,
|
||||
unsigned short * iport,
|
||||
int * proto,
|
||||
unsigned int * leasetime)
|
||||
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, ×tamp);
|
||||
iaddr, iaddrlen, iport, proto, ×tamp,
|
||||
&packets_tmp, &bytes_tmp);
|
||||
if(r >= 0) {
|
||||
time_t current_time;
|
||||
current_time = time(NULL);
|
||||
|
@ -785,6 +796,8 @@ upnp_get_pinhole_info(unsigned short uid,
|
|||
*leasetime = timestamp - current_time;
|
||||
else
|
||||
*leasetime = 0;
|
||||
if(packets)
|
||||
*packets = (unsigned int)packets_tmp;
|
||||
}
|
||||
return r;
|
||||
#else
|
||||
|
@ -1040,26 +1053,6 @@ upnp_check_pinhole_working(const char * uid,
|
|||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
upnp_get_pinhole_packets(const char * uid, int * packets)
|
||||
{
|
||||
/* TODO : to be implemented */
|
||||
#if 0
|
||||
int line=0, r;
|
||||
char cmd[256];
|
||||
r = check_rule_from_file(uid, &line);
|
||||
if(r < 0)
|
||||
return r;
|
||||
else
|
||||
{
|
||||
snprintf(cmd, sizeof(cmd), "ip6tables -L MINIUPNPD %d -v", line);
|
||||
return retrieve_packets(cmd, &line, packets);
|
||||
}
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
upnp_clean_expired_pinholes(unsigned int * next_timestamp)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: upnpredirect.h,v 1.30 2012/04/22 00:55:46 nanard Exp $ */
|
||||
/* $Id: upnpredirect.h,v 1.31 2012/04/22 23:08:48 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006-2012 Thomas Bernard
|
||||
|
@ -136,7 +136,8 @@ upnp_get_pinhole_info(unsigned short uid,
|
|||
char * iaddr, int iaddrlen,
|
||||
unsigned short * iport,
|
||||
int * proto,
|
||||
unsigned int * leasetime);
|
||||
unsigned int * leasetime,
|
||||
unsigned int * packets);
|
||||
|
||||
/* update the lease time */
|
||||
int
|
||||
|
@ -150,10 +151,6 @@ upnp_delete_inboundpinhole(unsigned short uid);
|
|||
int
|
||||
upnp_check_pinhole_working(const char * uid, char * eaddr, char * iaddr, unsigned short * eport, unsigned short * iport, char * protocol, int * rulenum_used);
|
||||
|
||||
/* number of packets that went through the pinhole */
|
||||
int
|
||||
upnp_get_pinhole_packets(const char * uid, int * packets);
|
||||
|
||||
/* ? */
|
||||
int
|
||||
upnp_clean_expired_pinholes(unsigned int * next_timestamp);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: upnpsoap.c,v 1.99 2012/04/22 00:02:46 nanard Exp $ */
|
||||
/* $Id: upnpsoap.c,v 1.104 2012/04/22 23:36:20 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006-2012 Thomas Bernard
|
||||
|
@ -1224,7 +1224,6 @@ PinholeVerification(struct upnphttp * h, char * int_ip, unsigned short int_port)
|
|||
{
|
||||
inet_ntop(AF_INET6, (struct in6_addr *) p, int_ip, sizeof(struct in6_addr));
|
||||
result_ip = *((struct in6_addr *) p);
|
||||
/* fprintf(stderr, "upnpsoap / AddPinhole: assuming int addr = %s", int_ip); */
|
||||
/* TODO : deal with more than one ip per hostname */
|
||||
break;
|
||||
}
|
||||
|
@ -1432,15 +1431,17 @@ clear_and_exit:
|
|||
static void
|
||||
UpdatePinhole(struct upnphttp * h, const char * action)
|
||||
{
|
||||
int r, n;
|
||||
int r/*, n*/;
|
||||
static const char resp[] =
|
||||
"<u:UpdatePinholeResponse "
|
||||
"xmlns:u=\"urn:schemas-upnp-org:service:WANIPv6FirewallControl:1\">"
|
||||
"</u:UpdatePinholeResponse>";
|
||||
struct NameValueParserData data;
|
||||
const char * uid, * leaseTime;
|
||||
#if 0
|
||||
char iaddr[40], proto[6], lt[12];
|
||||
unsigned short iport;
|
||||
#endif
|
||||
int ltime = -1;
|
||||
|
||||
if(CheckStatus(h)==0)
|
||||
|
@ -1461,6 +1462,7 @@ UpdatePinhole(struct upnphttp * h, const char * action)
|
|||
|
||||
/* Check that client is not deleting an pinhole
|
||||
* it doesn't have access to, because of its public access */
|
||||
#if 0
|
||||
n = upnp_get_pinhole_info(0, 0, iaddr, &iport, proto, uid, lt);
|
||||
if (n > 0)
|
||||
{
|
||||
|
@ -1470,6 +1472,7 @@ UpdatePinhole(struct upnphttp * h, const char * action)
|
|||
return ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
syslog(LOG_INFO, "%s: (inbound) updating lease duration to %s for pinhole with ID: %s", action, leaseTime, uid);
|
||||
|
||||
|
@ -1546,7 +1549,7 @@ GetOutboundPinholeTimeout(struct upnphttp * h, const char * action)
|
|||
static void
|
||||
DeletePinhole(struct upnphttp * h, const char * action)
|
||||
{
|
||||
int r, n;
|
||||
int n;
|
||||
|
||||
static const char resp[] =
|
||||
"<u:DeletePinholeResponse "
|
||||
|
@ -1554,73 +1557,81 @@ DeletePinhole(struct upnphttp * h, const char * action)
|
|||
"</u:DeletePinholeResponse>";
|
||||
|
||||
struct NameValueParserData data;
|
||||
const char * uid;
|
||||
char iaddr[40], proto[6], lt[12];
|
||||
const char * uid_str;
|
||||
char iaddr[INET6_ADDRSTRLEN];
|
||||
int proto;
|
||||
unsigned short iport;
|
||||
unsigned int leasetime;
|
||||
int uid;
|
||||
|
||||
if(CheckStatus(h)==0)
|
||||
return;
|
||||
|
||||
ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data);
|
||||
uid = GetValueFromNameValueList(&data, "UniqueID");
|
||||
uid_str = GetValueFromNameValueList(&data, "UniqueID");
|
||||
uid = uid_str ? atoi(uid_str) : -1;
|
||||
ClearNameValueList(&data);
|
||||
|
||||
if(!uid || atoi(uid) < 0 || atoi(uid) > 65535)
|
||||
if(uid < 0 || uid > 65535)
|
||||
{
|
||||
ClearNameValueList(&data);
|
||||
SoapError(h, 402, "Invalid Args");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check that client is not deleting an pinhole
|
||||
* it doesn't have access to, because of its public access */
|
||||
n = upnp_get_pinhole_info(0, 0, iaddr, &iport, proto, uid, lt);
|
||||
if (n > 0)
|
||||
n = upnp_get_pinhole_info(uid, NULL, 0, NULL,
|
||||
iaddr, sizeof(iaddr), &iport,
|
||||
&proto, &leasetime, NULL);
|
||||
if (n >= 0)
|
||||
{
|
||||
if(PinholeVerification(h, iaddr, iport)==0)
|
||||
{
|
||||
ClearNameValueList(&data);
|
||||
return ;
|
||||
}
|
||||
if(!PinholeVerification(h, iaddr, iport))
|
||||
return;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "%s: (inbound) delete pinhole with ID: %s", action, uid);
|
||||
|
||||
r = upnp_delete_inboundpinhole(uid);
|
||||
|
||||
if(r < 0)
|
||||
else if(n == -2)
|
||||
{
|
||||
syslog(LOG_INFO, "%s: (inbound) failed to remove pinhole with ID: %s", action, uid);
|
||||
if(r==-4)
|
||||
SoapError(h, 704, "NoSuchEntry");
|
||||
else
|
||||
SoapError(h, 501, "ActionFailed");
|
||||
SoapError(h, 704, "NoSuchEntry");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_INFO, "%s: (inbound) pinhole successfully removed", action);
|
||||
BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1);
|
||||
SoapError(h, 501, "ActionFailed");
|
||||
return;
|
||||
}
|
||||
ClearNameValueList(&data);
|
||||
|
||||
n = upnp_delete_inboundpinhole(uid);
|
||||
if(n < 0)
|
||||
{
|
||||
syslog(LOG_INFO, "%s: (inbound) failed to remove pinhole with ID: %d",
|
||||
action, uid);
|
||||
SoapError(h, 501, "ActionFailed");
|
||||
return;
|
||||
}
|
||||
syslog(LOG_INFO, "%s: (inbound) pinhole with ID %d successfully removed",
|
||||
action, uid);
|
||||
BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1);
|
||||
}
|
||||
|
||||
static void
|
||||
CheckPinholeWorking(struct upnphttp * h, const char * action)
|
||||
{
|
||||
int r, d;
|
||||
|
||||
#if 0
|
||||
static const char resp[] =
|
||||
"<u:%sResponse "
|
||||
"xmlns:u=\"%s\">"
|
||||
"<IsWorking>%d</IsWorking>"
|
||||
"</u:%sResponse>";
|
||||
|
||||
char body[512];
|
||||
int bodylen;
|
||||
int r, d;
|
||||
#endif
|
||||
struct NameValueParserData data;
|
||||
const char * uid;
|
||||
#if 0
|
||||
char eaddr[40], iaddr[40], proto[6], lt[12];
|
||||
unsigned short eport, iport;
|
||||
int isWorking = 0;
|
||||
#endif
|
||||
|
||||
if(CheckStatus(h)==0)
|
||||
return;
|
||||
|
@ -1637,6 +1648,7 @@ CheckPinholeWorking(struct upnphttp * h, const char * action)
|
|||
|
||||
/* Check that client is not checking a pinhole
|
||||
* it doesn't have access to, because of its public access */
|
||||
#if 0
|
||||
r = upnp_get_pinhole_info(eaddr, eport, iaddr, &iport, proto, uid, lt);
|
||||
if (r > 0)
|
||||
{
|
||||
|
@ -1694,6 +1706,7 @@ CheckPinholeWorking(struct upnphttp * h, const char * action)
|
|||
SoapError(h, 704, "NoSuchEntry");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
SoapError(h, 501, "ActionFailed");
|
||||
ClearNameValueList(&data);
|
||||
|
@ -1705,66 +1718,60 @@ CheckPinholeWorking(struct upnphttp * h, const char * action)
|
|||
static void
|
||||
GetPinholePackets(struct upnphttp * h, const char * action)
|
||||
{
|
||||
int r, n;
|
||||
|
||||
static const char resp[] =
|
||||
"<u:%sResponse "
|
||||
"xmlns:u=\"%s\">"
|
||||
"<PinholePackets>%d</PinholePackets>"
|
||||
"<PinholePackets>%u</PinholePackets>"
|
||||
"</u:%sResponse>";
|
||||
|
||||
char body[512];
|
||||
int bodylen;
|
||||
struct NameValueParserData data;
|
||||
const char * uid;
|
||||
char iaddr[40], proto[6], lt[12];
|
||||
const char * uid_str;
|
||||
int n;
|
||||
char iaddr[INET6_ADDRSTRLEN];
|
||||
unsigned short iport;
|
||||
int pinholePackets = 0;
|
||||
unsigned int packets = 0;
|
||||
int uid;
|
||||
int proto;
|
||||
unsigned int leasetime;
|
||||
|
||||
if(CheckStatus(h)==0)
|
||||
return;
|
||||
|
||||
ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data);
|
||||
uid = GetValueFromNameValueList(&data, "UniqueID");
|
||||
uid_str = GetValueFromNameValueList(&data, "UniqueID");
|
||||
uid = uid_str ? atoi(uid_str) : -1;
|
||||
ClearNameValueList(&data);
|
||||
|
||||
if(!uid)
|
||||
if(uid < 0 || uid > 65535)
|
||||
{
|
||||
ClearNameValueList(&data);
|
||||
SoapError(h, 402, "Invalid Args");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check that client is not getting infos of a pinhole
|
||||
* it doesn't have access to, because of its public access */
|
||||
r = upnp_get_pinhole_info(0, 0, iaddr, &iport, proto, uid, lt);
|
||||
if (r > 0)
|
||||
n = upnp_get_pinhole_info(uid, NULL, 0, NULL,
|
||||
iaddr, sizeof(iaddr), &iport,
|
||||
&proto, &leasetime, &packets);
|
||||
if (n >= 0)
|
||||
{
|
||||
if(PinholeVerification(h, iaddr, iport)==0)
|
||||
{
|
||||
ClearNameValueList(&data);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
n = upnp_get_pinhole_packets(uid, &pinholePackets);
|
||||
if(n > 0)
|
||||
{
|
||||
bodylen = snprintf(body, sizeof(body), resp,
|
||||
action, "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1",
|
||||
pinholePackets, action);
|
||||
BuildSendAndCloseSoapResp(h, body, bodylen);
|
||||
}
|
||||
#if 0
|
||||
else if(r == -4 || r == -1)
|
||||
{
|
||||
SoapError(h, 704, "NoSuchEntry");
|
||||
}
|
||||
else
|
||||
{
|
||||
SoapError(h, 501, "ActionFailed");
|
||||
ClearNameValueList(&data);
|
||||
return ;
|
||||
}
|
||||
ClearNameValueList(&data);
|
||||
#endif
|
||||
|
||||
bodylen = snprintf(body, sizeof(body), resp,
|
||||
action, "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1",
|
||||
packets, action);
|
||||
BuildSendAndCloseSoapResp(h, body, bodylen);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue