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