6 En-tête

Aperçu

L'en-tête est présent dans tous les messages de requête et de réponse entre les composants Zabbix. Il est nécessaire de déterminer la longueur du message, s'il est compressé ou non, s'il s'agit d'un gros paquet ou non.

Le protocole de communication Zabbix a une limite de taille de paquet de 1 Go par connexion. La limite de 1 Go s'applique à la fois à la longueur des données du paquet reçu et à la longueur des données non compressées.

Lors de l'envoi de la configuration au proxy Zabbix, la limite de taille de paquet est augmentée à 4 Go pour permettre la synchronisation de grandes configurations. Lorsque la longueur des données avant compression dépasse 4 Go, le serveur Zabbix démarre automatiquement en utilisant le grand format de paquet (flag 0x04) qui augmente la limite de taille de paquet à 16 Go.

Notez que bien qu'un grand format de paquet puisse être utilisé pour envoyer des données, actuellement seul le synchroniseur de configuration du proxy Zabbix peut gérer les paquets supérieurs à 1 Go.

Structure

L'en-tête se compose de quatre champs. Tous les nombres de l'en-tête sont formatés en little-endian.

Champ Taille Taille
(paquet volumineux)
Description
<PROTOCOL> 4 4 "ZBXD" ou 5A 42 58 44
<FLAGS> 1 1 Indicateurs du protocole :
0x01 - protocole de communication Zabbix
0x02 - compression
0x04 - paquet volumineux
<DATALEN> 4 8 Longueur des données.
<RESERVED> 4 8 Lorsque la compression est utilisée (indicateur 0x02) - longueur des données non compressées
Lorsque la compression n'est pas utilisée - 00 00 00 00

Exemples

Voici quelques extraits de code montrant comment ajouter un en-tête de protocole Zabbix aux données que vous souhaitez envoyer dans l'ordre pour obtenir le paquet que vous devez envoyer à Zabbix afin qu'il soit interprété correctement. Ces extraits de code supposent que les données ne dépassent pas 1 Go, le format de gros paquets n'est donc pas utilisé.

Python
packet = b"ZBXD\1" + struct.pack("<II", len(data), 0) + data

ou

def zbx_create_header(plain_data_size, compressed_data_size=None):
    protocol = b"ZBXD"
    flags = 0x01
    if compressed_data_size is None:
        datalen = plain_data_size
        reserved = 0
    else:
        flags |= 0x02
        datalen = compressed_data_size
        reserved = plain_data_size
    return protocol + struct.pack("<BII", flags, datalen, reserved)

packet = zbx_create_header(len(data)) + data
Perl
my $packet = "ZBXD\1" . pack("(II)<", length($data), 0) . $data;

ou

sub zbx_create_header($;$)
{
    my $plain_data_size = shift;
    my $compressed_data_size = shift;

    my $protocol = "ZBXD";
    my $flags = 0x01;
    my $datalen;
    my $reserved;

    if (!defined($compressed_data_size))
    {
        $datalen = $plain_data_size;
        $reserved = 0;
    }
    else
    {
        $flags |= 0x02;
        $datalen = $compressed_data_size;
        $reserved = $plain_data_size;
    }

    return $protocol . chr($flags) . pack("(II)<", $datalen, $reserved);
}

my $packet = zbx_create_header(length($data)) . $data;
PHP
$packet = "ZBXD\1" . pack("VV", strlen($data), 0) . $data;

ou

function zbx_create_header($plain_data_size, $compressed_data_size = null)
{
    $protocol = "ZBXD";
    $flags = 0x01;
    if (is_null($compressed_data_size))
    {
        $datalen = $plain_data_size;
        $reserved = 0;
    }
    else
    {
        $flags |= 0x02;
        $datalen = $compressed_data_size;
        $reserved = $plain_data_size;
    }
    return $protocol . chr($flags) . pack("VV", $datalen, $reserved);
}

$packet = zbx_create_header(strlen($data)) . $data;
Bash
datalen=$(printf "%08x" ${#data})
datalen="\\x${datalen:6:2}\\x${datalen:4:2}\\x${datalen:2:2}\\x${datalen:0:2}"
printf "ZBXD\1${datalen}\0\0\0\0%s" "$data"