blob: ceb1e0a320883132e96c479289b6caee53afa351 [file] [log] [blame]
Harald Welte468b6432014-09-11 13:05:51 +08001/*
2 * (C) 2013-2014 by Harald Welte <laforge@gnumonks.org>
3 * (C) 2014 by Holger Hans Peter Freyther
4 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
Harald Welte2d2e2cc2016-04-25 12:11:20 +020023/*! \addtogroup utils
24 * @{
25 */
26
27/*! \file loggingrb.c */
28
Harald Welte44c0f632017-01-15 17:58:29 +010029#include "config.h"
30
Harald Welte40d56f92014-08-18 19:03:40 +020031#include <stdint.h>
32#include <string.h>
33#include <stdlib.h>
Harald Welte78b08682014-08-21 02:37:57 +020034#include <unistd.h>
Harald Welte40d56f92014-08-18 19:03:40 +020035
Harald Welte2d2e2cc2016-04-25 12:11:20 +020036/*! \brief Parse a MAC address from human-readable notation
37 * This function parses an ethernet MAC address in the commonly-used
38 * hex/colon notation (00:00:00:00:00:00) and generates the binary
39 * representation from it.
40 * \param[out] out pointer to caller-allocated buffer of 6 bytes
41 * \param[in] in pointer to input data as string with hex/colon notation
42 */
Harald Welte40d56f92014-08-18 19:03:40 +020043int osmo_macaddr_parse(uint8_t *out, const char *in)
44{
45 /* 00:00:00:00:00:00 */
46 char tmp[18];
47 char *tok;
48 unsigned int i = 0;
49
50 if (strlen(in) < 17)
51 return -1;
52
53 strncpy(tmp, in, sizeof(tmp)-1);
54 tmp[sizeof(tmp)-1] = '\0';
55
56 for (tok = strtok(tmp, ":"); tok && (i < 6); tok = strtok(NULL, ":")) {
57 unsigned long ul = strtoul(tok, NULL, 16);
58 out[i++] = ul & 0xff;
59 }
60
61 return 0;
62}
Harald Weltefe3e42b2014-08-18 19:19:45 +020063
Holger Hans Peter Freyther18853952015-04-11 19:29:52 +020064#if defined(__FreeBSD__) || defined(__APPLE__)
Holger Hans Peter Freytherefe01002014-08-21 14:14:38 +020065#include <sys/socket.h>
66#include <sys/types.h>
67#include <ifaddrs.h>
68#include <net/if_dl.h>
69#include <net/if_types.h>
70
Harald Welte2d2e2cc2016-04-25 12:11:20 +020071/*! \brief Obtain the MAC address of a given network device
72 * \param[out] mac_out pointer to caller-allocated buffer of 6 bytes
73 * \param[in] dev_name string name of the network device
74 * \returns 0 in case of success; negative otherwise
75 */
Holger Hans Peter Freytherefe01002014-08-21 14:14:38 +020076int osmo_get_macaddr(uint8_t *mac_out, const char *dev_name)
77{
78 int rc = -1;
79 struct ifaddrs *ifa, *ifaddr;
80
81 if (getifaddrs(&ifaddr) != 0)
82 return -1;
83
84 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
85 struct sockaddr_dl *sdl;
86
87 sdl = (struct sockaddr_dl *) ifa->ifa_addr;
88 if (!sdl)
89 continue;
90 if (sdl->sdl_family != AF_LINK)
91 continue;
92 if (sdl->sdl_type != IFT_ETHER)
93 continue;
94 if (strcmp(ifa->ifa_name, dev_name) != 0)
95 continue;
96
97 memcpy(mac_out, LLADDR(sdl), 6);
98 rc = 0;
99 break;
100 }
101
102 freeifaddrs(ifaddr);
103 return 0;
104}
105
106#else
107
Harald Welte44c0f632017-01-15 17:58:29 +0100108#if (!EMBEDDED)
109
Harald Weltefe3e42b2014-08-18 19:19:45 +0200110#include <sys/ioctl.h>
111#include <net/if.h>
Harald Weltee15ac062014-12-04 14:15:36 +0100112#include <netinet/in.h>
Harald Weltefe3e42b2014-08-18 19:19:45 +0200113#include <netinet/ip.h>
114
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200115/*! \brief Obtain the MAC address of a given network device
116 * \param[out] mac_out pointer to caller-allocated buffer of 6 bytes
117 * \param[in] dev_name string name of the network device
118 * \returns 0 in case of success; negative otherwise
119 */
Harald Weltefe3e42b2014-08-18 19:19:45 +0200120int osmo_get_macaddr(uint8_t *mac_out, const char *dev_name)
121{
122 int fd, rc;
123 struct ifreq ifr;
124
125 fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
126 if (fd < 0)
127 return fd;
128
129 memset(&ifr, 0, sizeof(ifr));
130 memcpy(&ifr.ifr_name, dev_name, sizeof(ifr.ifr_name));
131 rc = ioctl(fd, SIOCGIFHWADDR, &ifr);
132 close(fd);
133
134 if (rc < 0)
135 return rc;
136
137 memcpy(mac_out, ifr.ifr_hwaddr.sa_data, 6);
138
139 return 0;
140}
Harald Welte44c0f632017-01-15 17:58:29 +0100141#endif /* !EMBEDDED */
142
Holger Hans Peter Freytherefe01002014-08-21 14:14:38 +0200143#endif
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200144
145/*! @} */