diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2017-02-28 18:58:57 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2017-02-28 18:58:57 (GMT) |
commit | 027305c2447b05de2c576e3f5ee32ced400f439f (patch) | |
tree | 96f35ddcd87129f3c4ccec69e8fa0216654215c9 /src/common | |
parent | 7d153f7d3a32a66d3eaf5199d396debbe3b675f5 (diff) |
Defined abstract packed buffers to transfert data.
Diffstat (limited to 'src/common')
-rwxr-xr-x | src/common/Makefile.am | 1 | ||||
-rw-r--r-- | src/common/packed.c | 300 | ||||
-rw-r--r-- | src/common/packed.h | 72 |
3 files changed, 373 insertions, 0 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 02c1718..b4d1a5b 100755 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -15,6 +15,7 @@ libcommon_la_SOURCES = \ leb128.h leb128.c \ macros.h \ net.h net.c \ + packed.h packed.c \ pathname.h pathname.c \ shuffle.h shuffle.c \ sort.h sort.c \ diff --git a/src/common/packed.c b/src/common/packed.c new file mode 100644 index 0000000..39df330 --- /dev/null +++ b/src/common/packed.c @@ -0,0 +1,300 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * packed.c - regroupement de bribes de paquets réseau + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "packed.h" + + +#include <assert.h> +#include <endian.h> +#include <malloc.h> +#include <string.h> + + + +/* Taille d'allocation en cas de besoin */ +#define PACKET_BLOCK_SIZE 1000 + + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à initialiser. [OUT] * +* * +* Description : Intialise un paquet réseau pour une constitution. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void init_packed_buffer(packed_buffer *pbuf) +{ + pbuf->allocated = PACKET_BLOCK_SIZE; + pbuf->data = malloc(pbuf->allocated * sizeof(uint8_t)); + + pbuf->used = 0; + pbuf->pos = sizeof(uint32_t); + + assert(pbuf->pos <= pbuf->allocated); + +} + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à libérer. * +* * +* Description : Efface les données contenues par un paquet réseau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void exit_packed_buffer(packed_buffer *pbuf) +{ + free(pbuf->data); + +} + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à compléter. * +* buf = nouvelles données à ajouter. * +* len = quantité de ces données. * +* hton = indique si une conversion est à réaliser. * +* * +* Description : Ajoute des données à un paquet en amont à un envoi. * +* * +* Retour : true. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool extend_packed_buffer(packed_buffer *pbuf, const void *buf, size_t len, bool hton) +{ + uint16_t tmp16; /* Valeur intermédiaire 16b */ + uint32_t tmp32; /* Valeur intermédiaire 32b */ + uint64_t tmp64; /* Valeur intermédiaire 64b */ + + /* Réallocation nécessaire ? */ + + while ((pbuf->pos + len) > pbuf->allocated) + { + pbuf->allocated += PACKET_BLOCK_SIZE; + pbuf->data = realloc(pbuf->data, pbuf->allocated * sizeof(uint8_t)); + } + + /* Conversion au formalisme du réseau */ + + if (!hton) + goto skip_conversion; + + switch (len) + { + case 1: + *((uint8_t *)(pbuf->data + pbuf->pos)) = *((uint8_t *)buf); + break; + + case 2: + tmp16 = htobe16(*(uint16_t *)buf); + *((uint16_t *)(pbuf->data + pbuf->pos)) = tmp16; + break; + + case 4: + tmp32 = htobe32(*(uint32_t *)buf); + *((uint32_t *)(pbuf->data + pbuf->pos)) = tmp32; + break; + + case 8: + tmp64 = htobe64(*(uint64_t *)buf); + *((uint64_t *)(pbuf->data + pbuf->pos)) = tmp64; + break; + + default: + + skip_conversion: + + /** + * Dans ce cas de figure, c'est à l'appelant de s'assurer que la + * conversion a bien été réalisée. + */ + assert(!hton); + + memcpy(pbuf->data + pbuf->pos, buf, len); + break; + + } + + pbuf->used += len; + pbuf->pos += len; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à consulter. * +* buf = nouvelles données à définir. * +* len = quantité de ces données. * +* ntoh = indique si une conversion est à réaliser. * +* * +* Description : Récupère des données depuis un paquet après une réception. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool extract_packed_buffer(packed_buffer *pbuf, void *buf, size_t len, bool ntoh) +{ + bool result; /* Bilan à retourner */ + uint16_t tmp16; /* Valeur intermédiaire 16b */ + uint32_t tmp32; /* Valeur intermédiaire 32b */ + uint64_t tmp64; /* Valeur intermédiaire 64b */ + + result = ((pbuf->pos + len - sizeof(uint32_t)) <= pbuf->used); + + /* Conversion au formalisme du réseau */ + + if (!ntoh) + goto skip_conversion; + + if (result) + { + switch (len) + { + case 1: + *((uint8_t *)buf) = *((uint8_t *)(pbuf->data + pbuf->pos)); + break; + + case 2: + tmp16 = be16toh(*(uint16_t *)(pbuf->data + pbuf->pos)); + *((uint16_t *)buf) = tmp16; + break; + + case 4: + tmp32 = be32toh(*(uint32_t *)(pbuf->data + pbuf->pos)); + *((uint32_t *)buf) = tmp32; + break; + + case 8: + tmp64 = be64toh(*(uint64_t *)(pbuf->data + pbuf->pos)); + *((uint64_t *)buf) = tmp64; + break; + + default: + + skip_conversion: + + /** + * Dans ce cas de figure, c'est à l'appelant de s'assurer que la + * conversion a bien été réalisée. + */ + assert(!ntoh); + + memcpy(buf, pbuf->data + pbuf->pos, len); + break; + + } + + pbuf->pos += len; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à constituer. [OUT] * +* fd = flux ouvert en lecture. * +* * +* Description : Réceptionne des données depuis un flux réseau. * +* * +* Retour : true si toutes les données ont été reçues, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool recv_packed_buffer(packed_buffer *pbuf, int fd) +{ + bool result; /* Bilan à retourner */ + uint32_t used; /* Taille de charge utile */ + + result = safe_recv(fd, &used, sizeof(uint32_t), 0); + + if (!result) + init_packed_buffer(pbuf); + + else + { + pbuf->allocated = sizeof(uint32_t) + used; + pbuf->data = malloc(pbuf->allocated * sizeof(uint8_t)); + + pbuf->used = used; + pbuf->pos = sizeof(uint32_t); + + result = safe_recv(fd, pbuf->data + pbuf->pos, used, 0); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à émettre. * +* fd = flux ouvert en écriture. * +* * +* Description : Envoie des données au travers un flux réseau. * +* * +* Retour : true si toutes les données ont été émises, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool send_packed_buffer(packed_buffer *pbuf, int fd) +{ + bool result; /* Bilan à retourner */ + + *((uint32_t *)pbuf->data) = pbuf->used; + + result = safe_send(fd, pbuf->data, sizeof(uint32_t) + pbuf->used, 0); + + return result; + +} diff --git a/src/common/packed.h b/src/common/packed.h new file mode 100644 index 0000000..bc038d8 --- /dev/null +++ b/src/common/packed.h @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * packed.h - prototypes pour le regroupement de bribes de paquets réseau + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _COMMON_PACKED_H +#define _COMMON_PACKED_H + + +#include <stdbool.h> +#include <stdint.h> +#include <sys/types.h> + + +#include "io.h" + + + +/* Rassemblement de données d'un paquet */ +typedef struct _packed_buffer +{ + uint8_t *data; /* Données à traiter */ + size_t allocated; /* Taille allouée */ + + size_t used; /* Quantité de données utiles */ + size_t pos; /* Tête de lecture/écriture */ + +} packed_buffer; + + +/* Intialise un paquet réseau pour une constitution. */ +void init_packed_buffer(packed_buffer *); + +/* Efface les données contenues par un paquet réseau. */ +void exit_packed_buffer(packed_buffer *); + +/* Ajoute des données à un paquet en amont à un envoi. */ +bool extend_packed_buffer(packed_buffer *, const void *, size_t, bool); + +/* Récupère des données depuis un paquet après une réception. */ +bool extract_packed_buffer(packed_buffer *, void *, size_t, bool); + +/* Réceptionne des données depuis un flux réseau. */ +bool recv_packed_buffer(packed_buffer *, int); + +/* Réceptionne des données depuis un flux réseau. */ +bool recv_packed_buffer(packed_buffer *, int); + +/* Envoie des données au travers un flux réseau. */ +bool send_packed_buffer(packed_buffer *, int); + + + +#endif /* _COMMON_PACKED_H */ |