This is netif.c in view mode; [Download] [Up]
/* * Copyright (c) 1992 Michael A. Cooper. * This software may be freely distributed provided it is not sold for * profit and the author is credited appropriately. */ #ifndef lint static char *RCSid = "$Header: /src/common/usc/bin/sysinfo/RCS/netif.c,v 1.20 1992/11/24 04:12:19 mcooper Exp mcooper $"; #endif /* * $Log: netif.c,v $ * Revision 1.20 1992/11/24 04:12:19 mcooper * Use new KVM/nlist interface. * * Revision 1.19 1992/07/07 23:28:38 mcooper * Put wrapper macro around nlist stuff to fix NeXT/Mach declaration * problem. Now works with NeXT 2.* cc compiler. * * Revision 1.18 1992/04/26 23:32:06 mcooper * Add Copyright notice * * Revision 1.17 1992/04/17 01:07:59 mcooper * More de-linting * * Revision 1.16 1992/04/16 02:25:39 mcooper * Bug fixes, de-linting, and other changes found with CodeCenter. * * Revision 1.15 1992/03/31 01:55:17 mcooper * Use new CheckNlist to check nlist success. * * Revision 1.14 1992/03/31 00:15:09 mcooper * Add error check for nlist.n_type. * * Revision 1.13 1992/03/28 21:29:38 mcooper * Initial port to NeXT. Only works partially. * * Revision 1.12 1992/03/22 00:20:10 mcooper * Major cleanup and re-org. * * Revision 1.11 1992/03/09 01:24:05 mcooper * Remove HAVE_NIT stuff. * * Revision 1.10 1992/03/08 23:09:18 mcooper * - Cleanup set_macinfo() code to support Ultrix packetfilter. * - Pass device down to set_macinfo(). * * Revision 1.9 1992/03/08 04:53:39 mcooper * Major re-write to clean things up and add better * support for multiple addresses per interface. * * Revision 1.8 1992/03/05 22:36:35 mcooper * Cleanup format. * * Revision 1.7 1992/03/05 22:11:02 mcooper * Cleanup variable declarations. * * Revision 1.6 1992/02/25 23:36:58 mcooper * Remove NULL garbage at end of source file. * * Revision 1.5 1992/02/25 03:08:43 mcooper * Fix gethostbyaddr() stuff for sun3/sun386. * * Revision 1.4 1992/02/25 00:16:57 mcooper * Use new mkmaster_from_devdata(). * * Revision 1.3 1992/02/22 02:20:19 mcooper * Major changes to support scanning kernel mainbus and * openprom data for device's. * * Revision 1.2 1992/02/20 04:15:16 mcooper * Update known interfaces. * * Revision 1.1 1992/02/16 22:48:39 mcooper * Initial revision * */ /* * Portions of code found in this file are based on the 4.3BSD * netstat(8) program. */ /* * Network Interface routines */ #include <stdio.h> #include "system.h" #include <fcntl.h> #include <nlist.h> #include <sys/types.h> #include <sys/socket.h> #if defined(NEED_SOCKIO) #include <sys/sockio.h> #endif /* NEED_SOCKIO */ #include <sys/param.h> #include <sys/errno.h> #include <net/if.h> #include <netinet/in.h> #include <netinet/in_var.h> #include <netinet/if_ether.h> #include <netdb.h> #include "defs.h" /* * Network Interface symbol */ char NetifSYM[] = "_ifnet"; static struct netent *GetNet(); static void SetMacInfo(); /* * Interface Address union */ union { struct ifaddr ifa; struct in_ifaddr in; } ifaddr; /* * Create a DEVICE for a network interface. */ static DEVICE *CreateNetif(FullName, IfNet, DevData, DevDataTab) char *FullName; struct ifnet *IfNet; DEVDATA *DevData; DEVDATATAB *DevDataTab; { DEVICE *dev; dev = NewDevice(NULL); dev->dv_name = strdup(FullName); dev->dv_type = DT_NETIF; dev->dv_unit = IfNet->if_unit; dev->dv_master = MkMasterFromDevData(DevData); #if defined(HAVE_IF_VERSION) if (IfNet->if_version && IfNet->if_version[0]) dev->dv_model = strdup(IfNet->if_version); else #endif /* HAVE_IF_VERSION */ dev->dv_model = DevDataTab->ddt_model; dev->dv_desc = DevDataTab->ddt_desc; return(dev); } /* * Get NETIF for an Internet address */ extern NETIF *GetNetifINET(aftab) AFTAB *aftab; { struct in_addr in_addr; struct netent *np; struct hostent *hp; struct sockaddr_in *sin; char *inet_ntoa(); NETIF *ni; ni = NewNetif(NULL); np = GetNet(htonl(ifaddr.in.ia_subnet), ifaddr.in.ia_subnetmask); in_addr.s_addr = ntohl(ifaddr.in.ia_subnet); ni->ni_netaddr = strdup(inet_ntoa(in_addr)); if (np) ni->ni_netname = strdup(np->n_name); sin = (struct sockaddr_in *)&ifaddr.in.ia_addr; ni->ni_hostaddr = strdup(inet_ntoa(sin->sin_addr)); hp = gethostbyaddr((char *) &(sin->sin_addr), sizeof(struct in_addr), AF_INET); if (hp) ni->ni_hostname = strdup(hp->h_name); if (aftab) ni->ni_typename = aftab->af_name; return(ni); } /* * Get NETIF for an unknown address type */ extern NETIF *GetNetifUnknown(aftab) AFTAB *aftab; { NETIF *ni = NULL; ni = NewNetif(NULL); ni->ni_hostaddr = "<unknown>"; if (aftab) { ni->ni_typename = aftab->af_name; } return(ni); } /* * Get an Address Family table entry */ static AFTAB *GetAFTab(type) int type; { extern AFTAB AFTab[]; register int i; for (i = 0; AFTab[i].af_name; ++i) if (AFTab[i].af_type == type) return(&AFTab[i]); return((AFTAB *) NULL); } /* * Get a linked list of NETIF's for each address starting at 'startaddr'. */ static NETIF *GetNetifAddrs(kd, startaddr, FullName, Device) kvm_t *kd; off_t startaddr; char *FullName; DEVICE *Device; { u_long addr; NETIF *base = NULL; register NETIF *ni, *pni; AFTAB *paftab; for (addr = startaddr; addr; addr = (off_t) ifaddr.ifa.ifa_next) { /* * Read the ifaddr structure from kernel space */ if (KVMread(kd, addr, (char *) &ifaddr, sizeof(ifaddr))) { Error("cannot read if address"); continue; } /* * Now get and call the Address Family specific routine * to extract a NETIF. */ if (paftab = GetAFTab(ifaddr.ifa.ifa_addr.sa_family)) { if (ni = (*paftab->af_getnetif)(paftab)) SetMacInfo(FullName, ni, Device); } else { if (Debug) Error("Address family %d is not defined.", ifaddr.ifa.ifa_addr.sa_family); continue; } /* * Add the new NETIF to the base of the linked list. */ if (base) { for (pni = base; pni && pni->ni_nxt; pni = pni->ni_nxt); pni->ni_nxt = ni; } else { base = ni; } } return(base); } /* * Find and set the MAC info */ static void SetMacInfo(DevName, NetIf, Device) char *DevName; NETIF *NetIf; DEVICE *Device; /* ARGSUSED */ { #if defined(HAVE_NIT) extern void SetMacInfoNIT(); SetMacInfoNIT(DevName, NetIf); return; #endif /* HAVE_NIT */ #if defined(HAVE_PACKETFILTER) extern void SetMacInfoPacketFilter(); SetMacInfoPacketFilter(DevName, NetIf, Device); return; #endif /* HAVE_PACKETFILTER */ } /* * Return the netent of the network whose address is given. * The address is assumed to be that of a net or subnet, not a host. */ static struct netent *GetNet(inaddr, mask) u_long inaddr; u_long mask; { u_long net; register u_long i, netaddr; int subnetshift; static struct in_addr in; if (in.s_addr = ntohl(inaddr)) { i = in.s_addr; if (mask == 0) { if (IN_CLASSA(i)) { mask = IN_CLASSA_NET; subnetshift = 8; } else if (IN_CLASSB(i)) { mask = IN_CLASSB_NET; subnetshift = 8; } else { mask = IN_CLASSC_NET; subnetshift = 4; } /* * If there are more bits than the standard mask * would suggest, subnets must be in use. * Guess at the subnet mask, assuming reasonable * width subnet fields. */ while (in.s_addr &~ mask) mask = (long)mask >> subnetshift; } net = in.s_addr & mask; while ((mask & 1) == 0) mask >>= 1, net >>= 1; netaddr = net; } else { netaddr = inaddr; } return(getnetbyaddr(netaddr, AF_INET)); } /* * Query/find network interface devices and add them to devicelist */ extern DEVICE *ProbeNetif(name, DevData, DevDataTab) char *name; DEVDATA *DevData; DEVDATATAB *DevDataTab; { DEVICE *dev = NULL; static struct ifnet ifnet; static char ifname[16], FullName[17]; struct nlist *nlptr; register char *p; u_long ifnetaddr; kvm_t *kd; if (!(kd = KVMopen())) return((DEVICE *) NULL); if ((nlptr = KVMnlist(kd, NetifSYM, (struct nlist *)NULL)) == NULL) return((DEVICE *) NULL); if (CheckNlist(nlptr)) return((DEVICE *) NULL); /* * Read address of ifnet structure from kernel space */ if (KVMread(kd, nlptr->n_value, (char *) &ifnetaddr, sizeof(ifnetaddr))) { if (Debug) Error("kvm_read ifnetaddr failed"); KVMclose(kd); return((DEVICE *) NULL); } /* * Read and then check each ifnet entry we found. */ for (; ifnetaddr; ifnetaddr = (off_t) ifnet.if_next) { /* * Read the ifnet structure */ if (KVMread(kd, ifnetaddr, (char *)&ifnet, sizeof(ifnet))) { if (Debug) Error("kvm_read ifnetaddr ifnet failed"); continue; } /* * Read if_name from kernel space */ if (KVMread(kd, (u_long)ifnet.if_name, ifname, sizeof(ifname))) { if (Debug) Error("kvm_read ifname failed"); continue; } /* * Copy if_name to 'FullName' and add unit number */ strncpy(FullName, ifname, sizeof(ifname)); p = (char *) index(FullName, C_NULL); *p++ = ifnet.if_unit + '0'; *p = C_NULL; ifname[sizeof(ifname)-1] = C_NULL; /* * Check to see if this is the interface we want. */ if (!EQ(FullName, name)) continue; /* * Create and set device */ dev = CreateNetif(FullName, &ifnet, DevData, DevDataTab); /* * Get and set address info */ if (ifnet.if_addrlist) { NETIF *ni; if (ni = GetNetifAddrs(kd, (off_t) ifnet.if_addrlist, FullName, dev)) dev->dv_devspec = (caddr_t *) ni; } } KVMclose(kd); return(dev); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.