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

📄 sys-osf.c

📁 unix and linux net driver
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * System-dependent procedures for pppd under Digital UNIX (OSF/1). * * Copyright (c) 1994 The Australian National University. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted, provided that the above copyright * notice appears in all copies.  This software is provided without any * warranty, express or implied. The Australian National University * makes no representations about the suitability of this software for * any purpose. * * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, * OR MODIFICATIONS. */#define RCSID	"$Id: sys-osf.c,v 1.31 1999/12/23 01:35:28 paulus Exp $"#include <syslog.h>#include <stdio.h>#include <stddef.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>#include <termios.h>#include <signal.h>#include <malloc.h>#include <utmp.h>#include <sys/types.h>#include <sys/param.h>#include <sys/socket.h>#include <sys/stream.h>#include <sys/stropts.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/poll.h>#include <sys/ioctl.h>#include <net/if.h>#include <net/if_dl.h>#include <net/if_arp.h>#include <net/route.h>#include <net/ppp_defs.h>#include <net/pppio.h>#include <netinet/in.h>#include <arpa/inet.h>#include "pppd.h"static const char rcsid[] = RCSID;static int	pppfd;static int	fdmuxid = -1;static int	iffd;static int	sockfd;static int	restore_term;static struct termios inittermios;static struct winsize wsinfo;	/* Initial window size info */static pid_t	tty_sid;	/* PID of our session leader */extern u_char	inpacket_buf[];	/* borrowed from main.c */static int	link_mtu, link_mru;#define NMODULES	32static int	tty_nmodules;static char	tty_modules[NMODULES][FMNAMESZ+1];static int closed_stdio;static int initfdflags = -1;static int orig_ttyfd = -1;static int	if_is_up;	/* Interface has been marked up */static u_int32_t ifaddrs[2];	/* local and remote addresses */static u_int32_t default_route_gateway;	/* Gateway for default route added */static u_int32_t proxy_arp_addr;	/* Addr for proxy arp entry added */#define MAX_POLLFDS	32static struct pollfd pollfds[MAX_POLLFDS];static int n_pollfds;/* Prototypes for procedures local to this file. */static int translate_speed __P((int));static int baud_rate_of __P((int));static int get_ether_addr __P((u_int32_t, struct sockaddr *));static int strioctl __P((int, int, void *, int, int));/* * sys_init - System-dependent initialization. */voidsys_init(){    int x;    openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);    setlogmask(LOG_UPTO(LOG_INFO));    if (debug)	setlogmask(LOG_UPTO(LOG_DEBUG));    /* Get an internet socket for doing socket ioctl's on. */    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)	fatal("Couldn't create IP socket: %m");    if (default_device)	tty_sid = getsid((pid_t)0);    /*     * Open the ppp device.     */    pppfd = open("/dev/streams/ppp", O_RDWR | O_NONBLOCK, 0);    if (pppfd < 0)	fatal("Can't open /dev/streams/ppp: %m");    if (kdebugflag) {	x = PPPDBG_LOG + PPPDBG_DRIVER;	strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0);    }    /* Assign a new PPA and get its unit number. */    if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0)	fatal("Can't create new PPP interface: %m");    /*     * Open the ppp device again and push the if_ppp module on it.     */    iffd = open("/dev/streams/ppp", O_RDWR, 0);    if (iffd < 0)	fatal("Can't open /dev/streams/ppp (2): %m");    if (kdebugflag) {	x = PPPDBG_LOG + PPPDBG_DRIVER;	strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0);    }    if (strioctl(iffd, PPPIO_ATTACH, &ifunit, sizeof(int), 0) < 0)	fatal("Couldn't attach ppp interface to device: %m");    if (ioctl(iffd, I_PUSH, "if_ppp") < 0)	fatal("Can't push ppp interface module: %m");    if (kdebugflag) {	x = PPPDBG_LOG + PPPDBG_IF;	strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0);    }    if (strioctl(iffd, PPPIO_NEWPPA, &ifunit, sizeof(int), 0) < 0)	fatal("Couldn't create ppp interface unit: %m");    x = PPP_IP;    if (strioctl(iffd, PPPIO_BIND, &x, sizeof(int), 0) < 0)	fatal("Couldn't bind ppp interface to IP SAP: %m");    n_pollfds = 0;}/* * sys_cleanup - restore any system state we modified before exiting: * mark the interface down, delete default route and/or proxy arp entry. * This shouldn't call die() because it's called from die(). */voidsys_cleanup(){    if (if_is_up)	sifdown(0);    if (ifaddrs[0])	cifaddr(0, ifaddrs[0], ifaddrs[1]);    if (default_route_gateway)	cifdefaultroute(0, 0, default_route_gateway);    if (proxy_arp_addr)	cifproxyarp(0, proxy_arp_addr);}/* * sys_close - Clean up in a child process before execing. */voidsys_close(){    close(iffd);    close(pppfd);    close(sockfd);    closelog();}/* * sys_check_options - check the options that the user specified */intsys_check_options(){    return 1;}#if 0/* * daemon - Detach us from controlling terminal session. */intdaemon(nochdir, noclose)    int nochdir, noclose;{    int pid;    if ((pid = fork()) < 0)	return -1;    if (pid != 0)	exit(0);		/* parent dies */    setsid();    if (!nochdir)	chdir("/");    if (!noclose) {	fclose(stdin);		/* don't need stdin, stdout, stderr */	fclose(stdout);	fclose(stderr);    }    return 0;}#endif/* * ppp_available - check whether the system has any ppp interfaces */intppp_available(){    struct stat buf;    return stat("/dev/streams/ppp", &buf) >= 0;}char pipename[] = "/dev/streams/pipe";/* *  streampipe -- Opens a STREAMS based pipe.  Used by streamify(). */int streampipe(int fd[2]){    if ((fd[0]=open(pipename, O_RDWR)) == -1)	return(-1);    else if ((fd[1]=open(pipename, O_RDWR)) == -1) {	close(fd[0]);	return(-1);    } else if (ioctl(fd[0], I_PIPE, fd[1]) != 0) {	close(fd[0]);	close(fd[1]);	return(-1);    } else {	return(ioctl(fd[0], I_PUSH, "pipemod"));    }}/* *  streamify -- Needed for Digital UNIX, since some tty devices are not STREAMS *               modules (but ptys are, and pipes can be). */#define BUFFSIZE 1000     /*  Size of buffer for streamify()  */int streamify(int fd){    int fdes[2];    fd_set readfds;    int ret, fret, rret, maxfd;    static char buffer[BUFFSIZE];    struct sigaction sa;    if (streampipe(fdes) != 0)	error("streampipe(): %m\n");    else if (isastream(fdes[0]) == 1) {	if ((fret=fork()) < 0) {	    error("fork(): %m\n");	} else if (fret == 0) {	    /*  Process to forward things from pipe to tty  */            sigemptyset(&(sa.sa_mask));	    sa.sa_handler = SIG_DFL;	    sa.sa_flags = 0;	    sigaction(SIGHUP, &sa, NULL);   /*  Go back to default actions */	    sigaction(SIGINT, &sa, NULL);   /*  for changed signals.  */	    sigaction(SIGTERM, &sa, NULL);	    sigaction(SIGCHLD, &sa, NULL);	    sigaction(SIGUSR1, &sa, NULL);	    sigaction(SIGUSR2, &sa, NULL);	    close(fdes[0]);	    maxfd = (fdes[1]>fd)?fdes[1]:fd;	    while (1) {		FD_ZERO(&readfds);		FD_SET(fdes[1], &readfds);		FD_SET(fd, &readfds);		ret = select(maxfd+1, &readfds, NULL, NULL, NULL);		if (FD_ISSET(fd, &readfds)) {		    rret = read(fd, buffer, BUFFSIZE);		    if (rret == 0) {			SYSDEBUG(("slave died:  EOF on tty."));			exit(0);		    } else {			write(fdes[1], buffer, rret);		    }		}		if (FD_ISSET(fdes[1], &readfds)) {		    rret = read(fdes[1], buffer, BUFFSIZE);		    if (rret == 0) {			SYSDEBUG(("slave died:  EOF on pipe."));			exit(0);		    } else {			write(fd, buffer, rret);		    }		}	    }	} else {	    close(fdes[1]);	    orig_ttyfd = fd;	    return(fdes[0]);        }    }    return(-1);}/* * establish_ppp - Turn the serial port into a ppp interface. */intestablish_ppp(fd)    int fd;{    int i;    if (isastream(fd) != 1) {	if ((ttyfd = fd = streamify(fd)) < 0)	    fatal("Couldn't get a STREAMS module!\n");    }    /* Pop any existing modules off the tty stream. */    for (i = 0;; ++i) {	if (ioctl(fd, I_LOOK, tty_modules[i]) < 0	    || ioctl(fd, I_POP, 0) < 0)	    break;        error("popping module %s\n", tty_modules[i]);    }    tty_nmodules = i;    /* Push the async hdlc module and the compressor module. */    if (ioctl(fd, I_PUSH, "ppp_ahdl") < 0)	fatal("Couldn't push PPP Async HDLC module: %m");    if (ioctl(fd, I_PUSH, "ppp_comp") < 0)	error("Couldn't push PPP compression module: %m");    /* read mode, message non-discard mode */    if (ioctl(fd, I_SRDOPT, RMSGN|RPROTNORM) < 0)        fatal("ioctl(I_SRDOPT, RMSGN): %m");    /* Link the serial port under the PPP multiplexor. */    if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0)	fatal("Can't link tty to PPP mux: %m");    /* close stdin, stdout, stderr if they might refer to the device */    if (default_device && !closed_stdio) {        int i;        for (i = 0; i <= 2; ++i)            if (i != fd && i != sockfd)                close(i);        closed_stdio = 1;	/* make sure 0, 1, 2 are open to /dev/null */	while ((i = open("/dev/null", O_RDWR)) >= 0) {	    if (i > 2) {		close(i);		break;	    }	}    }    /*     * Set device for non-blocking reads.     * XXX why do we need to do this?  don't we use pppfd not fd?     */    if ((initfdflags = fcntl(fd, F_GETFL)) == -1        || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {        warn("Couldn't set device to non-blocking mode: %m");    }    return pppfd;}/* * restore_loop - reattach the ppp unit to the loopback. * This doesn't need to do anything because disestablish_ppp does it. */voidrestore_loop(){}/* * disestablish_ppp - Restore the serial port to normal operation. * It attempts to reconstruct the stream with the previously popped * modules.  This shouldn't call die() because it's called from die(). */voiddisestablish_ppp(fd)    int fd;{    int i;    if (fdmuxid >= 0) {	if (ioctl(pppfd, I_UNLINK, fdmuxid) < 0) {	    if (!hungup)		error("Can't unlink tty from PPP mux: %m");	}	fdmuxid = -1;        /* Reset non-blocking mode on the file descriptor. */        if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0)            warn("Couldn't restore device fd flags: %m");        initfdflags = -1;	if (!hungup) {	    while (ioctl(fd, I_POP, 0) >= 0)		;	    for (i = tty_nmodules - 1; i >= 0; --i)		if (ioctl(fd, I_PUSH, tty_modules[i]) < 0)		    error("Couldn't restore tty module %s: %m",			   tty_modules[i]);	}	if (hungup && default_device && tty_sid > 0) {	    /*	     * If we have received a hangup, we need to send a SIGHUP	     * to the terminal's controlling process.  The reason is	     * that the original stream head for the terminal hasn't	     * seen the M_HANGUP message (it went up through the ppp	     * driver to the stream head for our fd to /dev/ppp).	     */	    dbglog("sending hangup to %d", tty_sid);	    if (kill(tty_sid, SIGHUP) < 0)		error("couldn't kill pgrp: %m");	}	if (orig_ttyfd >= 0) {	    close(fd);	    (void)wait((void *)0);	    ttyfd = orig_ttyfd;	    orig_ttyfd = -1;	}    }}/* * Check whether the link seems not to be 8-bit clean. */voidclean_check(){    int x;    char *s;    if (strioctl(pppfd, PPPIO_GCLEAN, &x, 0, sizeof(x)) < 0)	return;    s = NULL;    switch (~x) {    case RCV_B7_0:	s = "bit 7 set to 1";	break;    case RCV_B7_1:	s = "bit 7 set to 0";	break;    case RCV_EVNP:	s = "odd parity";	break;    case RCV_ODDP:	s = "even parity";	break;    }    if (s != NULL) {	warn("Serial link is not 8-bit clean:");	warn("All received characters had %s", s);    }}/* * List of valid speeds. */struct speed {    int speed_int, speed_val;} speeds[] = {#ifdef B50    { 50, B50 },#endif#ifdef B75    { 75, B75 },#endif#ifdef B110    { 110, B110 },#endif#ifdef B134    { 134, B134 },#endif#ifdef B150    { 150, B150 },#endif#ifdef B200    { 200, B200 },#endif#ifdef B300    { 300, B300 },#endif#ifdef B600    { 600, B600 },#endif#ifdef B1200    { 1200, B1200 },#endif#ifdef B1800    { 1800, B1800 },#endif#ifdef B2000    { 2000, B2000 },#endif#ifdef B2400    { 2400, B2400 },#endif#ifdef B3600    { 3600, B3600 },#endif#ifdef B4800    { 4800, B4800 },#endif#ifdef B7200    { 7200, B7200 },#endif#ifdef B9600    { 9600, B9600 },#endif#ifdef B19200    { 19200, B19200 },#endif#ifdef B38400    { 38400, B38400 },#endif#ifdef EXTA    { 19200, EXTA },#endif#ifdef EXTB    { 38400, EXTB },#endif#ifdef B57600    { 57600, B57600 },#endif#ifdef B115200    { 115200, B115200 },#endif    { 0, 0 }};/* * Translate from bits/second to a speed_t. */static inttranslate_speed(bps)    int bps;{    struct speed *speedp;    if (bps == 0)	return 0;    for (speedp = speeds; speedp->speed_int; speedp++)	if (bps == speedp->speed_int)	    return speedp->speed_val;    warn("speed %d not supported", bps);    return 0;}

⌨️ 快捷键说明

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