13#include <sys/socket.h>
14#include <netinet/in.h>
18#include <linux/netfilter/xt_DSCP.h>
19#include <libiptc/libiptc.h>
21#include <linux/version.h>
30#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
31#define __must_be_array(a) \
32 BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
33#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
34#define LIST_POISON2 ((void *) 0x00200200 )
37#include <linux/netfilter/nf_nat.h>
41#define ip_nat_multi_range nf_nat_multi_range
42#define ip_nat_range nf_nat_range
43#define IPTC_HANDLE struct iptc_handle *
46#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
47#include <linux/netfilter_ipv4/ip_nat.h>
50#include <linux/netfilter/nf_nat.h>
55#define IPTC_HANDLE iptc_handle_t
60#define IPT_ALIGN XT_ALIGN
90 if (
string == NULL || strlen(
string) > 30 ||
string[0] ==
'\0') {
91 syslog(LOG_ERR,
"%s(): invalid string argument '%s'",
"set_rdr_name",
string);
95 case RDR_NAT_PREROUTING_CHAIN_NAME:
98 case RDR_NAT_POSTROUTING_CHAIN_NAME:
101 case RDR_FORWARD_CHAIN_NAME:
105 syslog(LOG_ERR,
"%s(): tried to set invalid string parameter: %d",
"set_rdr_name", param);
114 const char * iaddr,
unsigned short iport,
119 const char * iaddr,
unsigned short iport);
121#ifdef ENABLE_PORT_TRIGGERING
123addmasqueraderule(
int proto,
124 unsigned short eport,
125 const char * iaddr,
unsigned short iport,
131 const char * eaddr,
unsigned short eport,
132 const char * iaddr,
unsigned short iport,
133 const char * rhost,
unsigned short rport);
137 const char * iaddr,
unsigned short iport,
138 const char * rhost,
unsigned short rport);
146 h = iptc_init(
"nat");
148 syslog(LOG_ERR,
"iptc_init() failed : %s",
149 iptc_strerror(errno));
169 return snprintf(dst, size,
170 "%u.%u.%u.%u", ip >> 24, (ip >> 16) & 0xff,
171 (ip >> 8) & 0xff, ip & 0xff);
177 struct rdr_desc *
next;
179 unsigned short eport;
190 const char * desc,
unsigned int timestamp)
197 l = strlen(desc) + 1;
198 p = malloc(
sizeof(
struct rdr_desc) + l);
204 p->proto = (short)
proto;
236 char * desc,
int desclen,
242 if(p->eport ==
eport && p->proto == (
short)
proto)
245 strncpy(desc, p->str, desclen);
253 strncpy(desc,
"miniupnpd", desclen);
261 const char * rhost,
unsigned short eport,
262 const char * iaddr,
unsigned short iport,
int proto,
263 const char * desc,
unsigned int timestamp)
271#ifdef ENABLE_PORT_TRIGGERING
276 r = addmasqueraderule(
proto,
eport, iaddr, iport, rhost);
278 syslog(LOG_NOTICE,
"add_redirect_rule2(): addmasqueraderule returned %d", r);
288 const char * rhost,
unsigned short rport,
289 const char * eaddr,
unsigned short eport,
290 const char * iaddr,
unsigned short iport,
int proto,
291 const char * desc,
unsigned int timestamp)
304 const char * rhost,
unsigned short rport,
306 const char * iaddr,
unsigned short iport,
int proto,
307 const char * desc,
unsigned int timestamp)
322 const char * rhost,
const char * iaddr,
323 unsigned short eport,
unsigned short iport,
324 int proto,
const char * desc)
337 char * iaddr,
int iaddrlen,
unsigned short * iport,
338 char * desc,
int desclen,
339 char * rhost,
int rhostlen,
341 u_int64_t * packets, u_int64_t * bytes)
345 iaddr, iaddrlen, iport,
353 char * iaddr,
int iaddrlen,
unsigned short * iport,
354 char * desc,
int desclen,
355 char * rhost,
int rhostlen,
357 u_int64_t * packets, u_int64_t * bytes)
361 const struct ipt_entry * e;
362 const struct ipt_entry_target * target;
363 const struct ip_nat_multi_range * mr;
364 const struct ipt_entry_match *match;
367 h = iptc_init(
"nat");
370 syslog(LOG_ERR,
"%s() : iptc_init() failed : %s",
371 "get_nat_redirect_rule", iptc_strerror(errno));
374 if(!iptc_is_chain(nat_chain_name,
h))
376 syslog(LOG_ERR,
"chain %s not found", nat_chain_name);
381 for(e = iptc_first_rule(nat_chain_name,
h);
383 e = iptc_next_rule(e,
h))
385 for(e = iptc_first_rule(nat_chain_name, &
h);
387 e = iptc_next_rule(e, &
h))
390 if(proto==e->ip.proto)
392 match = (
const struct ipt_entry_match *)&e->elems;
393 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
395 const struct ipt_tcp *
info;
396 info = (
const struct ipt_tcp *)match->data;
397 if(eport !=
info->dpts[0])
402 const struct ipt_udp *
info;
403 info = (
const struct ipt_udp *)match->data;
404 if(eport !=
info->dpts[0])
407 target = (
void *)e + e->target_offset;
409 mr = (
const struct ip_nat_multi_range *)&target->data[0];
410 snprintip(iaddr, iaddrlen, ntohl(mr->range[0].min_ip));
411 *iport = ntohs(mr->range[0].min.all);
414 *packets = e->counters.pcnt;
416 *bytes = e->counters.bcnt;
418 if(e->ip.src.s_addr && rhost) {
419 snprintip(rhost, rhostlen, ntohl(e->ip.src.s_addr));
439 char *
ifname,
unsigned short * eport,
440 char * iaddr,
int iaddrlen,
unsigned short * iport,
441 int * proto,
char * desc,
int desclen,
442 char * rhost,
int rhostlen,
443 unsigned int * timestamp,
444 u_int64_t * packets, u_int64_t * bytes)
449 const struct ipt_entry * e;
450 const struct ipt_entry_target * target;
451 const struct ip_nat_multi_range * mr;
452 const struct ipt_entry_match *match;
455 h = iptc_init(
"nat");
458 syslog(LOG_ERR,
"%s() : iptc_init() failed : %s",
459 "get_redirect_rule_by_index", iptc_strerror(errno));
471 e = iptc_next_rule(e,
h))
475 e = iptc_next_rule(e, &
h))
480 *proto = e->ip.proto;
481 match = (
const struct ipt_entry_match *)&e->elems;
482 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
484 const struct ipt_tcp *
info;
485 info = (
const struct ipt_tcp *)match->data;
486 *eport =
info->dpts[0];
490 const struct ipt_udp *
info;
491 info = (
const struct ipt_udp *)match->data;
492 *eport =
info->dpts[0];
494 target = (
void *)e + e->target_offset;
495 mr = (
const struct ip_nat_multi_range *)&target->data[0];
496 snprintip(iaddr, iaddrlen, ntohl(mr->range[0].min_ip));
497 *iport = ntohs(mr->range[0].min.all);
500 *packets = e->counters.pcnt;
502 *bytes = e->counters.bcnt;
504 if(rhost && rhostlen > 0) {
505 if(e->ip.src.s_addr) {
506 snprintip(rhost, rhostlen, ntohl(e->ip.src.s_addr));
530 char *
ifname,
unsigned short * eport,
531 char * iaddr,
int iaddrlen,
unsigned short * iport,
532 int * proto,
char * desc,
int desclen,
533 char * rhost,
int rhostlen,
unsigned short * rport,
534 unsigned int * timestamp,
535 u_int64_t * packets, u_int64_t * bytes)
540 const struct ipt_entry * e;
541 const struct ipt_entry_target * target;
542 const struct ip_nat_multi_range * mr;
543 const struct ipt_entry_match *match;
546 h = iptc_init(
"nat");
549 syslog(LOG_ERR,
"%s() : iptc_init() failed : %s",
550 "get_peer_rule_by_index", iptc_strerror(errno));
562 e = iptc_next_rule(e,
h))
566 e = iptc_next_rule(e, &
h))
571 *proto = e->ip.proto;
572 match = (
const struct ipt_entry_match *)&e->elems;
573 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
575 const struct ipt_tcp *
info;
576 info = (
const struct ipt_tcp *)match->data;
578 *rport =
info->dpts[0];
580 *iport =
info->spts[0];
584 const struct ipt_udp *
info;
585 info = (
const struct ipt_udp *)match->data;
587 *rport =
info->dpts[0];
589 *iport =
info->spts[0];
591 target = (
void *)e + e->target_offset;
592 mr = (
const struct ip_nat_multi_range *)&target->data[0];
593 *eport = ntohs(mr->range[0].min.all);
596 *packets = e->counters.pcnt;
598 *bytes = e->counters.bcnt;
600 if(rhost && rhostlen > 0) {
601 if(e->ip.dst.s_addr) {
602 snprintip(rhost, rhostlen, ntohl(e->ip.dst.s_addr));
607 if(iaddr && iaddrlen > 0) {
608 if(e->ip.src.s_addr) {
609 snprintip(iaddr, iaddrlen, ntohl(e->ip.src.s_addr));
633 const char * miniupnpd_chain,
634 const char * logcaller)
638 if(!iptc_delete_num_entry(miniupnpd_chain, index,
h))
640 if(!iptc_delete_num_entry(miniupnpd_chain, index, &
h))
643 syslog(LOG_ERR,
"%s() : iptc_delete_num_entry(): %s\n",
644 logcaller, iptc_strerror(errno));
648 else if(!iptc_commit(
h))
650 else if(!iptc_commit(&
h))
653 syslog(LOG_ERR,
"%s() : iptc_commit(): %s\n",
654 logcaller, iptc_strerror(errno));
675 const struct ipt_entry * e;
676 const struct ipt_entry_match *match;
679 if((
h = iptc_init(
"filter")))
686 e = iptc_next_rule(e,
h), i++)
690 e = iptc_next_rule(e, &
h), i++)
693 if(proto==e->ip.proto)
695 match = (
const struct ipt_entry_match *)&e->elems;
698 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
700 const struct ipt_tcp *
info;
701 info = (
const struct ipt_tcp *)match->data;
702 if(port !=
info->dpts[0])
707 const struct ipt_udp *
info;
708 info = (
const struct ipt_udp *)match->data;
709 if(port !=
info->dpts[0])
738 const struct ipt_entry * e;
739 const struct ipt_entry_target * target;
740 const struct ip_nat_multi_range * mr;
741 const struct ipt_entry_match *match;
742 unsigned short iport = 0;
745 h = iptc_init(
"nat");
748 syslog(LOG_ERR,
"%s() : iptc_init() failed : %s",
749 "delete_redirect_and_filter_rules", iptc_strerror(errno));
762 e = iptc_next_rule(e,
h), i++)
766 e = iptc_next_rule(e, &
h), i++)
769 if(proto==e->ip.proto)
771 match = (
const struct ipt_entry_match *)&e->elems;
772 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
774 const struct ipt_tcp *
info;
775 info = (
const struct ipt_tcp *)match->data;
776 if(eport !=
info->dpts[0])
781 const struct ipt_udp *
info;
782 info = (
const struct ipt_udp *)match->data;
783 if(eport !=
info->dpts[0])
789 target = (
void *)e + e->target_offset;
790 mr = (
const struct ip_nat_multi_range *)&target->data[0];
791 iaddr = mr->range[0].min_ip;
792 iport = ntohs(mr->range[0].min.all);
806 syslog(LOG_INFO,
"Trying to delete nat rule at index %u", index);
809 h = iptc_init(
"nat");
814 if((r == 0) && (
h = iptc_init(
"filter")))
821 e = iptc_next_rule(e,
h), i++)
825 e = iptc_next_rule(e, &
h), i++)
828 if(proto==e->ip.proto)
830 match = (
const struct ipt_entry_match *)&e->elems;
833 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
835 const struct ipt_tcp *
info;
836 info = (
const struct ipt_tcp *)match->data;
837 if(iport !=
info->dpts[0])
842 const struct ipt_udp *
info;
843 info = (
const struct ipt_udp *)match->data;
844 if(iport !=
info->dpts[0])
847 if(iaddr != e->ip.dst.s_addr)
850 syslog(LOG_INFO,
"Trying to delete filter rule at index %u", index);
866 if((
h = iptc_init(
"nat")))
873 e = iptc_next_rule(e,
h), i++)
877 e = iptc_next_rule(e, &
h), i++)
880 if(proto==e->ip.proto)
882 target = (
void *)e + e->target_offset;
883 mr = (
const struct ip_nat_multi_range *)&target->data[0];
884 syslog(LOG_DEBUG,
"postrouting rule #%u: %s %s %hu",
885 i, target->u.user.name, inet_ntoa(e->ip.src), ntohs(mr->range[0].min.all));
887 if (eport != ntohs(mr->range[0].min.all)) {
890 iaddr = e->ip.src.s_addr;
891 match = (
const struct ipt_entry_match *)&e->elems;
892 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
894 const struct ipt_tcp *
info;
895 info = (
const struct ipt_tcp *)match->data;
896 iport =
info->spts[0];
900 const struct ipt_udp *
info;
901 info = (
const struct ipt_udp *)match->data;
902 iport =
info->spts[0];
906 syslog(LOG_INFO,
"Trying to delete peer rule at index %u", index);
921 if((r2==0)&&(
h = iptc_init(
"mangle")))
929 e = iptc_next_rule(e,
h), i++)
933 e = iptc_next_rule(e, &
h), i++)
936 if(proto==e->ip.proto)
938 match = (
const struct ipt_entry_match *)&e->elems;
941 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
943 const struct ipt_tcp *
info;
944 info = (
const struct ipt_tcp *)match->data;
945 if(iport !=
info->spts[0])
950 const struct ipt_udp *
info;
951 info = (
const struct ipt_udp *)match->data;
952 if(iport !=
info->spts[0])
955 if(iaddr != e->ip.src.s_addr)
958 syslog(LOG_INFO,
"Trying to delete dscp rule at index %u", index);
979static struct ipt_entry_match *
982 struct ipt_entry_match *match;
983 struct ipt_tcp * tcpinfo;
985 size =
IPT_ALIGN(
sizeof(
struct ipt_entry_match))
987 match = calloc(1, size);
988 match->u.match_size = size;
989 strncpy(match->u.user.name,
"tcp",
sizeof(match->u.user.name));
990 tcpinfo = (
struct ipt_tcp *)match->data;
992 tcpinfo->spts[0] = 0;
993 tcpinfo->spts[1] = 0xFFFF;
995 tcpinfo->spts[0] = sport;
996 tcpinfo->spts[1] = sport;
999 tcpinfo->dpts[0] = 0;
1000 tcpinfo->dpts[1] = 0xFFFF;
1002 tcpinfo->dpts[0] = dport;
1003 tcpinfo->dpts[1] = dport;
1008static struct ipt_entry_match *
1011 struct ipt_entry_match *match;
1012 struct ipt_udp * udpinfo;
1014 size =
IPT_ALIGN(
sizeof(
struct ipt_entry_match))
1016 match = calloc(1, size);
1017 match->u.match_size = size;
1018 strncpy(match->u.user.name,
"udp",
sizeof(match->u.user.name));
1019 udpinfo = (
struct ipt_udp *)match->data;
1021 udpinfo->spts[0] = 0;
1022 udpinfo->spts[1] = 0xFFFF;
1024 udpinfo->spts[0] = sport;
1025 udpinfo->spts[1] = sport;
1028 udpinfo->dpts[0] = 0;
1029 udpinfo->dpts[1] = 0xFFFF;
1031 udpinfo->dpts[0] = dport;
1032 udpinfo->dpts[1] = dport;
1037static struct ipt_entry_target *
1040 struct ipt_entry_target * target;
1041 struct ip_nat_multi_range * mr;
1042 struct ip_nat_range * range;
1045 size =
IPT_ALIGN(
sizeof(
struct ipt_entry_target))
1046 +
IPT_ALIGN(
sizeof(
struct ip_nat_multi_range));
1047 target = calloc(1, size);
1048 target->u.target_size = size;
1049 strncpy(target->u.user.name,
"DNAT",
sizeof(target->u.user.name));
1051 mr = (
struct ip_nat_multi_range *)&target->data[0];
1053 range = &mr->range[0];
1054 range->min_ip = range->max_ip = inet_addr(daddr);
1056 range->min.all = range->max.all = htons(dport);
1061static struct ipt_entry_target *
1064 struct ipt_entry_target * target;
1065 struct ip_nat_multi_range * mr;
1066 struct ip_nat_range * range;
1069 size =
IPT_ALIGN(
sizeof(
struct ipt_entry_target))
1070 +
IPT_ALIGN(
sizeof(
struct ip_nat_multi_range));
1071 target = calloc(1, size);
1072 target->u.target_size = size;
1073 strncpy(target->u.user.name,
"SNAT",
sizeof(target->u.user.name));
1075 mr = (
struct ip_nat_multi_range *)&target->data[0];
1077 range = &mr->range[0];
1078 range->min_ip = range->max_ip = inet_addr(saddr);
1080 range->min.all = range->max.all = htons(sport);
1085static struct ipt_entry_target *
1088 struct ipt_entry_target * target;
1089 struct xt_DSCP_info * di;
1092 size =
IPT_ALIGN(
sizeof(
struct ipt_entry_target))
1093 +
IPT_ALIGN(
sizeof(
struct xt_DSCP_info));
1094 target = calloc(1, size);
1095 target->u.target_size = size;
1096 strncpy(target->u.user.name,
"DSCP",
sizeof(target->u.user.name));
1098 di = (
struct xt_DSCP_info *)&target->data[0];
1103#ifdef ENABLE_PORT_TRIGGERING
1104static struct ipt_entry_target *
1105get_masquerade_target(
unsigned short port)
1107 struct ipt_entry_target * target;
1108 struct ip_nat_multi_range * mr;
1109 struct ip_nat_range * range;
1112 size =
IPT_ALIGN(
sizeof(
struct ipt_entry_target))
1113 +
IPT_ALIGN(
sizeof(
struct ip_nat_multi_range));
1114 target = calloc(1, size);
1115 target->u.target_size = size;
1116 strncpy(target->u.user.name,
"MASQUERADE",
sizeof(target->u.user.name));
1118 mr = (
struct ip_nat_multi_range *)&target->data[0];
1120 range = &mr->range[0];
1121 range->min.tcp.port = range->max.tcp.port = htons(port);
1132 const char * miniupnpd_chain,
1133 struct ipt_entry * e,
1134 const char * logcaller)
1137 h = iptc_init(table);
1140 syslog(LOG_ERR,
"%s() : iptc_init() error : %s\n",
1141 logcaller, iptc_strerror(errno));
1144 if(!iptc_is_chain(miniupnpd_chain,
h))
1146 syslog(LOG_ERR,
"%s() : chain %s not found",
1147 logcaller, miniupnpd_chain);
1158 if(!iptc_append_entry(miniupnpd_chain, e,
h))
1160 if(!iptc_append_entry(miniupnpd_chain, e, &
h))
1163 syslog(LOG_ERR,
"%s() : iptc_append_entry() error : %s\n",
1164 logcaller, iptc_strerror(errno));
1176 if(!iptc_commit(&
h))
1179 syslog(LOG_ERR,
"%s() : iptc_commit() error : %s\n",
1180 logcaller, iptc_strerror(errno));
1203 const char * iaddr,
unsigned short iport,
1207 struct ipt_entry * e;
1208 struct ipt_entry * tmp;
1209 struct ipt_entry_match *match = NULL;
1210 struct ipt_entry_target *target = NULL;
1212 e = calloc(1,
sizeof(
struct ipt_entry));
1214 syslog(LOG_ERR,
"%s: calloc(%d) error",
"addnatrule",
1215 (
int)
sizeof(
struct ipt_entry));
1218 e->ip.proto = proto;
1219 if(proto == IPPROTO_TCP) {
1225 e->nfcache = NFC_UNKNOWN;
1229 e->nfcache |= NFC_IP_DST_PT;
1231 tmp = realloc(e,
sizeof(
struct ipt_entry)
1232 + match->u.match_size
1233 + target->u.target_size);
1235 syslog(LOG_ERR,
"%s: realloc(%d) error",
"addnatrule",
1236 (
int)(
sizeof(
struct ipt_entry) + match->u.match_size + target->u.target_size));
1243 memcpy(e->elems, match, match->u.match_size);
1244 memcpy(e->elems + match->u.match_size, target, target->u.target_size);
1245 e->target_offset =
sizeof(
struct ipt_entry)
1246 + match->u.match_size;
1247 e->next_offset =
sizeof(
struct ipt_entry)
1248 + match->u.match_size
1249 + target->u.target_size;
1251 if(rhost && (rhost[0] !=
'\0') && (0 != strcmp(rhost,
"*"))) {
1252 e->ip.src.s_addr = inet_addr(rhost);
1253 e->ip.smsk.s_addr = INADDR_NONE;
1273#ifdef ENABLE_PORT_TRIGGERING
1275addmasqueraderule(
int proto,
1276 unsigned short eport,
1277 const char * iaddr,
unsigned short iport,
1281 struct ipt_entry *
e;
1282 struct ipt_entry * tmp;
1283 struct ipt_entry_match *
match = NULL;
1284 struct ipt_entry_target *target = NULL;
1286 e = calloc(1,
sizeof(
struct ipt_entry));
1288 syslog(LOG_ERR,
"%s: calloc(%d) error",
"addmasqueraderule",
1289 (
int)
sizeof(
struct ipt_entry));
1293 if(proto == IPPROTO_TCP) {
1299 e->nfcache = NFC_UNKNOWN;
1301 target = get_masquerade_target(eport);
1303 e->nfcache |= NFC_IP_DST_PT;
1305 tmp = realloc(e,
sizeof(
struct ipt_entry)
1306 +
match->u.match_size
1307 + target->u.target_size);
1309 syslog(LOG_ERR,
"%s: realloc(%d) error",
"addmasqueraderule",
1310 (
int)(
sizeof(
struct ipt_entry) +
match->u.match_size + target->u.target_size));
1318 memcpy(
e->elems +
match->u.match_size, target, target->u.target_size);
1319 e->target_offset =
sizeof(
struct ipt_entry)
1321 e->next_offset =
sizeof(
struct ipt_entry)
1323 + target->
u.target_size;
1328 strncpy(
e->ip.outiface, extif,
sizeof(
e->ip.outiface));
1329 memset(
e->ip.outiface_mask, 0xff, strlen(
e->ip.outiface) + 1);
1333 if(iaddr && (iaddr[0] !=
'\0') && (0 != strcmp(iaddr,
"*")))
1335 e->ip.src.s_addr = inet_addr(iaddr);
1336 e->ip.smsk.s_addr = INADDR_NONE;
1339 if(rhost && (rhost[0] !=
'\0') && (0 != strcmp(rhost,
"*"))) {
1340 e->ip.dst.s_addr = inet_addr(rhost);
1341 e->ip.dmsk.s_addr = INADDR_NONE;
1359 const char * eaddr,
unsigned short eport,
1360 const char * iaddr,
unsigned short iport,
1361 const char * rhost,
unsigned short rport)
1364 struct ipt_entry * e;
1365 struct ipt_entry * tmp;
1366 struct ipt_entry_match *match = NULL;
1367 struct ipt_entry_target *target = NULL;
1369 e = calloc(1,
sizeof(
struct ipt_entry));
1371 syslog(LOG_ERR,
"%s: calloc(%d) error",
"addpeernatrule",
1372 (
int)
sizeof(
struct ipt_entry));
1375 e->ip.proto = proto;
1377 if(proto == IPPROTO_TCP) {
1383 e->nfcache = NFC_UNKNOWN;
1387 e->nfcache |= NFC_IP_DST_PT;
1390 e->nfcache |= NFC_IP_SRC_PT;
1392 tmp = realloc(e,
sizeof(
struct ipt_entry)
1393 + match->u.match_size
1394 + target->u.target_size);
1396 syslog(LOG_ERR,
"%s: realloc(%d) error",
"addpeernatrule",
1397 (
int)(
sizeof(
struct ipt_entry) + match->u.match_size + target->u.target_size));
1404 memcpy(e->elems, match, match->u.match_size);
1405 memcpy(e->elems + match->u.match_size, target, target->u.target_size);
1406 e->target_offset =
sizeof(
struct ipt_entry)
1407 + match->u.match_size;
1408 e->next_offset =
sizeof(
struct ipt_entry)
1409 + match->u.match_size
1410 + target->u.target_size;
1413 if(iaddr && (iaddr[0] !=
'\0') && (0 != strcmp(iaddr,
"*")))
1415 e->ip.src.s_addr = inet_addr(iaddr);
1416 e->ip.smsk.s_addr = INADDR_NONE;
1419 if(rhost && (rhost[0] !=
'\0') && (0 != strcmp(rhost,
"*")))
1421 e->ip.dst.s_addr = inet_addr(rhost);
1422 e->ip.dmsk.s_addr = INADDR_NONE;
1438 const char * iaddr,
unsigned short iport,
1439 const char * rhost,
unsigned short rport)
1442 struct ipt_entry * e;
1443 struct ipt_entry * tmp;
1444 struct ipt_entry_match *match = NULL;
1445 struct ipt_entry_target *target = NULL;
1447 e = calloc(1,
sizeof(
struct ipt_entry));
1449 syslog(LOG_ERR,
"%s: calloc(%d) error",
"addpeerdscprule",
1450 (
int)
sizeof(
struct ipt_entry));
1453 e->ip.proto = proto;
1455 if(proto == IPPROTO_TCP) {
1461 e->nfcache = NFC_UNKNOWN;
1465 e->nfcache |= NFC_IP_DST_PT;
1468 e->nfcache |= NFC_IP_SRC_PT;
1470 tmp = realloc(e,
sizeof(
struct ipt_entry)
1471 + match->u.match_size
1472 + target->u.target_size);
1474 syslog(LOG_ERR,
"%s: realloc(%d) error",
"addpeerdscprule",
1475 (
int)(
sizeof(
struct ipt_entry) + match->u.match_size + target->u.target_size));
1482 memcpy(e->elems, match, match->u.match_size);
1483 memcpy(e->elems + match->u.match_size, target, target->u.target_size);
1484 e->target_offset =
sizeof(
struct ipt_entry)
1485 + match->u.match_size;
1486 e->next_offset =
sizeof(
struct ipt_entry)
1487 + match->u.match_size
1488 + target->u.target_size;
1491 if(iaddr && (iaddr[0] !=
'\0') && (0 != strcmp(iaddr,
"*")))
1493 e->ip.src.s_addr = inet_addr(iaddr);
1494 e->ip.smsk.s_addr = INADDR_NONE;
1497 if(rhost && (rhost[0] !=
'\0') && (0 != strcmp(rhost,
"*")))
1499 e->ip.dst.s_addr = inet_addr(rhost);
1500 e->ip.dmsk.s_addr = INADDR_NONE;
1513static struct ipt_entry_target *
1516 struct ipt_entry_target * target = NULL;
1518 size =
IPT_ALIGN(
sizeof(
struct ipt_entry_target))
1520 target = calloc(1, size);
1521 target->u.user.target_size = size;
1522 strncpy(target->u.user.name,
"ACCEPT",
sizeof(target->u.user.name));
1530 const char * iaddr,
unsigned short iport)
1533 struct ipt_entry * e;
1534 struct ipt_entry * tmp;
1535 struct ipt_entry_match *match = NULL;
1536 struct ipt_entry_target *target = NULL;
1538 e = calloc(1,
sizeof(
struct ipt_entry));
1540 syslog(LOG_ERR,
"%s: calloc(%d) error",
"add_filter_rule",
1541 (
int)
sizeof(
struct ipt_entry));
1544 e->ip.proto = proto;
1545 if(proto == IPPROTO_TCP) {
1550 e->ip.dst.s_addr = inet_addr(iaddr);
1551 e->ip.dmsk.s_addr = INADDR_NONE;
1553 e->nfcache = NFC_UNKNOWN;
1557 e->nfcache |= NFC_IP_DST_PT;
1559 tmp = realloc(e,
sizeof(
struct ipt_entry)
1560 + match->u.match_size
1561 + target->u.target_size);
1563 syslog(LOG_ERR,
"%s: realloc(%d) error",
"add_filter_rule",
1564 (
int)(
sizeof(
struct ipt_entry) + match->u.match_size + target->u.target_size));
1571 memcpy(e->elems, match, match->u.match_size);
1572 memcpy(e->elems + match->u.match_size, target, target->u.target_size);
1573 e->target_offset =
sizeof(
struct ipt_entry)
1574 + match->u.match_size;
1575 e->next_offset =
sizeof(
struct ipt_entry)
1576 + match->u.match_size
1577 + target->u.target_size;
1579 if(rhost && (rhost[0] !=
'\0') && (0 != strcmp(rhost,
"*")))
1581 e->ip.src.s_addr = inet_addr(rhost);
1582 e->ip.smsk.s_addr = INADDR_NONE;
1596 int proto,
unsigned int * number)
1598 unsigned short * array;
1599 unsigned int capacity;
1600 unsigned short eport;
1602 const struct ipt_entry * e;
1603 const struct ipt_entry_match *match;
1607 array = calloc(capacity,
sizeof(
unsigned short));
1610 syslog(LOG_ERR,
"%s() : calloc error",
"get_portmappings_in_range");
1614 h = iptc_init(
"nat");
1617 syslog(LOG_ERR,
"%s() : iptc_init() failed : %s",
1618 "get_portmappings_in_range", iptc_strerror(errno));
1633 e = iptc_next_rule(e,
h))
1637 e = iptc_next_rule(e, &
h))
1640 if(proto == e->ip.proto)
1642 match = (
const struct ipt_entry_match *)&e->elems;
1643 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
1645 const struct ipt_tcp *
info;
1646 info = (
const struct ipt_tcp *)match->data;
1647 eport =
info->dpts[0];
1651 const struct ipt_udp *
info;
1652 info = (
const struct ipt_udp *)match->data;
1653 eport =
info->dpts[0];
1655 if(startport <= eport && eport <= endport)
1657 if(*number >= capacity)
1659 unsigned short * tmp;
1662 if (capacity <= *number)
1663 capacity = *number + 1;
1664 tmp = realloc(array,
sizeof(
unsigned short)*capacity);
1667 syslog(LOG_ERR,
"get_portmappings_in_range() : realloc(%u) error",
1668 (
unsigned)
sizeof(
unsigned short)*capacity);
1676 array[*number] = eport;
1693 unsigned short eport,
int proto,
1694 const char * desc,
unsigned int timestamp)
1704 unsigned index,
const struct ipt_entry * e)
1709 h = iptc_init(table);
1712 syslog(LOG_ERR,
"%s() : iptc_init() failed : %s",
1713 "update_rule_and_commit", iptc_strerror(errno));
1717 if(!iptc_replace_entry(chain, e, index,
h))
1719 if(!iptc_replace_entry(chain, e, index, &
h))
1722 syslog(LOG_ERR,
"%s(): iptc_replace_entry: %s",
1723 "update_rule_and_commit", iptc_strerror(errno));
1727 else if(!iptc_commit(
h))
1729 else if(!iptc_commit(&
h))
1732 syslog(LOG_ERR,
"%s(): iptc_commit: %s",
1733 "update_rule_and_commit", iptc_strerror(errno));
1746 unsigned short iport,
const char * desc,
1747 unsigned int timestamp)
1754 const struct ipt_entry * e;
1755 struct ipt_entry * new_e = NULL;
1757 struct ipt_entry_target * target;
1758 struct ip_nat_multi_range * mr;
1759 const struct ipt_entry_match *match;
1761 unsigned short old_iport = 0;
1763 h = iptc_init(
"nat");
1766 syslog(LOG_ERR,
"%s() : iptc_init() failed : %s",
1767 "update_portmapping", iptc_strerror(errno));
1781 e = iptc_next_rule(e,
h), i++)
1785 e = iptc_next_rule(e, &
h), i++)
1788 if(proto==e->ip.proto)
1790 match = (
const struct ipt_entry_match *)&e->elems;
1791 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
1793 const struct ipt_tcp *
info;
1794 info = (
const struct ipt_tcp *)match->data;
1795 if(eport !=
info->dpts[0])
1800 const struct ipt_udp *
info;
1801 info = (
const struct ipt_udp *)match->data;
1802 if(eport !=
info->dpts[0])
1808 target = (
void *)e + e->target_offset;
1809 mr = (
struct ip_nat_multi_range *)&target->data[0];
1810 iaddr = mr->range[0].min_ip;
1811 old_iport = ntohs(mr->range[0].min.all);
1812 entry_len =
sizeof(
struct ipt_entry) + match->u.match_size + target->u.target_size;
1813 new_e = malloc(entry_len);
1815 syslog(LOG_ERR,
"%s: malloc(%u) error",
1816 "update_portmapping", (
unsigned)entry_len);
1821 memcpy(new_e, e, entry_len);
1834 syslog(LOG_INFO,
"Trying to update nat rule at index %u", index);
1835 target = (
void *)new_e + new_e->target_offset;
1836 mr = (
struct ip_nat_multi_range *)&target->data[0];
1837 mr->range[0].min.all = mr->range[0].max.all = htons(iport);
1840 free(new_e); new_e = NULL;
1845 h = iptc_init(
"filter");
1848 syslog(LOG_ERR,
"%s() : iptc_init() failed : %s",
1849 "update_portmapping", iptc_strerror(errno));
1863 e = iptc_next_rule(e,
h), i++)
1867 e = iptc_next_rule(e, &
h), i++)
1870 if(proto!=e->ip.proto)
1872 target = (
void *)e + e->target_offset;
1873 match = (
const struct ipt_entry_match *)&e->elems;
1874 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
1876 const struct ipt_tcp *
info;
1877 info = (
const struct ipt_tcp *)match->data;
1878 if(old_iport !=
info->dpts[0])
1883 const struct ipt_udp *
info;
1884 info = (
const struct ipt_udp *)match->data;
1885 if(old_iport !=
info->dpts[0])
1888 if(iaddr != e->ip.dst.s_addr)
1892 entry_len =
sizeof(
struct ipt_entry) + match->u.match_size + target->u.target_size;
1893 new_e = malloc(entry_len);
1895 syslog(LOG_ERR,
"%s: malloc(%u) error",
1896 "update_portmapping", (
unsigned)entry_len);
1899 memcpy(new_e, e, entry_len);
1900 target = (
void *)new_e + new_e->target_offset;
1901 if (target->u.user.name[0] ==
'\0' && iptc_get_target(e,
h)) {
1902 strncpy(target->u.user.name, iptc_get_target(e,
h),
sizeof(target->u.user.name));
1916 syslog(LOG_INFO,
"Trying to update filter rule at index %u", index);
1917 match = (
struct ipt_entry_match *)&new_e->elems;
1918 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
1920 struct ipt_tcp *
info;
1921 info = (
struct ipt_tcp *)match->data;
1922 info->dpts[0] =
info->dpts[1] = iport;
1926 struct ipt_udp *
info;
1927 info = (
struct ipt_udp *)match->data;
1928 info->dpts[0] =
info->dpts[1] = iport;
1931 free(new_e); new_e = NULL;
1935#ifdef ENABLE_PORT_TRIGGERING
1937 h = iptc_init(
"nat");
1940 syslog(LOG_ERR,
"%s() : iptc_init() failed : %s",
1941 "update_portmapping", iptc_strerror(errno));
1955 e = iptc_next_rule(e,
h), i++)
1959 e = iptc_next_rule(e, &
h), i++)
1962 if(proto==e->ip.proto)
1964 target = (
void *)e + e->target_offset;
1965 mr = (
struct ip_nat_multi_range *)&target->data[0];
1966 syslog(LOG_DEBUG,
"postrouting rule #%u: %s %s %hu",
1967 i, target->u.user.name, inet_ntoa(e->ip.src), ntohs(mr->range[0].min.all));
1969 if (eport != ntohs(mr->range[0].min.all)) {
1972 match = (
const struct ipt_entry_match *)&e->elems;
1973 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
1975 const struct ipt_tcp *
info;
1976 info = (
const struct ipt_tcp *)match->data;
1977 if(old_iport !=
info->spts[0])
1982 const struct ipt_udp *
info;
1983 info = (
const struct ipt_udp *)match->data;
1984 if(old_iport !=
info->spts[0])
1987 if (iaddr != e->ip.src.s_addr) {
1992 entry_len =
sizeof(
struct ipt_entry) + match->u.match_size + target->u.target_size;
1993 new_e = malloc(entry_len);
1995 syslog(LOG_ERR,
"%s: malloc(%u) error",
1996 "update_portmapping", (
unsigned)entry_len);
1999 memcpy(new_e, e, entry_len);
2013 syslog(LOG_INFO,
"Trying to update snat rule at index %u", index);
2014 match = (
struct ipt_entry_match *)&new_e->elems;
2015 if(0 == strncmp(match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
2017 struct ipt_tcp *
info;
2018 info = (
struct ipt_tcp *)match->data;
2019 info->spts[0] =
info->spts[1] = iport;
2023 struct ipt_udp *
info;
2024 info = (
struct ipt_udp *)match->data;
2025 info->spts[0] =
info->spts[1] = iport;
2028 free(new_e); new_e = NULL;
2030 syslog(LOG_INFO,
"Trying to update snat rule at index %u fail!", index);
2040print_match(
const struct ipt_entry_match *match)
2042 printf(
"match %s :\n",
match->u.user.name);
2043 if(0 == strncmp(
match->u.user.name,
"tcp", IPT_FUNCTION_MAXNAMELEN))
2045 struct ipt_tcp * tcpinfo;
2046 tcpinfo = (
struct ipt_tcp *)
match->data;
2047 printf(
" srcport = %hu:%hu dstport = %hu:%hu\n",
2048 tcpinfo->spts[0], tcpinfo->spts[1],
2049 tcpinfo->dpts[0], tcpinfo->dpts[1]);
2051 else if(0 == strncmp(
match->u.user.name,
"udp", IPT_FUNCTION_MAXNAMELEN))
2053 struct ipt_udp * udpinfo;
2054 udpinfo = (
struct ipt_udp *)
match->data;
2055 printf(
" srcport = %hu:%hu dstport = %hu:%hu\n",
2056 udpinfo->spts[0], udpinfo->spts[1],
2057 udpinfo->dpts[0], udpinfo->dpts[1]);
2063print_iface(
const char * iface,
const unsigned char * mask,
int invert)
2070 for(i=0;
i<IFNAMSIZ;
i++)
2089 printf(
"%u.%u.%u.%u", ip >> 24, (ip >> 16) & 0xff,
2090 (ip >> 8) & 0xff, ip & 0xff);
2099 const struct ipt_entry *
e;
2100 const struct ipt_entry_target * target;
2101 const struct ip_nat_multi_range * mr;
2102 const char * target_str;
2103 char addr[16], mask[16];
2107 h = iptc_init(
"nat");
2110 printf(
"iptc_init() error : %s\n", iptc_strerror(errno));
2127 e = iptc_next_rule(e,
h))
2129 target_str = iptc_get_target(e,
h);
2133 e = iptc_next_rule(e, &
h))
2135 target_str = iptc_get_target(e, &
h);
2137 printf(
"=== rule #%u ===\n", index);
2138 inet_ntop(AF_INET, &
e->ip.src, addr,
sizeof(addr));
2139 inet_ntop(AF_INET, &
e->ip.smsk, mask,
sizeof(mask));
2140 printf(
"src = %s%s/%s\t", (
e->ip.invflags & IPT_INV_SRCIP)?
"! ":
"",
2143 inet_ntop(AF_INET, &
e->ip.dst, addr,
sizeof(addr));
2144 inet_ntop(AF_INET, &
e->ip.dmsk, mask,
sizeof(mask));
2145 printf(
"dst = %s%s/%s\n", (
e->ip.invflags & IPT_INV_DSTIP)?
"! ":
"",
2150 print_iface(
e->ip.iniface,
e->ip.iniface_mask,
2151 e->ip.invflags & IPT_INV_VIA_IN);
2152 printf(
"\tout_if = ");
2153 print_iface(
e->ip.outiface,
e->ip.outiface_mask,
2154 e->ip.invflags & IPT_INV_VIA_OUT);
2156 printf(
"ip.proto = %s%d\n", (
e->ip.invflags & IPT_INV_PROTO)?
"! ":
"",
2159 if(
e->target_offset)
2161 IPT_MATCH_ITERATE(e, print_match);
2164 printf(
"target = %s :\n", target_str);
2165 target = (
void *)e +
e->target_offset;
2166 mr = (
const struct ip_nat_multi_range *)&target->data[0];
2168 printip(ntohl(mr->range[0].min_ip));
2170 printip(ntohl(mr->range[0].max_ip));
2171 printf(
"\n ports %hu %hu\n", ntohs(mr->range[0].min.all),
2172 ntohs(mr->range[0].max.all));
2173 printf(
" flags = %x\n", mr->range[0].flags);
static uint64_t h
Definition blockchain_stats.cpp:55
void * memcpy(void *a, const void *b, size_t c)
Definition glibc_compat.cpp:16
static struct rdr_desc * rdr_desc_list
Definition ipfrdr.c:140
static const char * miniupnpd_nat_chain
Definition iptcrdr.c:71
static void get_redirect_desc(unsigned short eport, int proto, char *desc, int desclen, unsigned int *timestamp)
Definition iptcrdr.c:235
int add_peer_redirect_rule2(const char *ifname, const char *rhost, unsigned short rport, const char *eaddr, unsigned short eport, const char *iaddr, unsigned short iport, int proto, const char *desc, unsigned int timestamp)
Definition iptcrdr.c:287
int add_filter_rule2(const char *ifname, const char *rhost, const char *iaddr, unsigned short eport, unsigned short iport, int proto, const char *desc)
Definition iptcrdr.c:321
static struct ipt_entry_target * get_dnat_target(const char *daddr, unsigned short dport)
Definition iptcrdr.c:1038
int delete_redirect_and_filter_rules(unsigned short eport, int proto)
Definition iptcrdr.c:732
static void add_redirect_desc(unsigned short eport, int proto, const char *desc, unsigned int timestamp)
Definition iptcrdr.c:189
unsigned short * get_portmappings_in_range(unsigned short startport, unsigned short endport, int proto, unsigned int *number)
Definition iptcrdr.c:1595
void shutdown_redirect(void)
Definition iptcrdr.c:161
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)
Definition iptcrdr.c:336
static struct ipt_entry_target * get_accept_target(void)
Definition iptcrdr.c:1514
static const char * miniupnpd_forward_chain
Definition iptcrdr.c:79
static int delete_rule_and_commit(unsigned int index, IPTC_HANDLE h, const char *miniupnpd_chain, const char *logcaller)
Definition iptcrdr.c:632
static int update_rule_and_commit(const char *table, const char *chain, unsigned index, const struct ipt_entry *e)
Definition iptcrdr.c:1703
#define IPTC_HANDLE
Definition iptcrdr.c:55
static int iptc_init_verify_and_append(const char *table, const char *miniupnpd_chain, struct ipt_entry *e, const char *logcaller)
Definition iptcrdr.c:1131
static struct ipt_entry_target * get_snat_target(const char *saddr, unsigned short sport)
Definition iptcrdr.c:1062
static int addpeerdscprule(int proto, unsigned char dscp, const char *iaddr, unsigned short iport, const char *rhost, unsigned short rport)
Definition iptcrdr.c:1437
int set_rdr_name(rdr_name_type param, const char *string)
Definition iptcrdr.c:88
static struct ipt_entry_match * get_tcp_match(unsigned short dport, unsigned short sport)
Definition iptcrdr.c:980
int delete_filter_rule(const char *ifname, unsigned short port, int proto)
Definition iptcrdr.c:669
int update_portmapping(const char *ifname, unsigned short eport, int proto, unsigned short iport, const char *desc, unsigned int timestamp)
Definition iptcrdr.c:1745
static struct ipt_entry_target * get_dscp_target(unsigned char dscp)
Definition iptcrdr.c:1086
static int addpeernatrule(int proto, const char *eaddr, unsigned short eport, const char *iaddr, unsigned short iport, const char *rhost, unsigned short rport)
Definition iptcrdr.c:1358
static void del_redirect_desc(unsigned short eport, int proto)
Definition iptcrdr.c:212
static int snprintip(char *dst, size_t size, uint32_t ip)
Definition iptcrdr.c:167
int update_portmapping_desc_timestamp(const char *ifname, unsigned short eport, int proto, const char *desc, unsigned int timestamp)
Definition iptcrdr.c:1692
int 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)
Definition iptcrdr.c:438
static int add_filter_rule(int proto, const char *rhost, const char *iaddr, unsigned short iport)
Definition iptcrdr.c:1529
int get_nat_redirect_rule(const char *nat_chain_name, 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)
Definition iptcrdr.c:352
int 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)
Definition iptcrdr.c:260
static int addnatrule(int proto, unsigned short eport, const char *iaddr, unsigned short iport, const char *rhost)
Definition iptcrdr.c:1202
#define IPT_ALIGN
Definition iptcrdr.c:60
int add_peer_dscp_rule2(const char *ifname, const char *rhost, unsigned short rport, unsigned char dscp, const char *iaddr, unsigned short iport, int proto, const char *desc, unsigned int timestamp)
Definition iptcrdr.c:303
static const char * miniupnpd_nat_postrouting_chain
Definition iptcrdr.c:75
int get_peer_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 short *rport, unsigned int *timestamp, u_int64_t *packets, u_int64_t *bytes)
Definition iptcrdr.c:529
static struct ipt_entry_match * get_udp_match(unsigned short dport, unsigned short sport)
Definition iptcrdr.c:1009
int init_redirect(void)
Definition iptcrdr.c:142
int list_redirect_rule(const char *ifname)
static MDB_envinfo info
Definition mdb_load.c:37
match
Definition check_missing_rpc_methods.py:38
str proto
Definition pymoduletest.py:71
int i
Definition pymoduletest.py:23
u
Definition pymoduletest.py:20
e
Definition pymoduletest.py:79
r
Definition testupnpigd.py:61
#define IP_NAT_RANGE_MAP_IPS
Definition tiny_nf_nat.h:9
#define IP_NAT_RANGE_PROTO_SPECIFIED
Definition tiny_nf_nat.h:10
unsigned int uint32_t
Definition stdint.h:126
struct rdr_desc * next
Definition ipfrdr.c:132
char str[]
Definition ipfrdr.c:136
unsigned short eport
Definition ipfrdr.c:133
int proto
Definition ipfrdr.c:134
unsigned int timestamp
Definition ipfrdr.c:135
#define UNUSED(expr)
Definition test-libusb-version.c:31
static const char * ifname
Definition testipfwrdr.c:17