⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_subr.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lintstatic	char sccsid[] = "@(#)if_subr.c 1.1 92/07/30 Copyr 1986 Sun Micro";#endif/* * Device independent subroutines used by Ethernet device drivers. * Mostly this code takes care of protocols and sockets and * stuff.  Knows about Ethernet in general, but is ignorant of the * details of any particular Ethernet chip or board. */#include <sys/param.h>#include "boot/systm.h"#include <sys/mbuf.h>#include <sys/buf.h>#include <sys/socket.h>#include <sys/errno.h>#include <sys/time.h>#include <sys/reboot.h>#include <net/if.h>#include <net/if_arp.h>#include <net/route.h>#include <net/netisr.h>#ifdef NIT#include <net/nit.h>#endif#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/if_ether.h>#include <mon/sunromvec.h>#include <sys/dir.h>#include "boot/vnode.h"#include <ufs/fs.h>#include "boot/inode.h"#include <stand/saio.h>#include "boot/iob.h"#include <stand/sainet.h>#include "boot/inet.h"#ifdef OPENPROMS#include "boot/conf.h"#endifextern struct iob iob[NFILES];extern struct bootparam *boot_bp;extern struct in_addr my_in_addr;extern struct in_addr null_in_addr;#ifdef OPENPROMSextern struct ndevlist	ndevlist[];#endifstruct no_nd no_nd;		/* global for now - eliminate later */#ifdef DUMP_DEBUGstatic	int	dump_debug = 20;#endif DUMP_DEBUGethersetup(){	int	fdesc;	struct	iob	*file;	/*	 */	bzero(&my_in_addr, sizeof (struct in_addr));	bzero(&null_in_addr, sizeof (struct in_addr));	etherinit(&fdesc, &file);}/* * Interface exists: make available by filling in network interface * record.  System will initialize the interface when it is ready * to accept packets. * Any hardware-specific initialization is done by the caller. */ether_attach(ifp, unit, name, init, ioctl, output, reset)	register struct ifnet *ifp;	int unit;	char *name;	int (*init)(), (*ioctl)(), (*output)(), (*reset)();{	ifp->if_unit = unit;	ifp->if_name = name;	ifp->if_mtu = ETHERMTU;	ifp->if_addrlist = (struct ifaddr *)kmem_alloc(sizeof (struct ifaddr));	ifp->if_addrlist->ifa_ifp = ifp;	ifp->if_addrlist->ifa_next = (struct ifaddr *)0;	((struct sockaddr_in *)&((ifp->if_addrlist->ifa_addr)))->sin_family =	    AF_INET;	ifp->if_init = init;	ifp->if_ioctl = ioctl;	ifp->if_output = output;	ifp->if_reset = reset;	/*	 * Added to ensure that routing sees this interface.	 */	ifp->if_flags |= (IFF_UP | IFF_RUNNING);	if_attach(ifp);}address_known(ifp)	struct ifnet *ifp;{	return (((struct sockaddr_in *)&((ifp->if_addrlist->ifa_addr)))->sin_addr.s_addr != 0);}revarp_myaddr(ifp)	register struct ifnet *ifp;{	register struct sockaddr_in *sin;	sin = (struct sockaddr_in *)&(ifp->if_addrlist->ifa_addr);	if (bcmp(&my_in_addr, &null_in_addr, sizeof (struct in_addr)) == 0)  {		printf("revarp_myaddr: no IP address\n");		return;	}	bcopy(&my_in_addr, &sin->sin_addr, sizeof (struct in_addr));	if (if_setaddr(ifp, (struct sockaddr *)sin))		return;}etherinit(fdesc, file)	int	*fdesc;	register struct iob **file;{#ifndef sun4m	register struct ifnet *inet_ifp;	register struct boottab **tablep;	register struct boottab *dp;	int	status;	char	filename[3];	int	lfdesc;	register struct iob *lfile;	int (*init)(), (*ioctl)(), (*output)(), (*reset)();	register struct bootparam *bp;#ifdef	OPENPROMS	extern struct bootparam *prom_bootparam();#endif	OPENPROMS	extern struct boottab *(devsw[]);#endif !sun4m#ifdef OPENPROMS	if (prom_getversion() > 0)		return (obp_etherinit(fdesc, file));#endif#ifndef sun4m#ifdef	OPENPROMS	bp = prom_bootparam();#else	OPENPROMS	if (romp->v_bootparam == 0)	{		bp = (struct bootparam *)0x2000;	/* Old Sun-1 address */	} else	{		bp = *(romp->v_bootparam);		/* S-2: via romvec */	}#endif	OPENPROMS	/*	 * We are going to open an ether device, so obtain	 * a file descriptor record (iob).   Getiob exits	 * if it is out of iobs, so we assume that it returns	 * a good one.	 */	lfdesc = getiob();	lfile = &iob[lfdesc];	status = -1;try:	for (tablep = devsw;		(status == -1) && (0 != (dp = *tablep)); tablep++) {		if ((bp->bp_dev[0] == dp->b_dev[0]) &&			(bp->bp_dev[1] == dp->b_dev[1]))	{			/*			 * Fill in file table and open device.			 */			lfile->i_boottab = dp;			lfile->i_ino.i_dev = tablep-devsw;			lfile->i_ctlr = bp->bp_ctlr;			lfile->i_unit = bp->bp_unit;			lfile->i_boff = bp->bp_part;			status = opendev(lfdesc, lfile, 0);			if (status == -1)	{#ifdef  DUMP_DEBUG				dprint(dump_debug, 10,					"etherinit: could not open '%c%c'\n",					bp->bp_dev[0],					bp->bp_dev[1]);#endif  /* DUMP_DEBUG */			}			/*			 * prom ether drivers can't call etheropen			 * to do the revarp.  Test my ip addr to see			 * if this was the case.			 */			if (bcmp(&my_in_addr, &null_in_addr,			    sizeof (struct in_addr)) == 0)	{			    etheropen(&lfile->i_si);			}		} else {#ifdef  DUMP_DEBUG			dprint(dump_debug, 6,				"etherinit: not '%c%c'\n",				dp->b_dev[0],				dp->b_dev[1]);#endif  /* DUMP_DEBUG */		}	}	if (status == -1) {		char buf[16];#ifdef  DUMP_DEBUG		dprint(dump_debug, 10, "no ether device opened\n");#endif  /* DUMP_DEBUG */		printf ("input ether device name (");		for (tablep = devsw; (0 != (dp = *tablep)); tablep++)			printf (" %c%c%%d[01]",			    dp->b_dev[0], dp->b_dev[1]);		printf (" ): ");		gets(buf);		bp->bp_dev[0] = buf[0];		bp->bp_dev[1] = buf[1];		if ((buf[2] == '0') || (buf[2] == '1'))			bp->bp_ctlr = buf[2] - '0';		goto try;	}	/*	 * Then try to attach the ether device.	 */	inet_ifp = (struct ifnet *)kmem_alloc(sizeof (struct ifnet));	if (inet_ifp == (struct ifnet *)0)	{		printf("ether_init: bad kmem_alloc\n");	}	ifnet = inet_ifp;	init = 0;	ioctl = 0;	output = lfile->i_si.si_sif->sif_xmit;	reset = lfile->i_si.si_sif->sif_reset;	ether_attach(inet_ifp, 0, filename, init, ioctl, output, reset);	/*	 * Make the ifp point to the saioreq so that later	 * we can pass a pointer to the saioreq to if_output().	 * We are stealing if_lower for this purpose, since	 * it's not used in a stand-alone system.	 */	inet_ifp->if_lower = (struct ifnet *)(&lfile->i_si);	inet_ifp->if_next = (struct ifnet *)0;	/*	 * Pass the result back to the caller (ethersetup())	 */	*fdesc = lfdesc;	*file = lfile;	/*	 * Initialise the routing table for this interface.	 */	if_rtinit(inet_ifp, RTF_UP);#endif !sun4m}/* * Get server address and partition number from si_unit and si_boff. * * This uses the no_nd struct. */etheropen(sip)	struct saioreq *sip;{	inet_init(sip, &no_nd.no_nd_inet, no_nd.no_nd_buf);	return (0);}/* * Strategy routine.  User interface to do reads and writes * used to be through here.    No more.    Now we use the * ip routines, but the drivers need this stub. * We currently don't support writes. */intetherstrategy(sip, rw)	register struct saioreq *sip;	int rw;{#ifdef DUMP_DEBUG	dprint(dump_debug, 6, "etherstrategy(sip 0x%x, rw 0x%x)\n", sip, rw);#endif DUMP_DEBUG}set_ether_addr(ip_address, ether_address)	struct in_addr ip_address;	struct ether_addr *ether_address;{	struct saioreq *sip;	struct ifnet *ifp;	struct sainet *sain;	struct ifnet *if_ifwithaf();	if ((ifp = if_ifwithaf(AF_INET)) == (struct ifnet *)0)	{#ifdef  DUMP_DEBUG		dprint(dump_debug, 10, "set_ether_addr: bad ifp\n");#endif  /* DUMP_DEBUG */		return (-1);	}	sip = (struct saioreq *)ifp->if_lower;	sain = &no_nd.no_nd_inet;	/* get MAC address */#ifdef OPENPROMS	(*sip->si_sif->sif_macaddr)(sip->si_devdata, &sain->sain_myether);#else	(*sip->si_sif->sif_macaddr)(&sain->sain_myether);#endif	bcopy(&ip_address, &sain->sain_hisaddr.s_addr, sizeof (ip_address));	arp(sip, sain, no_nd.no_nd_buf);	bcopy(&sain->sain_hisether, ether_address, 6);	return (0);}#ifdef OPENPROMSobp_etherinit(fdesc, file)	int	*fdesc;	register struct iob **file;{	register struct ifnet *inet_ifp;	register struct boottab *dp;	int	status;	char	filename[3];	int	lfdesc;	register struct iob *lfile;	int (*init)(), (*ioctl)(), (*output)(), (*reset)();	char *prom_bootpath();	char	*pp;	dev_t	dev;	dev_t	getnetdev();	pp = prom_bootpath();	/*	 * We are going to open an ether device, so obtain	 * a file descriptor record (iob).   Getiob exits	 * if it is out of iobs, so we assume that it returns	 * a good one.	 */	lfdesc = getiob();	lfile = &iob[lfdesc];	status = -1;try:	dev = getnetdev("net");	dp = ndevlist[dev].nl_driver;	lfile->i_boottab = dp;	lfile->i_ino.i_dev = dev;	status = opendev(lfdesc, lfile, 0);	if (status == -1)	{#ifdef  DUMP_DEBUG		dprint(dump_debug, 10,			"etherinit: could not open '%s'\n", dp->b_desc);#endif  /* DUMP_DEBUG */		printf("could not open %s\n", dp->b_desc);		goto try;	} else {		if (status == -2) {			printf("not a net device %s\n", dp->b_desc);			goto try;		}	}	/*	 * prom ether drivers can't call etheropen	 * to do the revarp.  Test my ip addr to see	 * if this was the case.	 */	if (bcmp(&my_in_addr, &null_in_addr, sizeof (struct in_addr)) == 0) {		etheropen(&lfile->i_si);	}	/*	 * Then try to attach the ether device.	 */	inet_ifp = (struct ifnet *)kmem_alloc(sizeof (struct ifnet));	if (inet_ifp == (struct ifnet *)0)	{		printf("ether_init: bad kmem_alloc\n");	}	ifnet = inet_ifp;	init = 0;	ioctl = 0;	output = lfile->i_si.si_sif->sif_xmit;	reset = lfile->i_si.si_sif->sif_reset;	ether_attach(inet_ifp, 0, filename, init, ioctl, output, reset);	/*	 * Make the ifp point to the saioreq so that later	 * we can pass a pointer to the saioreq to if_output().	 * We are stealing if_lower for this purpose, since	 * it's not used in a stand-alone system.	 */	inet_ifp->if_lower = (struct ifnet *)(&lfile->i_si);	inet_ifp->if_next = (struct ifnet *)0;	/*	 * Pass the result back to the caller (ethersetup())	 */	*fdesc = lfdesc;	*file = lfile;	/*	 * Initialise the routing table for this interface.	 */	if_rtinit(inet_ifp, RTF_UP);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -