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

📄 sys-next.c

📁 unix and linux net driver
💻 C
📖 第 1 页 / 共 3 页
字号:
     * Scan through the system's network interfaces.     */    ifc.ifc_len = sizeof(ifs);    ifc.ifc_req = ifs;    if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {	warn("ioctl(SIOCGIFCONF): %m");	return mask;    }    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);    for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)	 	((char *)&ifr->ifr_addr + sizeof(struct sockaddr))) {	/*	 * Check the interface's internet address.	 */	if (ifr->ifr_addr.sa_family != AF_INET)	    continue;	ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;	if ((ntohl(ina) & nmask) != (addr & nmask))	    continue;	/*	 * Check that the interface is up, and not point-to-point or loopback.	 */	strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));	if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)	    continue;	if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))	    != IFF_UP)	    continue;	/*	 * Get its netmask and OR it into our mask.	 */	if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)	    continue;	mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;    }    return mask;}/* * have_route_to - determine if the system has any route to * a given IP address. * For demand mode to work properly, we have to ignore routes * through our own interface. */int have_route_to(u_int32_t addr){    return -1;}#if 0/* * daemon - Detach us from the terminal session. */intdaemon(nochdir, noclose)    int nochdir, noclose;{    int pid;    if ((pid = fork()) < 0)	return -1;    if (pid != 0)	exit(0);		/* parent dies */    (void)setsid();    if (!nochdir)	chdir("/");    if (!noclose) {	fclose(stdin);		/* don't need stdin, stdout, stderr */	fclose(stdout);	fclose(stderr);    }    return 0;}#endifchar *strdup(s)    const char *s;{    char *d = malloc(strlen(s) + 1);    if (d) strcpy(d, s);    return d;}/* * This logwtmp() implementation is subject to the following copyright: * * Copyright (c) 1988 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley.  The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#define WTMPFILE        "/usr/adm/wtmp"voidlogwtmp(line, name, host)    const char *line, *name, *host;{    int fd;    struct stat buf;    struct utmp ut;    if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)	return;    if (!fstat(fd, &buf)) {	strncpy(ut.ut_line, line, sizeof(ut.ut_line));	strncpy(ut.ut_name, name, sizeof(ut.ut_name));	strncpy(ut.ut_host, host, sizeof(ut.ut_host));	(void)time(&ut.ut_time);	if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))	    (void)ftruncate(fd, buf.st_size);    }    close(fd);}#if 0/* * Routines for locking and unlocking the serial device, moved here * from chat.c. */#define LOCK_PREFIX	"/usr/spool/uucp/LCK/LCK.."static char *lock_file;/* * lock - create a lock file for the named device */intlock(dev)    char *dev;{    int fd, pid, n;    char *p;    size_t l;    if ((p = strrchr(dev, '/')) != NULL)	dev = p + 1;    l = strlen(LOCK_PREFIX) + strlen(dev) + 1;    lock_file = malloc(l);    if (lock_file == NULL)	novm("lock file name");    slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev);    while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {	if (errno == EEXIST	    && (fd = open(lock_file, O_RDONLY, 0)) >= 0) {	    /* Read the lock file to find out who has the device locked */	    n = read(fd, &pid, sizeof(pid));	    if (n <= 0) {		error("Can't read pid from lock file %s", lock_file);		close(fd);	    } else {		if (kill(pid, 0) == -1 && errno == ESRCH) {		    /* pid no longer exists - remove the lock file */		    if (unlink(lock_file) == 0) {			close(fd);			notice("Removed stale lock on %s (pid %d)",			       dev, pid);			continue;		    } else			warn("Couldn't remove stale lock on %s", dev);		} else		    notice("Device %s is locked by pid %d",			   dev, pid);	    }	    close(fd);	} else	    error("Can't create lock file %s: %m", lock_file);	free(lock_file);	lock_file = NULL;	return -1;    }    pid = getpid();    write(fd, &pid, sizeof pid);    close(fd);    return 0;}/* * unlock - remove our lockfile */voidunlock(){    if (lock_file) {	unlink(lock_file);	free(lock_file);	lock_file = NULL;    }}#endif#if defined(i386) && defined(HAS_BROKEN_IOCTL)intioctl(fd, cmd, c)    int fd, cmd;    caddr_t c;{#undef	ioctl    int ret;#ifdef DEBUGIOCTL    int serrno;    u_char let, code, size;    size = (cmd >> 16) & IOCPARM_MASK;    let = (cmd >> 8);    code = cmd;    if (let == 't' && (75 <= code && code <= 90))    info("ioctl(%d, 0x%x ('%c', %d, %d), 0x%x)\n", fd, cmd,	   let, code, size, c);#endif    ret = ioctl(fd, cmd, c);#ifdef DEBUGIOCTL    serrno = errno;    if (ret == -1)	info("ioctl('%c', %d, %d) errno = %d (%m)\n",		let, code, size, errno);    if (let == 't' && (75 <= code && code <= 90) && (cmd & IOC_OUT)) {	int i, len = ((cmd >> 16) & IOCPARM_MASK);	for (i = 0; i < len / 4; ++i)		info("word[%d] @ 0x%06x = 0x%x\n",		       i, &((int *) c)[i],((int *)c)[i]);    }    errno = serrno;#endif    if (ret == -1 && errno == EPERM)	errno = ret = 0;    return ret;}#endif	/* HAS_BROKEN_IOCTL */#if defined(FIXSIGS) && (defined (hppa) || defined(sparc))/* * These redefinitions of Posix functions are necessary * because HPPA systems have an OS bug that causes  * sigaction to core dump: * * AlainF 9-Nov-1994	HACK FOR HP-PA/NEXTSTEP *			sigaction(3) seems broken in the HP-PA NeXTSTEP 3.2 *			Posix lib. This causes pppd to SIGBUS at the expiration *			of the first timeout (_sigtramp seems to invoke *			the SIGALRM handler at an unreasonably low address). *			All calls so sigaction(3) have been changed to calls *			to sigvec(2) and sigprocmask(SIG_BLOCK,...) to *			sigblock(2). *			This is kind of a hack, especially since there are *			other routines of the Posix lib still used, but *			it worked for me. * * Dave Hess <David-Hess@net.tamu.edu> noted that 3.3 Sparc seems to * have the same bug.  Thus this fix has been enabled for SPARC also. * * */int sigemptyset(sigset_t *mask){  *mask = 0;}sigaddset(sigset_t *mask, int which_sig){  *mask |= sigmask(which_sig);}int sigaction(int sig, const struct sigaction *act, struct sigaction *oact){   struct sigvec sv;   static int in = 0;   sv.sv_handler = act->sa_handler;   sv.sv_mask = act->sa_mask;   sv.sv_flags = 0;   if (!in)     {       in = 1;       warn("PPPD: Inside modified HP and SPARC sigaction\n");     }   return sigvec(sig, &sv, NULL);}#endif/* * Code following is added for 2.3 compatibility *//* * get_idle_time - return how long the link has been idle. */intget_idle_time(u, ip)    int u;    struct ppp_idle *ip;{  return (ioctl(ttyfd, PPPIOCGIDLE, ip) >= 0); }/* * get_ppp_stats - return statistics for the link. */intget_ppp_stats(u, stats)    int u;    struct pppd_stats *stats;{    struct ifpppstatsreq req;    memset (&req, 0, sizeof (req));    strlcpy(req.ifr_name, interface, sizeof(req.ifr_name));    if (ioctl(sockfd, SIOCGPPPSTATS, &req) < 0) {	error("Couldn't get PPP statistics: %m");	return 0;    }    stats->bytes_in = req.stats.p.ppp_ibytes;    stats->bytes_out = req.stats.p.ppp_obytes;    return 1;}/* * get_loop_output - read characters from the loopback, form them * into frames, and detect when we want to bring the real link up. * Return value is 1 if we need to bring up the link, 0 otherwise. */intget_loop_output(){#if 0    int rv = 0;    int n;    while ((n = read(loop_master, inbuf, sizeof(inbuf))) >= 0) {	if (loop_chars(inbuf, n))	    rv = 1;    }    if (n == 0)	fatal("eof on loopback");    if (errno != EWOULDBLOCK)	fatal("read from loopback: %m");    return rv;#endif    return 0;}/* * sifnpmode - Set the mode for handling packets for a given NP. */intsifnpmode(u, proto, mode)    int u;    int proto;    enum NPmode mode;{    struct npioctl npi;    npi.protocol = proto;    npi.mode = mode;    if (ioctl(ttyfd, PPPIOCSNPMODE, &npi) < 0) {	error("ioctl(set NP %d mode to %d): %m", proto, mode);	return 0;    }    return 1;}/* * open_ppp_loopback - open the device we use for getting * packets in demand mode, and connect it to a ppp interface. * Here we use a pty. */intopen_ppp_loopback(){#if 0    int flags;    struct termios tios;    int pppdisc = PPPDISC;    fatal("open_ppp_loopback called!");    if (openpty(&loop_master, &loop_slave, loop_name, NULL, NULL) < 0)	fatal("No free pty for loopback");    SYSDEBUG(("using %s for loopback", loop_name));    if (tcgetattr(loop_slave, &tios) == 0) {	tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);	tios.c_cflag |= CS8 | CREAD;	tios.c_iflag = IGNPAR;	tios.c_oflag = 0;	tios.c_lflag = 0;	if (tcsetattr(loop_slave, TCSAFLUSH, &tios) < 0)	    warn("couldn't set attributes on loopback: %m");    }    if ((flags = fcntl(loop_master, F_GETFL)) != -1) 	if (fcntl(loop_master, F_SETFL, flags | O_NONBLOCK) == -1)	    warn("couldn't set loopback to nonblock: %m");    ttyfd = loop_slave;    if (ioctl(ttyfd, TIOCSETD, &pppdisc) < 0)	fatal("ioctl(TIOCSETD): %m");    /*     * Find out which interface we were given.     */    if (ioctl(ttyfd, PPPIOCGUNIT, &ifunit) < 0)	fatal("ioctl(PPPIOCGUNIT): %m");    /*     * Enable debug in the driver if requested.     */    if (kdebugflag) {	if (ioctl(ttyfd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) {	    warn("ioctl (PPPIOCGFLAGS): %m");	} else {	    flags |= (kdebugflag & 0xFF) * SC_DEBUG;	    if (ioctl(ttyfd, PPPIOCSFLAGS, (caddr_t) &flags) < 0)		warn("ioctl(PPPIOCSFLAGS): %m");	}    }    return loop_master;#endif}/* * restore_loop - reattach the ppp unit to the loopback. */voidrestore_loop(){    int x;    /*     * Transfer the ppp interface back to the loopback.     */    if (ioctl(ttyfd, PPPIOCXFERUNIT, 0) < 0)	fatal("ioctl(transfer ppp unit): %m");    x = PPPDISC;    if (ioctl(loop_slave, TIOCSETD, &x) < 0)	fatal("ioctl(TIOCSETD): %m");    /*     * Check that we got the same unit again.     */    if (ioctl(loop_slave, PPPIOCGUNIT, &x) < 0)	fatal("ioctl(PPPIOCGUNIT): %m");    if (x != ifunit)	fatal("transfer_ppp failed: wanted unit %d, got %d",	      ifunit, x);    ttyfd = loop_slave;}/* * Use the hostid as part of the random number seed. */intget_host_seed(){    return gethostid();}/* * sys_check_options - check the options that the user specified */intsys_check_options(){  /*   * We don't support demand dialing yet.   */  if (demand)    {      option_error("PPP-2.3 for NeXTSTEP does not yet support demand dialing");      return 0;    }  return 1;}/* * sys_close - Clean up in a child process before execing. */voidsys_close(){    close(sockfd);    if (loop_slave >= 0) {	close(loop_slave);	close(loop_master);    }    closelog();}#if 0/* * wait_loop_output - wait until there is data available on the * loopback, for the length of time specified by *timo (indefinite * if timo is NULL). */void wait_loop_output(timo)    struct timeval *timo;{    fd_set ready;    int n;    FD_ZERO(&ready);    FD_SET(loop_master, &ready);    n = select(loop_master + 1, &ready, NULL, &ready, timo);    if (n < 0 && errno != EINTR)	fatal("select: %m");}/* * wait_time - wait for a given length of time or until a * signal is received. */void wait_time(timo)    struct timeval *timo;{    int n;    n = select(0, NULL, NULL, NULL, timo);    if (n < 0 && errno != EINTR)	fatal("select: %m");}#endif

⌨️ 快捷键说明

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