version 1.1.1.1, 2012/02/21 23:16:02
|
version 1.1.1.2, 2013/07/22 00:32:35
|
Line 131 struct rdr_desc {
|
Line 131 struct rdr_desc {
|
struct rdr_desc * next; |
struct rdr_desc * next; |
unsigned short eport; |
unsigned short eport; |
int proto; |
int proto; |
|
unsigned int timestamp; |
char str[]; |
char str[]; |
}; |
}; |
|
|
Line 138 struct rdr_desc {
|
Line 139 struct rdr_desc {
|
static struct rdr_desc * rdr_desc_list; |
static struct rdr_desc * rdr_desc_list; |
|
|
static void |
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; |
struct rdr_desc * p; |
size_t l; |
size_t l; |
| |
if (desc != NULL) { |
if (desc != NULL) { |
l = strlen(desc) + 1; |
l = strlen(desc) + 1; |
p = malloc(sizeof(struct rdr_desc) + l); |
p = malloc(sizeof(struct rdr_desc) + l); |
Line 150 add_redirect_desc(unsigned short eport, int proto, con
|
Line 152 add_redirect_desc(unsigned short eport, int proto, con
|
p->next = rdr_desc_list; |
p->next = rdr_desc_list; |
p->eport = eport; |
p->eport = eport; |
p->proto = proto; |
p->proto = proto; |
|
p->timestamp = timestamp; |
memcpy(p->str, desc, l); |
memcpy(p->str, desc, l); |
rdr_desc_list = p; |
rdr_desc_list = p; |
} |
} |
Line 175 del_redirect_desc(unsigned short eport, int proto)
|
Line 178 del_redirect_desc(unsigned short eport, int proto)
|
} |
} |
|
|
static void |
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; |
struct rdr_desc * p; |
| |
if (desc == NULL || desclen == 0) |
if (desc == NULL || desclen == 0) |
return; |
return; |
for (p = rdr_desc_list; p; p = p->next) { |
for (p = rdr_desc_list; p; p = p->next) { |
if (p->eport == eport && p->proto == proto) |
if (p->eport == eport && p->proto == proto) |
{ |
{ |
strncpy(desc, p->str, desclen); |
strncpy(desc, p->str, desclen); |
|
*timestamp = p->timestamp; |
return; |
return; |
} |
} |
} |
} |
|
return; |
} |
} |
|
|
int init_redirect(void) |
int init_redirect(void) |
{ |
{ |
| |
dev = open(IPNAT_NAME, O_RDWR); |
dev = open(IPNAT_NAME, O_RDWR); |
if (dev < 0) { |
if (dev < 0) { |
syslog(LOG_ERR, "open(\"%s\"): %m", IPNAT_NAME); |
syslog(LOG_ERR, "open(\"%s\"): %m", IPNAT_NAME); |
Line 208 int init_redirect(void)
|
Line 213 int init_redirect(void)
|
|
|
void shutdown_redirect(void) |
void shutdown_redirect(void) |
{ |
{ |
| |
if (dev >= 0) { |
if (dev >= 0) { |
close(dev); |
close(dev); |
dev = -1; |
dev = -1; |
Line 221 void shutdown_redirect(void)
|
Line 226 void shutdown_redirect(void)
|
} |
} |
|
|
int |
int |
add_redirect_rule2(const char * ifname, unsigned short eport, | add_redirect_rule2(const char * ifname, const char * rhost, |
const char * iaddr, unsigned short iport, int proto, | unsigned short eport, const char * iaddr, unsigned short iport, |
const char * desc) | int proto, const char * desc, unsigned int timestamp) |
{ |
{ |
struct ipnat ipnat; |
struct ipnat ipnat; |
struct ipfobj obj; |
struct ipfobj obj; |
Line 257 add_redirect_rule2(const char * ifname, unsigned short
|
Line 262 add_redirect_rule2(const char * ifname, unsigned short
|
} |
} |
#endif |
#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); |
inet_pton(AF_INET, iaddr, &ipnat.in_in[0].in4); |
ipnat.in_in[1].in4.s_addr = 0xffffffff; |
ipnat.in_in[1].in4.s_addr = 0xffffffff; |
|
|
Line 269 add_redirect_rule2(const char * ifname, unsigned short
|
Line 280 add_redirect_rule2(const char * ifname, unsigned short
|
if (r == -1) |
if (r == -1) |
syslog(LOG_ERR, "ioctl(SIOCADNAT): %m"); |
syslog(LOG_ERR, "ioctl(SIOCADNAT): %m"); |
else |
else |
add_redirect_desc(eport, proto, desc); | add_redirect_desc(eport, proto, timestamp, desc); |
return r; |
return r; |
} |
} |
|
|
Line 280 int
|
Line 291 int
|
get_redirect_rule(const char * ifname, unsigned short eport, int proto, |
get_redirect_rule(const char * ifname, unsigned short eport, int proto, |
char * iaddr, int iaddrlen, unsigned short * iport, |
char * iaddr, int iaddrlen, unsigned short * iport, |
char * desc, int desclen, |
char * desc, int desclen, |
|
char * rhost, int rhostlen, |
|
unsigned int * timestamp, |
u_int64_t * packets, u_int64_t * bytes) |
u_int64_t * packets, u_int64_t * bytes) |
{ |
{ |
ipfgeniter_t iter; |
ipfgeniter_t iter; |
Line 322 get_redirect_rule(const char * ifname, unsigned short
|
Line 335 get_redirect_rule(const char * ifname, unsigned short
|
*bytes = 0; |
*bytes = 0; |
if (iport != NULL) |
if (iport != NULL) |
*iport = ntohs(ipn.in_pnext); |
*iport = ntohs(ipn.in_pnext); |
if (desc != NULL) | if ((desc != NULL) && (timestamp != NULL)) |
get_redirect_desc(eport, proto, desc, desclen); | 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); |
inet_ntop(AF_INET, &ipn.in_in[0].in4, iaddr, iaddrlen); |
r = 0; |
r = 0; |
} |
} |
Line 337 get_redirect_rule_by_index(int index,
|
Line 352 get_redirect_rule_by_index(int index,
|
char * ifname, unsigned short * eport, |
char * ifname, unsigned short * eport, |
char * iaddr, int iaddrlen, unsigned short * iport, |
char * iaddr, int iaddrlen, unsigned short * iport, |
int * proto, char * desc, int desclen, |
int * proto, char * desc, int desclen, |
|
char * rhost, int rhostlen, |
|
unsigned int * timestamp, |
u_int64_t * packets, u_int64_t * bytes) |
u_int64_t * packets, u_int64_t * bytes) |
{ |
{ |
ipfgeniter_t iter; |
ipfgeniter_t iter; |
Line 387 get_redirect_rule_by_index(int index,
|
Line 404 get_redirect_rule_by_index(int index,
|
*packets = 0; |
*packets = 0; |
if (bytes != NULL) |
if (bytes != NULL) |
*bytes = 0; |
*bytes = 0; |
if (desc != NULL) | if ((desc != NULL) && (timestamp != NULL)) |
get_redirect_desc(*eport, *proto, desc, desclen); | 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); |
inet_ntop(AF_INET, &ipn.in_in[0].in4, iaddr, iaddrlen); |
r = 0; |
r = 0; |
} |
} |
Line 464 delete_redirect_rule(const char * ifname, unsigned sho
|
Line 483 delete_redirect_rule(const char * ifname, unsigned sho
|
|
|
/* thanks to Seth Mos for this function */ |
/* thanks to Seth Mos for this function */ |
int |
int |
add_filter_rule2(const char * ifname, const char * iaddr, | add_filter_rule2(const char * ifname, const char * rhost, |
unsigned short eport, unsigned short iport, | const char * iaddr, unsigned short eport, unsigned short iport, |
int proto, const char * desc) |
int proto, const char * desc) |
{ |
{ |
ipfobj_t obj; |
ipfobj_t obj; |
Line 507 add_filter_rule2(const char * ifname, const char * iad
|
Line 526 add_filter_rule2(const char * ifname, const char * iad
|
fr.fr_tcpfm = TH_SYN|TH_ACK|TH_RST|TH_FIN|TH_URG|TH_PUSH; |
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); |
inet_pton(AF_INET, iaddr, &fr.fr_daddr); |
fr.fr_dmask = 0xffffffff; |
fr.fr_dmask = 0xffffffff; |
|
|
Line 600 delete_filter_rule(const char * ifname, unsigned short
|
Line 625 delete_filter_rule(const char * ifname, unsigned short
|
return r; |
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; |
|
} |