Fix ipfilter support.
- Add support for timestamps - Add support for rhosts - Add get_portmappings_in_range
This commit is contained in:
parent
27b5ae6c9b
commit
a8e337326c
|
@ -131,6 +131,7 @@ struct rdr_desc {
|
|||
struct rdr_desc * next;
|
||||
unsigned short eport;
|
||||
int proto;
|
||||
unsigned int timestamp;
|
||||
char str[];
|
||||
};
|
||||
|
||||
|
@ -138,7 +139,8 @@ struct rdr_desc {
|
|||
static struct rdr_desc * rdr_desc_list;
|
||||
|
||||
static void
|
||||
add_redirect_desc(unsigned short eport, int proto, const char * desc)
|
||||
add_redirect_desc(unsigned short eport, int proto,
|
||||
unsigned int timestamp, const char * desc)
|
||||
{
|
||||
struct rdr_desc * p;
|
||||
size_t l;
|
||||
|
@ -150,6 +152,7 @@ add_redirect_desc(unsigned short eport, int proto, const char * desc)
|
|||
p->next = rdr_desc_list;
|
||||
p->eport = eport;
|
||||
p->proto = proto;
|
||||
p->timestamp = timestamp;
|
||||
memcpy(p->str, desc, l);
|
||||
rdr_desc_list = p;
|
||||
}
|
||||
|
@ -175,7 +178,7 @@ del_redirect_desc(unsigned short eport, int proto)
|
|||
}
|
||||
|
||||
static void
|
||||
get_redirect_desc(unsigned short eport, int proto, char * desc, int desclen)
|
||||
get_redirect_desc(unsigned short eport, int proto, char * desc, int desclen, unsigned int * timestamp)
|
||||
{
|
||||
struct rdr_desc * p;
|
||||
|
||||
|
@ -185,9 +188,11 @@ get_redirect_desc(unsigned short eport, int proto, char * desc, int desclen)
|
|||
if (p->eport == eport && p->proto == proto)
|
||||
{
|
||||
strncpy(desc, p->str, desclen);
|
||||
*timestamp = p->timestamp;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int init_redirect(void)
|
||||
|
@ -221,9 +226,9 @@ void shutdown_redirect(void)
|
|||
}
|
||||
|
||||
int
|
||||
add_redirect_rule2(const char * ifname, unsigned short eport,
|
||||
const char * iaddr, unsigned short iport, int proto,
|
||||
const char * desc)
|
||||
add_redirect_rule2(const char * ifname, const char * rhost,
|
||||
unsigned short eport, const char * iaddr, unsigned short iport,
|
||||
int proto, const char * desc, unsigned int timestamp)
|
||||
{
|
||||
struct ipnat ipnat;
|
||||
struct ipfobj obj;
|
||||
|
@ -257,6 +262,12 @@ add_redirect_rule2(const char * ifname, unsigned short eport,
|
|||
}
|
||||
#endif
|
||||
|
||||
if(rhost && rhost[0] != '\0' && rhost[0] != '*')
|
||||
{
|
||||
inet_pton(AF_INET, rhost, &ipnat.in_src[0].in4);
|
||||
ipnat.in_src[1].in4.s_addr = 0xffffffff;
|
||||
}
|
||||
|
||||
inet_pton(AF_INET, iaddr, &ipnat.in_in[0].in4);
|
||||
ipnat.in_in[1].in4.s_addr = 0xffffffff;
|
||||
|
||||
|
@ -269,7 +280,7 @@ add_redirect_rule2(const char * ifname, unsigned short eport,
|
|||
if (r == -1)
|
||||
syslog(LOG_ERR, "ioctl(SIOCADNAT): %m");
|
||||
else
|
||||
add_redirect_desc(eport, proto, desc);
|
||||
add_redirect_desc(eport, proto, timestamp, desc);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -280,6 +291,8 @@ int
|
|||
get_redirect_rule(const char * ifname, unsigned short eport, int proto,
|
||||
char * iaddr, int iaddrlen, unsigned short * iport,
|
||||
char * desc, int desclen,
|
||||
char * rhost, int rhostlen,
|
||||
unsigned int * timestamp,
|
||||
u_int64_t * packets, u_int64_t * bytes)
|
||||
{
|
||||
ipfgeniter_t iter;
|
||||
|
@ -322,8 +335,10 @@ get_redirect_rule(const char * ifname, unsigned short eport, int proto,
|
|||
*bytes = 0;
|
||||
if (iport != NULL)
|
||||
*iport = ntohs(ipn.in_pnext);
|
||||
if (desc != NULL)
|
||||
get_redirect_desc(eport, proto, desc, desclen);
|
||||
if ((desc != NULL) && (timestamp != NULL))
|
||||
get_redirect_desc(eport, proto, desc, desclen, timestamp);
|
||||
if ((rhost != NULL) && (rhostlen > 0))
|
||||
inet_ntop(AF_INET, &ipn.in_src[0].in4, rhost, rhostlen);
|
||||
inet_ntop(AF_INET, &ipn.in_in[0].in4, iaddr, iaddrlen);
|
||||
r = 0;
|
||||
}
|
||||
|
@ -337,6 +352,8 @@ get_redirect_rule_by_index(int index,
|
|||
char * ifname, unsigned short * eport,
|
||||
char * iaddr, int iaddrlen, unsigned short * iport,
|
||||
int * proto, char * desc, int desclen,
|
||||
char * rhost, int rhostlen,
|
||||
unsigned int * timestamp,
|
||||
u_int64_t * packets, u_int64_t * bytes)
|
||||
{
|
||||
ipfgeniter_t iter;
|
||||
|
@ -387,8 +404,10 @@ get_redirect_rule_by_index(int index,
|
|||
*packets = 0;
|
||||
if (bytes != NULL)
|
||||
*bytes = 0;
|
||||
if (desc != NULL)
|
||||
get_redirect_desc(*eport, *proto, desc, desclen);
|
||||
if ((desc != NULL) && (timestamp != NULL))
|
||||
get_redirect_desc(*eport, *proto, desc, desclen, timestamp);
|
||||
if ((rhost != NULL) && (rhostlen > 0))
|
||||
inet_ntop(AF_INET, &ipn.in_src[0].in4, rhost, rhostlen);
|
||||
inet_ntop(AF_INET, &ipn.in_in[0].in4, iaddr, iaddrlen);
|
||||
r = 0;
|
||||
}
|
||||
|
@ -464,8 +483,8 @@ delete_redirect_rule(const char * ifname, unsigned short eport, int proto)
|
|||
|
||||
/* thanks to Seth Mos for this function */
|
||||
int
|
||||
add_filter_rule2(const char * ifname, const char * iaddr,
|
||||
unsigned short eport, unsigned short iport,
|
||||
add_filter_rule2(const char * ifname, const char * rhost,
|
||||
const char * iaddr, unsigned short eport, unsigned short iport,
|
||||
int proto, const char * desc)
|
||||
{
|
||||
ipfobj_t obj;
|
||||
|
@ -507,6 +526,12 @@ add_filter_rule2(const char * ifname, const char * iaddr,
|
|||
fr.fr_tcpfm = TH_SYN|TH_ACK|TH_RST|TH_FIN|TH_URG|TH_PUSH;
|
||||
}
|
||||
|
||||
if(rhost && rhost[0] != '\0' && rhost[0] != '*')
|
||||
{
|
||||
inet_pton(AF_INET, rhost, &fr.fr_saddr);
|
||||
fr.fr_smask = 0xffffffff;
|
||||
}
|
||||
|
||||
inet_pton(AF_INET, iaddr, &fr.fr_daddr);
|
||||
fr.fr_dmask = 0xffffffff;
|
||||
|
||||
|
@ -600,3 +625,72 @@ delete_filter_rule(const char * ifname, unsigned short eport, int proto)
|
|||
return r;
|
||||
}
|
||||
|
||||
unsigned short *
|
||||
get_portmappings_in_range(unsigned short startport, unsigned short endport,
|
||||
int proto, unsigned int * number)
|
||||
{
|
||||
unsigned short * array;
|
||||
unsigned int capacity;
|
||||
unsigned short eport;
|
||||
ipfgeniter_t iter;
|
||||
ipfobj_t obj;
|
||||
ipnat_t ipn;
|
||||
|
||||
*number = 0;
|
||||
if (dev < 0) {
|
||||
syslog(LOG_ERR, "%s not open", IPNAT_NAME);
|
||||
return NULL;
|
||||
}
|
||||
capacity = 128;
|
||||
array = calloc(capacity, sizeof(unsigned short));
|
||||
if(!array)
|
||||
{
|
||||
syslog(LOG_ERR, "get_portmappings_in_range() : calloc error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(&obj, 0, sizeof(obj));
|
||||
obj.ipfo_rev = IPFILTER_VERSION;
|
||||
obj.ipfo_ptr = &iter;
|
||||
obj.ipfo_size = sizeof(iter);
|
||||
obj.ipfo_type = IPFOBJ_GENITER;
|
||||
|
||||
iter.igi_type = IPFGENITER_IPNAT;
|
||||
#if IPFILTER_VERSION > 4011300
|
||||
iter.igi_nitems = 1;
|
||||
#endif
|
||||
iter.igi_data = &ipn;
|
||||
|
||||
do {
|
||||
if (ioctl(dev, SIOCGENITER, &obj) == -1) {
|
||||
syslog(LOG_ERR, "%s:ioctl(SIOCGENITER): %m",
|
||||
"get_portmappings_in_range");
|
||||
break;
|
||||
}
|
||||
|
||||
if (strcmp(ipn.in_tag.ipt_tag, group_name) != 0)
|
||||
continue;
|
||||
|
||||
eport = ntohs(ipn.in_pmin);
|
||||
if( (eport == ntohs(ipn.in_pmax))
|
||||
&& (ipn.in_p == proto)
|
||||
&& (startport <= eport) && (eport <= endport) )
|
||||
{
|
||||
if(*number >= capacity)
|
||||
{
|
||||
/* need to increase the capacity of the array */
|
||||
capacity += 128;
|
||||
array = realloc(array, sizeof(unsigned short)*capacity);
|
||||
if(!array)
|
||||
{
|
||||
syslog(LOG_ERR, "get_portmappings_in_range() : realloc(%lu) error", sizeof(unsigned short)*capacity);
|
||||
*number = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
array[*number] = eport;
|
||||
(*number)++;
|
||||
}
|
||||
} while (ipn.in_next != NULL);
|
||||
return array;
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@
|
|||
#include "../commonrdr.h"
|
||||
|
||||
int
|
||||
add_redirect_rule2(const char * ifname, unsigned short eport,
|
||||
add_redirect_rule2(const char * ifname, const char * rhost, unsigned short eport,
|
||||
const char * iaddr, unsigned short iport, int proto,
|
||||
const char * desc);
|
||||
const char * desc, unsigned int timestamp);
|
||||
|
||||
int
|
||||
add_filter_rule2(const char * ifname, const char * iaddr,
|
||||
add_filter_rule2(const char * ifname, const char * rhost, const char * iaddr,
|
||||
unsigned short eport, unsigned short iport,
|
||||
int proto, const char * desc);
|
||||
|
||||
|
|
|
@ -1,25 +1,74 @@
|
|||
/* $Id: testipfrdr.c,v 1.3 2007/10/01 16:21:23 nanard Exp $ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include "ipfrdr.h"
|
||||
|
||||
extern void
|
||||
test_list_nat_rules();
|
||||
/* test program for ipfrdr.c */
|
||||
|
||||
int runtime_flags = 0;
|
||||
|
||||
void
|
||||
list_eports_tcp(void)
|
||||
{
|
||||
unsigned short * port_list;
|
||||
unsigned int number = 0;
|
||||
unsigned int i;
|
||||
port_list = get_portmappings_in_range(0, 65535, IPPROTO_TCP, &number);
|
||||
printf("%u ports redirected (TCP) :", number);
|
||||
for(i = 0; i < number; i++)
|
||||
{
|
||||
printf(" %hu", port_list[i]);
|
||||
}
|
||||
printf("\n");
|
||||
free(port_list);
|
||||
port_list = get_portmappings_in_range(0, 65535, IPPROTO_UDP, &number);
|
||||
printf("%u ports redirected (UDP) :", number);
|
||||
for(i = 0; i < number; i++)
|
||||
{
|
||||
printf(" %hu", port_list[i]);
|
||||
}
|
||||
printf("\n");
|
||||
free(port_list);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char * * argv)
|
||||
{
|
||||
char c;
|
||||
|
||||
openlog("testipfrdrd", LOG_CONS|LOG_PERROR, LOG_USER);
|
||||
printf("List nat rules :\n");
|
||||
test_list_nat_rules();
|
||||
if(init_redirect() < 0)
|
||||
{
|
||||
fprintf(stderr, "init_redirect() failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("List rdr ports :\n");
|
||||
list_eports_tcp();
|
||||
|
||||
printf("Add redirection !\n");
|
||||
add_redirect_rule2("ep0", 12345, "1.2.3.4", 54321, IPPROTO_UDP,
|
||||
"redirection description");
|
||||
printf("List nat rules :\n");
|
||||
test_list_nat_rules();
|
||||
add_redirect_rule2("xennet0", "*", 12345, "192.168.1.100", 54321, IPPROTO_UDP,
|
||||
"redirection description", 0);
|
||||
add_redirect_rule2("xennet0", "8.8.8.8", 12345, "192.168.1.100", 54321, IPPROTO_TCP,
|
||||
"redirection description", 0);
|
||||
|
||||
printf("Check redirect rules with \"ipnat -l\" then press any key.\n");
|
||||
c = getchar();
|
||||
|
||||
printf("List rdr ports :\n");
|
||||
list_eports_tcp();
|
||||
|
||||
printf("Delete redirection !\n");
|
||||
delete_redirect_rule("xennet0", 12345, IPPROTO_UDP);
|
||||
delete_redirect_rule("xennet0", 12345, IPPROTO_TCP);
|
||||
|
||||
printf("List rdr ports :\n");
|
||||
list_eports_tcp();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue