summaryrefslogtreecommitdiff
path: root/util/nvmutil
diff options
context:
space:
mode:
Diffstat (limited to 'util/nvmutil')
-rw-r--r--util/nvmutil/nvmutil.c121
1 files changed, 57 insertions, 64 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c
index f86e88bf..7c0d0c31 100644
--- a/util/nvmutil/nvmutil.c
+++ b/util/nvmutil/nvmutil.c
@@ -20,15 +20,12 @@ void cmd_setchecksum(void), cmd_brick(void), swap(int partnum), writeGbe(void),
parseMacString(const char *strMac, uint16_t *mac), cmd_swap(void),
openFiles(const char *path), cmd_copy(void), writeGbe_part(int),
readGbe_part(int), usage(char*), set_io_flags(int, char **),
- set_cmd(int, char **), setWord(int, int, uint16_t), check_bounds(int, int);
+ set_cmd(int, char **), setWord(int, int, uint16_t), check_bounds(int, int),
+ xopen (int *, const char *, int p, struct stat *);
int goodChecksum(int partnum);
uint8_t hextonum(char chs), rhex(void);
uint16_t word(int, int);
-#ifdef __OpenBSD__
-void block_unveil(void);
-#endif
-
#define COMMAND argv[2]
#define MAC_ADDRESS argv[3]
#define PARTN argv[3]
@@ -43,10 +40,10 @@ void block_unveil(void);
uint16_t mac[3] = {0, 0, 0};
ssize_t nf;
-size_t partsize, gbe[2];
+size_t partsize;
+uint8_t *gbe[2];
uint8_t nvmPartChanged[2] = {0, 0}, do_read[2] = {1, 1};
int flags, rfd, fd, part, e = 1;
-struct stat st;
const char *strMac = NULL, *strRMac = "xx:xx:xx:xx:xx:xx", *fname = NULL;
@@ -56,23 +53,17 @@ typedef struct op {
int args;
} op_t;
op_t op[] = {
-{ .str = "dump", .cmd = cmd_dump, .args = 3},
-{ .str = "setmac", .cmd = cmd_setmac, .args = 3},
-{ .str = "swap", .cmd = cmd_swap, .args = 3},
-{ .str = "copy", .cmd = cmd_copy, .args = 4},
-{ .str = "brick", .cmd = cmd_brick, .args = 4},
-{ .str = "setchecksum", .cmd = cmd_setchecksum, .args = 4},
+{ .str = "dump", .cmd = cmd_dump, .args = 3 },
+{ .str = "setmac", .cmd = cmd_setmac, .args = 3 },
+{ .str = "swap", .cmd = cmd_swap, .args = 3 },
+{ .str = "copy", .cmd = cmd_copy, .args = 4 },
+{ .str = "brick", .cmd = cmd_brick, .args = 4 },
+{ .str = "setchecksum", .cmd = cmd_setchecksum, .args = 4 },
};
void (*cmd)(void) = NULL;
-#define SET_ERR(x) errno = errno ? errno : x
-#define err_if(x) if (x) err(SET_ERR(ECANCELED), "%s", fname)
-
-#define xopen(f,l,p) \
- if ((f = open(l, p)) == -1) \
- err(SET_ERR(ECANCELED), "%s", l); \
- if (fstat(f, &st) == -1) \
- err(SET_ERR(ECANCELED), "%s", l)
+#define set_err(x) errno = errno ? errno : x
+#define err_if(x) if (x) err(set_err(ECANCELED), "%s", fname)
int
main(int argc, char *argv[])
@@ -86,13 +77,20 @@ main(int argc, char *argv[])
fname = argv[1];
set_io_flags(argc, argv);
#ifdef __OpenBSD__
- block_unveil();
+ if (flags == O_RDONLY) {
+ err_if(unveil(fname, "r") == -1);
+ err_if(unveil(NULL, NULL) == -1);
+ err_if(pledge("stdio rpath", NULL) == -1);
+ } else {
+ err_if(unveil(fname, "rw") == -1);
+ err_if(unveil(NULL, NULL) == -1);
+ err_if(pledge("stdio rpath wpath", NULL) == -1);
+ }
#endif
openFiles(fname);
#ifdef __OpenBSD__
err_if(pledge("stdio", NULL) == -1);
#endif
-
nvmalloc();
readGbe();
(*cmd)();
@@ -115,7 +113,7 @@ set_cmd(int argc, char *argv[])
cmd = op[i].cmd;
break;
}
- err(SET_ERR(EINVAL), "Too few args on command '%s'",
+ err(set_err(EINVAL), "Too few args on command '%s'",
op[i].str);
}
} else { /* argc == 2 */
@@ -149,7 +147,7 @@ void
checkdir(const char *path)
{
if (opendir(path) != NULL)
- err(SET_ERR(EISDIR), "%s", path);
+ err(set_err(EISDIR), "%s", path);
if (errno == ENOTDIR)
errno = 0;
err_if(errno);
@@ -158,11 +156,13 @@ checkdir(const char *path)
void
openFiles(const char *path)
{
+ struct stat st;
+
checkdir("/dev/urandom");
checkdir(fname);
- xopen(rfd, "/dev/urandom", O_RDONLY);
- xopen(fd, path, flags);
+ xopen(&rfd, "/dev/urandom", O_RDONLY, &st);
+ xopen(&fd, path, flags, &st);
switch(st.st_size) {
case SIZE_8KB:
@@ -171,12 +171,21 @@ openFiles(const char *path)
partsize = st.st_size >> 1;
break;
default:
- err(SET_ERR(ECANCELED), "Invalid file size (not 8/16/128KiB)");
+ err(set_err(ECANCELED), "Invalid file size (not 8/16/128KiB)");
break;
}
}
void
+xopen(int *f, const char *l, int p, struct stat *st)
+{
+ if ((*f = open(l, p)) == -1) \
+ err(set_err(ECANCELED), "%s", l); \
+ if (fstat(*f, st) == -1) \
+ err(set_err(ECANCELED), "%s", l);
+}
+
+void
nvmalloc(void)
{
/* same operations need the full block, others only 128 bytes */
@@ -189,11 +198,11 @@ nvmalloc(void)
do_read[part ^ 1] = 0;
/* only allocate one block if only one part being read */
- char *buf = malloc(nf << (do_read[0] & do_read[1]));
+ uint8_t *buf = (uint8_t *) malloc(nf << (do_read[0] & do_read[1]));
if (buf == NULL)
err(errno, NULL);
- gbe[0] = (size_t) buf;
+ gbe[0] = buf;
/* speedhack: for cmd copy, both pointers are set the same */
gbe[1] = gbe[0] + (nf * (do_read[0] & do_read[1]));
@@ -211,7 +220,7 @@ void
readGbe_part(int p)
{
if (pread(fd, (uint8_t *) gbe[p], nf, p * partsize) != nf)
- err(SET_ERR(ECANCELED),
+ err(set_err(ECANCELED),
"Can't read %ld b from '%s' p%d", nf, fname, p);
swap(p); /* handle big-endian host CPU */
}
@@ -247,12 +256,12 @@ parseMacString(const char *strMac, uint16_t *mac)
{
uint64_t total = 0;
if (strnlen(strMac, 20) != 17)
- err(SET_ERR(EINVAL), "Invalid MAC address string length");
+ err(set_err(EINVAL), "Invalid MAC address string length");
for (uint8_t h, i = 0; i < 16; i += 3) {
if (i != 15)
if (strMac[i + 2] != ':')
- err(SET_ERR(EINVAL),
+ err(set_err(EINVAL),
"Invalid MAC address separator '%c'",
strMac[i + 2]);
@@ -260,7 +269,7 @@ parseMacString(const char *strMac, uint16_t *mac)
for (int nib = 0; nib < 2; nib++, total += h) {
if ((h = hextonum(strMac[i + nib])) > 15)
- err(SET_ERR(EINVAL), "Invalid character '%c'",
+ err(set_err(EINVAL), "Invalid character '%c'",
strMac[i + nib]);
/* If random, ensure that local/unicast bits are set */
@@ -276,9 +285,9 @@ parseMacString(const char *strMac, uint16_t *mac)
}
if (total == 0)
- err(SET_ERR(EINVAL), "Invalid MAC (all-zero MAC address)");
+ err(set_err(EINVAL), "Invalid MAC (all-zero MAC address)");
if (mac[0] & 1)
- err(SET_ERR(EINVAL), "Invalid MAC (multicast bit set)");
+ err(set_err(EINVAL), "Invalid MAC (multicast bit set)");
}
uint8_t
@@ -381,9 +390,9 @@ cmd_swap(void) {
err_if(!(goodChecksum(0) || goodChecksum(1)));
errno = 0;
- gbe[0] ^= gbe[1];
- gbe[1] ^= gbe[0];
- gbe[0] ^= gbe[1];
+ uint8_t *chg = gbe[0];
+ gbe[0] = gbe[1];
+ gbe[1] = chg;
nvmPartChanged[0] = nvmPartChanged[1] = 1;
}
@@ -399,7 +408,7 @@ goodChecksum(int partnum)
return 1;
fprintf(stderr, "WARNING: BAD checksum in part %d\n", partnum);
- SET_ERR(ECANCELED);
+ set_err(ECANCELED);
return 0;
}
@@ -424,9 +433,9 @@ void
check_bounds(int c, int p)
{
if ((p != 0) && (p != 1))
- err(SET_ERR(EINVAL), "check_bounds: invalid partnum %d", p);
- if ((c < 0) || (c > nf))
- err(SET_ERR(EINVAL), "check_bounds: out of bounds %d", c);
+ err(set_err(EINVAL), "check_bounds: invalid partnum %d", p);
+ if ((c < 0) || (c > ((nf >> 1) - 1)))
+ err(set_err(EINVAL), "check_bounds: out of bounds %d", c);
}
void
@@ -443,7 +452,7 @@ writeGbe_part(int p)
{
swap(p); /* swap bytes on big-endian host CPUs */
if(pwrite(fd, (uint8_t *) gbe[p], nf, p * partsize) != nf)
- err(SET_ERR(ECANCELED),
+ err(set_err(ECANCELED),
"Can't write %ld b to '%s' p%d", nf, fname, p);
}
@@ -451,32 +460,16 @@ writeGbe_part(int p)
void
swap(int partnum)
{
- uint8_t *n = (uint8_t *) gbe[partnum];
+ uint8_t *n = gbe[partnum];
for (size_t w = NVM_SIZE * ((uint8_t *) &e)[0], x = 1;
w < NVM_SIZE; w += 2, x += 2) {
+ uint8_t chg = n[w];
n[w] ^= n[x];
- n[x] ^= n[w];
- n[w] ^= n[x];
+ n[x] ^= chg;
}
}
-#ifdef __OpenBSD__
-void
-block_unveil(void)
-{
- if (flags == O_RDONLY) {
- err_if(unveil(fname, "r") == -1);
- err_if(unveil(NULL, NULL) == -1);
- err_if(pledge("stdio rpath", NULL) == -1);
- } else {
- err_if(unveil(fname, "rw") == -1);
- err_if(unveil(NULL, NULL) == -1);
- err_if(pledge("stdio rpath wpath", NULL) == -1);
- }
-}
-#endif
-
void
usage(char *util)
{
@@ -494,5 +487,5 @@ usage(char *util)
" %s FILE brick 0|1\n"
" %s FILE setchecksum 0|1\n",
util, util, util, util, util, util, util);
- err(SET_ERR(ECANCELED), "Too few arguments");
+ err(set_err(ECANCELED), "Too few arguments");
}