]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
c25f01a6 | 2 | /* |
3 | * (C) Copyright 2016 | |
4 | * Olliver Schinagl <[email protected]> | |
c25f01a6 | 5 | */ |
6 | ||
7 | #include <ctype.h> | |
d2bf1152 | 8 | #include <stdbool.h> |
c25f01a6 | 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 | ||
19 | uint8_t nibble_to_hex(const char *nibble, bool lo) | |
20 | { | |
21 | return (strtol(nibble, NULL, 16) << (lo ? 0 : 4)) & (lo ? 0x0f : 0xf0); | |
22 | } | |
23 | ||
24 | int 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 | ||
48 | void 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 | ||
56 | int 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 | } |