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.
This commit is contained in:
Willy Tarreau 2014-07-15 21:03:26 +02:00
parent 5ad6e1dc09
commit 9700e5c914
2 changed files with 42 additions and 4 deletions

View File

@ -654,6 +654,27 @@ static int c_meth2str(struct sample *smp)
return 1; 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 matrix: */
/* sample_casts[from type][to type] */ /* 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, }, /* 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, }, /* 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, }, /* 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, }, /* 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, NULL, 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, }, /* 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, }, /* 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, }, /* METH */ { NULL, NULL, NULL, NULL, NULL, NULL, c_meth2str, c_meth2str, c_none, },

View File

@ -518,6 +518,23 @@ static void *k_ip2str(struct sample *smp, union stktable_key_data *kdata, size_t
return (void *)kdata->buf; 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) static void *k_bin2str(struct sample *smp, union stktable_key_data *kdata, size_t *len)
{ {
unsigned char c; 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 }, /* UINT */ { k_int2ip, NULL, k_int2int, k_int2str, NULL },
/* SINT */ { 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 }, /* ADDR */ { k_ip2ip, k_ip2ipv6, k_ip2int, k_ip2str, NULL },
/* IPV4 */ { 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, NULL }, /* IPV6 */ { k_ip2ip, k_ip2ipv6, k_ip2int, k_ip2str, k_ip2bin },
/* STR */ { k_str2ip, k_str2ipv6, k_str2int, k_str2str, k_str2str }, /* STR */ { k_str2ip, k_str2ipv6, k_str2int, k_str2str, k_str2str },
/* BIN */ { NULL, NULL, NULL, k_bin2str, k_str2str }, /* BIN */ { NULL, NULL, NULL, k_bin2str, k_str2str },
}; };