summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/nvmutil/nvmutil.c175
1 files changed, 105 insertions, 70 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c
index 6c1d929e..e60501ab 100644
--- a/util/nvmutil/nvmutil.c
+++ b/util/nvmutil/nvmutil.c
@@ -15,14 +15,15 @@
#include <unistd.h>
void cmd_setchecksum(void), cmd_brick(void), swap(int partnum), writeGbe(void),
- cmd_dump(void), cmd_setmac(void), readGbe(void),
- checkdir(const char *path), macf(int partnum), hexdump(int partnum),
+ cmd_dump(void), cmd_setmac(void), readGbe(void), print_mac_address(int),
+ hexdump(int), set_mac_nib(int, int, uint8_t *), checkdir(const char *),
parseMacString(const char *strMac, uint16_t *mac), cmd_swap(void),
- openFiles(void), cmd_copy(void), writeGbe_part(int),
- readGbe_part(int), usage(char*), set_io_flags(int, char **),
+ openFiles(void), cmd_copy(void), writeGbe_part(int), readGbe_part(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);
+ xopen(int *, const char *, int p, struct stat *), checkMacSeparator(int),
+ set_mac_byte(int, uint64_t *), usage(char*), set_io_flags(int, char **),
+ err_if(int);
+int goodChecksum(int partnum), write_mac_part(int), set_err(int);
uint8_t hextonum(char chs), rhex(void);
uint16_t word(int, int);
@@ -43,7 +44,7 @@ uint16_t mac[3] = {0, 0, 0};
size_t partsize;
int flags, rfd, fd, part, e = 1;
-const char *strMac = NULL, *strRMac = "xx:xx:xx:xx:xx:xx", *fname = NULL;
+const char *strMac = NULL, *strRMac = "xx:xx:xx:xx:xx:xx", *fname = "";
typedef struct op {
char *str;
@@ -60,9 +61,6 @@ op_t op[] = {
};
void (*cmd)(void) = NULL;
-#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[])
{
@@ -94,7 +92,7 @@ main(int argc, char *argv[])
writeGbe();
err_if((errno != 0) && (cmd != cmd_dump));
- return errno;
+ return errno ? EXIT_FAILURE : EXIT_SUCCESS;
}
void
@@ -141,24 +139,15 @@ set_io_flags(int argc, char *argv[])
}
void
-checkdir(const char *path)
-{
- if (opendir(path) != NULL)
- err(set_err(EISDIR), "%s", path);
- if (errno == ENOTDIR)
- errno = 0;
- err_if(errno);
-}
-
-void
openFiles(void)
{
struct stat st;
+ struct stat st_rfd;
checkdir("/dev/urandom");
checkdir(fname);
- xopen(&rfd, "/dev/urandom", O_RDONLY, &st);
+ xopen(&rfd, "/dev/urandom", O_RDONLY, &st_rfd);
xopen(&fd, fname, flags, &st);
switch(st.st_size) {
@@ -174,12 +163,22 @@ openFiles(void)
}
void
+checkdir(const char *path)
+{
+ struct stat st;
+ if (stat(path, &st) == -1)
+ err(set_err(ECANCELED), "%s", path);
+ if (S_ISDIR(st.st_mode))
+ err(set_err(EISDIR), "%s", path);
+}
+
+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);
+ if ((*f = open(l, p)) == -1)
+ err(set_err(ECANCELED), "%s", l);
+ if (fstat(*f, st) == -1)
+ err(set_err(ECANCELED), "%s", l);
}
void
@@ -206,20 +205,8 @@ cmd_setmac(void)
printf("MAC address to be written: %s\n", strMac);
- for (int partnum = 0; partnum < 2; partnum++) {
- if (!goodChecksum(part = partnum))
- continue;
-
- for (int w = 0; w < 3; w++)
- setWord(w, partnum, mac[w]);
-
- printf("Wrote MAC address to part %d: ", partnum);
- macf(partnum);
-
- cmd_setchecksum();
- mac_updated = 1;
- }
-
+ for (int partnum = 0; partnum < 2; partnum++)
+ mac_updated |= write_mac_part(partnum);
if (mac_updated)
errno = 0;
}
@@ -231,31 +218,8 @@ parseMacString(const char *strMac, uint16_t *mac)
if (strnlen(strMac, 20) != 17)
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),
- "Invalid MAC address separator '%c'",
- strMac[i + 2]);
-
- int byte = i / 3;
-
- for (int nib = 0; nib < 2; nib++, total += h) {
- if ((h = hextonum(strMac[i + nib])) > 15)
- err(set_err(EINVAL), "Invalid character '%c'",
- strMac[i + nib]);
-
- /* If random, ensure that local/unicast bits are set */
- if ((byte == 0) && (nib == 1))
- if ((strMac[i + nib] == '?') ||
- (strMac[i + nib] == 'x') ||
- (strMac[i + nib] == 'X')) /* random */
- h = (h & 0xE) | 2; /* local, unicast */
-
- mac[byte >> 1] |= ((uint16_t ) h)
- << ((8 * (byte % 2)) + (4 * (nib ^ 1)));
- }
- }
+ for (int strMacPos = 0; strMacPos < 16; strMacPos += 3)
+ set_mac_byte(strMacPos, &total);
if (total == 0)
err(set_err(EINVAL), "Invalid MAC (all-zero MAC address)");
@@ -263,6 +227,47 @@ parseMacString(const char *strMac, uint16_t *mac)
err(set_err(EINVAL), "Invalid MAC (multicast bit set)");
}
+void
+set_mac_byte(int strMacPos, uint64_t *total)
+{
+ uint8_t h = 0;
+ checkMacSeparator(strMacPos);
+
+ for (int nib = 0; nib < 2; nib++, *total += h)
+ set_mac_nib(strMacPos, nib, &h);
+}
+
+void
+checkMacSeparator(int strMacPos)
+{
+ if (strMacPos == 15)
+ return;
+ char separator = strMac[strMacPos + 2];
+ if (separator == ':')
+ return;
+ err(set_err(EINVAL), "Invalid MAC address separator '%c'", separator);
+}
+
+void
+set_mac_nib(int strMacPos, int nib, uint8_t *h)
+{
+ int byte = strMacPos / 3;
+
+ if ((*h = hextonum(strMac[strMacPos + nib])) > 15)
+ err(set_err(EINVAL), "Invalid character '%c'",
+ strMac[strMacPos + nib]);
+
+ /* If random, ensure that local/unicast bits are set */
+ if ((byte == 0) && (nib == 1))
+ if ((strMac[strMacPos + nib] == '?') ||
+ (strMac[strMacPos + nib] == 'x') ||
+ (strMac[strMacPos + nib] == 'X')) /* random */
+ *h = (*h & 0xE) | 2; /* local, unicast */
+
+ mac[byte >> 1] |= ((uint16_t ) *h) << ((8 * (byte % 2)) +
+ (4 * (nib ^ 1)));
+}
+
uint8_t
hextonum(char ch)
{
@@ -286,6 +291,22 @@ rhex(void)
return rnum[n--] & 0xf;
}
+int
+write_mac_part(int partnum)
+{
+ if (!goodChecksum(part = partnum))
+ return 0;
+
+ for (int w = 0; w < 3; w++)
+ setWord(w, partnum, mac[w]);
+
+ printf("Wrote MAC address to part %d: ", partnum);
+ print_mac_address(partnum);
+
+ cmd_setchecksum();
+ return 1;
+}
+
void
cmd_dump(void)
{
@@ -294,7 +315,7 @@ cmd_dump(void)
++numInvalid;
printf("MAC (part %d): ", partnum);
- macf(partnum);
+ print_mac_address(partnum);
hexdump(partnum);
if ((numInvalid < 2) && (partnum))
@@ -303,7 +324,7 @@ cmd_dump(void)
}
void
-macf(int partnum)
+print_mac_address(int partnum)
{
for (int c = 0; c < 3; c++) {
uint16_t val16 = word(c, partnum);
@@ -379,7 +400,7 @@ goodChecksum(int partnum)
return 1;
fprintf(stderr, "WARNING: BAD checksum in part %d\n", partnum);
- set_err(ECANCELED);
+ (void) set_err(ECANCELED);
return 0;
}
@@ -432,8 +453,8 @@ swap(int 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] ^= chg;
+ n[w] = n[x];
+ n[x] = chg;
}
}
@@ -456,3 +477,17 @@ usage(char *util)
util, util, util, util, util, util, util);
err(set_err(ECANCELED), "Too few arguments");
}
+
+void
+err_if(int x)
+{
+ if (x)
+ err(set_err(ECANCELED), "%s", fname);
+}
+
+int
+set_err(int x)
+{
+ errno = errno ? errno : x;
+ return EXIT_FAILURE;
+}