From: Willy Tarreau Date: Tue, 15 Jul 2014 19:03:26 +0000 (+0200) Subject: MINOR: sample: allow IP address to cast to binary X-Git-Tag: v1.6-dev1~353 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9700e5c914161a2bf78380bd935e7353ab8a0b50;p=thirdparty%2Fhaproxy.git MINOR: sample: allow IP address to cast to binary 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. --- diff --git a/src/sample.c b/src/sample.c index c260f7e66a..34f4c1d00c 100644 --- a/src/sample.c +++ b/src/sample.c @@ -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, }, diff --git a/src/stick_table.c b/src/stick_table.c index a6ee77fd4b..12265916c5 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -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 }, };