summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2021-08-08 17:34:49 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2021-08-08 17:34:49 +0100
commitc51f713eebe21071f22d0830fdaeb274b1a77059 (patch)
tree95da2d585f5a8556aed7bed8f5f056d0d6c12d56 /src
parentb003ce30f0038c2042303d18fc24f278de06a1f5 (diff)
Expansions: mask_n operator
Diffstat (limited to 'src')
-rw-r--r--src/src/expand.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/src/expand.c b/src/src/expand.c
index 4fb935528..83c0ad051 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -7333,11 +7333,11 @@ while (*s)
int count;
uschar *endptr;
int binary[4];
- int mask, maskoffset;
- int type = string_is_ip_address(sub, &maskoffset);
+ int type, mask, maskoffset;
+ BOOL normalised;
uschar buffer[64];
- if (type == 0)
+ if ((type = string_is_ip_address(sub, &maskoffset)) == 0)
{
expand_string_message = string_sprintf("\"%s\" is not an IP address",
sub);
@@ -7353,13 +7353,18 @@ while (*s)
mask = Ustrtol(sub + maskoffset + 1, &endptr, 10);
- if (*endptr != 0 || mask < 0 || mask > ((type == 4)? 32 : 128))
+ if (*endptr || mask < 0 || mask > (type == 4 ? 32 : 128))
{
expand_string_message = string_sprintf("mask value too big in \"%s\"",
sub);
goto EXPAND_FAILED;
}
+ /* If an optional 'n' was given, ipv6 gets normalised output:
+ colons rather than dots, and zero-compressed. */
+
+ normalised = arg && *arg == 'n';
+
/* Convert the address to binary integer(s) and apply the mask */
sub[maskoffset] = 0;
@@ -7368,8 +7373,14 @@ while (*s)
/* Convert to masked textual format and add to output. */
- yield = string_catn(yield, buffer,
- host_nmtoa(count, binary, mask, buffer, '.'));
+ if (type == 4 || !normalised)
+ yield = string_catn(yield, buffer,
+ host_nmtoa(count, binary, mask, buffer, '.'));
+ else
+ {
+ ipv6_nmtoa(binary, buffer);
+ yield = string_fmt_append(yield, "%s/%d", buffer, mask);
+ }
continue;
}