util.c revision 1.2.4.2 1 1.2.4.2 pgoyette /* $NetBSD: util.c,v 1.2.4.2 2018/04/22 07:20:16 pgoyette Exp $ */
2 1.2.4.2 pgoyette
3 1.2.4.2 pgoyette /*-
4 1.2.4.2 pgoyette * Copyright (c) 2017 Netflix, Inc
5 1.2.4.2 pgoyette * All rights reserved.
6 1.2.4.2 pgoyette *
7 1.2.4.2 pgoyette * Redistribution and use in source and binary forms, with or without
8 1.2.4.2 pgoyette * modification, are permitted provided that the following conditions
9 1.2.4.2 pgoyette * are met:
10 1.2.4.2 pgoyette * 1. Redistributions of source code must retain the above copyright
11 1.2.4.2 pgoyette * notice, this list of conditions and the following disclaimer.
12 1.2.4.2 pgoyette * 2. Redistributions in binary form must reproduce the above copyright
13 1.2.4.2 pgoyette * notice, this list of conditions and the following disclaimer in the
14 1.2.4.2 pgoyette * documentation and/or other materials provided with the distribution.
15 1.2.4.2 pgoyette *
16 1.2.4.2 pgoyette * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 1.2.4.2 pgoyette * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 1.2.4.2 pgoyette * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 1.2.4.2 pgoyette * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 1.2.4.2 pgoyette * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 1.2.4.2 pgoyette * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 1.2.4.2 pgoyette * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 1.2.4.2 pgoyette * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 1.2.4.2 pgoyette * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 1.2.4.2 pgoyette * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 1.2.4.2 pgoyette * SUCH DAMAGE.
27 1.2.4.2 pgoyette */
28 1.2.4.2 pgoyette
29 1.2.4.2 pgoyette #include <sys/cdefs.h>
30 1.2.4.2 pgoyette #ifndef lint
31 1.2.4.2 pgoyette __RCSID("$NetBSD: util.c,v 1.2.4.2 2018/04/22 07:20:16 pgoyette Exp $");
32 1.2.4.2 pgoyette #if 0
33 1.2.4.2 pgoyette __FBSDID("$FreeBSD: head/sbin/nvmecontrol/util.c 320423 2017-06-27 20:24:25Z imp $");
34 1.2.4.2 pgoyette #endif
35 1.2.4.2 pgoyette #endif
36 1.2.4.2 pgoyette
37 1.2.4.2 pgoyette #include <sys/endian.h>
38 1.2.4.2 pgoyette
39 1.2.4.2 pgoyette #include <stdlib.h>
40 1.2.4.2 pgoyette #include <string.h>
41 1.2.4.2 pgoyette
42 1.2.4.2 pgoyette #include "nvmectl.h"
43 1.2.4.2 pgoyette #include "bn.h"
44 1.2.4.2 pgoyette
45 1.2.4.2 pgoyette void
46 1.2.4.2 pgoyette nvme_strvis(u_char *dst, int dlen, const u_char *src, int slen)
47 1.2.4.2 pgoyette {
48 1.2.4.2 pgoyette #define STRVIS_ISWHITE(x) ((x) == ' ' || (x) == '\0' || (x) == (u_char)'\377')
49 1.2.4.2 pgoyette /* Trim leading and trailing blanks and NULs. */
50 1.2.4.2 pgoyette while (slen > 0 && STRVIS_ISWHITE(src[0]))
51 1.2.4.2 pgoyette ++src, --slen;
52 1.2.4.2 pgoyette while (slen > 0 && STRVIS_ISWHITE(src[slen - 1]))
53 1.2.4.2 pgoyette --slen;
54 1.2.4.2 pgoyette
55 1.2.4.2 pgoyette while (slen > 0) {
56 1.2.4.2 pgoyette if (*src < 0x20 || *src >= 0x80) {
57 1.2.4.2 pgoyette /* non-printable characters */
58 1.2.4.2 pgoyette dlen -= 4;
59 1.2.4.2 pgoyette if (dlen < 1)
60 1.2.4.2 pgoyette break;
61 1.2.4.2 pgoyette *dst++ = '\\';
62 1.2.4.2 pgoyette *dst++ = ((*src & 0300) >> 6) + '0';
63 1.2.4.2 pgoyette *dst++ = ((*src & 0070) >> 3) + '0';
64 1.2.4.2 pgoyette *dst++ = ((*src & 0007) >> 0) + '0';
65 1.2.4.2 pgoyette } else if (*src == '\\') {
66 1.2.4.2 pgoyette /* quote characters */
67 1.2.4.2 pgoyette dlen -= 2;
68 1.2.4.2 pgoyette if (dlen < 1)
69 1.2.4.2 pgoyette break;
70 1.2.4.2 pgoyette *dst++ = '\\';
71 1.2.4.2 pgoyette *dst++ = '\\';
72 1.2.4.2 pgoyette } else {
73 1.2.4.2 pgoyette /* normal characters */
74 1.2.4.2 pgoyette if (--dlen < 1)
75 1.2.4.2 pgoyette break;
76 1.2.4.2 pgoyette *dst++ = *src;
77 1.2.4.2 pgoyette }
78 1.2.4.2 pgoyette ++src, --slen;
79 1.2.4.2 pgoyette }
80 1.2.4.2 pgoyette
81 1.2.4.2 pgoyette *dst++ = 0;
82 1.2.4.2 pgoyette }
83 1.2.4.2 pgoyette
84 1.2.4.2 pgoyette #define METRIX_PREFIX_BUFSIZ 17
85 1.2.4.2 pgoyette #define NO_METRIX_PREFIX_BUFSIZ 42
86 1.2.4.2 pgoyette
87 1.2.4.2 pgoyette void
88 1.2.4.2 pgoyette print_bignum(const char *title, uint64_t v[2], const char *suffix)
89 1.2.4.2 pgoyette {
90 1.2.4.2 pgoyette char buf[64];
91 1.2.4.2 pgoyette uint8_t tmp[16];
92 1.2.4.2 pgoyette uint64_t h, l;
93 1.2.4.2 pgoyette
94 1.2.4.2 pgoyette #if _BYTE_ORDER != _LITTLE_ENDIAN
95 1.2.4.2 pgoyette /* Already Converted to host endian */
96 1.2.4.2 pgoyette h = v[0];
97 1.2.4.2 pgoyette l = v[1];
98 1.2.4.2 pgoyette memcpy(tmp, v, sizeof(tmp));
99 1.2.4.2 pgoyette #else
100 1.2.4.2 pgoyette h = v[1];
101 1.2.4.2 pgoyette l = v[0];
102 1.2.4.2 pgoyette
103 1.2.4.2 pgoyette tmp[ 0] = (h >> 56) & 0xff;
104 1.2.4.2 pgoyette tmp[ 1] = (h >> 48) & 0xff;
105 1.2.4.2 pgoyette tmp[ 2] = (h >> 40) & 0xff;
106 1.2.4.2 pgoyette tmp[ 3] = (h >> 32) & 0xff;
107 1.2.4.2 pgoyette tmp[ 4] = (h >> 24) & 0xff;
108 1.2.4.2 pgoyette tmp[ 5] = (h >> 16) & 0xff;
109 1.2.4.2 pgoyette tmp[ 6] = (h >> 8) & 0xff;
110 1.2.4.2 pgoyette tmp[ 7] = h & 0xff;
111 1.2.4.2 pgoyette tmp[ 8] = (l >> 56) & 0xff;
112 1.2.4.2 pgoyette tmp[ 9] = (l >> 48) & 0xff;
113 1.2.4.2 pgoyette tmp[10] = (l >> 40) & 0xff;
114 1.2.4.2 pgoyette tmp[11] = (l >> 32) & 0xff;
115 1.2.4.2 pgoyette tmp[12] = (l >> 24) & 0xff;
116 1.2.4.2 pgoyette tmp[13] = (l >> 16) & 0xff;
117 1.2.4.2 pgoyette tmp[14] = (l >> 8) & 0xff;
118 1.2.4.2 pgoyette tmp[15] = l & 0xff;
119 1.2.4.2 pgoyette #endif
120 1.2.4.2 pgoyette
121 1.2.4.2 pgoyette buf[0] = '\0';
122 1.2.4.2 pgoyette BIGNUM *bn = BN_bin2bn(tmp, sizeof(tmp), NULL);
123 1.2.4.2 pgoyette if (bn != NULL) {
124 1.2.4.2 pgoyette humanize_bignum(buf, METRIX_PREFIX_BUFSIZ + strlen(suffix),
125 1.2.4.2 pgoyette bn, suffix, HN_AUTOSCALE, HN_DECIMAL);
126 1.2.4.2 pgoyette BN_free(bn);
127 1.2.4.2 pgoyette }
128 1.2.4.2 pgoyette if (buf[0] == '\0')
129 1.2.4.2 pgoyette snprintf(buf, sizeof(buf), "0x%016" PRIx64 "%016" PRIx64, h, l);
130 1.2.4.2 pgoyette printf("%-31s %s\n", title, buf);
131 1.2.4.2 pgoyette }
132 1.2.4.2 pgoyette
133 1.2.4.2 pgoyette /* "Missing" from endian.h */
134 1.2.4.2 pgoyette uint64_t
135 1.2.4.2 pgoyette le48dec(const void *pp)
136 1.2.4.2 pgoyette {
137 1.2.4.2 pgoyette uint8_t const *p = (uint8_t const *)pp;
138 1.2.4.2 pgoyette
139 1.2.4.2 pgoyette return (((uint64_t)le16dec(p + 4) << 32) | le32dec(p));
140 1.2.4.2 pgoyette }
141