uboot/tools/gen_ethaddr_crc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2016
   4 * Olliver Schinagl <oliver@schinagl.nl>
   5 */
   6
   7#include <ctype.h>
   8#include <stdbool.h>
   9#include <stdint.h>
  10#include <stdio.h>
  11#include <stdlib.h>
  12#include <string.h>
  13#include <u-boot/crc.h>
  14
  15#define ARP_HLEN 6 /* Length of hardware address */
  16#define ARP_HLEN_ASCII (ARP_HLEN * 2) + (ARP_HLEN - 1) /* with separators */
  17#define ARP_HLEN_LAZY (ARP_HLEN * 2) /* separatorless hardware address length */
  18
  19uint8_t nibble_to_hex(const char *nibble, bool lo)
  20{
  21        return (strtol(nibble, NULL, 16) << (lo ? 0 : 4)) & (lo ? 0x0f : 0xf0);
  22}
  23
  24int process_mac(const char *mac_address)
  25{
  26        uint8_t ethaddr[ARP_HLEN + 1] = { 0x00 };
  27        uint_fast8_t i = 0;
  28
  29        while (*mac_address != '\0') {
  30                char nibble[2] = { 0x00, '\n' }; /* for strtol */
  31
  32                nibble[0] = *mac_address++;
  33                if (isxdigit(nibble[0])) {
  34                        if (isupper(nibble[0]))
  35                                nibble[0] = tolower(nibble[0]);
  36                        ethaddr[i >> 1] |= nibble_to_hex(nibble, (i % 2) != 0);
  37                        i++;
  38                }
  39        }
  40
  41        for (i = 0; i < ARP_HLEN; i++)
  42                printf("%.2x", ethaddr[i]);
  43        printf("%.2x\n", crc8(0, ethaddr, ARP_HLEN));
  44
  45        return 0;
  46}
  47
  48void print_usage(char *cmdname)
  49{
  50        printf("Usage: %s <mac_address>\n", cmdname);
  51        puts("<mac_address> may be with or without separators.");
  52        puts("Valid seperators are ':' and '-'.");
  53        puts("<mac_address> digits are in base 16.\n");
  54}
  55
  56int main(int argc, char *argv[])
  57{
  58        if (argc < 2) {
  59                print_usage(argv[0]);
  60                return 1;
  61        }
  62
  63        if (!((strlen(argv[1]) == ARP_HLEN_ASCII) || (strlen(argv[1]) == ARP_HLEN_LAZY))) {
  64                puts("The MAC address is not valid.\n");
  65                print_usage(argv[0]);
  66                return 1;
  67        }
  68
  69        if (process_mac(argv[1])) {
  70                puts("Failed to calculate the MAC's checksum.");
  71                return 1;
  72        }
  73
  74        return 0;
  75}
  76