Compare commits

..

1 Commits

Author SHA1 Message Date
xethyrion 0705909f4c Update
Almost finished
2016-11-01 16:52:58 +02:00
27 changed files with 741 additions and 2528 deletions

View File

@ -1,78 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.663343487">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.663343487" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration buildProperties="" id="cdt.managedbuild.toolchain.gnu.base.663343487" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.663343487.1554761701" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1976366028" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.base.790917044" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
<builder id="cdt.managedbuild.target.gnu.builder.base.667198033" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1340147019" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1587295855" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.548918774" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1621016424" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.298540641" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base">
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1326462310" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.107597551" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"/>
<tool id="cdt.managedbuild.tool.gnu.assembler.base.1765741010" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1331876933" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="c-multiaddr.null.2082036538" name="c-multiaddr"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildTarget>clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="rebuild" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>rebuild</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cproject>

11
.gitignore vendored
View File

@ -1,11 +0,0 @@
*
!.gitignore
!Makefile
!**/
*.o
*.a
.settings/language.settings.xml
test_multiaddr

View File

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>c-multiaddr</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

24
LICENSE
View File

@ -1,24 +0,0 @@
MIT License
Copyright (c) 2019 AGORISE, LTD.
An International Business Company, Cyprus Reg# ΗΕ375959
Contains works from BitShares Munich IVS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,33 +0,0 @@
CC = gcc
CFLAGS = -O0 -I include -std=c99
DEBUG = true
ifdef DEBUG
CFLAGS += -g3
endif
LFLAGS = -lm
DEPS = include/multiaddr/base58.h include/multiaddr/endian.h include/multiaddr/multiaddr.h \
include/multiaddr/protocols.h include/multiaddr/protoutils.h include/multiaddr/varhexutils.h \
include/multiaddr/varint.h
OBJS = base58.o varint.o varhexutils.o protoutils.o protocols.o multiaddr.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
libmultiaddr.a: $(OBJS)
ar rcs $@ $^
test_multiaddr: testing.o libmultiaddr.a
$(CC) -o $@ $^ $(LFLAGS)
all: test_multiaddr
clean:
rm -f *.o
rm -f libmultiaddr.a
rm -f test_multiaddr
rebuild: clean all

View File

@ -1,34 +1,2 @@
# c-multiaddr
multiaddr for IPFS in C.
### Multiaddr provides easy networking protocols nesting, easy encapsulation of extra protocols, easy tunneling, etc.
# Usage:
#### All you need to include is multiaddr.h
## Maddr struct:
* char * string; // String that contains addresses such as /ip4/192.168.1.1/
* uint8_t * bytes; // uint8_t * that contains the enecoded address
* size_t bsize; //size_t that contains the real bytes size (Use it whenever using the bytes so you don't input trash!)
## New Multi Address From String(multiaddress_new_from_string)
struct MultiAddress* a = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/8080/");
## Obtaining the byte buffer(.bytes, .bsize[0]):
printf("TEST BYTES: %s\n",Var_To_Hex(a->bsize, a->bytes));
Var_To_Hex = Byte Buffer to Hex String
Hex_To_Var = Hex String to Byte Buffer
## Encapsulation & Decapsulation(m_encapsulate, m_decapsulate)
#### Remember, Decapsulation happens from right to left, never in reverse, if you have /ip4/udp/ipfs/ if you decapsulate "udp" you will also take out ipfs!
* Now the string is: /ip4/192.168.1.1/
* multiaddress_encapsulate(a,"/udp/3333/"); //Adds udp/3333/
* Now the string is: /ip4/192.168.1.1/udp/3333/
* multiaddress_decapsulate(a,"udp"); //Removes udp protocol and its address
* Now the string is: /ip4/192.168.1.1/
* multiaddress_encapsulate(a,"/tcp/8080");
* Now the string is: /ip4/192.168.1.1/tcp/8080/
# Constructing a multiaddress from bytes:
* struct MultiAddress* beta;
* beta = multiaddress_new_from_bytes(a->bytes,a->bsize); //This will already construct back to the string too!
* printf("B STRING: %s\n",beta->string); //So after encapsulation and decapsulation atm this string would
* contain: /ip4/192.168.1.1/tcp/8080/

21
STATUS Normal file
View File

@ -0,0 +1,21 @@
STATUS:
Compatibility: Windows/Mac/Linux/Openbsd based systems (probably more)
-Finished Base58.h Encryption/Decryption Algorhytm
-Finished Endian.h Library for automating compiling for Linux/Mac/Windows
-Finished Varhexutils - Different conversion algorhytms between bytes and strings etc.
-Finsihed Varint.h - Conversion from Hex
-Finished Protocols.h - Library for loading protocols & manipulating them easily.
What needs to be done (known so far):
-Not finished: protoutils.h (performs final byte encodings and checks for validity
-Not started: Multiaddr.h
(The actual thing that makes everything simple, encapsulating different protocols easily for lower
internet consumption and higher overall efficiency.) (Basically simulating classes from other languages for easy development)
Other things to do:
Add conversion for bigendian machines (doubt anyone will actually need them tbh but portability was requested.)
Should work on all platforms so far.
Add proper documentation in case anyone needs to add protocols etc.
So far it's almost finished.

View File

@ -1,15 +0,0 @@
# STATUS:
* Compatibility: Windows/Mac/Linux/Openbsd based systems (probably more)
* Finished Base58.h Encryption/Decryption Algorhytm
* Finished Endian.h Library for automating compiling for Linux/Mac/Windows
* Finished Varhexutils - Different conversion algorhytms between bytes and strings etc.
* Finsihed Varint.h - Conversion from Hex
* Finished Protocols.h - Library for loading protocols & manipulating them easily.
* Finished: Multiaddr.h (easy library for developers)
* Finished: Protoutils.h Converting from string to hex/binary, analizing strings/bin for validity,parsing ipv4,etc.
* Finished: Readme - Documentation on how to use everything so any new developer can easily use all of this
# Secondary things that might need to be implemented:
* Protocols, everything except IP4,TCP,UDP,IPFS - These we actually need.
* Few issues that are not urgent:
- Decapsulation of tunneled protocols doesn't work, this will be fixed if needed in multiaddr.h/m_decapsulate
- Endianness Check - protoutils.h/in protocols UDP,TCP

200
base58.c
View File

@ -1,200 +0,0 @@
/*
* Copyright 2012-2014 Luke Dashjr
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the standard MIT license. See COPYING for more details.
*/
#include <string.h>
#include <math.h>
#include <stdint.h>
#include <sys/types.h>
static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
static const int8_t b58digits_map[] = {
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
-1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
-1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
};
/**
* convert a base58 encoded string into a binary array
* @param b58 the base58 encoded string
* @param base58_size the size of the encoded string
* @param bin the results buffer
* @param binszp the size of the results buffer
* @returns true(1) on success
*/
int multiaddr_encoding_base58_decode(const char* b58, size_t base58_size, unsigned char** bin, size_t* binszp)
{
size_t binsz = *binszp;
const unsigned char* b58u = (const void*)b58;
unsigned char* binu = *bin;
size_t outisz = (binsz + 3) / 4;
uint32_t outi[outisz];
uint64_t t;
uint32_t c;
size_t i, j;
uint8_t bytesleft = binsz % 4;
uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0;
unsigned zerocount = 0;
size_t b58sz;
b58sz = strlen(b58);
memset(outi, 0, outisz * sizeof(*outi));
// Leading zeros, just count
for (i = 0; i < b58sz && !b58digits_map[b58u[i]]; ++i) {
++zerocount;
}
for (; i < b58sz; ++i) {
if (b58u[i] & 0x80) {
// High-bit set on invalid digit
return 0;
}
if (b58digits_map[b58u[i]] == -1) {
// Invalid base58 digit
return 0;
}
c = (unsigned)b58digits_map[b58u[i]];
for (j = outisz; j--;) {
t = ((uint64_t)outi[j]) * 58 + c;
c = (t & 0x3f00000000) >> 32;
outi[j] = t & 0xffffffff;
}
if (c) {
// Output number too big (carry to the next int32)
memset(outi, 0, outisz * sizeof(*outi));
return 0;
}
if (outi[0] & zeromask) {
// Output number too big (last int32 filled too far)
memset(outi, 0, outisz * sizeof(*outi));
return 0;
}
}
j = 0;
switch (bytesleft) {
case 3:
*(binu++) = (outi[0] & 0xff0000) >> 16;
case 2:
*(binu++) = (outi[0] & 0xff00) >> 8;
case 1:
*(binu++) = (outi[0] & 0xff);
++j;
default:
break;
}
for (; j < outisz; ++j) {
*(binu++) = (outi[j] >> 0x18) & 0xff;
*(binu++) = (outi[j] >> 0x10) & 0xff;
*(binu++) = (outi[j] >> 8) & 0xff;
*(binu++) = (outi[j] >> 0) & 0xff;
}
// Count canonical base58 byte count
binu = *bin;
for (i = 0; i < binsz; ++i) {
if (binu[i]) {
break;
}
--*binszp;
}
*binszp += zerocount;
memset(outi, 0, outisz * sizeof(*outi));
return 1;
}
/**
* encode an array of bytes into a base58 string
* @param binary_data the data to be encoded
* @param binary_data_size the size of the data to be encoded
* @param base58 the results buffer
* @param base58_size the size of the results buffer
* @returns true(1) on success
*/
int multiaddr_encoding_base58_encode(const unsigned char* data, size_t binsz, unsigned char** b58, size_t* b58sz)
{
const uint8_t* bin = data;
int carry;
ssize_t i, j, high, zcount = 0;
size_t size;
while (zcount < (ssize_t)binsz && !bin[zcount]) {
++zcount;
}
size = (binsz - zcount) * 138 / 100 + 1;
uint8_t buf[size];
memset(buf, 0, size);
for (i = zcount, high = size - 1; i < (ssize_t)binsz; ++i, high = j) {
for (carry = bin[i], j = size - 1; (j > high) || carry; --j) {
carry += 256 * buf[j];
buf[j] = carry % 58;
carry /= 58;
}
}
for (j = 0; j < (ssize_t)size && !buf[j]; ++j)
;
if (*b58sz <= zcount + size - j) {
*b58sz = zcount + size - j + 1;
memset(buf, 0, size);
return 0;
}
if (zcount) {
memset(b58, '1', zcount);
}
for (i = zcount; j < (ssize_t)size; ++i, ++j) {
(*b58)[i] = b58digits_ordered[buf[j]];
}
(*b58)[i] = '\0';
*b58sz = i + 1;
memset(buf, 0, size);
return 1;
}
/***
* calculate the size of the binary results based on an incoming base58 string
* @param base58_string the string
* @returns the size in bytes had the string been decoded
*/
size_t multiaddr_encoding_base58_decode_size(const unsigned char* base58_string) {
size_t string_length = strlen((char*)base58_string);
size_t decoded_length = 0;
size_t radix = strlen(b58digits_ordered);
double bits_per_digit = log2(radix);
decoded_length = floor(string_length * bits_per_digit / 8);
return decoded_length;
}
/**
* calculate the max length in bytes of an encoding of n source bits
* @param base58_string the string
* @returns the maximum size in bytes had the string been decoded
*/
size_t multiaddr_encoding_base58_decode_max_size(const unsigned char* base58_string) {
size_t string_length = strlen((char*)base58_string);
size_t decoded_length = 0;
size_t radix = strlen(b58digits_ordered);
double bits_per_digit = log2(radix);
decoded_length = ceil(string_length * bits_per_digit / 8);
return decoded_length;
}

104
base58.h Normal file
View File

@ -0,0 +1,104 @@
#ifndef __BASE58_H__
#define __BASE58_H__
#include <stdio.h>
#include <string.h>
#define BASE58_DECODE_BASE 0
#define BASE58_ENCODE_BASE 0
#define BASE58_DECODE_OUT_OF_RANGE 1
void print_array(unsigned char* arr, int len){
int i = 0;
for (i=0; i<len; ++i){
printf("%02X ",arr[i]);
}
printf("\n");
}
static unsigned char alphabet[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
int base58Encode(const char* input,const unsigned int inLen,unsigned char *output,unsigned int outLen)
{
int i,j,tmp;
memset(output,0,outLen);
for(i=0;i<inLen;i++)
{
unsigned int c = input[i] & (0xff) ;
for(j=outLen-1;j>=0;j--)
{
tmp = output[j] * 256 + c;
c = tmp/58;
output[j] = tmp%58;
}
}
for(j=0; j<outLen; ++j)
{
output[j] = alphabet[output[j]];
}
return BASE58_ENCODE_BASE;
}
int base58Decode(const char* addr,const unsigned int addrLen,unsigned char *buf,unsigned int bufLen)
{
int i,j;
unsigned int tmp;
memset(buf,0,bufLen);
for(i=0;i<addrLen;i++)
{
unsigned int c = addr[i];
if (addr[i] < 58){ // Numbers
c -= 49;
}else if (addr[i] < 73){ // A-H
c -= 56;
}else if (addr[i] < 79){ // J-N
c -= 57;
}else if (addr[i] < 91){ // P-Z
c -= 58;
}else if (addr[i] < 108){ // a-k
c -= 64;
}else{ // m-z
c -= 65;
}
for(j=bufLen-1;j>=0;j--)
{
tmp = buf[j] * 58 + c;
c = (tmp & (~0xff)) >> 8;
buf[j] = tmp & (0xff);
}
}
return BASE58_DECODE_BASE;
}
#endif
/*int main()
{
//char addr[]="1NQEQ7fkCQQiVKDohBGuE3zSYs7xfDobbg";
char addr[]="Qmaa4Rw81a3a1VEx4LxB7HADUAXvZFhCoRdBzsMZyZmqHD";
//char addr[]="5R1";
//char addr[]="113YAvwi1V9WV9GEykK6XQ1UypmFPhVyh1";
const int addrLen = sizeof(addr)-1;
//char addr[]="115R";
//const int addrLen = 4;
const int bufLen = 40;
char buf[bufLen];
char addr2[addrLen];
memset(buf,0,bufLen);
printf("%s in Array[i] \BYTES AS HEX:", addr);
print_array(addr,addrLen);
printf("DECODED:");
base58Decode(addr, addrLen, buf, bufLen);
print_array(buf,bufLen);
printf("ENCODED:");
base58Encode(buf, bufLen, addr2, addrLen);
print_array(addr2,addrLen);
return 0;
}*/

View File

@ -1,39 +0,0 @@
#ifndef base58_h
#define base58_h
#include "varint.h"
/**
* convert a base58 encoded string into a binary array
* @param base58 the base58 encoded string
* @param base58_size the size of the encoded string
* @param binary_data the results buffer
* @param binary_data_size the size of the results buffer
* @returns true(1) on success
*/
int multiaddr_encoding_base58_decode(const char* base58, size_t base58_size, unsigned char** binary_data, size_t *binary_data_size);
/**
* encode an array of bytes into a base58 string
* @param binary_data the data to be encoded
* @param binary_data_size the size of the data to be encoded
* @param base58 the results buffer
* @param base58_size the size of the results buffer
* @returns true(1) on success
*/
int multiaddr_encoding_base58_encode(const unsigned char* binary_data, size_t binary_data_size, unsigned char** base58, size_t* base58_size);
/***
* calculate the size of the binary results based on an incoming base58 string with no initial padding
* @param base58_string the string
* @returns the size in bytes had the string been decoded
*/
size_t multiaddr_encoding_base58_decode_size(const unsigned char* base58_string);
/**
* calculate the max length in bytes of an encoding of n source bits
* @param base58_string the string
* @returns the maximum size in bytes had the string been decoded
*/
size_t multiaddr_encoding_base58_decode_max_size(const unsigned char* base58_string);
#endif /* base58_h */

View File

@ -1,106 +0,0 @@
#ifndef MULTIADDR
#define MULTIADDR
#include <string.h>
#include "varhexutils.h"
#include "varint.h"
#include "protocols.h"
#include "protoutils.h"
/**
* Normally, addresses have been represented using string addresses, like:
tcp4://127.0.0.1:1234
udp4://10.20.30.40:5060
ws://1.2.3.4:5678
tcp6://[1fff:0:a88:85a3::ac1f]:8001
This isn't optimal. Instead, addresses should be formatted so:
Binary format:
(varint proto><n byte addr>)+
<1 byte ipv4 code><4 byte ipv4 addr><1 byte udp code><2 byte udp port>
<1 byte ipv6 code><16 byte ipv6 addr><1 byte tcp code><2 byte tcp port>
String format:
(/<addr str code>/<addr str rep>)+
/ip4/<ipv4 str addr>/udp/<udp int port>
/ip6/<ipv6 str addr>/tcp/<tcp int port>
*/
struct MultiAddress
{
// A MultiAddress represented as a string
char* string;
// A MultiAddress represented as an array of bytes
//<varint proto><n byte addr><1 byte protocol code><4 byte ipv4 address or 16 byte ipv6 address><1 byte tcp/udp code><2 byte port>
uint8_t* bytes;
size_t bsize;
};
int strpos(char *haystack, char *needle);
struct MultiAddress* multiaddress_new_from_bytes(const uint8_t* byteaddress, int size); //Construct new address from bytes
struct MultiAddress* multiaddress_new_from_string(const char* straddress); //Construct new address from string
void multiaddress_free(struct MultiAddress* in);
struct MultiAddress* multiaddress_copy(const struct MultiAddress* source);
// helpers to parse the MultiAddress struct
int multiaddress_encapsulate(struct MultiAddress * result, char * string);
int multiaddress_decapsulate(struct MultiAddress * result, char * srci);
int multiaddress_is_ip(const struct MultiAddress* in);
int multiaddress_is_ip4(const struct MultiAddress* in);
int multiaddress_is_ip6(const struct MultiAddress* in);
int multiaddress_get_ip_family(const struct MultiAddress* in);
/***
* Pulls the textual representation of the IP address from a multihash
* @param in the multihash to parse
* @param ip where to put the ip address
* @returns true(1) on success, otherwise 0
*/
int multiaddress_get_ip_address(const struct MultiAddress* in, char** ip);
/***
* Pulls the IP port from a multiaddress
* @param in the multiaddress
* @param port where to put the port
* @returns the port, or a negative number for an error
*/
int multiaddress_get_ip_port(const struct MultiAddress* in);
/**
* Pulls the peer ID out of a multiaddress struct
* @param in the MultiAddress
* @returns the peer id string, or NULL NOTE: This allocates memory that needs to be freed
*/
char* multiaddress_get_peer_id(const struct MultiAddress* in);
/**
* Check to see how these two addresses compare
* @param a side A
* @param b side B
* @returns <0 if B > A; >0 if A > B; 0 if A == B
*/
int multiaddress_compare(const struct MultiAddress* a, const struct MultiAddress* b);
/**
* Check to see how these two addresses compare, ignoring IP address, only looking at ID hash
* @param a side A
* @param b side B
* @returns <0 if B > A; >0 if A > B; 0 if A == B
*/
int multiaddress_compare_id(const struct MultiAddress* a, const struct MultiAddress* b);
#endif

View File

@ -1,40 +0,0 @@
#ifndef PROTOCOLS
#define PROTOCOLS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "varhexutils.h"
struct Protocol
{
//char hexcode[21];
int deccode;
int size;
char name[30];
};
struct ProtocolListItem {
struct Protocol* current;
struct ProtocolListItem* next;
};
int protocol_REMOVE_id(struct ProtocolListItem* head, int remid); //Function to remove & shift back all data, sort of like c++ vectors.
void unload_protocols(struct ProtocolListItem* head);
/**
* load the available protocols into the global protocol_P
* @returns True(1) on success, otherwise 0
*/
int load_protocols(struct ProtocolListItem** head);
struct Protocol * proto_with_name(const struct ProtocolListItem* head, const char* proto_w_name); //Search for protocol with inputted name
struct Protocol * proto_with_deccode(const struct ProtocolListItem* head, int proto_w_deccode); //Search for protocol with inputted deccode
void protocols_with_string(const struct ProtocolListItem* head, char * meee, int sizi); // NOT FINISHED, DO NOT USE!
#endif

View File

@ -1,55 +0,0 @@
#ifndef PROTOUTILS
#define PROTOUTILS
//////////////////////////////////////////////////////////
char ASCII2bits(char ch);
void hex2bin (char *dst, char *src, int len);
char bits2ASCII(char b);
void bin2hex (char *dst, char *src, int len);
//////////////////////////////////////////////////////////
//IPv4 VALIDATOR
#define DELIM "."
/* return 1 if string contain only digits, else return 0 */
int valid_digit(char *ip_str);
/* return 1 if IP string is valid, else return 0 */
int is_valid_ipv4(char *ip_str);
//////////////IPv6 Validator
#define MAX_HEX_NUMBER_COUNT 8
int ishexdigit(char ch);
int is_valid_ipv6(char *str);
uint64_t ip2int(const char * ipconvertint);
char * int2ip(int inputintip);
/**
* Unserialize the bytes into a string
* @param results where to put the resultant string
* @param bytes the bytes to unserialize
* @param bytes_size the length of the bytes array
*/
int bytes_to_string(char** results, const uint8_t* bytes, int bytes_size);
/**
* Convert an address string to a byte representation
* @param protocol the protocol to use
* @param incoming the byte array
* @param incoming_size the size of the byte array
* @param results the results
* @param results_size the size of the results
* @returns the results array
*/
char * address_string_to_bytes(struct Protocol *protocol, const char *incoming, size_t incoming_size, char** results, int *results_size);
int string_to_bytes(uint8_t** finalbytes,size_t* realbbsize, const char * strx, size_t strsize);
#endif

View File

@ -1,60 +0,0 @@
#ifndef VARHEXUTILS
#define VARHEXUTILS
#include <stdio.h>
#include <inttypes.h>
#include "varint.h"
#include <stdlib.h>
#include <string.h>
#include "endian.h"
/*uint8_t * encode_big_endian_32(uint32_t ebex32)
{
uint8_t encbe[10] = {0};
memcpy(encbe, htobe32(ebex32));
return encbe;
}*/
int8_t Var_Bytes_Count(uint8_t * countbytesofthis);
uint8_t * Num_To_Varint_64(uint64_t TOV64INPUT); //UINT64_T TO VARINT
uint8_t * Num_To_Varint_32(uint32_t TOV32INPUT); // UINT32_T TO VARINT
uint64_t * Varint_To_Num_64(uint8_t TON64INPUT[60]); //VARINT TO UINT64_t
uint32_t * Varint_To_Num_32(uint8_t TON32INPUT[60]); //VARINT TO UINT32_t
//
char * Int_To_Hex(uint64_t int2hex); //VAR[binformat] TO HEX
uint64_t Hex_To_Int(char * hax);
/**
* Convert binary array to array of hex values
* @param incoming the binary array
* @param incoming_size the size of the incoming array
* @returns the allocated array
*/
unsigned char *Var_To_Hex(const char *incoming, int incoming_size);
/**
* Turn a hex string into a byte array
* @param incoming a string of hex values
* @param num_bytes the size of the result
* @returns a pointer to the converted value
*/
unsigned char* Hex_To_Var(char * Hexstr, size_t* num_bytes);
//
void convert(char * convert_result, uint8_t * buf); //Both of them read them properly.
char * Num_To_HexVar_64(uint64_t TOHVINPUT); //UINT64 TO HEXIFIED VAR
void convert2(char * convert_result2, uint8_t * bufhx);
char * Num_To_HexVar_32(uint32_t TOHVINPUT); //UINT32 TO HEXIFIED VAR
uint64_t HexVar_To_Num_64(char * theHEXstring); //HEXIFIED VAR TO UINT64_T
uint32_t HexVar_To_Num_32(char theHEXstring[]); //HEXIFIED VAR TO UINT32_T
#endif

View File

@ -1,397 +0,0 @@
#include <string.h>
#include <sys/socket.h>
#include "multiaddr/varhexutils.h"
#include "multiaddr/varint.h"
#include "multiaddr/protocols.h"
#include "multiaddr/protoutils.h"
#include "multiaddr/multiaddr.h"
int strpos(char *haystack, char *needle)
{
char *p = strstr(haystack, needle);
if (p)
{
return p - haystack;
}
else
{
return -1; // Not found = -1.
}
}
/**
* Construct a new MultiAddress struct
* @returns an empty MultiAddress struct
*/
struct MultiAddress* multiaddress_new() {
struct MultiAddress* out = (struct MultiAddress*)malloc(sizeof(struct MultiAddress));
if (out != NULL) {
out->bsize = 0;
out->bytes = NULL;
out->string = NULL;
}
return out;
}
/**
* construct a new MultiAddress from bytes
* @param byteaddress the byte array
* @param size the size of the byte array
* @returns a new MultiAddress struct filled in, or NULL on error
*/
struct MultiAddress* multiaddress_new_from_bytes(const uint8_t* byteaddress, int size)//Construct new address from bytes
{
struct MultiAddress* out = multiaddress_new();
if (out != NULL) {
if(byteaddress!=NULL)
{
out->bytes = malloc(size);
if (out->bytes == NULL) {
multiaddress_free(out);
return NULL;
}
out->bsize = size;
memcpy(out->bytes, byteaddress, size);
if(!bytes_to_string(&out->string,byteaddress,size))
{
multiaddress_free(out);
return NULL;
}
} else {
multiaddress_free(out);
return NULL;
}
}
return out;
}
struct MultiAddress* multiaddress_new_from_string(const char* straddress)//Construct new address from string
{
struct MultiAddress* out = multiaddress_new();
if (out != NULL) {
out->string = malloc(strlen(straddress) + 1);
if (out->string == NULL) {
multiaddress_free(out);
return NULL;
}
strcpy(out->string, straddress);
if (string_to_bytes(&(out->bytes), &out->bsize, out->string, strlen(out->string)) == 0 )
{
multiaddress_free(out);
return NULL;
}
}
return out;
}
int multiaddress_is_ip(const struct MultiAddress* in) {
if (in->bytes > 0) {
int byte = in->bytes[0];
if (byte == 4 || byte == 41)
return 1;
}
return 0;
}
int multiaddress_is_ip4(const struct MultiAddress* in) {
return in->bytes[0] == 4;
}
int multiaddress_is_ip6(const struct MultiAddress* in) {
return in->bytes[0] == 41;
}
int multiaddress_get_ip_family(const struct MultiAddress* in) {
if (in->bytes[0] == 4)
return AF_INET;
if (in->bytes[0] == 41)
return AF_INET6;
return 0;
}
/***
* Pulls the textual representation of the IP address from a multihash
* @param in the multihash to parse
* @param ip where to put the ip address
* @returns true(1) on success, otherwise 0
*/
int multiaddress_get_ip_address(const struct MultiAddress* in, char** ip) {
// the incoming address is not what was expected
if (strncmp(in->string, "/ip4/", 5) != 0 && strncmp(in->string, "/ip6/", 5) != 0)
return 0;
if (strstr(in->string, "/tcp/") == NULL && strstr(in->string, "/udp/") == NULL)
return 0;
// ip
char* str = malloc(strlen(in->string));
if (str == NULL)
return 0;
strcpy(str, &in->string[5]); // gets rid of /ip4/
char* pos = strchr(str, '/');
pos[0] = 0;
*ip = malloc(strlen(str) + 1);
strcpy(*ip, str);
free(str);
return 1;
}
/***
* Pulls the IP port from a multiaddress
* @param in the multiaddress
* @param port where to put the port
* @returns the port, or a negative number for an error
*/
int multiaddress_get_ip_port(const struct MultiAddress* in) {
char* ptr = strstr(in->string, "/tcp/");
if (ptr == NULL)
ptr = strstr(in->string, "/udp/");
if (ptr == NULL)
return -1;
ptr += 5;
char* end_ptr = strstr(ptr, "/");
if (end_ptr == NULL) {
return atoi(ptr);
}
char str[end_ptr - ptr + 1];
memcpy(str, ptr, end_ptr - ptr);
str[end_ptr-ptr] = '\0';
return atoi(str);
}
char* multiaddress_get_peer_id(const struct MultiAddress* in) {
char* result = NULL;
int str_len = 0;
char* slash = NULL;
char* ptr = NULL;
ptr = strstr(in->string, "/ipfs/");
if (ptr != NULL && ptr[6] != 0) {
ptr += 6;
str_len = strlen(ptr);
slash = strchr(ptr, '/');
if (slash != NULL) {
str_len = slash - ptr;
}
if (str_len > 0) {
result = malloc(str_len + 1);
if (result != NULL) {
memset(result, 0, str_len + 1);
memcpy(result, ptr, str_len);
}
}
}
return result;
}
void multiaddress_free(struct MultiAddress* in) {
if (in != NULL) {
if (in->bytes != NULL)
free(in->bytes);
if (in->string != NULL)
free(in->string);
free(in);
in = NULL;
}
}
/**
* Copy a multiaddress from one memory location to another
* @param in the source
* @returns the new struct MultiAddress or NULL if there was a problem (i.e. out of memory)
*/
struct MultiAddress* multiaddress_copy(const struct MultiAddress* in) {
struct MultiAddress* out = NULL;
if (in != NULL) {
out = (struct MultiAddress*)malloc(sizeof(struct MultiAddress));
if (out != NULL) {
if (in->bsize > 0) {
out->bytes = malloc(in->bsize);
if (out->bytes == NULL) {
free(out);
return NULL;
}
out->bsize = in->bsize;
memcpy(out->bytes, in->bytes, out->bsize);
} // bytes need to be copied
if (in->string != NULL) {
out->string = malloc(strlen(in->string) + 1);
if (out->string == NULL) {
if (out->bsize > 0)
free(out->bytes);
free(out);
return NULL;
}
strcpy(out->string, in->string);
} // string needs to be copied
} // structure allocated
} // good parameters
return out;
}
/**
* Put a string into the MultiAddress and recalculate the bytes
* @param result the struct
* @param string the new string
*/
int multiaddress_encapsulate(struct MultiAddress* result, char* string)
{
if(result != NULL && string != NULL)
{
// remove the old values
if (result->bytes != NULL)
free(result->bytes);
result->bytes = NULL;
result->bsize = 0;
char * exstr;
if(string[0] == '/')
{
exstr = (char *) malloc(strlen(result->string)+1);
}
else
{
exstr = (char *) malloc(strlen(result->string));
}
strcpy(exstr, result->string);
free(result->string);
// insert the new values
result->string = malloc(strlen(string) + strlen(exstr) + 1);
if (result->string == NULL) {
multiaddress_free(result);
return 0;
}
strcpy(result->string, exstr);
free(exstr);
if(string[0] == '/')
{
strcat(result->string, string+1);
}
else
{
strcat(result->string, string);
}
if(string_to_bytes(&result->bytes, &result->bsize, result->string, strlen(result->string)+1) == 0)
{
multiaddress_free(result);
return 0;
}
} else {
return 0;
}
return 1;
}
/**
* Find scri and remove it from the resultant value
* (ie /ip4/127.0.0.1/tcp/4001 becomes ip4/127.0.0.1 when you call decapsulate(addr, "/tcp")
* @param result the address to work with
* @param srci the string to look for
*/
int multiaddress_decapsulate(struct MultiAddress * result, char * srci)
{
if(result!=NULL && srci!=NULL)
{
char * procstr = NULL;
procstr = result->string;
int i=0;
int sz=strlen(procstr);
char * src = NULL;
src=srci;
// change slash to space
for(i=0;i<sz;i++)
{
if(procstr[i] == '/')
{
procstr[i]=' ';
}
}
int pos=-1;
pos=strpos(procstr,src);
if(pos!=-1)
{
// fill rest with 0s
for(i=pos;i<sz;i++)
{
procstr[i] = '\0';
}
// replace space with slash
for(i=0;i<sz;i++)
{
if(procstr[i] == ' ')
{
procstr[i] = '/';
}
}
//Bytes update
if (result->bytes != NULL)
free(result->bytes);
result->bytes = NULL;
result->bsize = 0;
if(string_to_bytes(&result->bytes, &result->bsize, result->string, strlen(result->string)+1) == 0)
{
multiaddress_free(result);
return 0;
}
return 1;
}
else
{
return 0;
}
return 0;
}
else
{
return 0;
}
}
/**
* Check to see how these two addresses compare
* @param a side A
* @param b side B
* @returns <0 if B > A; >0 if A > B; 0 if A == B
*/
int multiaddress_compare(const struct MultiAddress* a, const struct MultiAddress* b) {
if (a == NULL && b == NULL)
return 0;
if (a == NULL && b != NULL)
return -1;
if (a != NULL && b == NULL)
return 1;
int total = b->bsize - a->bsize;
if (total != 0)
return total;
for(size_t i = 0; i < b->bsize; i++) {
total = b->bytes[i] - a->bytes[i];
if (total != 0)
return total;
}
return 0;
}
/**
* Check to see how these two addresses compare, ignoring IP address,
* only looking at the first /ipfs/ID hash
* @param a side A
* @param b side B
* @returns <0 if B > A; >0 if A > B; 0 if A == B
*/
int multiaddress_compare_id(const struct MultiAddress* a, const struct MultiAddress* b) {
char* a_id = multiaddress_get_peer_id(a);
char* b_id = multiaddress_get_peer_id(b);
if (a_id == NULL && b_id == NULL)
return 0;
if (a_id == NULL && b_id != NULL)
return -1;
if (a_id != NULL && b_id == NULL)
return 1;
int retVal = strcmp(a_id, b_id);
if (a_id != NULL)
free(a_id);
if (b_id != NULL)
free(b_id);
return retVal;
}

View File

@ -1,15 +1,15 @@
hex-code dec-code size name
04 4 32 ip4
29 41 128 ip6
06 6 16 tcp
11 17 16 udp
21 33 16 dccp
84 132 16 sctp
12D 301 0 udt
12E 302 0 utp
2A 42 -1 ipfs
1E0 480 0 http
1BB 443 0 https
1DD 477 0 ws
1BC 444 10 onion
113 275 0 libp2p-webrtc-star
hex-code dec-code size name
84000000000000000000 4 32 ip4
A9000000000000000000 41 128 ip6
86000000000000000000 6 16 tcp
91000000000000000000 17 16 udp
A1000000000000000000 33 16 dccp
84810000000000000000 132 16 sctp
AD820000000000000000 301 0 udt
AE820000000000000000 302 0 utp
AA000000000000000000 42 -1 ipfs
E0830000000000000000 480 0 http
BB830000000000000000 443 0 https
DD830000000000000000 477 0 ws
BC830000000000000000 444 10 onion
93820000000000000000 275 0 libp2p-webrtc-star

View File

@ -1,28 +1,35 @@
#ifndef PROTOCOLS
#define PROTOCOLS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <errno.h>
#include "multiaddr/protocols.h"
#include "multiaddr/varhexutils.h"
/*
int protocol_REMOVE_id(struct ProtocolListItem* protocol_P, int remid)//Function to remove & shift back all data, sort of like c++ vectors.
#include "varhexutils.h"
int CNT_PROTOCOLNUM=0;
struct protocol
{
char hexcode[21];
int deccode;
int size;
char name[30];
};
struct protocol *protocol_P; //Pointer for holding multiple structures
int protocol_REMOVE_id(int remid)//Function to remove & shift back all data, sort of like c++ vectors.
{
if(remid < CNT_PROTOCOLNUM && remid >= 0&&CNT_PROTOCOLNUM!=0) //Checking to see if remid actually exists.
{
for(int i=remid; i<CNT_PROTOCOLNUM-1; ++i) //While i < num of registered protocols //Needs to be tested that -1 is for valgrind debugging
for(int i=remid; i<CNT_PROTOCOLNUM; ++i) //While i < num of registered protocols
{
//strcpy((protocol_P+i)->hexcode, (protocol_P+i+1)->hexcode); //shift memory to the user we want to remove.
strcpy((protocol_P+i)->hexcode, (protocol_P+i+1)->hexcode); //shift memory to the user we want to remove.
(protocol_P+i)->deccode = (protocol_P+i+1)->deccode; //Same as above
(protocol_P+i)->size = (protocol_P+i+1)->size; //Same as above
strcpy((protocol_P+i)->name, (protocol_P+i+1)->name); //Same as above
}//Overwriting user done. Time to get rid of that extra memory.
protocol_P = (struct Protocol*) realloc(protocol_P, (CNT_PROTOCOLNUM-1) * sizeof(struct Protocol));
//Memory erased,
protocol_P = (struct protocol*) realloc(protocol_P, (CNT_PROTOCOLNUM-1) * sizeof(struct protocol));
//Memory erased,
CNT_PROTOCOLNUM--; //Since the record no longer exists, we should decrease the ammount of users.
return 1; //Purely for error checking, in case someone ever wants it/
} //1 = Success
@ -39,52 +46,12 @@ int protocol_REMOVE_id(struct ProtocolListItem* protocol_P, int remid)//Function
return 0;
}
}
*/
void unload_protocols(struct ProtocolListItem* head)
void unload_protocols()
{
struct ProtocolListItem* current = head;
while (current != NULL) {
struct ProtocolListItem* next = current->next;
free(current->current);
free(current);
current = next;
}
free(protocol_P);
}
/**
* load the available protocols into the global protocol_P
* @returns True(1) on success, otherwise 0
*/
int load_protocols(struct ProtocolListItem** head)
void load_protocols()
{
unload_protocols(*head);
int num_protocols = 14;
int dec_code[] = {4, 41, 6, 17, 33, 132, 301, 302, 42, 480, 443, 477, 444, 275};
int size[] = {32, 128, 16, 16, 16, 16, 0, 0, -1, 0, 0, 0, 10, 0 };
char* name[] = { "ip4", "ip6", "tcp", "udp", "dccp", "sctp", "udt", "utp", "ipfs", "http", "https", "ws", "onion", "libp2p-webrtc-star" };
struct ProtocolListItem* last = NULL;
for(int i = 0; i < num_protocols; i++) {
struct ProtocolListItem* current_item = (struct ProtocolListItem*)malloc(sizeof(struct ProtocolListItem));
current_item->current = (struct Protocol*)malloc(sizeof(struct Protocol));
current_item->next = NULL;
current_item->current->deccode = dec_code[i];
strcpy(current_item->current->name, name[i]);
current_item->current->size = size[i];
if (*head == NULL) {
*head = current_item;
} else {
last->next = current_item;
}
last = current_item;
}
return 1;
}
/*
void load_protocols_from_file(struct Protocol** in)
{
struct Protocol* protocol_P = *in;
FILE *FPROC_POINT; //File pointer.
FPROC_POINT = fopen("proto-dat", "r");//Opening proto-dat Or protocols.csv, I just formatted it to my liking.
if(FPROC_POINT != NULL) //While pointer is not null.
@ -99,13 +66,13 @@ void load_protocols_from_file(struct Protocol** in)
//ADD MEMORY FOR NEW PROTOCOL
if(CNT_PROTOCOLNUM==0) //If there are no registered protocols yet, allocate memory to pointer.
{
protocol_P = (struct Protocol*) malloc (sizeof(struct Protocol));
protocol_P = (struct protocol*) malloc (sizeof(struct protocol));
}
else //Reallocate memory to fit one more Protocol
else //Reallocate memory to fit one more protocol
{
protocol_P = (struct Protocol*) realloc(protocol_P, (CNT_PROTOCOLNUM+1) * sizeof(struct protocol));
protocol_P = (struct protocol*) realloc(protocol_P, (CNT_PROTOCOLNUM+1) * sizeof(struct protocol));
}
//strcpy((protocol_P+CNT_PROTOCOLNUM)->hexcode, W_BUFF); //Copy word to structure at hexcode A hexcode is a string so we keep it as such
strcpy((protocol_P+CNT_PROTOCOLNUM)->hexcode, W_BUFF); //Copy word to structure at hexcode A hexcode is a string so we keep it as such
break;
}
case 1://Second word - DECCODE
@ -133,42 +100,52 @@ void load_protocols_from_file(struct Protocol** in)
}
}
fclose(FPROC_POINT);
protocol_REMOVE_id(protocol_P, 0);
protocol_REMOVE_id(0);
}
else
{
perror("Fatal Error:");
}
}
*/
struct Protocol* proto_with_name(const struct ProtocolListItem* head, const char* proto_w_name) //Search for Protocol with inputted name
struct protocol * proto_with_name(char proto_w_name[]) //Search for protocol with inputted name
{
const struct ProtocolListItem* current = head;
while(current != NULL)
for(int i=0; i<CNT_PROTOCOLNUM; i++)
{
if (strcmp(proto_w_name, current->current->name) == 0) {
return current->current;
if(strcmp(proto_w_name, (protocol_P+i)->name) == 0)
{
return (protocol_P+i);
}
current = current->next;
}
return NULL;
}
struct Protocol* proto_with_deccode(const struct ProtocolListItem* head, int proto_w_deccode) //Search for Protocol with inputted deccode
struct protocol * proto_with_deccode(int proto_w_deccode) //Search for protocol with inputted deccode
{
const struct ProtocolListItem* current = head;
while(current != NULL)
for(int i=0; i<CNT_PROTOCOLNUM; i++)
{
if (current->current->deccode == proto_w_deccode) {
return current->current;
if((protocol_P+i)->deccode == proto_w_deccode)
{
return (protocol_P+i);
}
current = current->next;
}
return NULL;
}
void protocols_with_string(const struct ProtocolListItem* head, char* meee, int sizi) // NOT FINISHED, DO NOT USE!
void pp() //Purely for debugging purposes, prints the entire loaded protocols.
{
for(int i=0;i<CNT_PROTOCOLNUM;i++)
{
if(i>=9)
{printf("=========== ~%d~ ===========\n", i+1);}
else
{printf("=========== ~0%d~ ===========\n", i+1);}
printf(">> HEX-CODE: %s\n", (protocol_P+i)->hexcode);
printf(">> DEC-CODE: %d\n", (protocol_P+i)->deccode);
printf(">> SIZE: %d\n", (protocol_P+i)->size);
printf(">> NAME: %s\n", (protocol_P+i)->name);
}
printf("----------------------------\n");
printf("TOTAL PROTOCOLS: %d\n",CNT_PROTOCOLNUM);
}
void protocols_with_string(char * meee,int sizi) // NOT FINISHED, DO NOT USE!
{
int finalsize = 0;
@ -188,7 +165,7 @@ void protocols_with_string(const struct ProtocolListItem* head, char* meee, int
{
strcpy(mestring,"\0");
}
char * words[50] = { NULL };
int atword = 0;
int mem = 0;
@ -228,3 +205,4 @@ void protocols_with_string(const struct ProtocolListItem* head, char* meee, int
}
}
}
#endif

View File

@ -1,717 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <math.h>
#include <inttypes.h>
#include <ctype.h>
#include "multiaddr/base58.h"
#include "multiaddr/varhexutils.h"
#include "multiaddr/protocols.h"
#include "multiaddr/protoutils.h"
extern char *strtok_r(char *, const char *, char **);
//////////////////////////////////////////////////////////
char ASCII2bits(char ch) {
if (ch >= '0' && ch <= '9') {
return (ch - '0');
} else if (ch >= 'a' && ch <= 'z') {
return (ch - 'a') + 10;
} else if (ch >= 'A' && ch <= 'Z') {
return (ch - 'A') + 10;
}
return 0; // fail
}
void hex2bin (char *dst, char *src, int len)
{
while (len--) {
*dst = ASCII2bits(*src++) << 4; // higher bits
*dst++ |= ASCII2bits(*src++); // lower bits
}
}
char bits2ASCII(char b) {
if (b >= 0 && b < 10) {
return (b + '0');
} else if (b >= 10 && b <= 15) {
return (b - 10 + 'a');
}
return 0; // fail
}
void bin2hex (char *dst, char *src, int len)
{
while (len--) {
*dst++ = bits2ASCII((*src >> 4) & 0xf); // higher bits
*dst++ = bits2ASCII(*src++ & 0xf); // lower bits
}
*dst = '\0';
}
//////////////////////////////////////////////////////////
//IPv4 VALIDATOR
#define DELIM "."
/* return 1 if string contain only digits, else return 0 */
int valid_digit(char *ip_str)
{
int err = 0;
while (*ip_str) {
if (*ip_str >= '0' && *ip_str <= '9')
++ip_str;
else
return 0;
}
return 1;
}
/* return 1 if IP string is valid, else return 0 */
int is_valid_ipv4(char *ip_str)
{
int i, num, dots = 0;
char *ptr;
int err=0;
if (ip_str == NULL)
err = 1;
// See following link for strtok()
// http://pubs.opengroup.org/onlinepubs/009695399/functions/strtok_r.html
ptr = strtok(ip_str, DELIM);
if (ptr == NULL)
err = 1;
while (ptr)
{
/* after parsing string, it must contain only digits */
if (!valid_digit(ptr))
err = 1;
num = atoi(ptr);
/* check for valid IP */
if (num >= 0 && num <= 255) {
/* parse remaining string */
ptr = strtok(NULL, DELIM);
if (ptr != NULL)
++dots;
} else
err = 1;
}
/* valid IP string must contain 3 dots */
if (dots != 3)
{
err = 1;
}
if(err == 0)
{
return 1;
}
else
{
return 0;
}
}
//////////////IPv6 Validator
#define MAX_HEX_NUMBER_COUNT 8
int ishexdigit(char ch)
{
if((ch>='0'&&ch<='9')||(ch>='a'&&ch<='f')||(ch>='A'&&ch<='F'))
return(1);
return(0);
}
int is_valid_ipv6(char *str)
{
int hdcount=0;
int hncount=0;
int err=0;
int packed=0;
if(*str==':')
{
str++;
if(*str!=':')
return(0);
else
{
packed=1;
hncount=1;
str++;
if(*str==0)
return(1);
}
}
if(ishexdigit(*str)==0)
{
return(0);
}
hdcount=1;
hncount=1;
str++;
while(err==0&&*str!=0)
{
if(*str==':')
{
str++;
if(*str==':')
{
if(packed==1)
err=1;
else
{
str++;
if(ishexdigit(*str) || (*str==0 && hncount < MAX_HEX_NUMBER_COUNT ))
{
packed=1;
hncount++;
if(ishexdigit(*str))
{
if(hncount==MAX_HEX_NUMBER_COUNT)
{
err=1;
} else
{
hdcount=1;
hncount++;
str++;
}
}
} else
{
err=1;
}
}
}
else
{
if(!ishexdigit(*str))
{
err=1;
} else
{
if(hncount==MAX_HEX_NUMBER_COUNT)
{
err=1;
} else
{
hdcount=1;
hncount++;
str++;
}
}
}
}
else
{
if(ishexdigit(*str))
{
if(hdcount==4)
err=1;
else
{
hdcount++;
str++;
}
} else
err=1;
}
}
if(hncount<MAX_HEX_NUMBER_COUNT&&packed==0)
err=1;
return(err==0);
}
uint64_t ip2int(const char * ipconvertint)
{
uint64_t final_result =0;
char * iproc;
int ipat1=0;
int ipat2=0;
int ipat3=0;
int ipat4=0;
char ip[16];
strcpy(ip, ipconvertint);
iproc = strtok (ip,".");
for(int i=0; i<4;i++)
{
switch(i)
{
case 0:
{
ipat1 = atoi(iproc);
break;
}
case 1:
{
ipat2 = atoi(iproc);
break;
}
case 2:
{
ipat3 = atoi(iproc);
break;
}
case 3:
{
ipat4 = atoi(iproc);
break;
}
default:
{
printf("Somebody misplaced an int\n");
break;
}
}
iproc = strtok (NULL,".");
}
final_result = ((ipat1*pow(2,24))+(ipat2*pow(2,16))+(ipat3*pow(2,8))+ipat4*1);
return final_result;
}
char * int2ip(int inputintip)
{
uint32_t ipint = inputintip;
static char xxx_int2ip_result[16] = "\0";
bzero(xxx_int2ip_result,16);
uint32_t ipint0 = (ipint >> 8*3) % 256;
uint32_t ipint1 = (ipint >> 8*2) % 256;
uint32_t ipint2 = (ipint >> 8*1) % 256;
uint32_t ipint3 = (ipint >> 8*0) % 256;
sprintf(xxx_int2ip_result, "%d.%d.%d.%d", ipint0,ipint1,ipint2,ipint3);
return xxx_int2ip_result;
}
/**
* Unserialize the bytes into a string
* @param results where to put the resultant string
* @param in_bytes the bytes to unserialize
* @param in_bytes_size the length of the bytes array
* @returns 0 on error, otherwise 1
*/
int bytes_to_string(char** buffer, const uint8_t* in_bytes, int in_bytes_size)
{
uint8_t * bytes = NULL;
char *results = NULL;
int size = in_bytes_size;
struct ProtocolListItem* head = NULL;
char hex[(in_bytes_size*2)+1];
//Positioning for memory jump:
int lastpos = 0;
char pid[3];
// set up variables
load_protocols(&head);
memset(hex, 0, (in_bytes_size * 2) + 1);
char* tmp = (char*)Var_To_Hex((char*)in_bytes, size);
memcpy(hex, tmp, in_bytes_size * 2);
free(tmp);
pid[2] = 0;
// allocate memory for results
*buffer = malloc(800);
results = *buffer;
memset(results, 0, 800);
//Process Hex String
NAX:
//Stage 1 ID:
pid[0] = hex[lastpos];
pid[1] = hex[lastpos+1];
int protocol_int = Hex_To_Int(pid);
struct Protocol* protocol = proto_with_deccode(head, protocol_int);
if(protocol != NULL)
{
//////////Stage 2: Address
if(strcmp(protocol->name,"ipfs")!=0)
{
lastpos = lastpos+2;
char address[(protocol->size/4)+1];
memset(address, 0, (protocol->size / 4) + 1);
memcpy(address, &hex[lastpos], protocol->size / 4);
//////////Stage 3 Process it back to string
lastpos= lastpos+(protocol->size/4);
//////////Address:
//Keeping Valgrind happy
char name[30];
bzero(name,30);
strcpy(name, protocol->name);
//
strcat(results, "/");
strcat(results, name);
strcat(results, "/");
if(strcmp(name, "ip4")==0)
{
strcat(results,int2ip(Hex_To_Int(address)));
}
else if(strcmp(name, "tcp")==0)
{
char a[5];
sprintf(a,"%lu",Hex_To_Int(address));
strcat(results,a);
}
else if(strcmp(name, "udp")==0)
{
char a[5];
sprintf(a,"%lu",Hex_To_Int(address));
strcat(results,a);
}
/////////////Done processing this, move to next if there is more.
if(lastpos<size*2)
{
goto NAX;
}
}
else//IPFS CASE
{
lastpos = lastpos + 4;
//fetch the size of the address based on the varint prefix
char prefixedvarint[3];
memset(prefixedvarint, 0, 3);
memcpy(prefixedvarint, &hex[lastpos-2], 2);
int addrsize = HexVar_To_Num_32(prefixedvarint);
// get the ipfs address as hex values
unsigned char IPFS_ADDR[addrsize+1];
memset(IPFS_ADDR, 0, addrsize + 1);
memcpy(IPFS_ADDR, &hex[lastpos], addrsize);
// convert the address from hex values to a binary array
size_t num_bytes = 0;
unsigned char* addrbuf = Hex_To_Var((char*)IPFS_ADDR, &num_bytes);
size_t b58_size = strlen((char*)IPFS_ADDR);
unsigned char b58[b58_size];
memset(b58, 0, b58_size);
unsigned char *ptr_b58 = b58;
int returnstatus = multiaddr_encoding_base58_encode(addrbuf, num_bytes, &ptr_b58, &b58_size);
free(addrbuf);
if(returnstatus == 0)
{
fprintf(stderr, "Unable to base58 encode MultiAddress %s\n", IPFS_ADDR);
unload_protocols(head);
return 0;
}
strcat(results, "/");
strcat(results, protocol->name);
strcat(results, "/");
strcat(results, (char*)b58);
}
}
strcat(results, "/");
unload_protocols(head);
return 1;
}
//
/**
* Convert an address string to a byte representation
* @param protocol the protocol to use
* @param incoming the byte array
* @param incoming_size the size of the byte array
* @param results the results
* @param results_size the size of the results
* @returns the results array
*/
char* address_string_to_bytes(struct Protocol * protocol, const char *incoming, size_t incoming_size, char** results, int* results_size)
{
static char astb__stringy[800] = "\0";
memset(astb__stringy, 0, 800);
int code = 0;
code = protocol->deccode;
switch(code)
{
case 4://IPv4
{
char testip[16] = "\0";
bzero(testip,16);
strcpy(testip,incoming);
if(is_valid_ipv4(testip)==1)
{
uint64_t iip = ip2int(incoming);
strcpy(astb__stringy,Int_To_Hex(iip));
protocol = NULL;
*results = malloc(strlen(astb__stringy));
memcpy(*results, astb__stringy, strlen(astb__stringy));
*results_size = strlen(astb__stringy);
return *results;
}
else
{
return "ERR";
}
break;
}
case 41://IPv6 Must be done
{
return "ERR";
break;
}
case 6: //Tcp
{
if(atoi(incoming)<65536&&atoi(incoming)>0)
{
static char himm_woot[5] = "\0";
bzero(himm_woot, 5);
strcpy(himm_woot, Int_To_Hex(atoi(incoming)));
if(himm_woot[2] == '\0')
{//manual switch
char swap0='0';
char swap1='0';
char swap2=himm_woot[0];
char swap3=himm_woot[1];
himm_woot[0] = swap0;
himm_woot[1] = swap1;
himm_woot[2] = swap2;
himm_woot[3] = swap3;
}
else if(himm_woot[3] == '\0')
{
char swap0='0';
char swap1=himm_woot[0];
char swap2=himm_woot[1];
char swap3=himm_woot[2];
himm_woot[0] = swap0;
himm_woot[1] = swap1;
himm_woot[2] = swap2;
himm_woot[3] = swap3;
}
himm_woot[4]='\0';
*results = malloc(5);
*results_size = 5;
memcpy(*results, himm_woot, 5);
return *results;
}
else
{
return "ERR";
}
break;
}
case 17: //Udp
{
if(atoi(incoming)<65536&&atoi(incoming)>0)
{
static char himm_woot2[5] = "\0";
bzero(himm_woot2, 5);
strcpy(himm_woot2, Int_To_Hex(atoi(incoming)));
if(himm_woot2[2] == '\0')
{//Manual Switch2be
char swap0='0';
char swap1='0';
char swap2=himm_woot2[0];
char swap3=himm_woot2[1];
himm_woot2[0] = swap0;
himm_woot2[1] = swap1;
himm_woot2[2] = swap2;
himm_woot2[3] = swap3;
}
else if(himm_woot2[3] == '\0')
{//Manual switch
char swap0='0';
char swap1=himm_woot2[0];
char swap2=himm_woot2[1];
char swap3=himm_woot2[2];
himm_woot2[0] = swap0;
himm_woot2[1] = swap1;
himm_woot2[2] = swap2;
himm_woot2[3] = swap3;
}
himm_woot2[4]='\0';
*results = malloc(5);
*results_size = 5;
memcpy(*results, himm_woot2, 5);
return *results;
}
else
{
return "ERR";
}
break;
}
case 33://dccp
{
return "ERR";
}
case 132://sctp
{
return "ERR";
}
case 301://udt
{
return "ERR";
}
case 302://utp
{
return "ERR";
}
case 42://IPFS - !!!
{
// decode the base58 to bytes
char * incoming_copy = NULL;
incoming_copy = (char*)incoming;
size_t incoming_copy_size = strlen(incoming_copy);
size_t result_buffer_length = multiaddr_encoding_base58_decode_max_size((unsigned char*)incoming_copy);
unsigned char result_buffer[result_buffer_length];
unsigned char* ptr_to_result = result_buffer;
memset(result_buffer, 0, result_buffer_length);
// now get the decoded address
int return_value = multiaddr_encoding_base58_decode(incoming_copy, incoming_copy_size, &ptr_to_result, &result_buffer_length);
if (return_value == 0)
{
return "ERR";
}
// throw everything in a hex string so we can debug the results
char addr_encoded[300];
memset(addr_encoded, 0, 300);
int ilen = 0;
for(int i = 0; i < result_buffer_length; i++)
{
// get the char so we can see it in the debugger
char miu[3];
sprintf(miu,"%02x", ptr_to_result[i]);
strcat(addr_encoded, miu);
}
ilen = strlen(addr_encoded);
char prefixed[3];
memset(prefixed, 0, 3);
strcpy(prefixed,Num_To_HexVar_32(ilen));
*results_size = ilen + 3;
*results = malloc(*results_size);
memset(*results, 0, *results_size);
strcat(*results, prefixed); // 2 bytes
strcat(*results, addr_encoded); // ilen bytes + null terminator
return *results;
}
case 480://http
{
return "ERR";
}
case 443://https
{
return "ERR";
}
case 477://ws
{
return "ERR";
}
case 444://onion
{
return "ERR";
}
case 275://libp2p-webrtc-star
{
return "ERR";
}
default:
{
printf("NO SUCH PROTOCOL!\n");
return "ERR";
}
}
}
/**
* convert a string address into bytes
* @param finalbytes the destination
* @param realbbsize the ultimate size of the destination
* @param strx the incoming string
* @param strsize the string length
*/
int string_to_bytes(uint8_t** finalbytes, size_t* realbbsize, const char* strx, size_t strsize)
{
if(strx[0] != '/')
{
fprintf(stderr, "multiaddr:string_to_bytes: Error, must start with '/' : [%s].\n", strx);
return 0;
}
//Initializing variables to store our processed HEX in:
int malf=0; //In case something goes wrong this will be 1.
char processed[800];//HEX CONTAINER
bzero(processed,800);
//Now Setting up variables for calculating which is the first
//and second word:
int firstorsecond = 1; //1=Protocol && 2 = Address
// copy input so as to not harm it
char pstring[strsize + 1];
strcpy(pstring,strx);
// load up the list of protocols
struct ProtocolListItem* head = NULL;
load_protocols(&head);
//Starting to extract words and process them:
char * wp;
char * end;
wp=strtok_r(pstring,"/",&end);
struct Protocol * protx;
while(wp)
{
if(firstorsecond==1)//This is the Protocol
{
protx = proto_with_name(head, wp);
if(protx != NULL)
{
strcat(processed, Int_To_Hex(protx->deccode));
firstorsecond=2;//Since the next word will be an address
}
else
{
printf("\nNo such protocol!\n\n");
malf=1;
break;
}
}
else//This is the address
{
char* s_to_b = NULL;
int s_to_b_size = 0;
if( strcmp(address_string_to_bytes(protx, wp,strlen(wp), &s_to_b, &s_to_b_size), "ERR") == 0)
{
malf = 1;
}
else
{
int temp_size = strlen(processed);
strncat(processed, s_to_b, s_to_b_size);
processed[temp_size + s_to_b_size] = 0;
free(s_to_b);
}
protx=NULL;//Since right now it doesn't need that assignment anymore.
firstorsecond=1;//Since the next word will be an protocol
}
wp=strtok_r(NULL,"/",&end);
}
protx=NULL;
unload_protocols(head);
if(malf==1)
{
return 0;
}
else
{
*finalbytes = Hex_To_Var(processed, realbbsize);
return 1;
}
}

357
protoutils.h Normal file
View File

@ -0,0 +1,357 @@
#ifndef PROTOUTILS
#define PROTOUTILS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//IP2INT
//IPv4 VALIDATOR
#define DELIM "."
/* return 1 if string contain only digits, else return 0 */
int valid_digit(char *ip_str)
{
while (*ip_str) {
if (*ip_str >= '0' && *ip_str <= '9')
++ip_str;
else
return 0;
}
return 1;
}
/* return 1 if IP string is valid, else return 0 */
int is_valid_ipv4(char *ip_str)
{
int i, num, dots = 0;
char *ptr;
if (ip_str == NULL)
return 0;
// See following link for strtok()
// http://pubs.opengroup.org/onlinepubs/009695399/functions/strtok_r.html
ptr = strtok(ip_str, DELIM);
if (ptr == NULL)
return 0;
while (ptr) {
/* after parsing string, it must contain only digits */
if (!valid_digit(ptr))
return 0;
num = atoi(ptr);
/* check for valid IP */
if (num >= 0 && num <= 255) {
/* parse remaining string */
ptr = strtok(NULL, DELIM);
if (ptr != NULL)
++dots;
} else
return 0;
}
/* valid IP string must contain 3 dots */
if (dots != 3)
return 0;
return 1;
}
//////////////IPv6 Validator
#define MAX_HEX_NUMBER_COUNT 8
int ishexdigit(char ch)
{
if((ch>='0'&&ch<='9')||(ch>='a'&&ch<='f')||(ch>='A'&&ch<='F'))
return(1);
return(0);
}
int is_valid_ipv6(char *str)
{
int hdcount=0;
int hncount=0;
int err=0;
int packed=0;
if(*str==':')
{
str++;
if(*str!=':')
return(0);
else
{
packed=1;
hncount=1;
str++;
if(*str==0)
return(1);
}
}
if(ishexdigit(*str)==0)
{
return(0);
}
hdcount=1;
hncount=1;
str++;
while(err==0&&*str!=0)
{
if(*str==':')
{
str++;
if(*str==':')
{
if(packed==1)
err=1;
else
{
str++;
if(ishexdigit(*str)||*str==0&&hncount<MAX_HEX_NUMBER_COUNT)
{
packed=1;
hncount++;
if(ishexdigit(*str))
{
if(hncount==MAX_HEX_NUMBER_COUNT)
{
err=1;
} else
{
hdcount=1;
hncount++;
str++;
}
}
} else
{
err=1;
}
}
}
else
{
if(!ishexdigit(*str))
{
err=1;
} else
{
if(hncount==MAX_HEX_NUMBER_COUNT)
{
err=1;
} else
{
hdcount=1;
hncount++;
str++;
}
}
}
}
else
{
if(ishexdigit(*str))
{
if(hdcount==4)
err=1;
else
{
hdcount++;
str++;
}
} else
err=1;
}
}
if(hncount<MAX_HEX_NUMBER_COUNT&&packed==0)
err=1;
return(err==0);
}
///Still in work
uint64_t ip2int(char * ipconvertint)
{
uint64_t final_result =0;
char * iproc;
int ipat1=0;
int ipat2=0;
int ipat3=0;
int ipat4=0;
char ip[16];
strcpy(ip, ipconvertint);
printf("ip: %s\n", ip);
iproc = strtok (ip,".");
for(int i=0; i<4;i++)
{
switch(i)
{
case 0:
{
ipat1 = atoi(iproc);
break;
}
case 1:
{
ipat2 = atoi(iproc);
break;
}
case 2:
{
ipat3 = atoi(iproc);
break;
}
case 3:
{
ipat4 = atoi(iproc);
break;
}
default:
{
printf("Somebody misplaced an int\n");
break;
}
}
iproc = strtok (NULL,".");
}
final_result = ((ipat1*pow(2,24))+(ipat2*pow(2,16))+(ipat3*pow(2,8))+1);
return final_result;
}
char * address_string_to_bytes(struct protocol * xx, char * abc)
{
static char astb__stringy[10] = "\0";
int code = 0;
code = xx->deccode;
switch(code)
{
case 4://IPv4
{
if(is_valid_ipv4(abc))
{
uint64_t iip = ip2int(abc);
strcpy(astb__stringy,Int_To_Hex(iip));
return astb__stringy;
}
else
{
return "ERR";
}
break;
}
case 41://IPv6
{
printf("IP6\n");
break;
}
case 6: //Tcp
{
printf("TCP!\n");
break;
}
case 17: //Udp
{
break;
}
case 33://dccp
{
break;
}
case 132://sctp
{
break;
}
case 301://udt
{
break;
}
case 302://utp
{
break;
}
case 42://IPFS - !!!
{
break;
}
case 480://http
{
break;
}
case 443://https
{
break;
}
case 477://ws
{
break;
}
case 444://onion
{
break;
}
case 275://libp2p-webrtc-star
{
break;
}
default:
{
printf("NO SUCH PROTOCOL!\n");
break;
}
}
}
uint8_t * string_to_bytes(char * strx, size_t strsize)
{
char str[strsize]; //This string will be bad later.
strcpy(str,strx);
if(str[0] == '/')
{
char * pch;
static char xxx[40] = "\0";
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str,"/");
load_protocols();
while (pch != NULL)
{
if(proto_with_name(pch))
{
struct protocol * protx;
protx = proto_with_name(pch);
char cut[20]="\0";
strcat(cut,Int_To_Hex(protx->deccode));
cut[2] = '\0';
strcat(xxx,cut);
pch = strtok (NULL, "/");
printf("ADDRESS: %s\n", pch);
if(address_string_to_bytes(protx, pch) != "ERR")
{
}
else
{
return 0;
}
}
else
{
pch = strtok (NULL, "/");
}
}
unload_protocols();
printf("S2B_RESULT: %s\n", xxx);
}
else
{
printf("ERROR, Multiaddr needs to start with '/'\n");
}
}
#endif

View File

@ -1,257 +0,0 @@
#pragma once
#include "multiaddr/multiaddr.h"
#include "multiaddr/varhexutils.h"
int test_new_like_libp2p() {
int retVal = 0;
char* ip = "10.211.55.2";
int port = 4001;
char str[strlen(ip) + 50];
sprintf(str, "/ip4/%s/tcp/%d/", ip, port);
struct MultiAddress* ma_string = multiaddress_new_from_string(str);
// convert to binary
struct MultiAddress* ma_binary = multiaddress_new_from_bytes(ma_string->bytes, ma_string->bsize);
if (strcmp(ma_string->string, ma_binary->string) != 0) {
fprintf(stderr, "%s does not equal %s\n", ma_string->string, ma_binary->string);
goto exit;
}
retVal = 1;
exit:
multiaddress_free(ma_string);
multiaddress_free(ma_binary);
return retVal;
}
int test_new_from_string() {
struct MultiAddress* a = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/8080/");
printf("Number of Bytes: %lu, Bytes: ", a->bsize);
for(int i = 0; i < a->bsize; i++) {
printf("%02x ", a->bytes[i]);
}
printf(" End of bytes\n");
multiaddress_free(a);
return 1;
}
int test_full() {
char addrstr[100];
strcpy(addrstr,"/ip4/192.168.1.1/");
printf("INITIAL: %s\n",addrstr);
struct MultiAddress* a;
a= multiaddress_new_from_string(addrstr);
unsigned char* tmp = Var_To_Hex((char*)a->bytes, a->bsize);
printf("TEST BYTES: %s\n", tmp);
free(tmp);
//Remember, Decapsulation happens from right to left, never in reverse!
printf("A STRING:%s\n",a->string);
multiaddress_encapsulate(a,"/udp/3333/");
printf("A STRING ENCAPSULATED:%s\n",a->string);
tmp = Var_To_Hex((char*)a->bytes, a->bsize);
printf("TEST BYTES: %s\n", tmp);
free(tmp);
multiaddress_decapsulate(a,"udp");
printf("A STRING DECAPSULATED UDP:%s\n",a->string);
tmp = Var_To_Hex((char*)a->bytes, a->bsize);
printf("TEST BYTES: %s\n", tmp);
free(tmp);
multiaddress_encapsulate(a,"/udp/3333/");
printf("A STRING ENCAPSULATED UDP: %s\n",a->string);
multiaddress_encapsulate(a,"/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG");
printf("A STRING ENCAPSULATED IPFS:%s\n",a->string);
tmp = Var_To_Hex((char*)a->bytes, a->bsize);
printf("TEST BYTES: %s\n", tmp);
free(tmp);
printf("TEST BYTE SIZE: %lu\n",a->bsize);
struct MultiAddress* beta;
beta = multiaddress_new_from_bytes(a->bytes,a->bsize);
printf("B STRING: %s\n",beta->string);
multiaddress_free(a);
multiaddress_free(beta);
return 1;
}
int test_hex_to_var() {
size_t d;
unsigned char* result = Hex_To_Var("04", &d);
if (d != 1)
return 0;
if (result[0] != 4)
return 0;
if (result != NULL)
free(result);
return 1;
}
int test_int_to_hex() {
int val = 2555351;
char* result = Int_To_Hex(val);
int retVal = Hex_To_Int(result);
if (retVal != val)
return 0;
return 1;
}
int test_multiaddr_utils() {
int retVal = 0;
struct MultiAddress* addr = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001/");
if (!multiaddress_is_ip(addr)) {
fprintf(stderr, "The address should be an IP\n");
return 0;
}
char* ip = NULL;
multiaddress_get_ip_address(addr, &ip);
if (ip == NULL) {
fprintf(stderr, "get_ip_address returned NULL\n");
goto exit;
}
if(strcmp(ip, "127.0.0.1") != 0) {
fprintf(stderr, "ip addresses are not equal\n");
goto exit;
}
int port = multiaddress_get_ip_port(addr);
if (port != 4001) {
fprintf(stderr, "port incorrect. %d was returned instead of %d\n", port, 4001);
goto exit;
}
retVal = 1;
exit:
if (ip != NULL)
free(ip);
if (addr != NULL)
multiaddress_free(addr);
return retVal;
}
int test_multiaddr_peer_id() {
char* orig_address = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG";
char full_string[255];
char* result = NULL;
char* bytes = NULL;
int retVal = 0, port = 0;
struct MultiAddress *addr = NULL, *addr2 = NULL;
sprintf(full_string, "/ip4/127.0.0.1/tcp/4001/ipfs/%s/", orig_address);
addr = multiaddress_new_from_string(full_string);
result = multiaddress_get_peer_id(addr);
if (result == NULL || strcmp(result, orig_address) != 0)
goto exit;
free(result);
result = NULL;
// switch to bytes and back again to verify the peer id follows...
// 1. display the original bytes
result = (char*)Var_To_Hex((char*)addr->bytes, addr->bsize);
fprintf(stderr, "Original Bytes: %s\n", result);
free(result);
result = NULL;
// make a new MultiAddress from bytes
bytes = malloc(addr->bsize);
memcpy(bytes, addr->bytes, addr->bsize);
addr2 = multiaddress_new_from_bytes((unsigned char*)bytes, addr->bsize);
free(bytes);
bytes = NULL;
// 2. Display the resultant bytes
result = (char*)Var_To_Hex((char*)addr2->bytes, addr2->bsize);
fprintf(stderr, "New Bytes: %s\n", result);
free(result);
result = NULL;
if (strcmp(full_string, addr2->string) != 0) {
fprintf(stderr, "Original string was %s but new string is %s\n", full_string, addr2->string);
goto exit;
}
port = multiaddress_get_ip_port(addr2);
if (port != 4001) {
fprintf(stderr, "Original string had port 4001, but now reporting %d\n", port);
goto exit;
}
result = multiaddress_get_peer_id(addr2);
if (strcmp(result, orig_address) != 0) {
fprintf(stderr, "New peer id %s does not match %s", result, orig_address);
goto exit;
}
free(result);
result = NULL;
retVal = 1;
exit:
if (addr != NULL)
multiaddress_free(addr);
if (addr2 != NULL)
multiaddress_free(addr2);
if (result != NULL)
free(result);
if (bytes != NULL)
free(bytes);
return retVal;
}
int test_multiaddr_get_peer_id() {
const char* orig_address = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG";
char full_string[255] = "";
char* result = NULL;
int retVal = 0;
struct MultiAddress *addr = NULL;
sprintf(full_string, "/ip4/127.0.0.1/tcp/4001/ipfs/%s/", orig_address);
addr = multiaddress_new_from_string(full_string);
result = multiaddress_get_peer_id(addr);
if (result == NULL)
goto exit;
if (strcmp(orig_address, result) != 0)
goto exit;
retVal = 1;
exit:
multiaddress_free(addr);
free(result);
result = NULL;
return retVal;
}
int test_multiaddr_bytes() {
int retVal = 0;
char* orig_address = "/ip4/127.0.0.1/tcp/4001/";
struct MultiAddress *orig = NULL, *result = NULL;
orig = multiaddress_new_from_string(orig_address);
result = multiaddress_new_from_bytes(orig->bytes, orig->bsize);
if (strcmp(orig_address, result->string) != 0) {
fprintf(stderr, "%s does not equal %s\n", orig_address, result->string);
goto exit;
}
retVal = 1;
exit:
if (orig != NULL)
multiaddress_free(orig);
if (result != NULL)
multiaddress_free(result);
return retVal;
}

View File

@ -1,84 +0,0 @@
#include <stdio.h>
#include "test_multiaddr.h"
const char* names[] = {
"test_new_from_string",
"test_full",
"test_hex_to_var",
"test_int_to_hex",
"test_multiaddr_utils",
"test_multiaddr_peer_id",
"test_multiaddr_get_peer_id",
"test_multiaddr_bytes",
"test_new_like_libp2p"
};
int (*funcs[])(void) = {
test_new_from_string,
test_full,
test_hex_to_var,
test_int_to_hex,
test_multiaddr_utils,
test_multiaddr_peer_id,
test_multiaddr_get_peer_id,
test_multiaddr_bytes,
test_new_like_libp2p
};
int testit(const char* name, int (*func)(void)) {
printf("Testing %s...\n", name);
int retVal = func();
if (retVal)
printf("%s success!\n", name);
else
printf("** Uh oh! %s failed.**\n", name);
return retVal;
}
int main(int argc, char** argv) {
int counter = 0;
int tests_ran = 0;
char* test_wanted;
int only_one = 0;
if(argc > 1) {
only_one = 1;
if (argv[1][0] == '\'') { // some shells put quotes around arguments
argv[1][strlen(argv[1])-1] = 0;
test_wanted = &(argv[1][1]);
}
else
test_wanted = argv[1];
}
int array_length = sizeof(funcs) / sizeof(funcs[0]);
int array2_length = sizeof(names) / sizeof(names[0]);
if (array_length != array2_length) {
printf("Test arrays are not of the same length. Funcs: %d, Names: %d\n", array_length, array2_length);
}
for (int i = 0; i < array_length; i++) {
if (only_one) {
const char* currName = names[i];
if (strcmp(currName, test_wanted) == 0) {
tests_ran++;
counter += testit(names[i], funcs[i]);
}
}
else
if (!only_one) {
tests_ran++;
counter += testit(names[i], funcs[i]);
}
}
if (tests_ran == 0)
printf("***** No tests found *****\n");
else {
if (tests_ran - counter > 0) {
printf("***** There were %d failed test(s) (%d successful) *****\n", tests_ran - counter, counter);
} else {
printf("All %d tests passed\n", tests_ran);
}
}
return 1;
}

View File

@ -1,259 +0,0 @@
#ifndef VARHEXUTILS
#define VARHEXUTILS
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <inttypes.h>
#include "multiaddr/varint.h"
#include "multiaddr/varhexutils.h"
/*uint8_t * encode_big_endian_32(uint32_t ebex32)
{
uint8_t encbe[10] = {0};
memcpy(encbe, htobe32(ebex32));
return encbe;
}*/
int8_t Var_Bytes_Count(uint8_t * countbytesofthis)
{
static int8_t xrzk_bytescnt = 0;
for(int8_t i=0; i<10; i++)
{
if(countbytesofthis[i] != 0)
{
xrzk_bytescnt++;
}
}
return xrzk_bytescnt;
}
uint8_t * Num_To_Varint_64(uint64_t TOV64INPUT) //UINT64_T TO VARINT
{
static uint8_t buffy_001[60] = {0};
uvarint_encode64(TOV64INPUT, buffy_001, 60);
return buffy_001;
}
uint8_t * Num_To_Varint_32(uint32_t TOV32INPUT) // UINT32_T TO VARINT
{
static uint8_t buffy_032[60] = {0};
uvarint_encode32(TOV32INPUT, buffy_032, 60);
return buffy_032;
}
uint64_t * Varint_To_Num_64(uint8_t TON64INPUT[60]) //VARINT TO UINT64_t
{
static uint64_t varintdecode_001 = 0;
uvarint_decode64(TON64INPUT, 60, &varintdecode_001);
return &varintdecode_001;
}
uint32_t * Varint_To_Num_32(uint8_t TON32INPUT[60]) //VARINT TO UINT32_t
{
static uint32_t varintdecode_032 = 0;
uvarint_decode32(TON32INPUT, 60, &varintdecode_032);
return &varintdecode_032;
}
/**
* Converts a 64 bit integer into a hex string
* @param int2hex the 64 bit integer
* @returns a hex representation as a string (leading zero if necessary)
*/
char * Int_To_Hex(uint64_t int2hex) //VAR[binformat] TO HEX
{
static char result[50];
memset(result, 0, 50);
sprintf(result, "%02lX", int2hex);
int slen = strlen(result);
if (slen % 2 != 0) {
for(int i = slen; i >= 0; --i) {
result[i+1] = result[i];
}
result[0] = '0';
}
return result;
}
uint64_t Hex_To_Int(char * hax)
{
char * hex = NULL;
hex=hax;
uint64_t val = 0;
while (*hex)
{
// get current character then increment
uint8_t byte = *hex++;
// transform hex character to the 4bit equivalent number, using the ascii table indexes
if (byte >= '0' && byte <= '9') byte = byte - '0';
else if (byte >= 'a' && byte <='f') byte = byte - 'a' + 10;
else if (byte >= 'A' && byte <='F') byte = byte - 'A' + 10;
// shift 4 to make space for new digit, and add the 4 bits of the new digit
val = (val << 4) | (byte & 0xF);
}
return val;
}
/**
* Convert a byte array into a hex byte array
* @param in the incoming byte array
* @param in_size the size of in
* @param out the resultant array of hex bytes
*/
void vthconvert(const unsigned char* in, int in_size, unsigned char** out)
{
*out = (unsigned char*)malloc( (in_size * 2) + 1);
memset(*out, 0, (in_size * 2) + 1);
unsigned char *ptr = *out;
for (int i = 0; i < in_size; i++) {
sprintf((char*)&ptr[i * 2], "%02x", in[i]);
}
}
/**
* Convert binary array to array of hex values
* @param incoming the binary array
* @param incoming_size the size of the incoming array
* @returns the allocated array
*/
unsigned char * Var_To_Hex(const unsigned char *incoming, int incoming_size)
{
if(incoming != NULL)
{
unsigned char* retVal = NULL;
// this does the real work
vthconvert(incoming, incoming_size, &retVal);
// we can't return an array that will be deallocated!
return retVal;
}
return NULL;
}
/**
* Turn a hex string into a byte array
* @param incoming a string of hex values
* @param num_bytes the size of the result
* @returns a pointer to the converted value
*/
unsigned char* Hex_To_Var(const char* incoming, size_t* num_bytes) //HEX TO VAR[BINFORMAT]
{
// the return value
unsigned char* retVal = NULL;
int incoming_size = strlen(incoming);
*num_bytes = incoming_size / 2;
retVal = (unsigned char*)malloc(*num_bytes);
char code[3];
code[2]='\0';
int pos = 0;
for(int i=0; i < incoming_size; i += 2)
{
code[0] = incoming[i];
code[1] = incoming[i+1];
uint64_t lu = strtol(code, NULL, 16);
retVal[pos] = (unsigned int)lu;
pos++;
}
return retVal;
}
//
void convert(char * convert_result, uint8_t * buf) //Both of them read them properly.
{
char conv_proc[800]="\0";
bzero(conv_proc,800);
int i;
for(i=0; i < 10; i++)
{
sprintf (conv_proc, "%02X", buf[i]);
//printf("%d:%d\n",i, buf[i]);
strcat(convert_result, conv_proc);
}
}
char * Num_To_HexVar_64(uint64_t TOHVINPUT) //UINT64 TO HEXIFIED VAR
{ //Code to varint - py
static char convert_result[800]="\0";//Note that the hex resulted from this will differ from py
bzero(convert_result,800);
memset(convert_result,0,sizeof(convert_result));//But if you make sure the string is always 20 chars in size
uint8_t buf[400] = {0};
bzero(buf,400);
uvarint_encode64(TOHVINPUT, buf, 800);
convert(convert_result,buf);
return convert_result;
}
void convert2(char * convert_result2, uint8_t * bufhx)
{
uint8_t * buf = NULL;
buf = bufhx;
char conv_proc[4]="\0";
conv_proc[3] = '\0';
bzero(conv_proc, 3);
int i;
for(i=0; i == 0; i++)
{
sprintf (conv_proc, "%02X", buf[i]);
//printf("aaaaaaaaaaah%d:%d\n",i, buf[i]);
strcat(convert_result2, conv_proc);
}
buf = NULL;
}
char * Num_To_HexVar_32(uint32_t TOHVINPUT) //UINT32 TO HEXIFIED VAR
{ //Code to varint - py
static char convert_result2[3]="\0";
bzero(convert_result2,3);
convert_result2[2] = '\0';
memset(convert_result2,0,sizeof(convert_result2));
uint8_t buf[1] = {0};
bzero(buf,1);
uvarint_encode32(TOHVINPUT, buf, 1);
convert2(convert_result2,buf);
return convert_result2;
}
uint64_t HexVar_To_Num_64(char * theHEXstring) //HEXIFIED VAR TO UINT64_T
{ //Varint to code - py
uint8_t buffy[400] = {0};
char codo[800] = "\0";
bzero(codo,800);
strcpy(codo, theHEXstring);
char code[3] = "\0";
int x = 0;
for(int i= 0;i<399;i++)
{
strncpy(&code[0],&codo[i],1);
strncpy(&code[1],&codo[i+1],1);
char *ck = NULL;
uint64_t lu = 0;
lu=strtoul(code, &ck, 16);
buffy[x] = lu;
i++;
x++;
}
static uint64_t decoded;
uvarint_decode64 (buffy, 400, &decoded);
return decoded;
}
uint32_t HexVar_To_Num_32(char theHEXstring[]) //HEXIFIED VAR TO UINT32_T
{ //Varint to code py
uint8_t buffy[400] = {0};
bzero(buffy,400);
char codo[800] = "\0";
bzero(codo,800);
strcpy(codo, theHEXstring);
char code[4] = "\0";
bzero(code,3);
code[3] = '\0';
int x = 0;
for(int i= 0;i<399;i++)
{
strncpy(&code[0],&codo[i],1);
strncpy(&code[1],&codo[i+1],1);
char *ck = NULL;
uint32_t lu = {0};
lu=strtoul(code, &ck, 16);
buffy[x] = lu;
i++;
x++;
}
static uint32_t decoded;
uvarint_decode32 (buffy, 10, &decoded);
return decoded;
}
#endif

186
varhexutils.h Normal file
View File

@ -0,0 +1,186 @@
#ifndef VARHEXUTILS
#define VARHEXUTILS
#include <stdio.h>
#include <inttypes.h>
#include "varint.h"
#include <stdlib.h>
#include <string.h>
#include "endian.h"
/*uint8_t * encode_big_endian_32(uint32_t ebex32)
{
uint8_t encbe[10] = {0};
memcpy(encbe, htobe32(ebex32));
return encbe;
}*/
int8_t Var_Bytes_Count(uint8_t countbytesofthis[10])
{
static int8_t xrzk_bytescnt = 0;
for(int8_t i=0; i<10; i++)
{
if(countbytesofthis[i] != 0)
{
xrzk_bytescnt++;
}
}
return xrzk_bytescnt;
}
uint8_t * Num_To_Varint_64(uint64_t TOV64INPUT) //UINT64_T TO VARINT
{
static uint8_t buffy_001[10] = {0};
uvarint_encode64(TOV64INPUT, buffy_001, 10);
return buffy_001;
}
uint8_t * Num_To_Varint_32(uint32_t TOV32INPUT) // UINT32_T TO VARINT
{
static uint8_t buffy_032[10] = {0};
uvarint_encode32(TOV32INPUT, buffy_032, 10);
return buffy_032;
}
uint64_t * Varint_To_Num_64(uint8_t TON64INPUT[10]) //VARINT TO UINT64_t
{
static uint64_t varintdecode_001 = 0;
uvarint_decode64(TON64INPUT, 10, &varintdecode_001);
return &varintdecode_001;
}
uint32_t * Varint_To_Num_32(uint8_t TON32INPUT[10]) //VARINT TO UINT32_t
{
static uint32_t varintdecode_032 = 0;
uvarint_decode32(TON32INPUT, 10, &varintdecode_032);
return &varintdecode_032;
}
//
char * Int_To_Hex(uint64_t int2hex) //VAR[binformat] TO HEX
{
static char int2hex_result[10]="\0";
memset(int2hex_result,0,sizeof(int2hex_result));
sprintf (int2hex_result, "%02lX", int2hex);
return int2hex_result;
}
//
char * Var_To_Hex(uint8_t TOHEXINPUT[10]) //VAR[binformat] TO HEX
{
static char convert_resultz1[20]="\0";
memset(convert_resultz1,0,sizeof(convert_resultz1));
void convert(uint8_t buf[10])
{
char conv_proc[10]="\0";
for(int i=0; i < 10; i++)
{
sprintf (conv_proc, "%02X", buf[i]);
//printf("%d:%d\n",i, buf[i]);
strcat(convert_resultz1, conv_proc);
}
}
convert(TOHEXINPUT);
return convert_resultz1;
}
uint8_t * Hex_To_Var(char * Hexstr) //HEX TO VAR[BINFORMAT]
{
static uint8_t buffy_HEX[10] = {0};
char codo[20] = "\0";
strcpy(codo, Hexstr);
char code[3] = "\0";
int x = 0;
for(int i= 0;i<20;i++)
{
strncpy(&code[0],&codo[i],1);
strncpy(&code[1],&codo[i+1],1);
char *ck = NULL;
uint64_t lu = 0;
lu=strtoul(code, &ck, 16);
buffy_HEX[x] = lu;
i++;
x++;
}
return buffy_HEX;
}
//
char * Num_To_HexVar_64(uint64_t TOHVINPUT) //UINT64 TO HEXIFIED VAR
{ //Code to varint - py
static char convert_result[10]="\0";//Note that the hex resulted from this will differ from py
memset(convert_result,0,sizeof(convert_result));//But if you make sure the string is always 20 chars in size
void convert(uint8_t buf[10]) //Both of them read them properly.
{
char conv_proc[10]="\0";
int i=0;
for(; i < 10; i++)
{
sprintf (conv_proc, "%02X", buf[i]);
//printf("%d:%d\n",i, buf[i]);
strcat(convert_result, conv_proc);
}
}
uint8_t buf[10] = {0};
uvarint_encode64(TOHVINPUT, buf, 10);
convert(buf);
return convert_result;
}
char * Num_To_HexVar_32(uint32_t TOHVINPUT) //UINT32 TO HEXIFIED VAR
{ //Code to varint - py
static char convert_result2[20]="\0";
memset(convert_result2,0,sizeof(convert_result2));
void convert(uint8_t buf[10])
{
char conv_proc[10]="\0";
int i=0;
for(; i < 10; i++)
{
sprintf (conv_proc, "%02X", buf[i]);
printf("%d:%d\n",i, buf[i]);
strcat(convert_result2, conv_proc);
}
}
uint8_t buf[10] = {0};
uvarint_encode32(TOHVINPUT, buf, 10);
convert(buf);
return convert_result2;
}
uint64_t HexVar_To_Num_64(char * theHEXstring) //HEXIFIED VAR TO UINT64_T
{ //Varint to code - py
uint8_t buffy[10] = {0};
char codo[20] = "\0";
strcpy(codo, theHEXstring);
char code[3] = "\0";
int x = 0;
for(int i= 0;i<20;i++)
{
strncpy(&code[0],&codo[i],1);
strncpy(&code[1],&codo[i+1],1);
char *ck = NULL;
uint64_t lu = 0;
lu=strtoul(code, &ck, 16);
buffy[x] = lu;
i++;
x++;
}
static uint64_t decoded;
uvarint_decode64 (buffy, 10, &decoded);
return decoded;
}
uint32_t HexVar_To_Num_32(char theHEXstring[]) //HEXIFIED VAR TO UINT32_T
{ //Varint to code py
uint8_t buffy[10] = {0};
char codo[20] = "\0";
strcpy(codo, theHEXstring);
char code[2] = "\0";
int x = 0;
for(int i= 0;i<20;i++)
{
strncpy(&code[0],&codo[i],1);
strncpy(&code[1],&codo[i+1],1);
char *ck = NULL;
uint32_t lu = {0};
lu=strtoul(code, &ck, 16);
buffy[x] = lu;
i++;
x++;
}
static uint32_t decoded;
uvarint_decode32 (buffy, 10, &decoded);
return decoded;
}
#endif

View File

@ -1,8 +1,8 @@
#include "multiaddr/varint.h"
#include "varint.h"
DEFN_ENCODER(32)
DEFN_DECODER(32)
DEFN_ENCODER(64)
DEFN_DECODER(64)
DEFN_DECODER(64)