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