Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
0705909f4c |
27 changed files with 741 additions and 2528 deletions
78
.cproject
78
.cproject
|
@ -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
11
.gitignore
vendored
|
@ -1,11 +0,0 @@
|
|||
*
|
||||
|
||||
!.gitignore
|
||||
!Makefile
|
||||
!**/
|
||||
|
||||
*.o
|
||||
*.a
|
||||
.settings/language.settings.xml
|
||||
test_multiaddr
|
||||
|
26
.project
26
.project
|
@ -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
24
LICENSE
|
@ -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.
|
33
Makefile
33
Makefile
|
@ -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
|
32
README.md
32
README.md
|
@ -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
21
STATUS
Normal 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.
|
15
STATUS.md
15
STATUS.md
|
@ -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
200
base58.c
|
@ -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
104
base58.h
Normal 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;
|
||||
}*/
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
397
multiaddr.c
397
multiaddr.c
|
@ -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;
|
||||
}
|
||||
|
28
proto-dat
28
proto-dat
|
@ -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
|
||||
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
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
#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));
|
||||
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/
|
||||
|
@ -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(char proto_w_name[]) //Search for protocol with inputted name
|
||||
{
|
||||
|
||||
struct Protocol* proto_with_name(const struct ProtocolListItem* head, const char* proto_w_name) //Search for Protocol with inputted name
|
||||
for(int i=0; i<CNT_PROTOCOLNUM; i++)
|
||||
{
|
||||
const struct ProtocolListItem* current = head;
|
||||
while(current != NULL)
|
||||
if(strcmp(proto_w_name, (protocol_P+i)->name) == 0)
|
||||
{
|
||||
if (strcmp(proto_w_name, current->current->name) == 0) {
|
||||
return current->current;
|
||||
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;
|
||||
|
||||
|
@ -228,3 +205,4 @@ void protocols_with_string(const struct ProtocolListItem* head, char* meee, int
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
717
protoutils.c
717
protoutils.c
|
@ -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
357
protoutils.h
Normal 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
|
257
test_multiaddr.h
257
test_multiaddr.h
|
@ -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;
|
||||
|
||||
}
|
||||
|
84
testing.c
84
testing.c
|
@ -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;
|
||||
}
|
||||
|
259
varhexutils.c
259
varhexutils.c
|
@ -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
186
varhexutils.h
Normal 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
|
2
varint.c
2
varint.c
|
@ -1,4 +1,4 @@
|
|||
#include "multiaddr/varint.h"
|
||||
#include "varint.h"
|
||||
|
||||
|
||||
DEFN_ENCODER(32)
|
||||
|
|
Loading…
Reference in a new issue