/****************************************************************************** * Copyright © 2014-2015 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * * holder information and the developer policies on copyright and licensing. * * * * Unless otherwise agreed in a custom licensing agreement, no part of the * * SuperNET software, including this file may be copied, modified, propagated * * or distributed except according to the terms contained in the LICENSE file * * * * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ #include "OS_portable.h" #include "../includes/curve25519.h" // threadsafe int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp) { int32_t i; uint64_t x; if ( rwflag == 0 ) { x = 0; for (i=len-1; i>=0; i--) { x <<= 8; x |= serialized[i]; } switch ( len ) { case 1: *(uint8_t *)endianedp = (uint8_t)x; break; case 2: *(uint16_t *)endianedp = (uint16_t)x; break; case 4: *(uint32_t *)endianedp = (uint32_t)x; break; case 8: *(uint64_t *)endianedp = (uint64_t)x; break; } } else { x = 0; switch ( len ) { case 1: x = *(uint8_t *)endianedp; break; case 2: x = *(uint16_t *)endianedp; break; case 4: x = *(uint32_t *)endianedp; break; case 8: x = *(uint64_t *)endianedp; break; } for (i=0; i>= 8) serialized[i] = (uint8_t)(x & 0xff); } return(len); } int32_t iguana_validatehdr(struct iguana_msghdr *H) { int32_t i,len; char *validcommands[] = { "SuperNET", "version", "verack", "getaddr", "addr", "inv", "getdata", "notfound", "getblocks", "getheaders", "headers", "tx", "block", "mempool", "ping", "pong", "reject", "filterload", "filteradd", "filterclear", "merkleblock", "alert" }; for (i=0; icommand,validcommands[i]) == 0 ) { iguana_rwnum(0,H->serdatalen,sizeof(H->serdatalen),(uint32_t *)&len); if ( len > IGUANA_MAXPACKETSIZE ) return(-1); return(len); } return(-1); } int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp) { int32_t i; if ( rwflag == 0 ) { for (i=0; inetmagic,netmagic,4); strncpy(H->command,command,12); iguana_rwnum(1,H->serdatalen,sizeof(int32_t),&datalen); if ( data != 0 && datalen != 0 ) { hash2 = bits256_doublesha256(0,data,datalen); iguana_rwbignum(1,tmp.bytes,sizeof(tmp),hash2.bytes); for (i=0; i<4; i++) H->hash[i] = tmp.bytes[i]; } else H->hash[0] = 0x5d, H->hash[1] = 0xf6, H->hash[2] = 0xe0, H->hash[3] = 0xe2; return(datalen + sizeof(*H)); } uint8_t *iguana_varint16(int32_t rwflag,uint8_t *serialized,uint16_t *varint16p) { uint16_t n = 0; if ( rwflag == 0 ) { n = *serialized++; n |= ((int32_t)*serialized++ << 8); *varint16p = n; } else { n = *varint16p; *serialized++ = (uint8_t)n & 0xff; *serialized++ = (uint8_t)(n >> 8) & 0xff; } return(serialized); } uint8_t *iguana_varint32(int32_t rwflag,uint8_t *serialized,uint16_t *varint16p) { serialized = iguana_varint16(rwflag,serialized,varint16p); serialized = iguana_varint16(rwflag,serialized,&varint16p[1]); return(serialized); } uint8_t *iguana_varint64(int32_t rwflag,uint8_t *serialized,uint32_t *varint32p) { serialized = iguana_varint32(rwflag,serialized,(uint16_t *)varint32p); serialized = iguana_varint32(rwflag,serialized,(uint16_t *)&varint32p[1]); return(serialized); } int32_t iguana_rwvarint(int32_t rwflag,uint8_t *serialized,uint64_t *varint64p) { uint64_t n; int32_t vlen = 1; if ( rwflag == 0 ) { *varint64p = 0; if ( (n= *serialized++) >= 0xfd ) { if ( n == 0xfd ) { n = 0; iguana_varint16(rwflag,serialized,(uint16_t *)&n); vlen += 2; } else if ( n == 0xfe ) { n = 0; iguana_varint32(rwflag,serialized,(uint16_t *)&n); vlen += 4; } else if ( n == 0xff ) { n = 0; iguana_varint64(rwflag,serialized,(uint32_t *)&n); vlen += 8; } } *varint64p = n; } else { n = *varint64p; if ( n < 0xfd ) *serialized++ = (uint8_t)n; else if ( n == 0xfd ) { *serialized++ = 0xfd; iguana_varint16(rwflag,serialized,(uint16_t *)varint64p); vlen += 2; } else if ( n == 0xfe ) { *serialized++ = 0xfe; iguana_varint32(rwflag,serialized,(uint16_t *)varint64p); vlen += 4; } else if ( n == 0xff ) { *serialized++ = 0xff; iguana_varint64(rwflag,serialized,(uint32_t *)varint64p); vlen += 8; } } return(vlen); } int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p) { int32_t len; uint64_t x = 0; if ( rwflag != 0 ) x = *int32p; len = iguana_rwvarint(rwflag,serialized,&x); if ( rwflag == 0 ) *int32p = (int32_t)x; return(len); } int32_t iguana_rwstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp) { int32_t vlen; uint64_t n; if ( rwflag == 0 ) { vlen = iguana_rwvarint(rwflag,serialized,&n); memcpy(endianedp,&serialized[vlen],n); ((uint8_t *)endianedp)[n] = 0; } else { n = strlen(endianedp); if ( n > maxlen ) n = maxlen; vlen = iguana_rwvarint(rwflag,serialized,&n); memcpy(&serialized[vlen],endianedp,n); } return((int32_t)(n + vlen)); } int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp) { if ( rwflag == 0 ) memcpy(endianedp,serialized,len); else memcpy(serialized,endianedp,len); return(len); }