162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <linux/string.h>
362306a36Sopenharmony_ci#include <linux/if_ether.h>
462306a36Sopenharmony_ci#include <linux/ctype.h>
562306a36Sopenharmony_ci#include <linux/export.h>
662306a36Sopenharmony_ci#include <linux/hex.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_cibool mac_pton(const char *s, u8 *mac)
962306a36Sopenharmony_ci{
1062306a36Sopenharmony_ci	size_t maxlen = 3 * ETH_ALEN - 1;
1162306a36Sopenharmony_ci	int i;
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci	/* XX:XX:XX:XX:XX:XX */
1462306a36Sopenharmony_ci	if (strnlen(s, maxlen) < maxlen)
1562306a36Sopenharmony_ci		return false;
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci	/* Don't dirty result unless string is valid MAC. */
1862306a36Sopenharmony_ci	for (i = 0; i < ETH_ALEN; i++) {
1962306a36Sopenharmony_ci		if (!isxdigit(s[i * 3]) || !isxdigit(s[i * 3 + 1]))
2062306a36Sopenharmony_ci			return false;
2162306a36Sopenharmony_ci		if (i != ETH_ALEN - 1 && s[i * 3 + 2] != ':')
2262306a36Sopenharmony_ci			return false;
2362306a36Sopenharmony_ci	}
2462306a36Sopenharmony_ci	for (i = 0; i < ETH_ALEN; i++) {
2562306a36Sopenharmony_ci		mac[i] = (hex_to_bin(s[i * 3]) << 4) | hex_to_bin(s[i * 3 + 1]);
2662306a36Sopenharmony_ci	}
2762306a36Sopenharmony_ci	return true;
2862306a36Sopenharmony_ci}
2962306a36Sopenharmony_ciEXPORT_SYMBOL(mac_pton);
30