aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2011-05-07 19:00:07 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-09 15:10:49 -0400
commit4940fc889e1e63667a15243028ddcd84d471cd8e (patch)
treec52bb193d0ad4f13e0f617748ed1db297261f521 /net
parent99f823f98fb981b55c663a3783c3d2293958ece4 (diff)
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>
Diffstat (limited to 'net')
-rw-r--r--net/core/netpoll.c26
-rw-r--r--net/core/pktgen.c53
-rw-r--r--net/core/utils.c24
3 files changed, 33 insertions, 70 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 46d9c3a4de2f..2d7d6d473781 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -698,32 +698,8 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
698 698
699 if (*cur != 0) { 699 if (*cur != 0) {
700 /* MAC address */ 700 /* MAC address */
701 if ((delim = strchr(cur, ':')) == NULL) 701 if (!mac_pton(cur, np->remote_mac))
702 goto parse_failed; 702 goto parse_failed;
703 *delim = 0;
704 np->remote_mac[0] = simple_strtol(cur, NULL, 16);
705 cur = delim + 1;
706 if ((delim = strchr(cur, ':')) == NULL)
707 goto parse_failed;
708 *delim = 0;
709 np->remote_mac[1] = simple_strtol(cur, NULL, 16);
710 cur = delim + 1;
711 if ((delim = strchr(cur, ':')) == NULL)
712 goto parse_failed;
713 *delim = 0;
714 np->remote_mac[2] = simple_strtol(cur, NULL, 16);
715 cur = delim + 1;
716 if ((delim = strchr(cur, ':')) == NULL)
717 goto parse_failed;
718 *delim = 0;
719 np->remote_mac[3] = simple_strtol(cur, NULL, 16);
720 cur = delim + 1;
721 if ((delim = strchr(cur, ':')) == NULL)
722 goto parse_failed;
723 *delim = 0;
724 np->remote_mac[4] = simple_strtol(cur, NULL, 16);
725 cur = delim + 1;
726 np->remote_mac[5] = simple_strtol(cur, NULL, 16);
727 } 703 }
728 704
729 netpoll_print_options(np); 705 netpoll_print_options(np);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index d41d88b53e18..379270f14771 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -1420,11 +1420,6 @@ static ssize_t pktgen_if_write(struct file *file,
1420 return count; 1420 return count;
1421 } 1421 }
1422 if (!strcmp(name, "dst_mac")) { 1422 if (!strcmp(name, "dst_mac")) {
1423 char *v = valstr;
1424 unsigned char old_dmac[ETH_ALEN];
1425 unsigned char *m = pkt_dev->dst_mac;
1426 memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN);
1427
1428 len = strn_len(&user_buffer[i], sizeof(valstr) - 1); 1423 len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
1429 if (len < 0) 1424 if (len < 0)
1430 return len; 1425 return len;
@@ -1432,35 +1427,16 @@ static ssize_t pktgen_if_write(struct file *file,
1432 memset(valstr, 0, sizeof(valstr)); 1427 memset(valstr, 0, sizeof(valstr));
1433 if (copy_from_user(valstr, &user_buffer[i], len)) 1428 if (copy_from_user(valstr, &user_buffer[i], len))
1434 return -EFAULT; 1429 return -EFAULT;
1435 i += len;
1436
1437 for (*m = 0; *v && m < pkt_dev->dst_mac + 6; v++) {
1438 int value;
1439
1440 value = hex_to_bin(*v);
1441 if (value >= 0)
1442 *m = *m * 16 + value;
1443
1444 if (*v == ':') {
1445 m++;
1446 *m = 0;
1447 }
1448 }
1449 1430
1431 if (!mac_pton(valstr, pkt_dev->dst_mac))
1432 return -EINVAL;
1450 /* Set up Dest MAC */ 1433 /* Set up Dest MAC */
1451 if (compare_ether_addr(old_dmac, pkt_dev->dst_mac)) 1434 memcpy(&pkt_dev->hh[0], pkt_dev->dst_mac, ETH_ALEN);
1452 memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
1453 1435
1454 sprintf(pg_result, "OK: dstmac"); 1436 sprintf(pg_result, "OK: dstmac %pM", pkt_dev->dst_mac);
1455 return count; 1437 return count;
1456 } 1438 }
1457 if (!strcmp(name, "src_mac")) { 1439 if (!strcmp(name, "src_mac")) {
1458 char *v = valstr;
1459 unsigned char old_smac[ETH_ALEN];
1460 unsigned char *m = pkt_dev->src_mac;
1461
1462 memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN);
1463
1464 len = strn_len(&user_buffer[i], sizeof(valstr) - 1); 1440 len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
1465 if (len < 0) 1441 if (len < 0)
1466 return len; 1442 return len;
@@ -1468,26 +1444,13 @@ static ssize_t pktgen_if_write(struct file *file,
1468 memset(valstr, 0, sizeof(valstr)); 1444 memset(valstr, 0, sizeof(valstr));
1469 if (copy_from_user(valstr, &user_buffer[i], len)) 1445 if (copy_from_user(valstr, &user_buffer[i], len))
1470 return -EFAULT; 1446 return -EFAULT;
1471 i += len;
1472
1473 for (*m = 0; *v && m < pkt_dev->src_mac + 6; v++) {
1474 int value;
1475
1476 value = hex_to_bin(*v);
1477 if (value >= 0)
1478 *m = *m * 16 + value;
1479
1480 if (*v == ':') {
1481 m++;
1482 *m = 0;
1483 }
1484 }
1485 1447
1448 if (!mac_pton(valstr, pkt_dev->src_mac))
1449 return -EINVAL;
1486 /* Set up Src MAC */ 1450 /* Set up Src MAC */
1487 if (compare_ether_addr(old_smac, pkt_dev->src_mac)) 1451 memcpy(&pkt_dev->hh[6], pkt_dev->src_mac, ETH_ALEN);
1488 memcpy(&(pkt_dev->hh[6]), pkt_dev->src_mac, ETH_ALEN);
1489 1452
1490 sprintf(pg_result, "OK: srcmac"); 1453 sprintf(pg_result, "OK: srcmac %pM", pkt_dev->src_mac);
1491 return count; 1454 return count;
1492 } 1455 }
1493 1456
diff --git a/net/core/utils.c b/net/core/utils.c
index 5fea0ab21902..2012bc797f9c 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -296,3 +296,27 @@ void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
296 csum_unfold(*sum))); 296 csum_unfold(*sum)));
297} 297}
298EXPORT_SYMBOL(inet_proto_csum_replace4); 298EXPORT_SYMBOL(inet_proto_csum_replace4);
299
300int mac_pton(const char *s, u8 *mac)
301{
302 int i;
303
304 /* XX:XX:XX:XX:XX:XX */
305 if (strlen(s) < 3 * ETH_ALEN - 1)
306 return 0;
307
308 /* Don't dirty result unless string is valid MAC. */
309 for (i = 0; i < ETH_ALEN; i++) {
310 if (!strchr("0123456789abcdefABCDEF", s[i * 3]))
311 return 0;
312 if (!strchr("0123456789abcdefABCDEF", s[i * 3 + 1]))
313 return 0;
314 if (i != ETH_ALEN - 1 && s[i * 3 + 2] != ':')
315 return 0;
316 }
317 for (i = 0; i < ETH_ALEN; i++) {
318 mac[i] = (hex_to_bin(s[i * 3]) << 4) | hex_to_bin(s[i * 3 + 1]);
319 }
320 return 1;
321}
322EXPORT_SYMBOL(mac_pton);