Skip to content
Extraits de code Groupes Projets
Valider 42cb9a9e rédigé par Vany Ingenzi's avatar Vany Ingenzi
Parcourir les fichiers

Staed implemting packets casting

parent bab02832
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
*.o
.vscode/
\ No newline at end of file
# You can use clang if you prefer
CC = gcc
# Feel free to add other C flags
CFLAGS += -c -std=gnu99 -Wall -Werror -Wextra -O2
# By default, we colorize the output, but this might be ugly in log files, so feel free to remove the following line.
CFLAGS += -D_COLOR
# You may want to add something here
LDFLAGS +=
HEADERS_DIR = -Iheaders
LDFLAGS = -lz
# Adapt these as you want to fit with your project
SENDER_SOURCES = $(wildcard src/sender.c src/log.c)
......@@ -19,7 +16,7 @@ RECEIVER_OBJECTS = $(RECEIVER_SOURCES:.c=.o)
SENDER = sender
RECEIVER = receiver
all: $(SENDER) $(RECEIVER)
all: debug $(SENDER) $(RECEIVER)
$(SENDER): $(SENDER_OBJECTS)
$(CC) $(SENDER_OBJECTS) -o $@ $(LDFLAGS)
......@@ -28,11 +25,11 @@ $(RECEIVER): $(RECEIVER_OBJECTS)
$(CC) $(RECEIVER_OBJECTS) -o $@ $(LDFLAGS)
%.o: %.c
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
$(CC) $(HEADERS_DIR) $(CFLAGS) $< -o $@ $(LDFLAGS)
.PHONY: clean mrproper
clean:
clean: mrproper
rm -f $(SENDER_OBJECTS) $(RECEIVER_OBJECTS)
mrproper:
......
# My Wonderful LINFO1341 Project
# Implementation of TRTP Protocol - LINFO1341 Project
The very first thing you might want to do in this folder is the following command:
```bash
git init
```
## Introduction
This will initialize your Git repository.
You should also put it in a **private** repository (GitHub, GitLab, Bitbucket,... it is up to you but it **has to** stay private).
For a 3rd year bachelors Computer Networks given to computer science students at UCLouvain, we had to implement a transport protocol. The protocol is entitled Truncated Relieable Transport Protocol (TRTP)on top of a Ipv6 Network layer. The implementation also implement the Forward Erasure Correction (FEC) to recover corrupted packets. The full description is to be found in the `statement.pdf`.
The Makefile contains all the required targets, but you might want to extend their behavior.
## Folder Organization
Very basic skelettons of receiver and sender source files are present, have a look to understand how you can enable logging or not.
```
| `headers\`
| `src\`
| `tests\`
```
A very simple test case is present, you probably want to update it.
## Execution
You might be interested in the link simulator that can be found at https://github.com/cnp3/Linksimulator
## Testing
And finally, if this message is still there at your final submission, it looks like you forgot to provide a proper README.
\ No newline at end of file
## System Architecture
\ No newline at end of file
Fichier déplacé
/**
* @file packet_interface.h
* @brief This header contains structs and definitions needed in order to encode and decode TRTP packets
*/
#ifndef __PACKET_INTERFACE_H_
#define __PACKET_INTERFACE_H_
#include <stddef.h> /* size_t */
#include <stdint.h> /* uintx_t */
#include <stdio.h> /* ssize_t */
/* Raccourci pour struct pkt */
typedef struct pkt pkt_t;
/* Types de paquets */
typedef enum {
PTYPE_DATA = 1,
PTYPE_ACK = 2,
PTYPE_NACK = 3,
} ptypes_t;
/* Taille maximale permise pour le payload */
#define MAX_PAYLOAD_SIZE 512
/* Taille maximale de Window */
#define MAX_WINDOW_SIZE 31
/* Valeur de retours des fonctions */
typedef enum {
PKT_OK = 0, /* Le paquet a ete traite avec succes */
E_TYPE, /* Erreur liee au champs Type */
E_TR, /* Erreur liee au champ TR */
E_LENGTH, /* Erreur liee au champs Length */
E_CRC, /* CRC invalide */
E_WINDOW, /* Erreur liee au champs Window */
E_SEQNUM, /* Numero de sequence invalide */
E_NOMEM, /* Pas assez de memoire */
E_NOHEADER, /* Le paquet n'a pas de header (trop court) */
E_UNCONSISTENT, /* Le paquet est incoherent */
} pkt_status_code;
/* Alloue et initialise une struct pkt
* @return: NULL en cas d'erreur */
pkt_t* pkt_new();
/* Libere le pointeur vers la struct pkt, ainsi que toutes les
* ressources associees
*/
void pkt_del(pkt_t*);
/*
* Decode des donnees recues et cree une nouvelle structure pkt.
* Le paquet recu est en network byte-order.
* La fonction verifie que:
* - Le CRC32 du header recu est le même que celui decode a la fin
* du header (en considerant le champ TR a 0)
* - S'il est present, le CRC32 du payload recu est le meme que celui
* decode a la fin du payload
* - Le type du paquet est valide
* - La longueur du paquet et le champ TR sont valides et coherents
* avec le nombre d'octets recus.
*
* @data: L'ensemble d'octets constituant le paquet recu
* @len: Le nombre de bytes recus
* @pkt: Une struct pkt valide
* @post: pkt est la representation du paquet recu
*
* @return: Un code indiquant si l'operation a reussi ou representant
* l'erreur rencontree.
*/
pkt_status_code pkt_decode(const char *data, const size_t len, pkt_t *pkt);
/*
* Encode une struct pkt dans un buffer, prêt a être envoye sur le reseau
* (c-a-d en network byte-order), incluant le CRC32 du header et
* eventuellement le CRC32 du payload si celui-ci est non nul.
*
* @pkt: La structure a encoder
* @buf: Le buffer dans lequel la structure sera encodee
* @len: La taille disponible dans le buffer
* @len-POST: Le nombre de d'octets ecrit dans le buffer
* @return: Un code indiquant si l'operation a reussi ou E_NOMEM si
* le buffer est trop petit.
*/
pkt_status_code pkt_encode(const pkt_t*, char *buf, size_t *len);
/* Accesseurs pour les champs toujours presents du paquet.
* Les valeurs renvoyees sont toutes dans l'endianness native
* de la machine!
*/
ptypes_t pkt_get_type (const pkt_t*);
uint8_t pkt_get_tr (const pkt_t*);
uint8_t pkt_get_window (const pkt_t*);
uint8_t pkt_get_seqnum (const pkt_t*);
uint16_t pkt_get_length (const pkt_t*);
uint32_t pkt_get_timestamp(const pkt_t*);
uint32_t pkt_get_crc1 (const pkt_t*);
/* Renvoie un pointeur vers le payload du paquet, ou NULL s'il n'y
* en a pas.
*/
const char* pkt_get_payload(const pkt_t*);
/* Renvoie le CRC2 dans l'endianness native de la machine. Si
* ce field n'est pas present, retourne 0.
*/
uint32_t pkt_get_crc2(const pkt_t*);
/* Setters pour les champs obligatoires du paquet. Si les valeurs
* fournies ne sont pas dans les limites acceptables, les fonctions
* doivent renvoyer un code d'erreur adapte.
* Les valeurs fournies sont dans l'endianness native de la machine!
*/
pkt_status_code pkt_set_type (pkt_t*, const ptypes_t type);
pkt_status_code pkt_set_tr (pkt_t*, const uint8_t tr);
pkt_status_code pkt_set_window (pkt_t*, const uint8_t window);
pkt_status_code pkt_set_seqnum (pkt_t*, const uint8_t seqnum);
pkt_status_code pkt_set_length (pkt_t*, const uint16_t length);
pkt_status_code pkt_set_timestamp(pkt_t*, const uint32_t timestamp);
pkt_status_code pkt_set_crc1 (pkt_t*, const uint32_t crc1);
/* Defini la valeur du champs payload du paquet.
* @data: Une succession d'octets representants le payload
* @length: Le nombre d'octets composant le payload
* @POST: pkt_get_length(pkt) == length */
pkt_status_code pkt_set_payload(pkt_t*,
const char *data,
const uint16_t length);
/* Setter pour CRC2. Les valeurs fournies sont dans l'endianness
* native de la machine!
*/
pkt_status_code pkt_set_crc2(pkt_t*, const uint32_t crc2);
/*
* Decode un varuint (entier non signe de taille variable dont le premier bit indique la longueur)
* encode en network byte-order dans le buffer data disposant d'une taille maximale len.
* @post: place à l'adresse retval la valeur en host byte-order de l'entier de taille variable stocke
* dans data si aucune erreur ne s'est produite
* @return:
*
* -1 si data ne contient pas un varuint valide (la taille du varint
* est trop grande par rapport à la place disponible dans data)
*
* le nombre de bytes utilises si aucune erreur ne s'est produite
*/
ssize_t varuint_decode(const uint8_t *data, const size_t len, uint16_t *retval);
/*
* Encode un varuint en network byte-order dans le buffer data disposant d'une
* taille maximale len.
* @pre: val < 0x8000 (val peut être encode en varuint)
* @return:
* -1 si data ne contient pas une taille suffisante pour encoder le varuint
*
* la taille necessaire pour encoder le varuint (1 ou 2 bytes) si aucune erreur ne s'est produite
*/
ssize_t varuint_encode(uint16_t val, uint8_t *data, const size_t len);
/*
* @pre: data pointe vers un buffer d'au moins 1 byte
* @return: la taille en bytes du varuint stocke dans data, soit 1 ou 2 bytes.
*/
size_t varuint_len(const uint8_t *data);
/*
* @return: la taille en bytes que prendra la valeur val
* une fois encodee en varuint si val contient une valeur varuint valide (val < 0x8000).
-1 si val ne contient pas une valeur varuint valide
*/
ssize_t varuint_predict_len(uint16_t val);
/*
* Retourne la longueur du header en bytes si le champs pkt->length
* a une valeur valide pour un champs de type varuint (i.e. pkt->length < 0x8000).
* Retourne -1 sinon
* @pre: pkt contient une adresse valide (!= NULL)
*/
ssize_t predict_header_length(const pkt_t *pkt);
#endif /* __PACKET_INTERFACE_H_ */
\ No newline at end of file
/**
* @file receiver.h
* @brief This header contains all the structures and functions definitions that ae going to be used by the receiver.c
*/
\ No newline at end of file
#include "packet_interface.h"
#include <arpa/inet.h>
#include <zlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
/*************** Structures definition ***************/
struct __attribute__((__packed__)) pkt {
header_t header;
uint8_t payload[512];
};
typedef uint8_t header_t[32];
/************* Functions definition *************/
pkt_t* pkt_new()
{
pkt_t * toReturn = (pkt_t *) malloc(sizeof(pkt_t));
return toReturn;
}
void pkt_del(pkt_t *pkt)
{
free(pkt);
}
/**
* @brief Calculates the CRC32
*
* @param buffer : The buffer on which to calculate CRC32.
* @param len : The number of bytes of the buffer.
* @return uint32_t
*/
uint32_t calculate_crc(char * buffer, uint32_t len)
{
return (uint32_t) crc32(0, (const void *) buffer, len);
}
pkt_status_code pkt_decode_data_fec(const char *data, const size_t len, pkt_t *pkt)
{
}
pkt_status_code pkt_decode_ack_nack(const char *data, const size_t len, pkt_t *pkt)
{
if (len < 8)
return E_NOHEADER;
// REMINDER : *data will read the first byte
ptypes_t type = ((*data) & 0xC0) >> 6;
if ( type != PTYPE_ACK && type != PTYPE_NACK )
return E_TYPE;
if ( ((*data) & 0x20) != 0)
return E_TR;
uint8_t seqnum, window;
memcpy((char *) &seqnum, data+1, 1);
memcpy((char *) &window, data, 1);
window = window & 0x1F;
if (seqnum > window)
return E_SEQNUM;
// CheckSum no need to set TR at 0 as it should be at 0
char crc[4];
memcpy(crc, data+4, 4);
if (calculate_crc(data, 4) != ntohl((uint32_t) crc))
return E_CRC;
}
pkt_status_code pkt_decode(const char *data, const size_t len, pkt_t *pkt)
{
int is_ack_nack = len <= 8; // Maximum ACK or NACK size is 12 bytes
if (is_ack_nack)
return pkt_decode_ack_nack(data, len, pkt);
else
return pkt_decode_data_fec(data, len, pkt);
}
pkt_status_code pkt_encode(const pkt_t* pkt, char *buf, size_t *len)
{
/* Your code will be inserted here */
}
ptypes_t pkt_get_type (const pkt_t* pkt)
{
/* Your code will be inserted here */
}
uint8_t pkt_get_tr(const pkt_t* pkt)
{
/* Your code will be inserted here */
}
uint8_t pkt_get_window(const pkt_t* pkt)
{
/* Your code will be inserted here */
}
uint8_t pkt_get_seqnum(const pkt_t* pkt)
{
/* Your code will be inserted here */
}
uint16_t pkt_get_length(const pkt_t* pkt)
{
/* Your code will be inserted here */
}
uint32_t pkt_get_timestamp (const pkt_t* pkt)
{
/* Your code will be inserted here */
}
uint32_t pkt_get_crc1 (const pkt_t* pkt)
{
/* Your code will be inserted here */
}
uint32_t pkt_get_crc2 (const pkt_t* pkt)
{
/* Your code will be inserted here */
}
const char* pkt_get_payload(const pkt_t* pkt)
{
/* Your code will be inserted here */
}
pkt_status_code pkt_set_type(pkt_t *pkt, const ptypes_t type)
{
/* Your code will be inserted here */
}
pkt_status_code pkt_set_tr(pkt_t *pkt, const uint8_t tr)
{
/* Your code will be inserted here */
}
pkt_status_code pkt_set_window(pkt_t *pkt, const uint8_t window)
{
/* Your code will be inserted here */
}
pkt_status_code pkt_set_seqnum(pkt_t *pkt, const uint8_t seqnum)
{
/* Your code will be inserted here */
}
pkt_status_code pkt_set_length(pkt_t *pkt, const uint16_t length)
{
/* Your code will be inserted here */
}
pkt_status_code pkt_set_timestamp(pkt_t *pkt, const uint32_t timestamp)
{
/* Your code will be inserted here */
}
pkt_status_code pkt_set_crc1(pkt_t *pkt, const uint32_t crc1)
{
/* Your code will be inserted here */
}
pkt_status_code pkt_set_crc2(pkt_t *pkt, const uint32_t crc2)
{
/* Your code will be inserted here */
}
pkt_status_code pkt_set_payload(pkt_t *pkt,
const char *data,
const uint16_t length)
{
/* Your code will be inserted here */
}
ssize_t varuint_decode(const uint8_t *data, const size_t len, uint16_t *retval)
{
/* Your code will be inserted here */
}
ssize_t varuint_encode(uint16_t val, uint8_t *data, const size_t len)
{
/* Your code will be inserted here */
}
size_t varuint_len(const uint8_t *data)
{
/* Your code will be inserted here */
}
ssize_t varuint_predict_len(uint16_t val)
{
/* Your code will be inserted here */
}
ssize_t predict_header_length(const pkt_t *pkt)
{
/* Your code will be inserted here */
}
\ No newline at end of file
Fichier ajouté
Fichier ajouté
#include <stdio.h>
#include <zlib.h>
int main() {
char * arr = "123456789";
printf("%ld\n", crc32(0, (const void *) arr, 9));
return 0;
}
\ No newline at end of file
Hello Receiver I'm a Friendly Sender !
\ No newline at end of file
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter