Index: head/sys/conf/files =================================================================== --- head/sys/conf/files (revision 17351) +++ head/sys/conf/files (revision 17352) @@ -1,388 +1,389 @@ ddb/db_access.c optional ddb ddb/db_aout.c optional ddb ddb/db_break.c optional ddb ddb/db_command.c optional ddb ddb/db_examine.c optional ddb ddb/db_expr.c optional ddb ddb/db_input.c optional ddb ddb/db_lex.c optional ddb ddb/db_output.c optional ddb ddb/db_print.c optional ddb ddb/db_ps.c optional ddb ddb/db_run.c optional ddb ddb/db_sym.c optional ddb ddb/db_trap.c optional ddb ddb/db_variables.c optional ddb ddb/db_watch.c optional ddb ddb/db_write_cmd.c optional ddb dev/ccd/ccd.c optional ccd device-driver dev/vn/vn.c optional vn gnu/isdn/iitel.c optional itel device-driver gnu/isdn/iitty.c optional ity device-driver gnu/isdn/if_ii.c optional ii device-driver gnu/isdn/isdn.c optional isdn device-driver gnu/isdn/iispy.c optional ispy device-driver isofs/cd9660/cd9660_bmap.c optional cd9660 isofs/cd9660/cd9660_lookup.c optional cd9660 isofs/cd9660/cd9660_node.c optional cd9660 isofs/cd9660/cd9660_rrip.c optional cd9660 isofs/cd9660/cd9660_util.c optional cd9660 isofs/cd9660/cd9660_vfsops.c optional cd9660 isofs/cd9660/cd9660_vnops.c optional cd9660 kern/imgact_aout.c standard kern/imgact_elf.c standard kern/imgact_gzip.c optional gzip kern/imgact_shell.c standard kern/inflate.c optional gzip kern/init_main.c standard kern/init_sysent.c standard kern/init_sysvec.c standard kern/kern_acct.c standard kern/kern_clock.c standard kern/kern_conf.c standard kern/kern_descrip.c standard kern/kern_devconf.c standard kern/kern_exec.c standard kern/kern_exit.c standard kern/kern_fork.c standard kern/kern_ktrace.c standard kern/kern_lkm.c standard kern/kern_lockf.c standard kern/kern_malloc.c standard kern/kern_mib.c standard kern/kern_ntptime.c standard kern/kern_physio.c standard kern/kern_proc.c standard kern/kern_prot.c standard kern/kern_resource.c standard kern/kern_sig.c standard kern/kern_subr.c standard kern/kern_synch.c standard kern/kern_sysctl.c standard kern/kern_time.c standard kern/kern_xxx.c standard kern/subr_diskslice.c standard kern/subr_dkbad.c standard kern/subr_log.c standard kern/subr_prf.c standard kern/subr_prof.c standard kern/subr_rlist.c standard kern/subr_xxx.c standard kern/sys_generic.c standard kern/sys_process.c standard kern/sys_socket.c standard kern/sys_pipe.c standard kern/sysv_ipc.c standard kern/sysv_msg.c optional sysvmsg kern/sysv_sem.c optional sysvsem kern/sysv_shm.c optional sysvshm kern/tty.c standard kern/tty_compat.c standard kern/tty_conf.c standard kern/tty_pty.c optional pty kern/tty_snoop.c optional snp kern/tty_subr.c standard kern/tty_tb.c optional tb kern/tty_tty.c standard kern/uipc_domain.c standard kern/uipc_mbuf.c standard kern/uipc_proto.c standard kern/uipc_socket.c standard kern/uipc_socket2.c standard kern/uipc_syscalls.c standard kern/uipc_usrreq.c standard kern/vfs_bio.c standard kern/vfs_cache.c standard kern/vfs_cluster.c standard kern/vfs_conf.c standard kern/vfs_init.c standard kern/vfs_lookup.c standard kern/vfs_subr.c standard kern/vfs_syscalls.c standard kern/vfs_vnops.c standard miscfs/deadfs/dead_vnops.c standard miscfs/fdesc/fdesc_vfsops.c optional fdesc miscfs/fdesc/fdesc_vnops.c optional fdesc miscfs/fifofs/fifo_vnops.c standard miscfs/kernfs/kernfs_vfsops.c optional kernfs miscfs/kernfs/kernfs_vnops.c optional kernfs miscfs/nullfs/null_subr.c optional nullfs miscfs/nullfs/null_vfsops.c optional nullfs miscfs/nullfs/null_vnops.c optional nullfs miscfs/portal/portal_vfsops.c optional portal miscfs/portal/portal_vnops.c optional portal miscfs/procfs/procfs_ctl.c optional procfs miscfs/procfs/procfs_fpregs.c standard miscfs/procfs/procfs_mem.c standard miscfs/procfs/procfs_note.c optional procfs miscfs/procfs/procfs_regs.c standard miscfs/procfs/procfs_status.c optional procfs miscfs/procfs/procfs_subr.c optional procfs miscfs/procfs/procfs_vfsops.c optional procfs miscfs/procfs/procfs_vnops.c optional procfs miscfs/procfs/procfs_map.c optional procfs miscfs/procfs/procfs_type.c optional procfs miscfs/specfs/spec_vnops.c standard miscfs/umapfs/umap_subr.c optional umapfs miscfs/umapfs/umap_vfsops.c optional umapfs miscfs/umapfs/umap_vnops.c optional umapfs miscfs/union/union_subr.c optional union miscfs/union/union_vfsops.c optional union miscfs/union/union_vnops.c optional union miscfs/devfs/devfs_vnops.c optional devfs miscfs/devfs/devfs_vfsops.c optional devfs miscfs/devfs/devfs_tree.c optional devfs msdosfs/msdosfs_conv.c optional msdosfs msdosfs/msdosfs_denode.c optional msdosfs msdosfs/msdosfs_fat.c optional msdosfs msdosfs/msdosfs_lookup.c optional msdosfs msdosfs/msdosfs_vfsops.c optional msdosfs msdosfs/msdosfs_vnops.c optional msdosfs net/bpf.c optional bpfilter net/bpf_filter.c optional bpfilter net/bsd_comp.c optional ppp net/if.c standard net/if_disc.c optional disc net/if_ethersubr.c optional ether net/if_fddisubr.c optional fddi net/if_loop.c optional loop +net/if_mib.c standard net/if_ppp.c optional ppp net/if_sl.c optional sl net/if_spppsubr.c optional sppp net/ppp_tty.c optional ppp net/radix.c standard net/raw_cb.c standard net/raw_usrreq.c standard net/route.c standard net/rtsock.c standard net/slcompress.c optional ppp net/slcompress.c optional sl net/if_tun.c optional tun netatalk/aarp.c optional netatalk netatalk/at_control.c optional netatalk netatalk/at_proto.c optional netatalk netatalk/at_rmx.c optional netatalkdebug netatalk/ddp_input.c optional netatalk netatalk/ddp_output.c optional netatalk netatalk/ddp_usrreq.c optional netatalk #netccitt/ccitt_proto.c optional ccitt #netccitt/hd_debug.c optional hdlc #netccitt/hd_input.c optional hdlc #netccitt/hd_output.c optional hdlc #netccitt/hd_subr.c optional hdlc #netccitt/hd_timer.c optional hdlc #netccitt/if_x25subr.c optional ccitt #netccitt/llc_input.c optional llc #netccitt/llc_output.c optional llc #netccitt/llc_subr.c optional llc #netccitt/llc_timer.c optional llc #netccitt/pk_acct.c optional ccitt #netccitt/pk_debug.c optional ccitt #netccitt/pk_input.c optional ccitt #netccitt/pk_llcsubr.c optional hdlc #netccitt/pk_llcsubr.c optional llc #netccitt/pk_output.c optional ccitt #netccitt/pk_subr.c optional ccitt #netccitt/pk_timer.c optional ccitt #netccitt/pk_usrreq.c optional ccitt #netimp/if_imp.c optional imp #netimp/if_imphost.c optional imp #netimp/raw_imp.c optional imp netinet/if_ether.c optional ether netinet/igmp.c optional inet netinet/in.c optional inet netinet/in_pcb.c optional inet netinet/in_proto.c optional inet netinet/in_rmx.c optional inet netinet/ip_icmp.c optional inet netinet/ip_input.c optional inet netinet/ip_mroute.c optional inet netinet/ip_output.c optional inet netinet/ip_divert.c optional ipdivert netinet/raw_ip.c optional inet netinet/ip_fw.c optional ipfirewall netinet/tcp_debug.c optional tcpdebug netinet/tcp_input.c optional inet netinet/tcp_output.c optional inet netinet/tcp_subr.c optional inet netinet/tcp_timer.c optional inet netinet/tcp_usrreq.c optional inet netinet/udp_usrreq.c optional inet netipx/ipx_usrreq.c optional ipx netipx/ipx.c optional ipx netipx/ipx_cksum.c optional ipx netipx/ipx_error.c optional ipx netipx/ipx_input.c optional ipx netipx/ipx_ip.c optional ipx netipx/ipx_outputfl.c optional ipx netipx/ipx_pcb.c optional ipx netipx/ipx_proto.c optional ipx netipx/ipx_tun.c optional ipx netipx/spx_debug.c optional ipx netipx/spx_usrreq.c optional ipx #netiso/clnp_debug.c optional iso #netiso/clnp_er.c optional iso #netiso/clnp_frag.c optional iso #netiso/clnp_input.c optional iso #netiso/clnp_options.c optional iso #netiso/clnp_output.c optional iso #netiso/clnp_raw.c optional iso #netiso/clnp_subr.c optional iso #netiso/clnp_timer.c optional iso #netiso/cltp_usrreq.c optional iso #netiso/esis.c optional iso #netiso/idrp_usrreq.c optional iso #netiso/if_eon.c optional eon #netiso/iso.c optional iso #netiso/iso_chksum.c optional iso #netiso/iso_pcb.c optional iso #netiso/iso_proto.c optional iso #netiso/iso_snpac.c optional iso #netiso/tp_astring.c optional iso #netiso/tp_astring.c optional tpip #netiso/tp_cons.c optional iso #netiso/tp_driver.c optional iso #netiso/tp_driver.c optional tpip #netiso/tp_emit.c optional iso #netiso/tp_emit.c optional tpip #netiso/tp_inet.c optional iso #netiso/tp_inet.c optional tpip #netiso/tp_input.c optional iso #netiso/tp_input.c optional tpip #netiso/tp_iso.c optional iso #netiso/tp_meas.c optional iso #netiso/tp_meas.c optional tpip #netiso/tp_output.c optional iso #netiso/tp_output.c optional tpip #netiso/tp_pcb.c optional iso #netiso/tp_pcb.c optional tpip #netiso/tp_subr.c optional iso #netiso/tp_subr.c optional tpip #netiso/tp_subr2.c optional iso #netiso/tp_subr2.c optional tpip #netiso/tp_timer.c optional iso #netiso/tp_timer.c optional tpip #netiso/tp_trace.c optional iso #netiso/tp_trace.c optional tpip #netiso/tp_usrreq.c optional iso #netiso/tp_usrreq.c optional tpip #netiso/tuba_subr.c optional iso tuba #netiso/tuba_table.c optional iso tuba #netiso/tuba_usrreq.c optional iso tuba netkey/key.c optional key #netns/idp_usrreq.c optional ns #netns/ns.c optional ns #netns/ns_error.c optional ns #netns/ns_input.c optional ns #netns/ns_ip.c optional ns #netns/ns_output.c optional ns #netns/ns_pcb.c optional ns #netns/ns_proto.c optional ns #netns/spp_debug.c optional ns #netns/spp_usrreq.c optional ns nfs/nfs_bio.c optional nfs nfs/nfs_node.c optional nfs nfs/nfs_nqlease.c optional nfs nfs/nfs_serv.c optional nfs nfs/nfs_socket.c optional nfs nfs/nfs_srvcache.c optional nfs nfs/nfs_subs.c optional nfs nfs/nfs_syscalls.c optional nfs nfs/nfs_vfsops.c optional nfs nfs/nfs_vnops.c optional nfs pccard/pccard.c optional crd pccard/pcic.c optional pcic device-driver pci/aic7870.c optional ahc device-driver pci/bt9xx.c optional bt device-driver pci/if_de.c optional de device-driver pci/if_ed_p.c optional ed device-driver pci/if_fxp.c optional fxp device-driver pci/if_lnc_p.c optional lnc device-driver pci/if_vx.c optional vx device-driver pci/ncr.c optional ncr device-driver pci/pci.c optional pci device-driver pci/pcisupport.c optional pci pci/if_pdq.c optional fea device-driver pci/pdq.c optional fea device-driver pci/if_pdq.c optional fpa device-driver pci/pdq.c optional fpa device-driver pci/meteor.c optional meteor device-driver scsi/cd.c optional cd scsi/ch.c optional ch scsi/od.c optional od scsi/scsi_base.c optional scbus scsi/scsi_sense.c optional scbus scsi/scsi_ioctl.c optional scbus scsi/scsiconf.c optional scbus scsi/scsi_driver.c optional scbus scsi/uk.c optional scbus scsi/pt.c optional pt scsi/sd.c optional sd scsi/st.c optional st scsi/worm.c optional worm scsi/su.c optional su scsi/ssc.c optional ssc scsi/sctarg.c optional sctarg ufs/ffs/ffs_alloc.c optional ffs ufs/ffs/ffs_alloc.c optional mfs ufs/ffs/ffs_balloc.c optional ffs ufs/ffs/ffs_balloc.c optional mfs ufs/ffs/ffs_inode.c optional ffs ufs/ffs/ffs_inode.c optional mfs ufs/ffs/ffs_subr.c optional ffs ufs/ffs/ffs_subr.c optional mfs ufs/ffs/ffs_tables.c optional ffs ufs/ffs/ffs_tables.c optional mfs ufs/ffs/ffs_vfsops.c optional ffs ufs/ffs/ffs_vfsops.c optional mfs ufs/ffs/ffs_vnops.c optional ffs ufs/ffs/ffs_vnops.c optional mfs ufs/lfs/lfs_alloc.c optional lfs ufs/lfs/lfs_balloc.c optional lfs ufs/lfs/lfs_bio.c optional lfs ufs/lfs/lfs_cksum.c optional lfs ufs/lfs/lfs_debug.c optional lfs ufs/lfs/lfs_inode.c optional lfs ufs/lfs/lfs_segment.c optional lfs ufs/lfs/lfs_subr.c optional lfs ufs/lfs/lfs_syscalls.c optional lfs ufs/lfs/lfs_vfsops.c optional lfs ufs/lfs/lfs_vnops.c optional lfs ufs/mfs/mfs_vfsops.c optional mfs ufs/mfs/mfs_vnops.c optional mfs gnu/ext2fs/ext2_balloc.c optional ext2fs gnu/ext2fs/ext2_inode.c optional ext2fs gnu/ext2fs/ext2_subr.c optional ext2fs gnu/ext2fs/ext2_vfsops.c optional ext2fs gnu/ext2fs/ext2_vnops.c optional ext2fs gnu/ext2fs/ext2_inode_cnv.c optional ext2fs gnu/ext2fs/ext2_lookup.c optional ext2fs gnu/ext2fs/ext2_linux_ialloc.c optional ext2fs gnu/ext2fs/ext2_linux_balloc.c optional ext2fs gnu/ext2fs/ext2_alloc.c optional ext2fs ufs/ufs/ufs_bmap.c standard ufs/ufs/ufs_disksubr.c standard ufs/ufs/ufs_ihash.c standard ufs/ufs/ufs_inode.c standard ufs/ufs/ufs_lookup.c standard ufs/ufs/ufs_quota.c standard ufs/ufs/ufs_vfsops.c standard ufs/ufs/ufs_vnops.c standard vm/default_pager.c standard vm/device_pager.c standard vm/kern_lock.c standard vm/swap_pager.c standard vm/vm_fault.c standard vm/vm_glue.c standard vm/vm_init.c standard vm/vm_kern.c standard vm/vm_map.c standard vm/vm_meter.c standard vm/vm_mmap.c standard vm/vm_object.c standard vm/vm_page.c standard vm/vm_pageout.c standard vm/vm_pager.c standard vm/vm_swap.c standard vm/vm_unix.c standard vm/vnode_pager.c standard Index: head/sys/net/if.c =================================================================== --- head/sys/net/if.c (revision 17351) +++ head/sys/net/if.c (revision 17352) @@ -1,747 +1,747 @@ /* * Copyright (c) 1980, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)if.c 8.3 (Berkeley) 1/4/94 - * $Id: if.c,v 1.33 1996/07/11 16:32:26 wollman Exp $ + * $Id: if.c,v 1.34 1996/07/24 19:59:53 wollman Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * System initialization */ static int ifconf __P((int, caddr_t)); static void ifinit __P((void *)); static void if_qflush __P((struct ifqueue *)); static void if_slowtimo __P((void *)); static void link_rtrequest __P((int, struct rtentry *, struct sockaddr *)); SYSINIT(interfaces, SI_SUB_PROTO_IF, SI_ORDER_FIRST, ifinit, NULL) int ifqmaxlen = IFQ_MAXLEN; struct ifnet *ifnet; /* * Network interface utility routines. * * Routines with ifa_ifwith* names take sockaddr *'s as * parameters. * * This routine assumes that it will be called at splimp() or higher. */ /* ARGSUSED*/ void ifinit(dummy) void *dummy; { register struct ifnet *ifp; for (ifp = ifnet; ifp; ifp = ifp->if_next) if (ifp->if_snd.ifq_maxlen == 0) ifp->if_snd.ifq_maxlen = ifqmaxlen; if_slowtimo(0); } -static int if_index = 0; -static struct ifaddr **ifnet_addrs; +int if_index = 0; +struct ifaddr **ifnet_addrs; /* * Attach an interface to the * list of "active" interfaces. */ void if_attach(ifp) struct ifnet *ifp; { unsigned socksize, ifasize; int namelen, masklen; char workbuf[64]; register struct ifnet **p = &ifnet; register struct sockaddr_dl *sdl; register struct ifaddr *ifa; static int if_indexlim = 8; while (*p) p = &((*p)->if_next); *p = ifp; ifp->if_index = ++if_index; microtime(&ifp->if_lastchange); if (ifnet_addrs == 0 || if_index >= if_indexlim) { unsigned n = (if_indexlim <<= 1) * sizeof(ifa); struct ifaddr **q = (struct ifaddr **) malloc(n, M_IFADDR, M_WAITOK); bzero((caddr_t)q, n); if (ifnet_addrs) { bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2); free((caddr_t)ifnet_addrs, M_IFADDR); } ifnet_addrs = q; } /* * create a Link Level name for this device */ namelen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit); #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m)) masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen; socksize = masklen + ifp->if_addrlen; #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1))) socksize = ROUNDUP(socksize); if (socksize < sizeof(*sdl)) socksize = sizeof(*sdl); ifasize = sizeof(*ifa) + 2 * socksize; ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK); if (ifa) { bzero((caddr_t)ifa, ifasize); sdl = (struct sockaddr_dl *)(ifa + 1); sdl->sdl_len = socksize; sdl->sdl_family = AF_LINK; bcopy(workbuf, sdl->sdl_data, namelen); sdl->sdl_nlen = namelen; sdl->sdl_index = ifp->if_index; sdl->sdl_type = ifp->if_type; ifnet_addrs[if_index - 1] = ifa; ifa->ifa_ifp = ifp; ifa->ifa_next = ifp->if_addrlist; ifa->ifa_rtrequest = link_rtrequest; ifp->if_addrlist = ifa; ifa->ifa_addr = (struct sockaddr *)sdl; sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); ifa->ifa_netmask = (struct sockaddr *)sdl; sdl->sdl_len = masklen; while (namelen != 0) sdl->sdl_data[--namelen] = 0xff; } } /* * Locate an interface based on a complete address. */ /*ARGSUSED*/ struct ifaddr * ifa_ifwithaddr(addr) register struct sockaddr *addr; { register struct ifnet *ifp; register struct ifaddr *ifa; #define equal(a1, a2) \ (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0) for (ifp = ifnet; ifp; ifp = ifp->if_next) for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr->sa_family != addr->sa_family) continue; if (equal(addr, ifa->ifa_addr)) return (ifa); if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr && equal(ifa->ifa_broadaddr, addr)) return (ifa); } return ((struct ifaddr *)0); } /* * Locate the point to point interface with a given destination address. */ /*ARGSUSED*/ struct ifaddr * ifa_ifwithdstaddr(addr) register struct sockaddr *addr; { register struct ifnet *ifp; register struct ifaddr *ifa; for (ifp = ifnet; ifp; ifp = ifp->if_next) if (ifp->if_flags & IFF_POINTOPOINT) for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr->sa_family != addr->sa_family) continue; if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)) return (ifa); } return ((struct ifaddr *)0); } /* * Find an interface on a specific network. If many, choice * is most specific found. */ struct ifaddr * ifa_ifwithnet(addr) struct sockaddr *addr; { register struct ifnet *ifp; register struct ifaddr *ifa; struct ifaddr *ifa_maybe = (struct ifaddr *) 0; u_int af = addr->sa_family; char *addr_data = addr->sa_data, *cplim; if (af == AF_LINK) { register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr; if (sdl->sdl_index && sdl->sdl_index <= if_index) return (ifnet_addrs[sdl->sdl_index - 1]); } for (ifp = ifnet; ifp; ifp = ifp->if_next) { for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { register char *cp, *cp2, *cp3; if (ifa->ifa_addr->sa_family != af) next: continue; if (ifp->if_flags & IFF_POINTOPOINT) { if (ifa->ifa_dstaddr != 0 && equal(addr, ifa->ifa_dstaddr)) return (ifa); } else { if (ifa->ifa_netmask == 0) continue; cp = addr_data; cp2 = ifa->ifa_addr->sa_data; cp3 = ifa->ifa_netmask->sa_data; cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; while (cp3 < cplim) if ((*cp++ ^ *cp2++) & *cp3++) goto next; if (ifa_maybe == 0 || rn_refines((caddr_t)ifa->ifa_netmask, (caddr_t)ifa_maybe->ifa_netmask)) ifa_maybe = ifa; } } } return (ifa_maybe); } /* * Find an interface address specific to an interface best matching * a given address. */ struct ifaddr * ifaof_ifpforaddr(addr, ifp) struct sockaddr *addr; register struct ifnet *ifp; { register struct ifaddr *ifa; register char *cp, *cp2, *cp3; register char *cplim; struct ifaddr *ifa_maybe = 0; u_int af = addr->sa_family; if (af >= AF_MAX) return (0); for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr->sa_family != af) continue; ifa_maybe = ifa; if (ifa->ifa_netmask == 0) { if (equal(addr, ifa->ifa_addr) || (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))) return (ifa); continue; } if (ifp->if_flags & IFF_POINTOPOINT) { if (equal(addr, ifa->ifa_dstaddr)) return (ifa); } else { cp = addr->sa_data; cp2 = ifa->ifa_addr->sa_data; cp3 = ifa->ifa_netmask->sa_data; cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; for (; cp3 < cplim; cp3++) if ((*cp++ ^ *cp2++) & *cp3) break; if (cp3 == cplim) return (ifa); } } return (ifa_maybe); } #include /* * Default action when installing a route with a Link Level gateway. * Lookup an appropriate real ifa to point to. * This should be moved to /sys/net/link.c eventually. */ static void link_rtrequest(cmd, rt, sa) int cmd; register struct rtentry *rt; struct sockaddr *sa; { register struct ifaddr *ifa; struct sockaddr *dst; struct ifnet *ifp; if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) || ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0)) return; ifa = ifaof_ifpforaddr(dst, ifp); if (ifa) { IFAFREE(rt->rt_ifa); rt->rt_ifa = ifa; ifa->ifa_refcnt++; if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) ifa->ifa_rtrequest(cmd, rt, sa); } } /* * Mark an interface down and notify protocols of * the transition. * NOTE: must be called at splnet or eqivalent. */ void if_down(ifp) register struct ifnet *ifp; { register struct ifaddr *ifa; ifp->if_flags &= ~IFF_UP; microtime(&ifp->if_lastchange); for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) pfctlinput(PRC_IFDOWN, ifa->ifa_addr); if_qflush(&ifp->if_snd); rt_ifmsg(ifp); } /* * Mark an interface up and notify protocols of * the transition. * NOTE: must be called at splnet or eqivalent. */ void if_up(ifp) register struct ifnet *ifp; { ifp->if_flags |= IFF_UP; microtime(&ifp->if_lastchange); #ifdef notyet register struct ifaddr *ifa; /* this has no effect on IP, and will kill all iso connections XXX */ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) pfctlinput(PRC_IFUP, ifa->ifa_addr); #endif rt_ifmsg(ifp); } /* * Flush an interface queue. */ static void if_qflush(ifq) register struct ifqueue *ifq; { register struct mbuf *m, *n; n = ifq->ifq_head; while ((m = n) != 0) { n = m->m_act; m_freem(m); } ifq->ifq_head = 0; ifq->ifq_tail = 0; ifq->ifq_len = 0; } /* * Handle interface watchdog timer routines. Called * from softclock, we decrement timers (if set) and * call the appropriate interface routine on expiration. */ static void if_slowtimo(arg) void *arg; { register struct ifnet *ifp; int s = splimp(); for (ifp = ifnet; ifp; ifp = ifp->if_next) { if (ifp->if_timer == 0 || --ifp->if_timer) continue; if (ifp->if_watchdog) (*ifp->if_watchdog)(ifp); } splx(s); timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); } /* * Map interface name to * interface structure pointer. */ struct ifnet * ifunit(name) register char *name; { register char *cp; register struct ifnet *ifp; int unit; unsigned len; char *ep, c; for (cp = name; cp < name + IFNAMSIZ && *cp; cp++) if (*cp >= '0' && *cp <= '9') break; if (*cp == '\0' || cp == name + IFNAMSIZ) return ((struct ifnet *)0); /* * Save first char of unit, and pointer to it, * so we can put a null there to avoid matching * initial substrings of interface names. */ len = cp - name + 1; c = *cp; ep = cp; for (unit = 0; *cp >= '0' && *cp <= '9'; ) unit = unit * 10 + *cp++ - '0'; if (*cp != '\0') return 0; /* no trailing garbage allowed */ *ep = 0; for (ifp = ifnet; ifp; ifp = ifp->if_next) { if (bcmp(ifp->if_name, name, len)) continue; if (unit == ifp->if_unit) break; } *ep = c; return (ifp); } /* * Interface ioctls. */ int ifioctl(so, cmd, data, p) struct socket *so; int cmd; caddr_t data; struct proc *p; { register struct ifnet *ifp; register struct ifreq *ifr; int error; switch (cmd) { case SIOCGIFCONF: case OSIOCGIFCONF: return (ifconf(cmd, data)); } ifr = (struct ifreq *)data; ifp = ifunit(ifr->ifr_name); if (ifp == 0) return (ENXIO); switch (cmd) { case SIOCGIFFLAGS: ifr->ifr_flags = ifp->if_flags; break; case SIOCGIFMETRIC: ifr->ifr_metric = ifp->if_metric; break; case SIOCGIFMTU: ifr->ifr_mtu = ifp->if_mtu; break; case SIOCGIFPHYS: ifr->ifr_phys = ifp->if_physical; break; case SIOCSIFFLAGS: error = suser(p->p_ucred, &p->p_acflag); if (error) return (error); if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { int s = splimp(); if_down(ifp); splx(s); } if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { int s = splimp(); if_up(ifp); splx(s); } ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | (ifr->ifr_flags &~ IFF_CANTCHANGE); if (ifp->if_ioctl) (void) (*ifp->if_ioctl)(ifp, cmd, data); microtime(&ifp->if_lastchange); break; case SIOCSIFMETRIC: error = suser(p->p_ucred, &p->p_acflag); if (error) return (error); ifp->if_metric = ifr->ifr_metric; microtime(&ifp->if_lastchange); break; case SIOCSIFPHYS: error = suser(p->p_ucred, &p->p_acflag); if (error) return error; if (!ifp->if_ioctl) return EOPNOTSUPP; error = (*ifp->if_ioctl)(ifp, cmd, data); if (error == 0) microtime(&ifp->if_lastchange); return(error); case SIOCSIFMTU: error = suser(p->p_ucred, &p->p_acflag); if (error) return (error); if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); /* * 72 was chosen below because it is the size of a TCP/IP * header (40) + the minimum mss (32). */ if (ifr->ifr_mtu < 72 || ifr->ifr_mtu > 65535) return (EINVAL); error = (*ifp->if_ioctl)(ifp, cmd, data); if (error == 0) microtime(&ifp->if_lastchange); return(error); case SIOCADDMULTI: case SIOCDELMULTI: error = suser(p->p_ucred, &p->p_acflag); if (error) return (error); if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); error = (*ifp->if_ioctl)(ifp, cmd, data); if (error == 0 ) microtime(&ifp->if_lastchange); return(error); default: if (so->so_proto == 0) return (EOPNOTSUPP); #ifndef COMPAT_43 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp)); #else { int ocmd = cmd; switch (cmd) { case SIOCSIFDSTADDR: case SIOCSIFADDR: case SIOCSIFBRDADDR: case SIOCSIFNETMASK: #if BYTE_ORDER != BIG_ENDIAN if (ifr->ifr_addr.sa_family == 0 && ifr->ifr_addr.sa_len < 16) { ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; ifr->ifr_addr.sa_len = 16; } #else if (ifr->ifr_addr.sa_len == 0) ifr->ifr_addr.sa_len = 16; #endif break; case OSIOCGIFADDR: cmd = SIOCGIFADDR; break; case OSIOCGIFDSTADDR: cmd = SIOCGIFDSTADDR; break; case OSIOCGIFBRDADDR: cmd = SIOCGIFBRDADDR; break; case OSIOCGIFNETMASK: cmd = SIOCGIFNETMASK; } error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp)); switch (ocmd) { case OSIOCGIFADDR: case OSIOCGIFDSTADDR: case OSIOCGIFBRDADDR: case OSIOCGIFNETMASK: *(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family; } return (error); } #endif } return (0); } /* * Set/clear promiscuous mode on interface ifp based on the truth value * of pswitch. The calls are reference counted so that only the first * "on" request actually has an effect, as does the final "off" request. * Results are undefined if the "off" and "on" requests are not matched. */ int ifpromisc(ifp, pswitch) struct ifnet *ifp; int pswitch; { struct ifreq ifr; if (pswitch) { /* * If the device is not configured up, we cannot put it in * promiscuous mode. */ if ((ifp->if_flags & IFF_UP) == 0) return (ENETDOWN); if (ifp->if_pcount++ != 0) return (0); ifp->if_flags |= IFF_PROMISC; log(LOG_INFO, "%s%d: promiscuous mode enabled\n", ifp->if_name, ifp->if_unit); } else { if (--ifp->if_pcount > 0) return (0); ifp->if_flags &= ~IFF_PROMISC; } ifr.ifr_flags = ifp->if_flags; return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr)); } /* * Return interface configuration * of system. List may be used * in later ioctl's (above) to get * other information. */ /*ARGSUSED*/ static int ifconf(cmd, data) int cmd; caddr_t data; { register struct ifconf *ifc = (struct ifconf *)data; register struct ifnet *ifp = ifnet; register struct ifaddr *ifa; struct ifreq ifr, *ifrp; int space = ifc->ifc_len, error = 0; ifrp = ifc->ifc_req; for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) { char workbuf[64]; int ifnlen; ifnlen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit); if(ifnlen + 1 > sizeof ifr.ifr_name) { error = ENAMETOOLONG; } else { strcpy(ifr.ifr_name, workbuf); } if ((ifa = ifp->if_addrlist) == 0) { bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr)); if (error) break; space -= sizeof (ifr), ifrp++; } else for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) { register struct sockaddr *sa = ifa->ifa_addr; #ifdef COMPAT_43 if (cmd == OSIOCGIFCONF) { struct osockaddr *osa = (struct osockaddr *)&ifr.ifr_addr; ifr.ifr_addr = *sa; osa->sa_family = sa->sa_family; error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr)); ifrp++; } else #endif if (sa->sa_len <= sizeof(*sa)) { ifr.ifr_addr = *sa; error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr)); ifrp++; } else { space -= sa->sa_len - sizeof(*sa); if (space < sizeof (ifr)) break; error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr.ifr_name)); if (error == 0) error = copyout((caddr_t)sa, (caddr_t)&ifrp->ifr_addr, sa->sa_len); ifrp = (struct ifreq *) (sa->sa_len + (caddr_t)&ifrp->ifr_addr); } if (error) break; space -= sizeof (ifr); } } ifc->ifc_len -= space; return (error); } SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers"); SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management"); Index: head/sys/net/if.h =================================================================== --- head/sys/net/if.h (revision 17351) +++ head/sys/net/if.h (revision 17352) @@ -1,432 +1,448 @@ /* * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)if.h 8.1 (Berkeley) 6/10/93 - * $Id: if.h,v 1.30 1996/07/22 20:06:01 wollman Exp $ + * $Id: if.h,v 1.31 1996/07/23 14:44:46 wollman Exp $ */ #ifndef _NET_IF_H_ #define _NET_IF_H_ /* * Structures defining a network interface, providing a packet * transport mechanism (ala level 0 of the PUP protocols). * * Each interface accepts output datagrams of a specified maximum * length, and provides higher level routines with input datagrams * received from its medium. * * Output occurs when the routine if_output is called, with three parameters: * (*ifp->if_output)(ifp, m, dst, rt) * Here m is the mbuf chain to be sent and dst is the destination address. * The output routine encapsulates the supplied datagram if necessary, * and then transmits it on its medium. * * On input, each interface unwraps the data received by it, and either * places it on the input queue of a internetwork datagram routine * and posts the associated software interrupt, or passes the datagram to a raw * packet input routine. * * Routines exist for locating interfaces by their addresses * or for locating a interface on a certain network, as well as more general * routing and gateway routines maintaining information used to locate * interfaces. These routines live in the files if.c and route.c */ #include /* for struct sockaddr */ #ifndef _TIME_ /* XXX fast fix for SNMP, going away soon */ #include #endif #ifdef __STDC__ /* * Forward structure declarations for function prototypes [sic]. */ struct mbuf; struct proc; struct rtentry; struct socket; struct ether_header; #endif struct if_data { /* generic interface information */ u_char ifi_type; /* ethernet, tokenring, etc */ u_char ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */ u_char ifi_addrlen; /* media address length */ u_char ifi_hdrlen; /* media header length */ + u_char ifi_recvquota; /* polling quota for receive intrs */ + u_char ifi_xmitquota; /* polling quota for xmit intrs */ u_long ifi_mtu; /* maximum transmission unit */ u_long ifi_metric; /* routing metric (external only) */ u_long ifi_baudrate; /* linespeed */ /* volatile statistics */ u_long ifi_ipackets; /* packets received on interface */ u_long ifi_ierrors; /* input errors on interface */ u_long ifi_opackets; /* packets sent on interface */ u_long ifi_oerrors; /* output errors on interface */ u_long ifi_collisions; /* collisions on csma interfaces */ u_long ifi_ibytes; /* total number of octets received */ u_long ifi_obytes; /* total number of octets sent */ u_long ifi_imcasts; /* packets received via multicast */ u_long ifi_omcasts; /* packets sent via multicast */ u_long ifi_iqdrops; /* dropped on input, this interface */ u_long ifi_noproto; /* destined for unsupported protocol */ + u_long ifi_recvtiming; /* usec spent receiving when timing */ + u_long ifi_xmittiming; /* usec spent xmitting when timing */ struct timeval ifi_lastchange; /* time of last administrative change */ }; /* * Structure defining a queue for a network interface. * * (Would like to call this struct ``if'', but C isn't PL/1.) */ struct ifqueue { struct mbuf *ifq_head; struct mbuf *ifq_tail; int ifq_len; int ifq_maxlen; int ifq_drops; }; /* * Structure describing information about an interface * which may be of interest to management entities. */ struct ifnet { void *if_softc; /* pointer to driver state */ char *if_name; /* name, e.g. ``en'' or ``lo'' */ struct ifnet *if_next; /* all struct ifnets are chained */ struct ifaddr *if_addrlist; /* linked list of addresses per if */ int if_pcount; /* number of promiscuous listeners */ struct bpf_if *if_bpf; /* packet filter structure */ u_short if_index; /* numeric abbreviation for this if */ short if_unit; /* sub-unit for lower level driver */ short if_timer; /* time 'til if_watchdog called */ short if_flags; /* up/down, broadcast, etc. */ - u_char if_recvquota, if_sendquota; /* quotas for send, receive */ - u_char if_ipending; /* interrupts pending */ + int if_ipending; /* interrupts pending */ + void *if_linkmib; /* link-type-specific MIB data */ + size_t if_linkmiblen; /* length of above data */ struct if_data if_data; /* procedure handles */ int (*if_output) /* output routine (enqueue) */ __P((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *)); void (*if_start) /* initiate output routine */ __P((struct ifnet *)); int (*if_done) /* output complete routine */ __P((struct ifnet *)); /* (XXX not used; fake prototype) */ int (*if_ioctl) /* ioctl routine */ __P((struct ifnet *, int, caddr_t)); void (*if_watchdog) /* timer routine */ __P((struct ifnet *)); - void (*if_poll_recv) /* polled receive routine */ + int (*if_poll_recv) /* polled receive routine */ __P((struct ifnet *, int *)); - void (*if_poll_xmit) /* polled transmit routine */ + int (*if_poll_xmit) /* polled transmit routine */ __P((struct ifnet *, int *)); void (*if_poll_intren) /* polled interrupt reenable routine */ __P((struct ifnet *)); void (*if_poll_slowinput) /* input routine for slow devices */ __P((struct ifnet *, struct mbuf *)); struct ifqueue if_snd; /* output queue */ struct ifqueue *if_poll_slowq; /* input queue for slow devices */ }; #define if_mtu if_data.ifi_mtu #define if_type if_data.ifi_type #define if_physical if_data.ifi_physical #define if_addrlen if_data.ifi_addrlen #define if_hdrlen if_data.ifi_hdrlen #define if_metric if_data.ifi_metric #define if_baudrate if_data.ifi_baudrate #define if_ipackets if_data.ifi_ipackets #define if_ierrors if_data.ifi_ierrors #define if_opackets if_data.ifi_opackets #define if_oerrors if_data.ifi_oerrors #define if_collisions if_data.ifi_collisions #define if_ibytes if_data.ifi_ibytes #define if_obytes if_data.ifi_obytes #define if_imcasts if_data.ifi_imcasts #define if_omcasts if_data.ifi_omcasts #define if_iqdrops if_data.ifi_iqdrops #define if_noproto if_data.ifi_noproto #define if_lastchange if_data.ifi_lastchange +#define if_recvquota if_data.ifi_recvquota +#define if_xmitquota if_data.ifi_xmitquota #define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)0) #define IFF_UP 0x1 /* interface is up */ #define IFF_BROADCAST 0x2 /* broadcast address valid */ #define IFF_DEBUG 0x4 /* turn on debugging */ #define IFF_LOOPBACK 0x8 /* is a loopback net */ #define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */ /*#define IFF_NOTRAILERS 0x20 * obsolete: avoid use of trailers */ #define IFF_RUNNING 0x40 /* resources allocated */ #define IFF_NOARP 0x80 /* no address resolution protocol */ #define IFF_PROMISC 0x100 /* receive all packets */ #define IFF_ALLMULTI 0x200 /* receive all multicast packets */ #define IFF_OACTIVE 0x400 /* transmission in progress */ #define IFF_SIMPLEX 0x800 /* can't hear own transmissions */ #define IFF_LINK0 0x1000 /* per link layer defined bit */ #define IFF_LINK1 0x2000 /* per link layer defined bit */ #define IFF_LINK2 0x4000 /* per link layer defined bit */ #define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */ #define IFF_MULTICAST 0x8000 /* supports multicast */ /* flags set internally only: */ #define IFF_CANTCHANGE \ (IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\ IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI) /* * These really don't belong here, but there's no other obviously appropriate * location. */ #define IFP_AUI 0 #define IFP_10BASE2 1 #define IFP_10BASET 2 /* etc. */ /* * Bit values in if_ipending */ #define IFI_RECV 1 /* I want to receive */ #define IFI_XMIT 2 /* I want to transmit */ /* - * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1) - * input routines have queues of messages stored on ifqueue structures + * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq) + * are queues of messages stored on ifqueue structures * (defined above). Entries are added to and deleted from these structures * by these macros, which should be called with ipl raised to splimp(). */ #define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) #define IF_DROP(ifq) ((ifq)->ifq_drops++) #define IF_ENQUEUE(ifq, m) { \ (m)->m_nextpkt = 0; \ if ((ifq)->ifq_tail == 0) \ (ifq)->ifq_head = m; \ else \ (ifq)->ifq_tail->m_nextpkt = m; \ (ifq)->ifq_tail = m; \ (ifq)->ifq_len++; \ } #define IF_PREPEND(ifq, m) { \ (m)->m_nextpkt = (ifq)->ifq_head; \ if ((ifq)->ifq_tail == 0) \ (ifq)->ifq_tail = (m); \ (ifq)->ifq_head = (m); \ (ifq)->ifq_len++; \ } #define IF_DEQUEUE(ifq, m) { \ (m) = (ifq)->ifq_head; \ if (m) { \ if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) \ (ifq)->ifq_tail = 0; \ (m)->m_nextpkt = 0; \ (ifq)->ifq_len--; \ } \ } #ifdef KERNEL #define IF_ENQ_DROP(ifq, m) if_enq_drop(ifq, m) #if defined(__GNUC__) && defined(MT_HEADER) static inline int if_queue_drop(struct ifqueue *ifq, struct mbuf *m) { IF_DROP(ifq); return 0; } static inline int if_enq_drop(struct ifqueue *ifq, struct mbuf *m) { if (IF_QFULL(ifq) && !if_queue_drop(ifq, m)) return 0; IF_ENQUEUE(ifq, m); return 1; } #else #ifdef MT_HEADER int if_enq_drop __P((struct ifqueue *, struct mbuf *)); #endif #endif #endif /* KERNEL */ #define IFQ_MAXLEN 50 #define IFNET_SLOWHZ 1 /* granularity is 1 second */ /* * The ifaddr structure contains information about one address * of an interface. They are maintained by the different address families, * are allocated and attached when an address is set, and are linked * together so all addresses for an interface can be located. */ struct ifaddr { struct sockaddr *ifa_addr; /* address of interface */ struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ struct sockaddr *ifa_netmask; /* used to determine subnet */ struct ifnet *ifa_ifp; /* back-pointer to interface */ struct ifaddr *ifa_next; /* next address for interface */ void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */ __P((int, struct rtentry *, struct sockaddr *)); u_short ifa_flags; /* mostly rt_flags for cloning */ short ifa_refcnt; /* extra to malloc for link info */ int ifa_metric; /* cost of going out this interface */ #ifdef notdef struct rtentry *ifa_rt; /* XXXX for ROUTETOIF ????? */ #endif }; #define IFA_ROUTE RTF_UP /* route installed */ /* * Message format for use in obtaining information about interfaces * from getkerninfo and the routing socket */ struct if_msghdr { u_short ifm_msglen; /* to skip over non-understood messages */ u_char ifm_version; /* future binary compatability */ u_char ifm_type; /* message type */ int ifm_addrs; /* like rtm_addrs */ int ifm_flags; /* value of if_flags */ u_short ifm_index; /* index for associated ifp */ struct if_data ifm_data;/* statistics and other data about if */ }; /* * Message format for use in obtaining information about interface addresses * from getkerninfo and the routing socket */ struct ifa_msghdr { u_short ifam_msglen; /* to skip over non-understood messages */ u_char ifam_version; /* future binary compatability */ u_char ifam_type; /* message type */ int ifam_addrs; /* like rtm_addrs */ int ifam_flags; /* value of ifa_flags */ u_short ifam_index; /* index for associated ifp */ int ifam_metric; /* value of ifa_metric */ }; /* * Interface request structure used for socket * ioctl's. All interface ioctl's must have parameter * definitions which begin with ifr_name. The * remainder may be interface specific. */ struct ifreq { #define IFNAMSIZ 16 char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; short ifru_flags; int ifru_metric; int ifru_mtu; int ifru_phys; caddr_t ifru_data; } ifr_ifru; #define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ #define ifr_flags ifr_ifru.ifru_flags /* flags */ #define ifr_metric ifr_ifru.ifru_metric /* metric */ #define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ #define ifr_phys ifr_ifru.ifru_phys /* physical wire */ #define ifr_data ifr_ifru.ifru_data /* for use by interface */ }; struct ifaliasreq { char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */ struct sockaddr ifra_addr; struct sockaddr ifra_broadaddr; struct sockaddr ifra_mask; }; /* * Structure used in SIOCGIFCONF request. * Used to retrieve interface configuration * for machine (useful for programs which * must know all networks accessible). */ struct ifconf { int ifc_len; /* size of associated buffer */ union { caddr_t ifcu_buf; struct ifreq *ifcu_req; } ifc_ifcu; #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ #define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */ }; #include #ifdef KERNEL #define IFAFREE(ifa) \ if ((ifa)->ifa_refcnt <= 0) \ ifafree(ifa); \ else \ (ifa)->ifa_refcnt--; extern struct ifnet *ifnet; extern int ifqmaxlen; extern struct ifnet loif[]; +extern int if_index; +extern struct ifaddr **ifnet_addrs; void ether_ifattach __P((struct ifnet *)); void ether_input __P((struct ifnet *, struct ether_header *, struct mbuf *)); int ether_output __P((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *)); void if_attach __P((struct ifnet *)); void if_down __P((struct ifnet *)); void if_up __P((struct ifnet *)); #ifdef vax void ifubareset __P((int)); #endif /*void ifinit __P((void));*/ /* declared in systm.h for main() */ int ifioctl __P((struct socket *, int, caddr_t, struct proc *)); int ifpromisc __P((struct ifnet *, int)); struct ifnet *ifunit __P((char *)); + +int if_poll_recv_slow __P((struct ifnet *ifp, int *quotap)); +void if_poll_xmit_slow __P((struct ifnet *ifp, int *quotap)); +void if_poll_throttle __P((void)); +void if_poll_unthrottle __P((void *)); +void if_poll_init __P((void)); +void if_poll __P((void)); struct ifaddr *ifa_ifwithaddr __P((struct sockaddr *)); struct ifaddr *ifa_ifwithdstaddr __P((struct sockaddr *)); struct ifaddr *ifa_ifwithnet __P((struct sockaddr *)); struct ifaddr *ifa_ifwithroute __P((int, struct sockaddr *, struct sockaddr *)); struct ifaddr *ifaof_ifpforaddr __P((struct sockaddr *, struct ifnet *)); void ifafree __P((struct ifaddr *)); int looutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *)); #endif /* KERNEL */ #endif /* !_NET_IF_H_ */ Index: head/sys/net/if_mib.c =================================================================== --- head/sys/net/if_mib.c (nonexistent) +++ head/sys/net/if_mib.c (revision 17352) @@ -0,0 +1,150 @@ +/* + * Copyright 1996 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * A sysctl(3) MIB for generic interface information. This information + * is exported in the net.link.generic branch, which has the following + * structure: + * + * net.link.generic .system - system-wide control variables + * and statistics (node) + * .ifdata..general + * - what's in `struct ifdata' + * plus some other info + * .ifdata..linkspecific + * - a link-type-specific data + * structure (as might be used + * by an SNMP agent + * + * Perhaps someday we will make addresses accessible via this interface + * as well (then there will be four such...). The reason that the + * index comes before the last element in the name is because it + * seems more orthogonal that way, particularly with the possibility + * of other per-interface data living down here as well (e.g., integrated + * services stuff). + */ + +SYSCTL_NODE(_net_link_generic, IFMIB_SYSTEM, system, CTLFLAG_RW, 0, + "Variables global to all interfaces"); +SYSCTL_INT(_net_link_generic_system, IFMIB_IFCOUNT, ifcount, CTLFLAG_RD, + &if_index, 0, "Number of configured interfaces"); + +static int +sysctl_ifdata SYSCTL_HANDLER_ARGS /* XXX bad syntax! */ +{ + int *name = (int *)arg1; + int error, ifnlen; + u_int namelen = arg2; + struct ifnet *ifp; + char workbuf[64]; + struct ifmibdata ifmd; + + if (namelen != 2) + return EINVAL; + + if (name[0] <= 0 || name[0] > if_index) + return ENOENT; + + ifp = ifnet_addrs[name[0] - 1]->ifa_ifp; + + switch(name[1]) { + default: + return ENOENT; + + case IFDATA_GENERAL: + ifnlen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit); + if(ifnlen + 1 > sizeof ifmd.ifmd_name) { + return ENAMETOOLONG; + } else { + strcpy(ifmd.ifmd_name, workbuf); + } + +#define COPY(fld) ifmd.ifmd_##fld = ifp->if_##fld + COPY(pcount); + COPY(flags); + COPY(data); +#undef COPY + ifmd.ifmd_snd_len = ifp->if_snd.ifq_len; + ifmd.ifmd_snd_maxlen = ifp->if_snd.ifq_maxlen; + ifmd.ifmd_snd_drops = ifp->if_snd.ifq_drops; + + error = SYSCTL_OUT(req, &ifmd, sizeof ifmd); + if (error || !req->newptr) + return error; + + error = SYSCTL_IN(req, &ifmd, sizeof ifmd); + if (error) + return error; + +#define DONTCOPY(fld) ifmd.ifmd_data.ifi_##fld = ifp->if_data.ifi_##fld + DONTCOPY(type); + DONTCOPY(physical); + DONTCOPY(addrlen); + DONTCOPY(hdrlen); + DONTCOPY(mtu); + DONTCOPY(metric); + DONTCOPY(baudrate); +#undef DONTCOPY +#define COPY(fld) ifp->if_##fld = ifmd.ifmd_##fld + COPY(data); + ifp->if_snd.ifq_maxlen = ifmd.ifmd_snd_maxlen; + ifp->if_snd.ifq_drops = ifmd.ifmd_snd_drops; +#undef COPY + break; + + case IFDATA_LINKSPECIFIC: + error = SYSCTL_OUT(req, ifp->if_linkmib, ifp->if_linkmiblen); + if (error || !req->newptr) + return error; + + error = SYSCTL_IN(req, ifp->if_linkmib, ifp->if_linkmiblen); + if (error) + return error; + + } + return 0; +} + +SYSCTL_NODE(_net_link_generic, IFMIB_IFDATA, ifdata, CTLFLAG_RW, + sysctl_ifdata, "Interface table"); + Property changes on: head/sys/net/if_mib.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/net/if_mib.h =================================================================== --- head/sys/net/if_mib.h (nonexistent) +++ head/sys/net/if_mib.h (revision 17352) @@ -0,0 +1,78 @@ +/* + * Copyright 1996 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _NET_IF_MIB_H +#define _NET_IF_MIB_H 1 + +struct ifmibdata { + char ifmd_name[IFNAMSIZ]; /* name of interface */ + int ifmd_pcount; /* number of promiscuous listeners */ + int ifmd_flags; /* interface flags */ + struct if_data ifmd_data; /* generic information and statistics */ + int ifmd_snd_len; /* instantaneous length of send queue */ + int ifmd_snd_maxlen; /* maximum length of send queue */ + int ifmd_snd_drops; /* number of drops in send queue */ +}; + +/* + * sysctl MIB tags at the net.link.generic level + */ +#define IFMIB_SYSTEM 1 /* non-interface-specific */ +#define IFMIB_IFDATA 2 /* per-interface data table */ + +/* + * MIB tags for the various net.link.generic.ifdata tables + */ +#define IFDATA_GENERAL 1 /* generic stats for all kinds of ifaces */ +#define IFDATA_LINKSPECIFIC 2 /* specific to the type of interface */ + +/* + * MIB tags at the net.link.generic.system level + */ +#define IFMIB_IFCOUNT 1 /* number of interfaces configured */ + +/* + * MIB tags as the net.link level + * All of the other values are IFT_* names defined in if_types.h. + */ +#define NETLINK_GENERIC 0 /* functions not specific to a type of iface */ + +/* + * The reason why the IFDATA_LINKSPECIFIC stuff is not under the + * net.link. branches is twofold: + * 1) It's easier to code this way, and doesn't require duplication. + * 2) The fourth level under net.link. is ; that is to say, + * the net.link. tree instruments the adaptation layers between + * and a particular protocol family (e.g., net.link.ether.inet + * instruments ARP). This does not really leave room for anything else + * that needs to have a well-known number. + */ +#endif /* _NET_IF_MIB_H */ Property changes on: head/sys/net/if_mib.h ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property