blob: 951f75277add156ec1f45e76cd021ea347979f17 [file] [log] [blame]
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <sys/time.h>
#include <OBJECT_IDENTIFIER.h>
#include <RELATIVE-OID.h>
static int
_print(const void *buffer, size_t size, void *app_key) {
(void)app_key;
fwrite(buffer, size, 1, stdout);
return 0;
}
static void
check_OID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf, int ck_len) {
OBJECT_IDENTIFIER_t *oid;
asn_dec_rval_t rval;
unsigned long arcs[10];
int alen;
int i;
printf("%03d: Checking {", lineno);
for(i = 0; i < (int)len; i++) { printf("%s%02x", i?" ":"", buf[i]); }
printf("} against {");
for(i = 0; i < ck_len; i++) { printf("%s%u", i?" ":"", ck_buf[i]); }
printf("}\n");
oid = NULL;
rval = ber_decode(0, &asn_DEF_OBJECT_IDENTIFIER, (void *)&oid, buf, len);
assert(rval.code == RC_OK);
assert((ssize_t)oid->size == (ssize_t)len - 2);
/*
* Print the contents for visual debugging.
*/
printf("OBJECT_IDENTIFIER_print() => ");
OBJECT_IDENTIFIER_print(&asn_DEF_OBJECT_IDENTIFIER, oid, 0, _print, 0);
printf("\n");
memset(arcs, 'A', sizeof(arcs));
alen = OBJECT_IDENTIFIER_get_arcs(oid,
arcs, sizeof(arcs[0]), sizeof(arcs)/sizeof(arcs[0]));
assert(alen > 0);
printf("OBJECT_IDENTIFIER_get_arcs() => {");
/*
* Make sure they are equivalent.
*/
for(i = 0; i < alen; i++) {
printf(" %lu", arcs[i]);
if(alen == ck_len) {
assert(arcs[i] == ck_buf[i]);
}
}
printf(" }\n");
assert(alen == ck_len);
ASN_STRUCT_FREE(asn_DEF_OBJECT_IDENTIFIER, oid);
}
static void
check_ROID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf, int ck_len) {
RELATIVE_OID_t *oid;
asn_dec_rval_t rval;
unsigned long arcs[10];
int alen;
int i;
printf("%03d: Checking {", lineno);
for(i = 0; i < (ssize_t)len; i++) { printf("%s%02x", i?" ":"", buf[i]); }
printf("} against {");
for(i = 0; i < ck_len; i++) { printf("%s%u", i?" ":"", ck_buf[i]); }
printf("}\n");
oid = NULL;
rval = ber_decode(0, &asn_DEF_RELATIVE_OID, (void *)&oid, buf, len);
assert(rval.code == RC_OK);
assert((ssize_t)oid->size == (ssize_t)len - 2);
/*
* Print the contents for visual debugging.
*/
printf("RELATIVE_OID_print() => ");
RELATIVE_OID_print(&asn_DEF_RELATIVE_OID, oid, 0, _print, 0);
printf("\n");
memset(arcs, 'A', sizeof(arcs));
alen = RELATIVE_OID_get_arcs(oid,
arcs, sizeof(arcs[0]), sizeof(arcs)/sizeof(arcs[0]));
assert(alen > 0);
assert(alen == ck_len);
/*
* Make sure they are equivalent.
*/
printf("RELATIVE_OID_get_arcs() => {");
for(i = 0; i < alen; i++) {
printf(" %lu", arcs[i]);
assert(arcs[i] == ck_buf[i]);
}
printf(" }\n");
ASN_STRUCT_FREE(asn_DEF_RELATIVE_OID, oid);
}
static int
check_speed() {
uint8_t buf[] = { 0x80 | 7, 0x80 | 2, 0x80 | 3, 0x80 | 4, 13 };
int ret = 0;
int cycles = 100000000;
double a, b, c;
struct timeval tv;
unsigned long value;
int i;
ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), 0, &value, sizeof(value));
assert(ret == 0);
assert(value == 0x7040c20d);
gettimeofday(&tv, 0);
a = tv.tv_sec + tv.tv_usec / 1000000.0;
for(i = 0; i < cycles; i++) {
ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), 0,
&value, sizeof(value));
}
assert(ret == 0);
assert(value == 0x7040c20d);
gettimeofday(&tv, 0);
b = tv.tv_sec + tv.tv_usec / 1000000.0;
for(i = 0; i < cycles; i++) {
ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), 0,
&value, sizeof(value));
}
assert(ret == 0);
assert(value == 0x7040c20d);
gettimeofday(&tv, 0);
c = tv.tv_sec + tv.tv_usec / 1000000.0;
a = b - a;
b = c - b;
printf("Time for single_arc(): %f\n", a);
printf("Time for get_arc_l(): %f\n", b);
return 0;
}
static void check_parse(const char *oid_txt, int retval) {
int ret;
long l[2];
const char *p = oid_txt - 13;
assert(p < oid_txt);
ret = OBJECT_IDENTIFIER_parse_arcs(oid_txt, -1, l, 2, &p);
printf("[%s] => %d == %d\n", oid_txt, ret, retval);
assert(ret == retval);
assert(p >= oid_txt);
}
static void check_xer(int expect_arcs, char *xer) {
asn_dec_rval_t rc;
RELATIVE_OID_t *st = 0;
long arcs[10];
int ret;
int i;
printf("[%s] => ", xer); fflush(stdout);
rc = asn_DEF_RELATIVE_OID.op->xer_decoder(0,
&asn_DEF_RELATIVE_OID, (void **)&st, "t",
xer, strlen(xer));
if(expect_arcs == -1) {
if(rc.code != RC_OK) {
printf("-1\n");
ASN_STRUCT_FREE(asn_DEF_RELATIVE_OID, st);
return;
}
}
assert(rc.code == RC_OK);
ret = RELATIVE_OID_get_arcs(st, arcs, sizeof(arcs[0]),
sizeof(arcs)/sizeof(arcs[0]));
assert(ret < 10);
if(expect_arcs == -1) {
assert(ret == -1);
ASN_STRUCT_FREE(asn_DEF_RELATIVE_OID, st);
return;
}
for(i = 0; i < ret; i++) {
if(i) printf(".");
printf("%ld", arcs[i]);
if(arcs[i] != i + 1) printf(" != %d\n", i + 1);
assert(arcs[i] == i + 1);
}
printf(": %d == %d\n", ret, expect_arcs);
assert(ret == expect_arcs);
ASN_STRUCT_FREE(asn_DEF_RELATIVE_OID, st);
}
#define CHECK_OID(n) \
check_OID(__LINE__, buf##n, sizeof(buf##n), buf##n##_check, \
sizeof(buf##n##_check) / sizeof(buf##n##_check[0]))
#define CHECK_ROID(n) \
check_ROID(__LINE__, buf##n, sizeof(buf##n), buf##n##_check, \
sizeof(buf##n##_check) / sizeof(buf##n##_check[0]))
static void
check_binary_parsing() {
/* {joint-iso-itu-t 230 3} */
uint8_t buf1[] = {
0x06, /* OBJECT IDENTIFIER */
0x03, /* Length */
0x82, 0x36, 0x03
};
unsigned buf1_check[] = { 2, 230, 3 };
/* {8571 3 2} */
uint8_t buf2[] = {
0x0D, /* RELATIVE-OID */
0x04, /* Length */
0xC2, 0x7B, 0x03, 0x02
};
unsigned buf2_check[] = { 8571, 3, 2 };
/* {joint-iso-itu-t 42 } */
uint8_t buf3[] = {
0x06, /* OBJECT IDENTIFIER */
0x01, /* Length */
0x7A
};
unsigned buf3_check[] = { 2, 42 };
/* {joint-iso-itu-t 25957 } */
uint8_t buf4[] = {
0x06, /* OBJECT IDENTIFIER */
0x03, /* Length */
0x81, 0x80 + 0x4B, 0x35
};
unsigned buf4_check[] = { 2, 25957 };
/* { jounsigned-iso-itu-t 2 1 1 } */
uint8_t buf5[] = {
0x06, /* OBJECT IDENTIFIER */
0x03, /* Length */
0x52, 0x01, 0x01
};
unsigned buf5_check[] = { 2, 2, 1, 1 };
/* { jounsigned-iso-itu-t 2 1 0 1 } */
uint8_t buf6[] = {
0x06, /* OBJECT IDENTIFIER */
0x04, /* Length */
0x52, 0x01, 0x00, 0x01
};
unsigned buf6_check[] = { 2, 2, 1, 0, 1 };
CHECK_OID(1);
CHECK_ROID(2);
CHECK_OID(3);
CHECK_OID(4);
CHECK_OID(5);
CHECK_OID(6);
}
static void
check_text_parsing() {
check_parse("", 0);
check_parse(" ", 0);
check_parse(".", -1);
check_parse(" .", -1);
check_parse(".1", -1);
check_parse("1.", -1);
check_parse("1. ", -1);
check_parse(".1. ", -1);
check_parse(" .1. ", -1);
check_parse(" 1", 1);
check_parse(" 1.2", 2);
check_parse(" 1.", -1);
check_parse(" 1. ", -1);
check_parse("1. ", -1);
check_parse("1.2", 2);
check_parse("1.2 ", 2);
check_parse("1.2 ", 2);
check_parse(" 1.2 ", 2);
check_parse("1. 2", -1);
check_parse("1 .2", -1);
check_parse(" 1 .2", -1);
check_parse(" 1 .2 ", -1);
check_parse("1 .2 ", -1);
check_parse("1.+1", -1);
check_parse("10.30.234.234", 4);
check_parse("10.30.234.234 ", 4);
check_parse("10.30.234. 234 ", -1);
check_parse("10.30.234.234.", -1);
check_parse("1.2000000000.3", 3);
check_parse("1.2147483647.3", 3);
if(sizeof(long) == 4) {
check_parse("1.2147483648.3", -1); /* overflow on ILP32 */
check_parse("1.2147483649.3", -1); /* overflow on ILP32 */
check_parse("1.3000000000.3", -1);
check_parse("1.4000000000.3", -1);
check_parse("1.5000000000.3", -1);
check_parse("1.6000000000.3", -1);
check_parse("1.9000000000.3", -1);
} else if(sizeof(long) == 8) {
check_parse("1.2147483648.3", 3);
check_parse("1.9223372036854775807.3", 3);
check_parse("1.9223372036854775808.3", -1);
}
check_parse("1.900a0000000.3", -1);
check_parse("1.900a.3", -1);
}
static void
check_xer_parsing() {
check_xer(-1, "<t></t>");
check_xer(2, "<t>1.2</t>");
check_xer(3, "<t>1.2.3</t>");
check_xer(3, "<t> 1.2.3 </t>");
check_xer(-1, "<t>1.2.3 1</t>");
}
int
main() {
check_binary_parsing();
check_text_parsing();
check_xer_parsing();
if(getenv("CHECK_SPEED")) {
/* Useful for developers only */
check_speed();
}
return 0;
}