1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77#ifdef HAVE_CONFIG_H 78#include <config.h> 79#endif 80 81/* Horrible Darwin/BSD hack */ 82#if (defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)) && defined(_POSIX_C_SOURCE) 83#undef _POSIX_C_SOURCE 84#endif 85 86#include <stdio.h> 87#include <fcntl.h> 88#include <unistd.h> 89#include <string.h> 90#include <stdlib.h> 91#ifndef UUID_BUILD_STANDALONE 92#include <dce/dce.h> 93#include <dce/dce_utils.h> 94#else 95#include "uuid.h" 96#endif 97#include <sys/types.h> 98#include <sys/socket.h> 99#include <sys/ioctl.h> 100/* Bizarre hack for HP-UX ia64 where a system header 101 * makes reference to a kernel-only data structure 102 */ 103#if defined(__hpux) && defined(__ia64) 104union mpinfou {}; 105#endif 106#include <net/if.h> 107#ifdef HAVE_SYS_SOCKIO_H 108#include <sys/sockio.h> 109#endif 110#ifdef notdef 111#include <sys/sysctl.h> 112#endif 113#ifdef HAVE_NET_IF_DL_H 114#include <net/if_dl.h> 115#endif 116#ifdef HAVE_NET_IF_ARP_H 117#include <net/if_arp.h> 118#endif 119void dce_get_802_addr(dce_802_addr_t *addr, error_status_t *st) 120{ 121 char buf[sizeof(struct ifreq) * 128]; 122 struct ifconf ifc; 123 struct ifreq *ifr; 124 int s, i; 125 struct sockaddr *sa; 126#ifdef AF_LINK 127 struct sockaddr_dl *sdl; 128#endif 129#if defined(SIOCGARP) 130 struct arpreq arpreq; 131#endif 132 struct ifreq ifreq; 133 134 s = socket(AF_INET, SOCK_DGRAM, 0); 135 if (s < 0) { 136 *st = utils_s_802_cant_read; 137 return; 138 } 139 140 ifc.ifc_len = sizeof(buf); 141 ifc.ifc_buf = buf; 142 memset(buf, 0, sizeof(buf)); 143 144 i = ioctl(s, SIOCGIFCONF, (char *)&ifc); 145 if (i < 0) { 146 *st = utils_s_802_cant_read; 147 close(s); 148 return; 149 } 150 151 for (i = 0; i < ifc.ifc_len; ) { 152 ifr = (struct ifreq *)&ifc.ifc_buf[i]; 153 /* Initialize sa here because it is used under the next 154 * label, and the loopback check could jump directly 155 * to the next label. 156 */ 157#ifdef AF_LINK 158 sa = &ifr->ifr_addr; 159#else 160 sa = NULL; 161#endif 162 163#ifdef SIOCGIFFLAGS 164 /* Skip over loopback and point-to-point interfaces. */ 165 memcpy(&ifreq, ifr, sizeof(ifreq)); 166 if (ioctl(s, SIOCGIFFLAGS, &ifreq) == 0) { 167 if (ifreq.ifr_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) { 168 goto next; 169 } 170 } 171#endif 172 173#ifdef AF_LINK 174 if (sa->sa_family == AF_LINK) { 175 sdl = (struct sockaddr_dl *)sa; 176 if (sdl->sdl_alen == 6) { 177 memcpy(addr->eaddr, (unsigned char *)sdl->sdl_data + sdl->sdl_nlen, 6); 178 *st = error_status_ok; 179 close(s); 180 return; 181 } 182 } 183#endif /* AF_LINK */ 184 185#if defined(SIOCGIFHWADDR) 186 memcpy(&ifreq, ifr, sizeof(ifreq)); 187 if (ioctl(s, SIOCGIFHWADDR, &ifreq) == 0) { 188 memcpy(addr->eaddr, &ifreq.ifr_hwaddr.sa_data, 6); 189 *st = error_status_ok; 190 close(s); 191 return; 192 } 193#elif defined(SIOCGARP) 194 memset(&arpreq, 0, sizeof(arpreq)); 195 arpreq.arp_pa = ifr->ifr_dstaddr; 196 arpreq.arp_flags = 0; 197 if (ioctl(s, SIOCGARP, &arpreq) == 0) { 198#ifdef AF_LINK 199 sdl = (struct sockaddr_dl *)&arpreq.arp_ha; 200 memcpy(addr->eaddr, (unsigned char *)&sdl->sdl_data + sdl->sdl_nlen, 6); 201#else 202 memcpy(addr->eaddr, (unsigned char*)&arpreq.arp_ha.sa_data[0], 6); 203#endif 204 *st = error_status_ok; 205 close(s); 206 return; 207 } 208#elif defined(SIOCGENADDR) 209 memcpy(&ifreq, ifr, sizeof(ifreq)); 210 if (ioctl(s, SIOCGENADDR, &ifreq) == 0) { 211 memcpy(addr->eaddr, ifreq.ifr_enaddr, 6); 212 *st = error_status_ok; 213 close(s); 214 return; 215 } 216#else 217 //#error Please implement dce_get_802_addr() for your operating system 218#endif 219 220 next: 221#if !defined(__svr4__) && !defined(linux) && !defined(_HPUX) /* XXX FixMe to be portable */ 222 if (sa && sa->sa_len > sizeof(ifr->ifr_addr)) { 223 i += sizeof(ifr->ifr_name) + sa->sa_len; 224 } else 225#endif 226 i += sizeof(*ifr); 227 228 } 229 230 { 231 unsigned int seed = 1; 232 unsigned char* buf = (unsigned char*) addr->eaddr; 233 int i; 234 235 for (i = 0; i < 6; i++) 236 { 237 buf[i] = rand_r(&seed); 238 } 239 240 close(s); 241 return; 242 } 243 244 *st = utils_s_802_cant_read; 245 close(s); 246 return; 247} 248