diff options
| -rw-r--r-- | util/nvmutil/nvmutil.c | 175 |
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; +} |
