net: add mac_pton() for parsing MAC address

mac_pton() parses MAC address in form XX:XX:XX:XX:XX:XX and only in that form.

mac_pton() doesn't dirty result until it's sure string representation is valid.

mac_pton() doesn't care about characters _after_ last octet,
it's up to caller to deal with it.

mac_pton() diverges from 0/-E return value convention.
Target usage:

	if (!mac_pton(str, whatever->mac))
		return -EINVAL;
	/* ->mac being u8 [ETH_ALEN] is filled at this point. */
	/* optionally check str[3 * ETH_ALEN - 1] for termination */

Use mac_pton() in pktgen and netconsole for start.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Alexey Dobriyan
2011-05-07 23:00:07 +00:00
committed by David S. Miller
parent 99f823f98f
commit 4940fc889e
5 changed files with 38 additions and 86 deletions

View File

@@ -1420,11 +1420,6 @@ static ssize_t pktgen_if_write(struct file *file,
return count;
}
if (!strcmp(name, "dst_mac")) {
char *v = valstr;
unsigned char old_dmac[ETH_ALEN];
unsigned char *m = pkt_dev->dst_mac;
memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN);
len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
if (len < 0)
return len;
@@ -1432,35 +1427,16 @@ static ssize_t pktgen_if_write(struct file *file,
memset(valstr, 0, sizeof(valstr));
if (copy_from_user(valstr, &user_buffer[i], len))
return -EFAULT;
i += len;
for (*m = 0; *v && m < pkt_dev->dst_mac + 6; v++) {
int value;
value = hex_to_bin(*v);
if (value >= 0)
*m = *m * 16 + value;
if (*v == ':') {
m++;
*m = 0;
}
}
if (!mac_pton(valstr, pkt_dev->dst_mac))
return -EINVAL;
/* Set up Dest MAC */
if (compare_ether_addr(old_dmac, pkt_dev->dst_mac))
memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
memcpy(&pkt_dev->hh[0], pkt_dev->dst_mac, ETH_ALEN);
sprintf(pg_result, "OK: dstmac");
sprintf(pg_result, "OK: dstmac %pM", pkt_dev->dst_mac);
return count;
}
if (!strcmp(name, "src_mac")) {
char *v = valstr;
unsigned char old_smac[ETH_ALEN];
unsigned char *m = pkt_dev->src_mac;
memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN);
len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
if (len < 0)
return len;
@@ -1468,26 +1444,13 @@ static ssize_t pktgen_if_write(struct file *file,
memset(valstr, 0, sizeof(valstr));
if (copy_from_user(valstr, &user_buffer[i], len))
return -EFAULT;
i += len;
for (*m = 0; *v && m < pkt_dev->src_mac + 6; v++) {
int value;
value = hex_to_bin(*v);
if (value >= 0)
*m = *m * 16 + value;
if (*v == ':') {
m++;
*m = 0;
}
}
if (!mac_pton(valstr, pkt_dev->src_mac))
return -EINVAL;
/* Set up Src MAC */
if (compare_ether_addr(old_smac, pkt_dev->src_mac))
memcpy(&(pkt_dev->hh[6]), pkt_dev->src_mac, ETH_ALEN);
memcpy(&pkt_dev->hh[6], pkt_dev->src_mac, ETH_ALEN);
sprintf(pg_result, "OK: srcmac");
sprintf(pg_result, "OK: srcmac %pM", pkt_dev->src_mac);
return count;
}