This commit adds the base2 converter to turn binary input into it's
string representation. Each input byte is converted into a series of
eight characters which are either 0s and 1s using the new base2tab array
which maps every possible value of a byte to its string representation.
---
 doc/configuration.txt |  7 +++++
 src/sample.c          | 65 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index dff2b491e8..62c79c5058 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -19932,6 +19932,7 @@ aes_gcm_dec(bits,nonce,key,aead_tag)               
binary       binary
 aes_gcm_enc(bits,nonce,key,aead_tag)               binary       binary
 and(value)                                         integer      integer
 b64dec                                             string       binary
+base2                                              binary       string
 base64                                             binary       string
 be2dec(separator,chunk_size[,truncate])            binary       string
 le2dec(separator,chunk_size[,truncate])            binary       string
@@ -20156,6 +20157,12 @@ b64dec
   For base64url("URL and Filename Safe Alphabet" (RFC 4648)) variant
   see "ub64dec".
 
+base2
+  Converts a binary input sample to a binary string containing eight binary
+  digits per input byte. It is used to be able to perform longest prefix match
+  on types where the native representation does not allow prefix matching, for
+  example IP prefixes.
+
 base64
   Converts a binary input sample to a base64 string. It is used to log or
   transfer binary content in a way that can be reliably transferred (e.g.
diff --git a/src/sample.c b/src/sample.c
index c5ee623fa5..d495643b97 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -352,6 +352,52 @@ static const char *fetch_ckp_names[SMP_CKP_ENTRIES] = {
        [SMP_CKP_CLI_PARSER] = "CLI parser",
 };
 
+static const char base2tab[256][8] = {
+       "00000000", "00000001", "00000010", "00000011", "00000100", "00000101",
+       "00000110", "00000111", "00001000", "00001001", "00001010", "00001011",
+       "00001100", "00001101", "00001110", "00001111", "00010000", "00010001",
+       "00010010", "00010011", "00010100", "00010101", "00010110", "00010111",
+       "00011000", "00011001", "00011010", "00011011", "00011100", "00011101",
+       "00011110", "00011111", "00100000", "00100001", "00100010", "00100011",
+       "00100100", "00100101", "00100110", "00100111", "00101000", "00101001",
+       "00101010", "00101011", "00101100", "00101101", "00101110", "00101111",
+       "00110000", "00110001", "00110010", "00110011", "00110100", "00110101",
+       "00110110", "00110111", "00111000", "00111001", "00111010", "00111011",
+       "00111100", "00111101", "00111110", "00111111", "01000000", "01000001",
+       "01000010", "01000011", "01000100", "01000101", "01000110", "01000111",
+       "01001000", "01001001", "01001010", "01001011", "01001100", "01001101",
+       "01001110", "01001111", "01010000", "01010001", "01010010", "01010011",
+       "01010100", "01010101", "01010110", "01010111", "01011000", "01011001",
+       "01011010", "01011011", "01011100", "01011101", "01011110", "01011111",
+       "01100000", "01100001", "01100010", "01100011", "01100100", "01100101",
+       "01100110", "01100111", "01101000", "01101001", "01101010", "01101011",
+       "01101100", "01101101", "01101110", "01101111", "01110000", "01110001",
+       "01110010", "01110011", "01110100", "01110101", "01110110", "01110111",
+       "01111000", "01111001", "01111010", "01111011", "01111100", "01111101",
+       "01111110", "01111111", "10000000", "10000001", "10000010", "10000011",
+       "10000100", "10000101", "10000110", "10000111", "10001000", "10001001",
+       "10001010", "10001011", "10001100", "10001101", "10001110", "10001111",
+       "10010000", "10010001", "10010010", "10010011", "10010100", "10010101",
+       "10010110", "10010111", "10011000", "10011001", "10011010", "10011011",
+       "10011100", "10011101", "10011110", "10011111", "10100000", "10100001",
+       "10100010", "10100011", "10100100", "10100101", "10100110", "10100111",
+       "10101000", "10101001", "10101010", "10101011", "10101100", "10101101",
+       "10101110", "10101111", "10110000", "10110001", "10110010", "10110011",
+       "10110100", "10110101", "10110110", "10110111", "10111000", "10111001",
+       "10111010", "10111011", "10111100", "10111101", "10111110", "10111111",
+       "11000000", "11000001", "11000010", "11000011", "11000100", "11000101",
+       "11000110", "11000111", "11001000", "11001001", "11001010", "11001011",
+       "11001100", "11001101", "11001110", "11001111", "11010000", "11010001",
+       "11010010", "11010011", "11010100", "11010101", "11010110", "11010111",
+       "11011000", "11011001", "11011010", "11011011", "11011100", "11011101",
+       "11011110", "11011111", "11100000", "11100001", "11100010", "11100011",
+       "11100100", "11100101", "11100110", "11100111", "11101000", "11101001",
+       "11101010", "11101011", "11101100", "11101101", "11101110", "11101111",
+       "11110000", "11110001", "11110010", "11110011", "11110100", "11110101",
+       "11110110", "11110111", "11111000", "11111001", "11111010", "11111011",
+       "11111100", "11111101", "11111110", "11111111",
+};
+
 /* This function returns the most accurate expected type of the data returned
  * by the sample_expr. It assumes that the <expr> and all of its converters are
  * properly initialized.
@@ -2151,6 +2197,24 @@ static int sample_conv_bin2hex(const struct arg *arg_p, 
struct sample *smp, void
        return 1;
 }
 
+static int sample_conv_bin2base2(const struct arg *arg_p, struct sample *smp, 
void *private)
+{
+       struct buffer *trash = get_trash_chunk();
+       unsigned char c;
+       int ptr = 0;
+
+       trash->data = 0;
+       while (ptr < smp->data.u.str.data && trash->data <= trash->size - 8) {
+               c = smp->data.u.str.area[ptr++];
+               memcpy(trash->area + trash->data, base2tab[c], 8);
+               trash->data += 8;
+       }
+       smp->data.u.str = *trash;
+       smp->data.type = SMP_T_STR;
+       smp->flags &= ~SMP_F_CONST;
+       return 1;
+}
+
 static int sample_conv_hex2int(const struct arg *arg_p, struct sample *smp, 
void *private)
 {
        long long int n = 0;
@@ -5441,6 +5505,7 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, 
{
        { "upper",   sample_conv_str2upper,    0,                     NULL,     
                SMP_T_STR,  SMP_T_STR  },
        { "lower",   sample_conv_str2lower,    0,                     NULL,     
                SMP_T_STR,  SMP_T_STR  },
        { "length",  sample_conv_length,       0,                     NULL,     
                SMP_T_STR,  SMP_T_SINT },
+       { "base2",   sample_conv_bin2base2,    0,                     NULL,     
                SMP_T_BIN,  SMP_T_STR  },
        { "be2dec",  sample_conv_be2dec,       ARG3(1,STR,SINT,SINT), 
sample_conv_2dec_check,   SMP_T_BIN,  SMP_T_STR  },
        { "le2dec",  sample_conv_le2dec,       ARG3(1,STR,SINT,SINT), 
sample_conv_2dec_check,   SMP_T_BIN,  SMP_T_STR  },
        { "be2hex",  sample_conv_be2hex,       ARG3(1,STR,SINT,SINT), 
sample_conv_be2hex_check, SMP_T_BIN,  SMP_T_STR  },
-- 
2.51.0



Reply via email to