Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "packet_interface.h"
- /* Extra #includes */
- /* Don 't forget to include - lz flag ! */
- #include <stdio.h>
- #include <stdlib.h>
- #include <zlib.h>
- #include <arpa/inet.h>
- #include <string.h>
- struct __attribute__((__packed__)) pkt {
- uint8_t pwindow:5;
- uint8_t ptr:1;
- ptypes_t ptype:2;
- uint16_t plength;
- uint8_t pseqnum;
- uint32_t ptimestamp;
- uint32_t pcrc1;
- char* ppayload;
- uint32_t pcrc2;
- };
- pkt_t* pkt_new()
- {
- return (pkt_t *) calloc(1,sizeof(pkt_t));
- }
- void pkt_del(pkt_t *pkt)
- {
- if (pkt==NULL) {
- return;
- }else if (pkt->ppayload != NULL) {
- free(pkt-> ppayload);
- }
- free(pkt);
- }
- pkt_status_code pkt_decode(const char *data, const size_t len, pkt_t *pkt)
- {
- if (len == 0 || data == NULL) {
- fprintf(stderr, "Erreur decode E_UNCONSISTENT\n");
- return E_UNCONSISTENT;
- }
- if (len < sizeof(uint8_t)*11) {
- fprintf(stderr, "Erreur decode E_NOHEADER1\n");
- return E_NOHEADER;
- }
- /* Read first bytes */
- memcpy(pkt, data, sizeof(uint8_t));
- //Read length /!\ TODO : Clear this stuff ! not clear what "data" means when "data" in varuint_decode != "data" in pkt_decode !
- uint16_t tmplength;
- ssize_t sizeoflength = varuint_decode((uint8_t*)data+sizeof(uint8_t),varuint_len((uint8_t *) data+sizeof(uint8_t)),&tmplength);
- if (sizeoflength == -1) {
- fprintf(stderr, "Erreur decode sizeoflength\n");
- return E_LENGTH;
- }
- if(pkt_set_length(pkt,tmplength) != PKT_OK){
- fprintf(stderr, "Erreur decode set length\n");
- return E_LENGTH;
- }
- size_t sizeAfterLength = sizeof(uint8_t)+sizeoflength;
- /*Read Seqnum*/
- memcpy(&(pkt->pseqnum),data+sizeAfterLength,sizeof(uint8_t));
- /*Read timestamp*/
- memcpy(&(pkt->ptimestamp),data+sizeAfterLength+sizeof(uint8_t),sizeof(uint32_t));
- ssize_t headersize = predict_header_length(pkt);
- if ((size_t) headersize != sizeAfterLength+sizeof(uint8_t)+sizeof(uint32_t)) {
- fprintf(stderr, "Erreur headersize\n");
- return E_UNCONSISTENT;
- }
- // if (len < (size_t)headersize) {
- // fprintf(stderr, "Erreur decode E_NOHEADER2\n");
- // return E_NOHEADER;
- // }
- /*Read CRC1*/
- memcpy(&(pkt->pcrc1),data+headersize,sizeof(uint32_t));
- //Attention network byte order
- //pkt->pseqnum = ntohs(pkt->pseqnum);
- pkt->pcrc1 = ntohl(pkt->pcrc1);
- /*Verify header*/
- //Type
- if (pkt->ptype != PTYPE_ACK && pkt->ptype != PTYPE_DATA && pkt->ptype != PTYPE_NACK) {
- fprintf(stderr, "Erreur liee au champ Type\n");
- return E_TYPE;
- }
- //TR
- if (pkt->ptr == 1 && pkt->ptype != PTYPE_DATA) {
- fprintf(stderr, "Erreur liee au champ TR\n");
- return E_TR;
- }
- //Window
- if (pkt->pwindow > MAX_WINDOW_SIZE) {
- fprintf(stderr, "Erreur liee au champ Window\n");
- return E_WINDOW;
- }
- //Lenght
- if (pkt->plength > MAX_PAYLOAD_SIZE) {
- fprintf(stderr, "Erreur Max Payload\n");
- return E_LENGTH;
- }
- //crc1
- if (pkt->ptr == 1) {
- uint8_t tr = pkt->ptr;
- pkt->ptr = 0;//TR a 0 lors du crc
- char* dataTR0 = malloc(headersize);
- if (!dataTR0) {
- fprintf(stderr, "Erreur malloc dataTR0\n");
- return E_NOMEM;
- }
- memcpy(dataTR0,pkt,sizeof(uint8_t));
- size_t sizeoflentr0 = varuint_encode(pkt_get_length(pkt), (uint8_t*) dataTR0+sizeof(uint8_t),sizeof(uint16_t));
- //uint8_t tmpseqTR0 = htons(pkt_get_seqnum(pkt));
- memcpy(dataTR0+sizeof(uint8_t)+sizeoflentr0,&(pkt->pseqnum),sizeof(uint8_t));
- memcpy(dataTR0+sizeof(uint8_t)+sizeoflentr0+sizeof(uint8_t), &(pkt->ptimestamp), sizeof(uint32_t));
- uint32_t crc1decode = (uint32_t) crc32(0L,Z_NULL,0);
- if((uint32_t) crc32(crc1decode,(Bytef *)dataTR0,headersize) != pkt->pcrc1){
- free(dataTR0);
- fprintf(stderr, "Erreur calcul crc1\n");
- pkt->ptr = tr;
- return E_CRC;
- }
- free(dataTR0);
- pkt->ptr=tr;
- }else{
- uint32_t crc1decode0 = (uint32_t) crc32(0L,Z_NULL,0);
- crc1decode0 = (uint32_t) crc32(crc1decode0,(Bytef *)data,headersize);
- if (crc1decode0 != pkt_get_crc1(pkt)) {
- fprintf(stderr, "Erreur calcul crc1\n");
- return E_CRC;
- }
- }
- /*Read Payload*/
- if (pkt_get_type(pkt) == PTYPE_DATA && pkt_get_length(pkt) !=0 ) {
- pkt_set_payload(pkt,data+headersize+sizeof(uint32_t),pkt_get_length(pkt));
- memcpy(&(pkt->pcrc2),data+headersize+sizeof(uint32_t)+pkt_get_length(pkt),sizeof(uint32_t));
- //Attention ntoh
- pkt->pcrc2 = ntohl(pkt->pcrc2);
- //CRC2
- uint32_t crc2decode = (uint32_t) crc32(0L, Z_NULL, 0);
- if ((uint32_t) crc32(crc2decode,(Bytef *) data+headersize+sizeof(uint32_t), pkt_get_length(pkt)) != pkt->pcrc2) {
- fprintf(stderr, "Erreur crc2\n");
- return E_CRC;
- }
- return PKT_OK;
- }
- pkt->pcrc2 = 0;
- //All OK
- return PKT_OK;
- }
- pkt_status_code pkt_encode(const pkt_t* pkt, char *buf, size_t *len)
- {
- if (pkt == NULL) {
- fprintf(stderr, "Erreur encode pkt null\n");
- return E_UNCONSISTENT;
- }
- if (buf == NULL) {
- fprintf(stderr, "Erreur encode buf null\n");
- return E_NOMEM;
- }
- if (len == NULL) {
- fprintf(stderr, "Erreur encode len\n");
- return E_LENGTH;
- }
- if (pkt_get_tr(pkt) == 1 && (pkt_get_type(pkt) != PTYPE_DATA)) {
- fprintf(stderr, "Erreur encode type and tr\n");
- return E_UNCONSISTENT;
- }
- if (*len < predict_header_length(pkt)+sizeof(uint32_t)) {
- fprintf(stderr, "Erreur encode len too small\n");
- return E_NOMEM;
- }
- if (*len < predict_header_length(pkt)+sizeof(uint64_t)+pkt_get_length(pkt) && pkt->ptype != PTYPE_DATA) {
- fprintf(stderr, "Erreur encode len too small\n");
- return E_NOMEM;
- }
- //Put first byte
- memcpy(buf,pkt,sizeof(uint8_t));
- //Put Lenght
- size_t afterlen = 0;
- ssize_t lenlenght = varuint_encode(pkt->plength, (uint8_t *) buf+sizeof(uint8_t) ,sizeof(uint16_t));
- if (lenlenght == -1) {
- fprintf(stderr, "Erreur lenlenght\n");
- return E_LENGTH;
- }
- afterlen = lenlenght + sizeof(uint8_t);
- //Put Seqnum
- //uint8_t tmpseq = htons(pkt->pseqnum);
- memcpy(buf+afterlen, &(pkt->pseqnum), sizeof(uint8_t));
- //Put timestamp
- memcpy(buf+afterlen+sizeof(uint8_t),&(pkt->ptimestamp), sizeof(uint32_t));
- size_t headersizeencode = predict_header_length(pkt);
- if (headersizeencode != afterlen+sizeof(uint8_t)+sizeof(uint32_t)) {
- fprintf(stderr, "Erreur headersize\n");
- return E_UNCONSISTENT;
- }
- //Put crc1
- uint32_t crc1calc = crc32(0L, Z_NULL, 0);
- crc1calc = crc32(crc1calc, (Bytef *) buf, headersizeencode);
- crc1calc = htonl(crc1calc);
- memcpy(buf+headersizeencode, &(crc1calc), sizeof(uint32_t));
- //Put payload & crc2
- *len = (size_t) headersizeencode+sizeof(uint32_t);
- if(pkt->ptype == PTYPE_DATA && pkt_get_length(pkt) != 0){
- memcpy(buf+headersizeencode+sizeof(uint32_t), pkt->ppayload,pkt_get_length(pkt));
- uint32_t crc2calc = crc32(0L, Z_NULL, 0);
- crc2calc = crc32(crc2calc,(Bytef *)buf+headersizeencode+sizeof(uint32_t),pkt_get_length(pkt));
- crc2calc = htonl(crc2calc);
- memcpy(buf+headersizeencode+sizeof(uint32_t)+pkt_get_length(pkt), &(crc2calc),sizeof(uint32_t));
- *len = (size_t) headersizeencode + sizeof(uint64_t)+pkt_get_length(pkt);
- }
- // fprintf(stderr, "Encode len final %ld\n", *len);
- return PKT_OK;
- }
- ptypes_t pkt_get_type (const pkt_t* pkt)
- {
- return pkt->ptype;
- }
- uint8_t pkt_get_tr(const pkt_t* pkt)
- {
- return pkt->ptr;
- }
- uint8_t pkt_get_window(const pkt_t* pkt)
- {
- return pkt->pwindow;
- }
- uint8_t pkt_get_seqnum(const pkt_t* pkt)
- {
- return pkt->pseqnum;
- }
- uint16_t pkt_get_length(const pkt_t* pkt)
- {
- return pkt->plength;
- }
- uint32_t pkt_get_timestamp (const pkt_t* pkt)
- {
- return pkt->ptimestamp;
- }
- uint32_t pkt_get_crc1 (const pkt_t* pkt)
- {
- return pkt->pcrc1;
- }
- uint32_t pkt_get_crc2 (const pkt_t* pkt)
- {
- return pkt->pcrc2;
- }
- const char* pkt_get_payload(const pkt_t* pkt)
- {
- if (pkt->ptype == PTYPE_DATA && pkt->plength != 0 && pkt->ptr != 1) {
- return pkt->ppayload;
- }
- return NULL;
- }
- pkt_status_code pkt_set_type(pkt_t *pkt, const ptypes_t type)
- {
- if (pkt == NULL) {
- return E_UNCONSISTENT;
- }
- if(type!= PTYPE_DATA && type != PTYPE_ACK && type != PTYPE_NACK) {
- fprintf(stderr, "Erreur de type\n");
- return E_TYPE;
- }
- pkt->ptype = type;
- return PKT_OK;
- }
- pkt_status_code pkt_set_tr(pkt_t *pkt, const uint8_t tr)
- {
- if (pkt == NULL) {
- return E_UNCONSISTENT;
- }
- if(pkt_get_type(pkt)!=PTYPE_DATA && tr!=0) {
- fprintf(stderr, "Erreur set_tr\n");
- return E_TR;
- }
- pkt->ptr=tr;
- return PKT_OK;
- }
- pkt_status_code pkt_set_window(pkt_t *pkt, const uint8_t window)
- {
- if (pkt == NULL) {
- return E_UNCONSISTENT;
- }
- if(window > MAX_WINDOW_SIZE) {
- fprintf(stderr, "Erreur : set_window\n");
- return E_WINDOW;
- }
- pkt->pwindow=window;
- return PKT_OK;
- }
- pkt_status_code pkt_set_seqnum(pkt_t *pkt, const uint8_t seqnum)
- {
- if (pkt == NULL) {
- return E_UNCONSISTENT;
- }
- pkt->pseqnum = seqnum;
- return PKT_OK;
- }
- pkt_status_code pkt_set_length(pkt_t *pkt, const uint16_t length)
- {
- if (pkt == NULL) {
- return E_UNCONSISTENT;
- }
- if(length>MAX_PAYLOAD_SIZE) {
- fprintf(stderr, "Erreur pkt_set_length1\n");
- return E_LENGTH;
- }
- pkt->plength = length;
- return PKT_OK;
- }
- pkt_status_code pkt_set_timestamp(pkt_t *pkt, const uint32_t timestamp)
- {
- if (pkt == NULL) {
- return E_UNCONSISTENT;
- }
- pkt->ptimestamp=timestamp;
- return PKT_OK;
- }
- pkt_status_code pkt_set_crc1(pkt_t *pkt, const uint32_t crc1)
- {
- if (pkt == NULL) {
- return E_UNCONSISTENT;
- }
- pkt->pcrc1=crc1;
- return PKT_OK;
- }
- pkt_status_code pkt_set_crc2(pkt_t *pkt, const uint32_t crc2)
- {
- if (pkt == NULL) {
- return E_UNCONSISTENT;
- }
- pkt->pcrc2=crc2;
- return PKT_OK;
- }
- pkt_status_code pkt_set_payload(pkt_t *pkt,const char *data,const uint16_t length)
- {
- if (pkt == NULL || data == NULL) {
- return E_UNCONSISTENT;
- }
- if(pkt_get_tr(pkt)!=0){
- fprintf(stderr, "Erreur set payload E_UNCONSISTENT\n");
- return E_UNCONSISTENT;
- }
- if (length > MAX_PAYLOAD_SIZE) {
- fprintf(stderr, "Erreur set payload length too large\n");
- return E_LENGTH;
- }
- if(pkt->ppayload!=NULL){
- free(pkt->ppayload);
- }
- pkt->ppayload = malloc(length);
- if(pkt->ppayload==NULL)
- {
- fprintf(stderr, "Erreur set payload E_NOMEM\n");
- return E_NOMEM;
- }
- memcpy(pkt->ppayload, data, length);
- if(pkt_set_tr(pkt, 0)!=PKT_OK) {
- fprintf(stderr, "Erreur set payload tr\n");
- return E_TR;
- }
- if(pkt_set_type(pkt, PTYPE_DATA)!=PKT_OK) {
- fprintf(stderr, "Erreur set payload type\n");
- return E_TYPE;
- }
- if (pkt_set_length(pkt,length) != PKT_OK) {
- fprintf(stderr, "Erreur set payload le\n");
- return E_LENGTH;
- }
- return PKT_OK;
- }
- ssize_t varuint_decode(const uint8_t *data, const size_t len, uint16_t *retval)
- {
- size_t sizeofdata = varuint_len(data);
- if (sizeofdata > len || (int) sizeofdata == -1) {
- return -1;
- }
- if (sizeofdata == sizeof(uint8_t)) {
- *retval = *data & 127;
- }else{
- *retval = ntohs(*(uint16_t *) data) & 32767;
- }
- return sizeofdata;
- }
- ssize_t varuint_encode(uint16_t val, uint8_t *data, const size_t len)
- {
- size_t sizeofvaruint = varuint_predict_len(val);
- if (sizeofvaruint > len || (int)sizeofvaruint == -1) {
- return -1;
- }
- if (sizeofvaruint == sizeof(uint8_t)) {
- uint8_t nval = (uint8_t) val;
- memcpy(data,&nval,sizeofvaruint);
- }else{
- uint16_t nval = htons(1<<15| val);
- memcpy(data,&nval,sizeofvaruint);
- }
- return sizeofvaruint;
- }
- size_t varuint_len(const uint8_t *data)
- {
- if((*data & 1<<7) != 0){
- return sizeof(uint16_t);
- }else {
- return sizeof(uint8_t);
- }
- }
- ssize_t varuint_predict_len(uint16_t val)
- {
- if(val >= 0x8000){
- return -1;
- }
- if (val <= 127) {
- return sizeof(uint8_t);
- }
- return sizeof(uint16_t);
- }
- ssize_t predict_header_length(const pkt_t *pkt)
- {
- if(pkt->plength >= 0x8000){
- return -1;
- }
- if(varuint_predict_len(pkt->plength) == sizeof(uint8_t)){
- return (sizeof(uint32_t)+sizeof(uint16_t)+sizeof(uint8_t));
- }else if (varuint_predict_len(pkt->plength) == sizeof(uint16_t)) {
- return (sizeof(uint64_t));
- }else{
- return -1;
- }
- }
- //
- //
- // int main(int argc, char const *argv[]) {
- // pkt_t* pkt = pkt_new();
- // pkt_set_type(pkt,PTYPE_DATA);
- // pkt_set_tr(pkt,(uint8_t)0);
- // pkt_set_window(pkt,(uint8_t)5);
- // pkt_set_seqnum(pkt,(uint8_t)42);
- // pkt_set_length(pkt,(uint16_t)513);
- // pkt_set_timestamp(pkt,(uint32_t)11111111);
- // pkt_set_crc1(pkt,(uint32_t)0);
- // pkt_set_payload(pkt,(char *) 512,sizeof(uint16_t));
- // pkt_set_crc2(pkt,(uint32_t)0);
- // char* buf = malloc(8*sizeof(uint64_t));
- // size_t leng = 8*sizeof(uint64_t);
- // pkt_encode(pkt,buf,&leng);
- // pkt_del(pkt);
- //
- // pkt_t* pktout = pkt_new();
- // pkt_decode(buf,8*sizeof(uint64_t),pktout);
- //
- // free(buf);
- //
- // fprintf(stdout, "%u\n",pkt_get_type(pktout));
- // fprintf(stdout, "%u\n",pkt_get_tr(pktout));
- // fprintf(stdout, "%u\n",pkt_get_window(pktout));
- // fprintf(stdout, "%u\n",pkt_get_bigl(pktout));
- // fprintf(stdout, "%u\n",pkt_get_length(pktout));
- // fprintf(stdout, "%u\n",pkt_get_seqnum(pktout));
- // fprintf(stdout, "%u\n",pkt_get_timestamp(pktout));
- // fprintf(stdout, "%u\n",pkt_get_crc1(pktout));
- // //fprintf(stdout, "%u\n",pkt_get_payload(pktout));
- // fprintf(stdout, "%u\n",pkt_get_crc2(pktout));
- //
- // return 0;
- // }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement