]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: sample: allow IP address to cast to binary
authorWilly Tarreau <w@1wt.eu>
Tue, 15 Jul 2014 19:03:26 +0000 (21:03 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 15 Jul 2014 19:36:15 +0000 (21:36 +0200)
IP addresses are a perfect example of fixed size data which we could
cast to binary, still it was not allowed by lack of cast function,
eventhough the opposite was allowed in ACLs. Make that possible both
in sample expressions and in stick tables.

src/sample.c
src/stick_table.c

index c260f7e66a77cba7ac84e4bdd229197cba231b6e..34f4c1d00c8ce0d30b01439eec75d1cb037296f5 100644 (file)
@@ -654,6 +654,27 @@ static int c_meth2str(struct sample *smp)
        return 1;
 }
 
+static int c_addr2bin(struct sample *smp)
+{
+       struct chunk *chk = get_trash_chunk();
+
+       if (smp->type == SMP_T_IPV4) {
+               chk->len = 4;
+               memcpy(chk->str, &smp->data.ipv4, chk->len);
+       }
+       else if (smp->type == SMP_T_IPV6) {
+               chk->len = 16;
+               memcpy(chk->str, &smp->data.ipv6, chk->len);
+       }
+       else
+               return 0;
+
+       smp->data.str = *chk;
+       smp->type = SMP_T_BIN;
+       return 1;
+}
+
+
 /*****************************************************************/
 /*      Sample casts matrix:                                     */
 /*           sample_casts[from type][to type]                    */
@@ -666,8 +687,8 @@ sample_cast_fct sample_casts[SMP_TYPES][SMP_TYPES] = {
 /*       UINT */ { c_none,    c_none,    c_none,    c_int2ip,   c_int2ip, NULL,       c_int2str,  NULL,       NULL,       },
 /*       SINT */ { c_none,    c_none,    c_none,    c_int2ip,   c_int2ip, NULL,       c_int2str,  NULL,       NULL,       },
 /*       ADDR */ { NULL,      NULL,      NULL,      NULL,       NULL,     NULL,       NULL,       NULL,       NULL,       },
-/*       IPV4 */ { NULL,      c_ip2int,  c_ip2int,  c_none,     c_none,   c_ip2ipv6,  c_ip2str,   NULL,       NULL,       },
-/*       IPV6 */ { NULL,      NULL,      NULL,      c_none,     NULL,     c_none,     c_ipv62str, NULL,       NULL,       },
+/*       IPV4 */ { NULL,      c_ip2int,  c_ip2int,  c_none,     c_none,   c_ip2ipv6,  c_ip2str,   c_addr2bin, NULL,       },
+/*       IPV6 */ { NULL,      NULL,      NULL,      c_none,     NULL,     c_none,     c_ipv62str, c_addr2bin, NULL,       },
 /*        STR */ { c_str2int, c_str2int, c_str2int, c_str2addr, c_str2ip, c_str2ipv6, c_none,     c_none,     c_str2meth, },
 /*        BIN */ { NULL,      NULL,      NULL,      NULL,       NULL,     NULL,       c_bin2str,  c_none,     c_str2meth, },
 /*       METH */ { NULL,      NULL,      NULL,      NULL,       NULL,     NULL,       c_meth2str, c_meth2str, c_none,     },
index a6ee77fd4b54bbca119b23cff174f56533511712..12265916c53dbeb54d4ea285740f4cc5f97b4b41 100644 (file)
@@ -518,6 +518,23 @@ static void *k_ip2str(struct sample *smp, union stktable_key_data *kdata, size_t
        return (void *)kdata->buf;
 }
 
+static void *k_ip2bin(struct sample *smp, union stktable_key_data *kdata, size_t *len)
+{
+       if (smp->type == SMP_T_IPV4) {
+               if (*len > 4)
+                       *len = 4;
+               memcpy(kdata->buf, &smp->data.ipv4, *len);
+       }
+       else if (smp->type == SMP_T_IPV6) {
+               if (*len > 16)
+                       *len = 16;
+               memcpy(kdata->buf, &smp->data.ipv6, *len);
+       }
+       else
+               *len = 0;
+       return (void *)kdata->buf;
+}
+
 static void *k_bin2str(struct sample *smp, union stktable_key_data *kdata, size_t *len)
 {
        unsigned char c;
@@ -591,8 +608,8 @@ static sample_to_key_fct sample_to_key[SMP_TYPES][STKTABLE_TYPES] = {
 /*             UINT */ { k_int2ip, NULL,        k_int2int, k_int2str,  NULL      },
 /*             SINT */ { k_int2ip, NULL,        k_int2int, k_int2str,  NULL      },
 /*             ADDR */ { k_ip2ip,  k_ip2ipv6,   k_ip2int,  k_ip2str,   NULL      },
-/*             IPV4 */ { k_ip2ip,  k_ip2ipv6,   k_ip2int,  k_ip2str,   NULL      },
-/*             IPV6 */ { k_ip2ip,  k_ip2ipv6,   k_ip2int,  k_ip2str,   NULL      },
+/*             IPV4 */ { k_ip2ip,  k_ip2ipv6,   k_ip2int,  k_ip2str,   k_ip2bin  },
+/*             IPV6 */ { k_ip2ip,  k_ip2ipv6,   k_ip2int,  k_ip2str,   k_ip2bin  },
 /*              STR */ { k_str2ip, k_str2ipv6,  k_str2int, k_str2str,  k_str2str },
 /*              BIN */ { NULL,     NULL,        NULL,      k_bin2str,  k_str2str },
 };