aboutgitcodebugslistschat
path: root/fwd_rule.c
diff options
context:
space:
mode:
Diffstat (limited to 'fwd_rule.c')
-rw-r--r--fwd_rule.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/fwd_rule.c b/fwd_rule.c
index 42ec68e..312bc60 100644
--- a/fwd_rule.c
+++ b/fwd_rule.c
@@ -115,10 +115,15 @@ __attribute__((noinline))
const char *fwd_rule_fmt(const struct fwd_rule *rule, char *dst, size_t size)
{
const char *percent = *rule->ifname ? "%" : "";
+ char taddr[INANY_ADDRSTRLEN] = { 0 };
const char *weak = "", *scan = "";
char addr[INANY_ADDRSTRLEN];
int len;
+ if (!inany_is_unspecified(&rule->taddr)) {
+ (void)snprintf(taddr, sizeof(taddr), "%s:",
+ inany_ntop(&rule->taddr, addr, sizeof(addr)));
+ }
inany_ntop(fwd_rule_addr(rule), addr, sizeof(addr));
if (rule->flags & FWD_WEAK)
weak = " (best effort)";
@@ -127,16 +132,17 @@ const char *fwd_rule_fmt(const struct fwd_rule *rule, char *dst, size_t size)
if (rule->first == rule->last) {
len = snprintf(dst, size,
- "%s [%s]%s%s:%hu => %hu %s%s",
+ "%s [%s]%s%s:%hu => %s%hu %s%s",
ipproto_name(rule->proto), addr, percent,
- rule->ifname, rule->first, rule->to, weak, scan);
+ rule->ifname, rule->first,
+ taddr, rule->to, weak, scan);
} else {
in_port_t tolast = rule->last - rule->first + rule->to;
len = snprintf(dst, size,
- "%s [%s]%s%s:%hu-%hu => %hu-%hu %s%s",
+ "%s [%s]%s%s:%hu-%hu => %s%hu-%hu %s%s",
ipproto_name(rule->proto), addr, percent,
rule->ifname, rule->first, rule->last,
- rule->to, tolast, weak, scan);
+ taddr, rule->to, tolast, weak, scan);
}
if (len < 0 || (size_t)len >= size)
@@ -325,6 +331,36 @@ int fwd_rule_add(struct fwd_table *fwd, const struct fwd_rule *new)
return -EINVAL;
}
+ if (!inany_is_unspecified(&new->taddr)) {
+ char tastr[INANY_ADDRSTRLEN];
+
+ if (inany_is_multicast(&new->taddr)) {
+ warn("Multicast target address %s for forwarding rule",
+ inany_ntop(&new->taddr, tastr, sizeof(tastr)));
+ return -EINVAL;
+ }
+
+ if (new->flags & FWD_DUAL_STACK_ANY) {
+ warn("Dual stack forward to %s address %s unsupported",
+ inany_v4(&new->taddr) ? "IPv4" : "IPv6",
+ inany_ntop(&new->taddr, tastr, sizeof(tastr)));
+ warn("Did you mean %s/... instead?",
+ inany_v4(&new->taddr) ? "0.0.0.0" : "[::]");
+ return -EINVAL;
+ }
+
+ if (!!inany_v4(&new->addr) != !!inany_v4(&new->taddr)) {
+ char lastr[INANY_ADDRSTRLEN];
+
+ warn("Forward from %s (%s) to %s (%s) unsupported",
+ inany_v4(&new->addr) ? "IPv4" : "IPv6",
+ inany_ntop(&new->addr, lastr, sizeof(lastr)),
+ inany_v4(&new->taddr) ? "IPv4" : "IPv6",
+ inany_ntop(&new->taddr, tastr, sizeof(tastr)));
+ return -EINVAL;
+ }
+ }
+
for (i = 0; i < fwd->count; i++) {
char newstr[FWD_RULE_STRLEN], rulestr[FWD_RULE_STRLEN];
@@ -393,6 +429,7 @@ static void fwd_rule_range_except(struct fwd_table *fwd, bool del,
{
struct fwd_rule rule = {
.addr = addr ? *addr : inany_any6,
+ .taddr = tgt_addr ? *tgt_addr : inany_any6,
.ifname = { 0 },
.proto = proto,
.flags = flags,
@@ -401,14 +438,6 @@ static void fwd_rule_range_except(struct fwd_table *fwd, bool del,
char rulestr[FWD_RULE_STRLEN];
unsigned base, i;
- if (tgt_addr && !inany_is_unspecified(tgt_addr)) {
- char astr[INANY_ADDRSTRLEN];
-
- info("Target address: %s",
- inany_ntop(tgt_addr, astr, sizeof(astr)));
- die("Target address remapping not yet implemented");
- }
-
if (!addr)
rule.flags |= FWD_DUAL_STACK_ANY;
if (ifname) {