mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-25 08:37:13 +09:00
Add sodium_ip2bin, sodium_bin2ip
This commit is contained in:
@@ -19,7 +19,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
SODIUM_EXPORT
|
||||
void sodium_memzero(void * const pnt, const size_t len);
|
||||
void sodium_memzero(void *const pnt, const size_t len);
|
||||
|
||||
SODIUM_EXPORT
|
||||
void sodium_stackzero(const size_t len);
|
||||
@@ -31,8 +31,8 @@ void sodium_stackzero(const size_t len);
|
||||
* This function is not designed for lexicographical comparisons.
|
||||
*/
|
||||
SODIUM_EXPORT
|
||||
int sodium_memcmp(const void * const b1_, const void * const b2_, size_t len)
|
||||
__attribute__ ((warn_unused_result));
|
||||
int sodium_memcmp(const void *const b1_, const void *const b2_, size_t len)
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
/*
|
||||
* sodium_compare() returns -1 if b1_ < b2_, 1 if b1_ > b2_ and 0 if b1_ == b2_
|
||||
@@ -41,8 +41,8 @@ int sodium_memcmp(const void * const b1_, const void * const b2_, size_t len)
|
||||
* However, it is slower than sodium_memcmp().
|
||||
*/
|
||||
SODIUM_EXPORT
|
||||
int sodium_compare(const unsigned char *b1_, const unsigned char *b2_,
|
||||
size_t len) __attribute__ ((warn_unused_result));
|
||||
int sodium_compare(const unsigned char *b1_, const unsigned char *b2_, size_t len)
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_is_zero(const unsigned char *n, const size_t nlen);
|
||||
@@ -57,16 +57,13 @@ SODIUM_EXPORT
|
||||
void sodium_sub(unsigned char *a, const unsigned char *b, const size_t len);
|
||||
|
||||
SODIUM_EXPORT
|
||||
char *sodium_bin2hex(char * const hex, const size_t hex_maxlen,
|
||||
const unsigned char * const bin, const size_t bin_len)
|
||||
__attribute__ ((nonnull(1)));
|
||||
char *sodium_bin2hex(char *const hex, const size_t hex_maxlen, const unsigned char *const bin,
|
||||
const size_t bin_len) __attribute__((nonnull(1)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen,
|
||||
const char * const hex, const size_t hex_len,
|
||||
const char * const ignore, size_t * const bin_len,
|
||||
const char ** const hex_end)
|
||||
__attribute__ ((nonnull(1)));
|
||||
int sodium_hex2bin(unsigned char *const bin, const size_t bin_maxlen, const char *const hex,
|
||||
const size_t hex_len, const char *const ignore, size_t *const bin_len,
|
||||
const char **const hex_end) __attribute__((nonnull(1)));
|
||||
|
||||
#define sodium_base64_VARIANT_ORIGINAL 1
|
||||
#define sodium_base64_VARIANT_ORIGINAL_NO_PADDING 3
|
||||
@@ -77,33 +74,37 @@ int sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen,
|
||||
* Computes the required length to encode BIN_LEN bytes as a base64 string
|
||||
* using the given variant. The computed length includes a trailing \0.
|
||||
*/
|
||||
#define sodium_base64_ENCODED_LEN(BIN_LEN, VARIANT) \
|
||||
(((BIN_LEN) / 3U) * 4U + \
|
||||
((((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) | (((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) >> 1)) & 1U) * \
|
||||
(4U - (~((((VARIANT) & 2U) >> 1) - 1U) & (3U - ((BIN_LEN) - ((BIN_LEN) / 3U) * 3U)))) + 1U)
|
||||
#define sodium_base64_ENCODED_LEN(BIN_LEN, VARIANT) \
|
||||
(((BIN_LEN) / 3U) * 4U + \
|
||||
((((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) | (((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) >> 1)) & 1U) * \
|
||||
(4U - (~((((VARIANT) & 2U) >> 1) - 1U) & (3U - ((BIN_LEN) - ((BIN_LEN) / 3U) * 3U)))) + \
|
||||
1U)
|
||||
|
||||
SODIUM_EXPORT
|
||||
size_t sodium_base64_encoded_len(const size_t bin_len, const int variant);
|
||||
|
||||
SODIUM_EXPORT
|
||||
char *sodium_bin2base64(char * const b64, const size_t b64_maxlen,
|
||||
const unsigned char * const bin, const size_t bin_len,
|
||||
const int variant) __attribute__ ((nonnull(1)));
|
||||
char *sodium_bin2base64(char *const b64, const size_t b64_maxlen, const unsigned char *const bin,
|
||||
const size_t bin_len, const int variant) __attribute__((nonnull(1)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen,
|
||||
const char * const b64, const size_t b64_len,
|
||||
const char * const ignore, size_t * const bin_len,
|
||||
const char ** const b64_end, const int variant)
|
||||
__attribute__ ((nonnull(1)));
|
||||
int sodium_base642bin(unsigned char *const bin, const size_t bin_maxlen, const char *const b64,
|
||||
const size_t b64_len, const char *const ignore, size_t *const bin_len,
|
||||
const char **const b64_end, const int variant) __attribute__((nonnull(1)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mlock(void * const addr, const size_t len)
|
||||
__attribute__ ((nonnull));
|
||||
int sodium_ip2bin(unsigned char out[16], const char *src) __attribute__((warn_unused_result))
|
||||
__attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_munlock(void * const addr, const size_t len)
|
||||
__attribute__ ((nonnull));
|
||||
char *sodium_bin2ip(char *dst, size_t dst_len, const unsigned char in[16])
|
||||
__attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mlock(void *const addr, const size_t len) __attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_munlock(void *const addr, const size_t len) __attribute__((nonnull));
|
||||
|
||||
/* WARNING: sodium_malloc() and sodium_allocarray() are not general-purpose
|
||||
* allocation functions.
|
||||
@@ -116,7 +117,8 @@ int sodium_munlock(void * const addr, const size_t len)
|
||||
* region may also kill the process if a buffer underflow is detected.
|
||||
*
|
||||
* The memory layout is:
|
||||
* [unprotected region size (read only)][guard page (no access)][unprotected pages (read/write)][guard page (no access)]
|
||||
* [unprotected region size (read only)][guard page (no access)][unprotected pages
|
||||
* (read/write)][guard page (no access)]
|
||||
*
|
||||
* The layout of the unprotected pages is:
|
||||
* [optional padding][16-bytes canary][user region]
|
||||
@@ -139,34 +141,30 @@ int sodium_munlock(void * const addr, const size_t len)
|
||||
*/
|
||||
|
||||
SODIUM_EXPORT
|
||||
void *sodium_malloc(const size_t size)
|
||||
__attribute__ ((malloc));
|
||||
void *sodium_malloc(const size_t size) __attribute__((malloc));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void *sodium_allocarray(size_t count, size_t size)
|
||||
__attribute__ ((malloc));
|
||||
void *sodium_allocarray(size_t count, size_t size) __attribute__((malloc));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void sodium_free(void *ptr);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mprotect_noaccess(void *ptr) __attribute__ ((nonnull));
|
||||
int sodium_mprotect_noaccess(void *ptr) __attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mprotect_readonly(void *ptr) __attribute__ ((nonnull));
|
||||
int sodium_mprotect_readonly(void *ptr) __attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mprotect_readwrite(void *ptr) __attribute__ ((nonnull));
|
||||
int sodium_mprotect_readwrite(void *ptr) __attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_pad(size_t *padded_buflen_p, unsigned char *buf,
|
||||
size_t unpadded_buflen, size_t blocksize, size_t max_buflen)
|
||||
__attribute__ ((nonnull(2)));
|
||||
int sodium_pad(size_t *padded_buflen_p, unsigned char *buf, size_t unpadded_buflen,
|
||||
size_t blocksize, size_t max_buflen) __attribute__((nonnull(2)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf,
|
||||
size_t padded_buflen, size_t blocksize)
|
||||
__attribute__ ((nonnull(2)));
|
||||
int sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf, size_t padded_buflen,
|
||||
size_t blocksize) __attribute__((nonnull(2)));
|
||||
|
||||
/* -------- */
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
@@ -333,3 +334,280 @@ sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ip_hex_digit(int ch)
|
||||
{
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
return ch - '0';
|
||||
}
|
||||
if (((unsigned int) ch | 32U) >= 'a' && ((unsigned int) ch | 32U) <= 'f') {
|
||||
return ((unsigned int) ch | 32U) - 'a' + 10;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_ipv4(const char *src, const char *end, unsigned char out[4])
|
||||
{
|
||||
const char *p = src;
|
||||
int i;
|
||||
|
||||
if (src == NULL || end == NULL || out == NULL || src >= end) {
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
unsigned int val = 0U;
|
||||
int digits = 0;
|
||||
|
||||
while (p < end && *p >= '0' && *p <= '9') {
|
||||
val = val * 10U + (unsigned int) (*p++ - '0');
|
||||
if (++digits > 3 || val > 255U) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (digits == 0) {
|
||||
return 0;
|
||||
}
|
||||
out[i] = (unsigned char) val;
|
||||
|
||||
if (i < 3) {
|
||||
if (p >= end || *p++ != '.') {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return p == end;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_ipv6(const char *src, const char *end, unsigned char out[16])
|
||||
{
|
||||
unsigned char tmp[16] = { 0 };
|
||||
unsigned char *tp = tmp;
|
||||
unsigned char *endp = tmp + 16;
|
||||
unsigned char *colonp = NULL;
|
||||
const char *p = src;
|
||||
const char *curtok = src;
|
||||
unsigned int val = 0U;
|
||||
int saw_xdigit = 0;
|
||||
int xdigits = 0;
|
||||
int ch;
|
||||
int hv;
|
||||
|
||||
if (src == NULL || end == NULL || out == NULL || src >= end) {
|
||||
return 0;
|
||||
}
|
||||
if (*p == ':') {
|
||||
if (++p >= end || *p != ':') {
|
||||
return 0;
|
||||
}
|
||||
colonp = tp;
|
||||
curtok = ++p;
|
||||
}
|
||||
while (p < end) {
|
||||
ch = *p;
|
||||
|
||||
if (ch == ':') {
|
||||
if (!saw_xdigit) {
|
||||
if (colonp != NULL) {
|
||||
return 0;
|
||||
}
|
||||
colonp = tp;
|
||||
curtok = ++p;
|
||||
continue;
|
||||
}
|
||||
if (tp + 2 > endp) {
|
||||
return 0;
|
||||
}
|
||||
*tp++ = (unsigned char) (val >> 8);
|
||||
*tp++ = (unsigned char) (val & 0xffU);
|
||||
val = 0U;
|
||||
saw_xdigit = 0;
|
||||
xdigits = 0;
|
||||
curtok = ++p;
|
||||
if (p >= end) {
|
||||
return 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (ch == '.') {
|
||||
if (tp + 4 > endp || parse_ipv4(curtok, end, tp) == 0) {
|
||||
return 0;
|
||||
}
|
||||
tp += 4;
|
||||
saw_xdigit = 0;
|
||||
break;
|
||||
}
|
||||
hv = ip_hex_digit(ch);
|
||||
if (hv < 0 || xdigits >= 4) {
|
||||
return 0;
|
||||
}
|
||||
val = (val << 4) | (unsigned int) hv;
|
||||
saw_xdigit = 1;
|
||||
xdigits++;
|
||||
p++;
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + 2 > endp) {
|
||||
return 0;
|
||||
}
|
||||
*tp++ = (unsigned char) (val >> 8);
|
||||
*tp++ = (unsigned char) (val & 0xffU);
|
||||
}
|
||||
if (colonp != NULL) {
|
||||
size_t n = (size_t) (tp - colonp);
|
||||
|
||||
if (tp == endp) {
|
||||
return 0;
|
||||
}
|
||||
memmove(endp - n, colonp, n);
|
||||
memset(colonp, 0, (size_t) (endp - n - colonp));
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(out, tmp, 16U);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
sodium_ip2bin(unsigned char out[16], const char *src)
|
||||
{
|
||||
const char *end;
|
||||
const char *z;
|
||||
unsigned char v4[4];
|
||||
|
||||
if (src == NULL || out == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (end = src; *end != 0 && *end != '%'; end++) {
|
||||
/* empty */
|
||||
}
|
||||
if (*end == '%') {
|
||||
for (z = end + 1; *z != 0; z++) {
|
||||
if (isspace((unsigned char) *z)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (z == end + 1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (memchr(src, ':', (size_t) (end - src)) != NULL) {
|
||||
return parse_ipv6(src, end, out) != 0 ? 0 : -1;
|
||||
}
|
||||
if (*end == '%') {
|
||||
return -1;
|
||||
}
|
||||
if (parse_ipv4(src, end, v4) == 0) {
|
||||
return -1;
|
||||
}
|
||||
memset(out, 0, 10U);
|
||||
out[10] = 0xffU;
|
||||
out[11] = 0xffU;
|
||||
memcpy(out + 12, v4, 4U);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const unsigned char ipv4_mapped_prefix[12] = { 0U, 0U, 0U, 0U, 0U, 0U,
|
||||
0U, 0U, 0U, 0U, 0xffU, 0xffU };
|
||||
|
||||
static void
|
||||
ip_write_num(char **p, unsigned int val, int base)
|
||||
{
|
||||
char buf[4];
|
||||
int n = 0;
|
||||
|
||||
do {
|
||||
unsigned int d = val % (unsigned int) base;
|
||||
|
||||
buf[n++] = (char) (d < 10U ? '0' + d : 'a' + d - 10U);
|
||||
val /= (unsigned int) base;
|
||||
} while (val != 0U);
|
||||
|
||||
while (n-- > 0) {
|
||||
*(*p)++ = buf[n];
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
sodium_bin2ip(char *dst, size_t dst_len, const unsigned char in[16])
|
||||
{
|
||||
char buf[46];
|
||||
char *p = buf;
|
||||
int i;
|
||||
int best_start = -1;
|
||||
int best_len = 0;
|
||||
int cur_start = -1;
|
||||
int cur_len = 0;
|
||||
size_t len;
|
||||
|
||||
if (dst == NULL || in == NULL || dst_len == 0U) {
|
||||
return NULL;
|
||||
}
|
||||
if (memcmp(in, ipv4_mapped_prefix, 12U) == 0) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (i != 0) {
|
||||
*p++ = '.';
|
||||
}
|
||||
ip_write_num(&p, (unsigned int) in[12 + i], 10);
|
||||
}
|
||||
len = (size_t) (p - buf);
|
||||
if (len >= dst_len) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(dst, buf, len + 1U);
|
||||
dst[len] = 0;
|
||||
|
||||
return dst;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
unsigned int word = ((unsigned int) in[i * 2] << 8) | (unsigned int) in[i * 2 + 1];
|
||||
|
||||
if (word == 0U) {
|
||||
if (cur_start < 0) {
|
||||
cur_start = i;
|
||||
}
|
||||
cur_len++;
|
||||
} else {
|
||||
if (cur_len > best_len) {
|
||||
best_start = cur_start;
|
||||
best_len = cur_len;
|
||||
}
|
||||
cur_start = -1;
|
||||
cur_len = 0;
|
||||
}
|
||||
}
|
||||
if (cur_len > best_len) {
|
||||
best_start = cur_start;
|
||||
best_len = cur_len;
|
||||
}
|
||||
if (best_len < 2) {
|
||||
best_start = -1;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i == best_start) {
|
||||
*p++ = ':';
|
||||
*p++ = ':';
|
||||
i += best_len - 1;
|
||||
continue;
|
||||
}
|
||||
if (i != 0 && (best_start < 0 || i != best_start + best_len)) {
|
||||
*p++ = ':';
|
||||
}
|
||||
ip_write_num(&p, ((unsigned int) in[i * 2] << 8) | (unsigned int) in[i * 2 + 1], 16);
|
||||
}
|
||||
len = (size_t) (p - buf);
|
||||
if (len >= dst_len) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(dst, buf, len);
|
||||
dst[len] = 0;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
@@ -247,5 +247,184 @@ main(void)
|
||||
sodium_free(bin);
|
||||
sodium_free(b64_);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char ip_bytes[16];
|
||||
unsigned char ip_expected[16];
|
||||
char ip_str[46];
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "192.168.1.1") == 0);
|
||||
memset(ip_expected, 0, 10);
|
||||
ip_expected[10] = 0xff;
|
||||
ip_expected[11] = 0xff;
|
||||
ip_expected[12] = 192;
|
||||
ip_expected[13] = 168;
|
||||
ip_expected[14] = 1;
|
||||
ip_expected[15] = 1;
|
||||
assert(memcmp(ip_bytes, ip_expected, 16) == 0);
|
||||
printf("ip2bytes(192.168.1.1): OK\n");
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "0.0.0.0") == 0);
|
||||
assert(sodium_ip2bin(ip_bytes, "255.255.255.255") == 0);
|
||||
assert(sodium_ip2bin(ip_bytes, "127.0.0.1") == 0);
|
||||
printf("ip2bytes IPv4 basic: OK\n");
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "256.1.1.1") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "1.999.1.1") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "192.168.1") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "192.168.1.1.1") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, ".1.2.3") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "1.2.3.") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "1..2.3") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "1.2.a.3") == -1);
|
||||
printf("ip2bytes IPv4 invalid: OK\n");
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "2001:db8:85a3:0:0:8a2e:370:7334") == 0);
|
||||
ip_expected[0] = 0x20; ip_expected[1] = 0x01;
|
||||
ip_expected[2] = 0x0d; ip_expected[3] = 0xb8;
|
||||
ip_expected[4] = 0x85; ip_expected[5] = 0xa3;
|
||||
ip_expected[6] = 0x00; ip_expected[7] = 0x00;
|
||||
ip_expected[8] = 0x00; ip_expected[9] = 0x00;
|
||||
ip_expected[10] = 0x8a; ip_expected[11] = 0x2e;
|
||||
ip_expected[12] = 0x03; ip_expected[13] = 0x70;
|
||||
ip_expected[14] = 0x73; ip_expected[15] = 0x34;
|
||||
assert(memcmp(ip_bytes, ip_expected, 16) == 0);
|
||||
printf("ip2bytes(2001:db8:85a3:0:0:8a2e:370:7334): OK\n");
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "::1") == 0);
|
||||
memset(ip_expected, 0, 16);
|
||||
ip_expected[15] = 1;
|
||||
assert(memcmp(ip_bytes, ip_expected, 16) == 0);
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "::") == 0);
|
||||
memset(ip_expected, 0, 16);
|
||||
assert(memcmp(ip_bytes, ip_expected, 16) == 0);
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "2001:db8::1") == 0);
|
||||
assert(sodium_ip2bin(ip_bytes, "fe80::1") == 0);
|
||||
printf("ip2bytes IPv6 compressed: OK\n");
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "fe80::1%eth0") == 0);
|
||||
assert(sodium_ip2bin(ip_bytes, "fe80::1%15") == 0);
|
||||
printf("ip2bytes IPv6 zone: OK\n");
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "2001:::1") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "2001::1::1") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "1:2:3:4:5:6:7:8:9") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "12345:1:1:1:1:1:1:1") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "2001:db8:g:1:1:1:1:1") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, ":2001:db8::1") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "2001:db8:1:") == -1);
|
||||
assert(sodium_ip2bin(ip_bytes, "fe80::1%") == -1);
|
||||
printf("ip2bytes IPv6 invalid: OK\n");
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "::ffff:192.168.1.1") == 0);
|
||||
memset(ip_expected, 0, 10);
|
||||
ip_expected[10] = 0xff;
|
||||
ip_expected[11] = 0xff;
|
||||
ip_expected[12] = 192;
|
||||
ip_expected[13] = 168;
|
||||
ip_expected[14] = 1;
|
||||
ip_expected[15] = 1;
|
||||
assert(memcmp(ip_bytes, ip_expected, 16) == 0);
|
||||
printf("ip2bytes IPv4-mapped: OK\n");
|
||||
|
||||
printf("ip NULL handling: OK\n");
|
||||
|
||||
memset(ip_bytes, 0, 10);
|
||||
ip_bytes[10] = 0xff;
|
||||
ip_bytes[11] = 0xff;
|
||||
ip_bytes[12] = 192;
|
||||
ip_bytes[13] = 168;
|
||||
ip_bytes[14] = 1;
|
||||
ip_bytes[15] = 1;
|
||||
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
|
||||
assert(strcmp(ip_str, "192.168.1.1") == 0);
|
||||
|
||||
ip_bytes[12] = 0;
|
||||
ip_bytes[13] = 0;
|
||||
ip_bytes[14] = 0;
|
||||
ip_bytes[15] = 0;
|
||||
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
|
||||
assert(strcmp(ip_str, "0.0.0.0") == 0);
|
||||
|
||||
ip_bytes[12] = 255;
|
||||
ip_bytes[13] = 255;
|
||||
ip_bytes[14] = 255;
|
||||
ip_bytes[15] = 255;
|
||||
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
|
||||
assert(strcmp(ip_str, "255.255.255.255") == 0);
|
||||
printf("bytes2ip IPv4: OK\n");
|
||||
|
||||
memset(ip_bytes, 0, 16);
|
||||
ip_bytes[15] = 1;
|
||||
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
|
||||
assert(strcmp(ip_str, "::1") == 0);
|
||||
|
||||
memset(ip_bytes, 0, 16);
|
||||
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
|
||||
assert(strcmp(ip_str, "::") == 0);
|
||||
|
||||
memset(ip_bytes, 0xff, 16);
|
||||
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
|
||||
assert(strcmp(ip_str, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") == 0);
|
||||
printf("bytes2ip IPv6: OK\n");
|
||||
|
||||
memset(ip_bytes, 0, 10);
|
||||
ip_bytes[10] = 0xff;
|
||||
ip_bytes[11] = 0xff;
|
||||
ip_bytes[12] = 255;
|
||||
ip_bytes[13] = 255;
|
||||
ip_bytes[14] = 255;
|
||||
ip_bytes[15] = 255;
|
||||
assert(sodium_bin2ip(ip_str, 16, ip_bytes) != NULL);
|
||||
assert(sodium_bin2ip(ip_str, 15, ip_bytes) == NULL);
|
||||
|
||||
memset(ip_bytes, 0xff, 16);
|
||||
assert(sodium_bin2ip(ip_str, 40, ip_bytes) != NULL);
|
||||
assert(sodium_bin2ip(ip_str, 39, ip_bytes) == NULL);
|
||||
|
||||
memset(ip_bytes, 0, 16);
|
||||
assert(sodium_bin2ip(ip_str, 3, ip_bytes) != NULL);
|
||||
assert(sodium_bin2ip(ip_str, 2, ip_bytes) == NULL);
|
||||
printf("bytes2ip buffer size: OK\n");
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "10.20.30.40") == 0);
|
||||
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
|
||||
assert(strcmp(ip_str, "10.20.30.40") == 0);
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "::1") == 0);
|
||||
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
|
||||
assert(strcmp(ip_str, "::1") == 0);
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "2001:db8::1") == 0);
|
||||
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
|
||||
assert(strcmp(ip_str, "2001:db8::1") == 0);
|
||||
|
||||
assert(sodium_ip2bin(ip_bytes, "2001:db8:85a3:1234:5678:8a2e:370:7334") == 0);
|
||||
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
|
||||
assert(strcmp(ip_str, "2001:db8:85a3:1234:5678:8a2e:370:7334") == 0);
|
||||
printf("ip round-trip: OK\n");
|
||||
|
||||
{
|
||||
unsigned char lower[16], upper[16], mixed[16];
|
||||
assert(sodium_ip2bin(lower, "abcd:ef01:2345:6789:abcd:ef01:2345:6789") == 0);
|
||||
assert(sodium_ip2bin(upper, "ABCD:EF01:2345:6789:ABCD:EF01:2345:6789") == 0);
|
||||
assert(sodium_ip2bin(mixed, "AbCd:eF01:2345:6789:aBcD:Ef01:2345:6789") == 0);
|
||||
assert(memcmp(lower, upper, 16) == 0);
|
||||
assert(memcmp(lower, mixed, 16) == 0);
|
||||
}
|
||||
printf("ip case insensitive: OK\n");
|
||||
|
||||
{
|
||||
unsigned char direct[16], mapped[16];
|
||||
assert(sodium_ip2bin(direct, "192.168.1.1") == 0);
|
||||
assert(sodium_ip2bin(mapped, "::ffff:192.168.1.1") == 0);
|
||||
assert(memcmp(direct, mapped, 16) == 0);
|
||||
}
|
||||
printf("ip IPv4-mapped equivalence: OK\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -28,3 +28,18 @@ ZXkgaW50by Bzb3VuZA==]
|
||||
[This is a journ]
|
||||
[
|
||||
ZXkgaW50by Bzb3VuZA==]
|
||||
ip2bytes(192.168.1.1): OK
|
||||
ip2bytes IPv4 basic: OK
|
||||
ip2bytes IPv4 invalid: OK
|
||||
ip2bytes(2001:db8:85a3:0:0:8a2e:370:7334): OK
|
||||
ip2bytes IPv6 compressed: OK
|
||||
ip2bytes IPv6 zone: OK
|
||||
ip2bytes IPv6 invalid: OK
|
||||
ip2bytes IPv4-mapped: OK
|
||||
ip NULL handling: OK
|
||||
bytes2ip IPv4: OK
|
||||
bytes2ip IPv6: OK
|
||||
bytes2ip buffer size: OK
|
||||
ip round-trip: OK
|
||||
ip case insensitive: OK
|
||||
ip IPv4-mapped equivalence: OK
|
||||
|
||||
Reference in New Issue
Block a user