1 /* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If
17    not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /*
21  *  2002-12-24  Nick Fedchik <nick@fedchik.org.ua>
22  * 	- initial uClibc port
23  */
24 
25 #include <ctype.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <netinet/ether.h>
29 #include <netinet/if_ether.h>
30 
ether_aton_r(const char * asc,struct ether_addr * addr)31 struct ether_addr *ether_aton_r(const char *asc, struct ether_addr *addr)
32 {
33 	/* asc is "X:XX:XX:x:xx:xX" */
34 	int cnt;
35 
36 	for (cnt = 0; cnt < 6; ++cnt) {
37 		unsigned char number;
38 		char ch = *asc++;
39 
40 		if (ch < 0x20)
41 			return NULL;
42 		/* | 0x20 is cheap tolower(), valid for letters/numbers only */
43 		ch |= 0x20;
44 		if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f'))
45 			return NULL;
46 		number = !(ch > '9') ? (ch - '0') : (ch - 'a' + 10);
47 
48 		ch = *asc++;
49 		if ((cnt != 5 && ch != ':') /* not last group */
50 		/* What standard says ASCII ether address representation
51 		 * may also finish with whitespace, not only NUL?
52 		 * We can get rid of isspace() otherwise */
53 		 || (cnt == 5 && ch != '\0' /*&& !isspace(ch)*/)
54 		) {
55 			ch |= 0x20; /* cheap tolower() */
56 			if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f'))
57 				return NULL;
58 			number = (number << 4) + (!(ch > '9') ? (ch - '0') : (ch - 'a' + 10));
59 
60 			if (cnt != 5) {
61 				ch = *asc++;
62 				if (ch != ':')
63 					return NULL;
64 			}
65 		}
66 
67 		/* Store result.  */
68 		addr->ether_addr_octet[cnt] = number;
69 	}
70 	/* Looks like we allow garbage after last group?
71 	 * "1:2:3:4:5:66anything_at_all"? */
72 
73 	return addr;
74 }
libc_hidden_def(ether_aton_r)75 libc_hidden_def(ether_aton_r)
76 
77 struct ether_addr *ether_aton(const char *asc)
78 {
79 	static struct ether_addr result;
80 
81 	return ether_aton_r(asc, &result);
82 }
83 
ether_ntoa_r(const struct ether_addr * addr,char * buf)84 char *ether_ntoa_r(const struct ether_addr *addr, char *buf)
85 {
86 	sprintf(buf, "%x:%x:%x:%x:%x:%x",
87 			addr->ether_addr_octet[0], addr->ether_addr_octet[1],
88 			addr->ether_addr_octet[2], addr->ether_addr_octet[3],
89 			addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
90 	return buf;
91 }
libc_hidden_def(ether_ntoa_r)92 libc_hidden_def(ether_ntoa_r)
93 
94 char *ether_ntoa(const struct ether_addr *addr)
95 {
96 	static char asc[18];
97 
98 	return ether_ntoa_r(addr, asc);
99 }
100