MINOR: net_helper: add an option to ip.fp() to append the source address

The new value 4 will permit to append the source address to the
fingerprint, making it easier to build rules checking a specific path.
This commit is contained in:
Willy Tarreau 2026-01-01 10:26:23 +01:00
parent 70ffae3614
commit a206f85f96
2 changed files with 15 additions and 2 deletions

View file

@ -21146,15 +21146,18 @@ ip.fp([<mode>])
- 1: the received TTL value is appended to the fingerprint (1 byte)
- 2: the list of TCP option kinds, as returned by "tcp.options_list",
made of 0 to 40 extra bytes, is appended to the fingerprint
- 4: the source IP address is appended to the fingerprint, which adds
4 bytes for IPv4 and 16 for IPv6.
Example:
Example: make a 12..24 bytes fingerprint using the base FP, the TTL and the
source address (1+4=5):
frontend test
mode http
bind :4445 tcp-ss 1
tcp-request connection set-var(sess.syn) fc_saved_syn
http-request return status 200 content-type text/plain lf-string \
"src=%[var(sess.syn),ip.src] fp=%[var(sess.syn),ip.fp,hex]\n"
"src=%[var(sess.syn),ip.src] fp=%[var(sess.syn),ip.fp(5),hex]\n"
See also "fc_saved_syn", "tcp-ss", "eth.data", "ip.df", "ip.ttl", "tcp.win",
"tcp.options.mss", and "tcp.options_list".

View file

@ -659,6 +659,7 @@ static int sample_conv_tcp_win(const struct arg *arg_p, struct sample *smp, void
static int sample_conv_ip_fp(const struct arg *arg_p, struct sample *smp, void *private)
{
struct buffer *trash = get_trash_chunk();
char *ipsrc;
uchar ipver;
uchar iptos;
uchar ipttl;
@ -698,6 +699,7 @@ static int sample_conv_ip_fp(const struct arg *arg_p, struct sample *smp, void *
pktlen = read_n16(smp->data.u.str.area + 2);
ipdf = !!(smp->data.u.str.area[6] & 0x40);
ipttl = smp->data.u.str.area[8];
ipsrc = smp->data.u.str.area + 12;
}
else if (ipver == 6) {
/* check fields for IPv6 */
@ -712,6 +714,7 @@ static int sample_conv_ip_fp(const struct arg *arg_p, struct sample *smp, void *
iptos = read_n16(smp->data.u.str.area) >> 4;
ipdf = 1; // no fragments by default in IPv6
ipttl = smp->data.u.str.area[7];
ipsrc = smp->data.u.str.area + 8;
}
else
return 0;
@ -800,6 +803,13 @@ static int sample_conv_ip_fp(const struct arg *arg_p, struct sample *smp, void *
write_n16(trash->area + 3, tcpwin);
write_n16(trash->area + 5, tcpmss);
/* mode 4: append source IP address */
if (mode & 4) {
iplen = (ipver == 4) ? 4 : 16;
memcpy(trash->area + trash->data, ipsrc, iplen);
trash->data += iplen;
}
/* option kinds if any are stored starting at offset 7 */
smp->data.u.str = *trash;
smp->flags &= ~SMP_F_CONST;