11541Srgrimes/* $NetBSD: device.c,v 1.11 2009/11/17 18:58:07 drochner Exp $ */ 21541Srgrimes 31541Srgrimes/* 41541Srgrimes * Copyright (c) 1993-95 Mats O Jansson. All rights reserved. 51541Srgrimes * 61541Srgrimes * Redistribution and use in source and binary forms, with or without 71541Srgrimes * modification, are permitted provided that the following conditions 81541Srgrimes * are met: 91541Srgrimes * 1. Redistributions of source code must retain the above copyright 101541Srgrimes * notice, this list of conditions and the following disclaimer. 111541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 121541Srgrimes * notice, this list of conditions and the following disclaimer in the 131541Srgrimes * documentation and/or other materials provided with the distribution. 141541Srgrimes * 151541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161541Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171541Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181541Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191541Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201541Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211541Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221541Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231541Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241541Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251541Srgrimes */ 261541Srgrimes 271541Srgrimes#include <sys/cdefs.h> 281541Srgrimes#ifndef lint 291541Srgrimes__RCSID("$NetBSD: device.c,v 1.11 2009/11/17 18:58:07 drochner Exp $"); 301541Srgrimes#endif 311541Srgrimes 321541Srgrimes#include "os.h" 3350477Speter#include "common.h" 341541Srgrimes#include "device.h" 351541Srgrimes#include "mopdef.h" 361541Srgrimes#include "pf.h" 371541Srgrimes#include "log.h" 381541Srgrimes 3974729Speterstruct if_info *iflist; /* Interface List */ 4074740Speter 4174729Spetervoid deviceOpen(const char *, u_short, int); 421549Srgrimes 4374729Speter#ifdef DEV_NEW_CONF 4474740Speter/* 4574729Speter * Return ethernet address for interface 4674729Speter */ 471541Srgrimes 481549Srgrimesvoid 491549SrgrimesdeviceEthAddr(const char *ifname, u_char *eaddr) 501549Srgrimes{ 511549Srgrimes struct sockaddr_dl *sdl; 521549Srgrimes struct ifaddrs *ifap, *ifa; 531541Srgrimes 541541Srgrimes if (getifaddrs(&ifap) != 0) 551541Srgrimes mopLogErr("deviceEthAddr: getifaddrs"); 561541Srgrimes 5755205Speter for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 581541Srgrimes sdl = (struct sockaddr_dl *)ifa->ifa_addr; 5974740Speter if (sdl->sdl_family != AF_LINK || sdl->sdl_type != IFT_ETHER || 601541Srgrimes sdl->sdl_alen != 6) 6174729Speter continue; 6274729Speter if (!strcmp(ifa->ifa_name, ifname)) { 6374729Speter memmove((caddr_t)eaddr, (caddr_t)LLADDR(sdl), 6); 6474729Speter freeifaddrs(ifap); 6574729Speter return; 6674729Speter } 6755205Speter } 681541Srgrimes 691541Srgrimes freeifaddrs(ifap); 70 mopLogErrX("deviceEthAddr: Never saw interface `%s'!", ifname); 71} 72#endif /* DEV_NEW_CONF */ 73 74void 75deviceOpen(const char *ifname, u_short proto, int trans) 76{ 77 struct if_info *p, tmp; 78 79 strlcpy(tmp.if_name, ifname, sizeof(tmp.if_name)); 80 tmp.iopen = pfInit; 81 82 switch (proto) { 83 case MOP_K_PROTO_RC: 84 tmp.read = mopReadRC; 85 tmp.fd = mopOpenRC(&tmp, trans); 86 break; 87 case MOP_K_PROTO_DL: 88 tmp.read = mopReadDL; 89 tmp.fd = mopOpenDL(&tmp, trans); 90 break; 91 default: 92 break; 93 } 94 95 if (tmp.fd != -1) { 96 p = (struct if_info *)malloc(sizeof(*p)); 97 if (p == 0) 98 mopLogErr("deviceOpen: malloc"); 99 100 p->next = iflist; 101 iflist = p; 102 103 strlcpy(p->if_name, tmp.if_name, sizeof(p->if_name)); 104 p->iopen = tmp.iopen; 105 p->write = pfWrite; 106 p->read = tmp.read; 107 memset((char *)p->eaddr, 0, sizeof(p->eaddr)); 108 p->fd = tmp.fd; 109 110#ifdef DEV_NEW_CONF 111 deviceEthAddr(p->if_name,&p->eaddr[0]); 112#else 113 p->eaddr[0]= tmp.eaddr[0]; 114 p->eaddr[1]= tmp.eaddr[1]; 115 p->eaddr[2]= tmp.eaddr[2]; 116 p->eaddr[3]= tmp.eaddr[3]; 117 p->eaddr[4]= tmp.eaddr[4]; 118 p->eaddr[5]= tmp.eaddr[5]; 119#endif /* DEV_NEW_CONF */ 120 121 } 122} 123 124void 125deviceInitOne(const char *ifname) 126{ 127 char interface[IFNAME_SIZE]; 128 struct if_info *p; 129 int trans; 130#ifdef _AIX 131 char dev[IFNAME_SIZE]; 132 int unit,j; 133 134 unit = 0; 135 for (j = 0; j < strlen(ifname); j++) { 136 if (isalpha(ifname[j])) { 137 dev[j] = ifname[j]; 138 } else { 139 if (isdigit(ifname[j])) { 140 unit = unit*10 + ifname[j] - '0'; 141 dev[j] = '\0'; 142 } 143 } 144 } 145 146 if ((strlen(dev) == 2) && 147 (dev[0] == 'e') && 148 ((dev[1] == 'n') || (dev[1] == 't'))) { 149 snprintf(interface, sizeof(interface), "ent%d\0", unit); 150 } else { 151 snprintf(interface, sizeof(interface), "%s%d\0", dev, unit); 152 } 153#else 154 snprintf(interface, sizeof(interface), "%s", ifname); 155#endif /* _AIX */ 156 157 /* Ok, init it just once */ 158 159 p = iflist; 160 for (p = iflist; p; p = p->next) { 161 if (strcmp(p->if_name,interface) == 0) { 162 return; 163 } 164 } 165 166 if (!mopInteractive) 167 syslog(LOG_INFO, "Initialized %s", interface); 168 169 /* Ok, get transport information */ 170 171 trans = pfTrans(interface); 172 173#ifndef NORC 174 /* Start with MOP Remote Console */ 175 176 switch (trans) { 177 case TRANS_ETHER: 178 deviceOpen(interface,MOP_K_PROTO_RC,TRANS_ETHER); 179 break; 180 case TRANS_8023: 181 deviceOpen(interface,MOP_K_PROTO_RC,TRANS_8023); 182 break; 183 case TRANS_ETHER+TRANS_8023: 184 deviceOpen(interface,MOP_K_PROTO_RC,TRANS_ETHER); 185 deviceOpen(interface,MOP_K_PROTO_RC,TRANS_8023); 186 break; 187 case TRANS_ETHER+TRANS_8023+TRANS_AND: 188 deviceOpen(interface,MOP_K_PROTO_RC,TRANS_ETHER+TRANS_8023); 189 break; 190 } 191#endif 192 193#ifndef NODL 194 /* and next MOP Dump/Load */ 195 196 switch (trans) { 197 case TRANS_ETHER: 198 deviceOpen(interface,MOP_K_PROTO_DL,TRANS_ETHER); 199 break; 200 case TRANS_8023: 201 deviceOpen(interface,MOP_K_PROTO_DL,TRANS_8023); 202 break; 203 case TRANS_ETHER+TRANS_8023: 204 deviceOpen(interface,MOP_K_PROTO_DL,TRANS_ETHER); 205 deviceOpen(interface,MOP_K_PROTO_DL,TRANS_8023); 206 break; 207 case TRANS_ETHER+TRANS_8023+TRANS_AND: 208 deviceOpen(interface,MOP_K_PROTO_DL,TRANS_ETHER+TRANS_8023); 209 break; 210 } 211#endif 212 213} 214 215/* 216 * Initialize all "candidate" interfaces that are in the system 217 * configuration list. A "candidate" is up, not loopback and not 218 * point to point. 219 */ 220void 221deviceInitAll(void) 222{ 223#ifdef DEV_NEW_CONF 224 struct sockaddr_dl *sdl; 225 struct ifaddrs *ifap, *ifa; 226 227 if (getifaddrs(&ifap) != 0) 228 mopLogErr("deviceInitAll: socket"); 229 230 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 231 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 232 if (sdl->sdl_family != AF_LINK || sdl->sdl_type != IFT_ETHER || 233 sdl->sdl_alen != 6) 234 continue; 235 if ((ifa->ifa_flags & 236 (IFF_UP | IFF_LOOPBACK | IFF_POINTOPOINT)) != IFF_UP) 237 continue; 238 deviceInitOne(ifa->ifa_name); 239 } 240 241 freeifaddrs(ifap); 242#else 243 struct ifaddrs *ifap, *ifa; 244 245 if (getifaddrs(&ifap) != 0) 246 mopLogErr("deviceInitAll: old socket"); 247 248 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 249 if (/*(ifa->ifa_flags & IFF_UP) == 0 ||*/ 250 ifa->ifa_flags & IFF_LOOPBACK || 251 ifa->ifa_flags & IFF_POINTOPOINT) 252 continue; 253 deviceInitOne(ifa->ifa_name); 254 } 255 256 freeifaddrs(ifap); 257#endif /* DEV_NEW_CONF */ 258} 259