📄 sys-solaris.c
字号:
if (ip6fd < 0) fatal("Couldn't open IP device (2): %m");#endif /* defined(INET6) && defined(SOL2) */ if (default_device && !notty) tty_sid = getsid((pid_t)0); pppfd = open(PPP_DEV_NAME, O_RDWR | O_NONBLOCK, 0); if (pppfd < 0) fatal("Can't open %s: %m", PPP_DEV_NAME); if (kdebugflag & 1) { 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");#if defined(SOL2) /* * Since sys_init() is called prior to ifname being set in main(), * we need to get the ifname now, otherwise slifname(), and others, * will fail, or maybe, I should move them to a later point ? * <adi.masputra@sun.com> */ sprintf(ifname, PPP_DRV_NAME "%d", ifunit);#endif /* defined(SOL2) */ /* * Open the ppp device again and link it under the ip multiplexor. * IP will assign a unit number which hopefully is the same as ifunit. * I don't know any way to be certain they will be the same. :-( */ ifd = open(PPP_DEV_NAME, O_RDWR, 0); if (ifd < 0) fatal("Can't open %s (2): %m", PPP_DEV_NAME); if (kdebugflag & 1) { x = PPPDBG_LOG + PPPDBG_DRIVER; strioctl(ifd, PPPIO_DEBUG, &x, sizeof(int), 0); }#if defined(INET6) && defined(SOL2) i6fd = open(PPP_DEV_NAME, O_RDWR, 0); if (i6fd < 0) { close(ifd); fatal("Can't open %s (3): %m", PPP_DEV_NAME); } if (kdebugflag & 1) { x = PPPDBG_LOG + PPPDBG_DRIVER; strioctl(i6fd, PPPIO_DEBUG, &x, sizeof(int), 0); }#endif /* defined(INET6) && defined(SOL2) */#if defined(SOL2) if (ioctl(ifd, I_PUSH, IP_MOD_NAME) < 0) { close(ifd);#if defined(INET6) close(i6fd);#endif /* defined(INET6) */ fatal("Can't push IP module: %m"); } /* * Assign ppa according to the unit number returned by ppp device * after plumbing is completed above. */ if (sifppa(ifd, ifunit) < 0) { close (ifd);#if defined(INET6) close(i6fd);#endif /* defined(INET6) */ fatal("Can't set ppa for unit %d: %m", ifunit); }#if defined(INET6) /* * An IPv6 interface is created anyway, even when the user does not * explicitly enable it. Note that the interface will be marked * IPv6 during slifname(). */ if (ioctl(i6fd, I_PUSH, IP_MOD_NAME) < 0) { close(ifd); close(i6fd); fatal("Can't push IP module (2): %m"); } /* * Assign ppa according to the unit number returned by ppp device * after plumbing is completed above. In addition, mark the interface * as an IPv6 interface. */ if (slifname(i6fd, ifunit) < 0) { close(ifd); close(i6fd); fatal("Can't set ifname for unit %d: %m", ifunit); }#endif /* defined(INET6) */ ipmuxid = ioctl(ipfd, I_PLINK, ifd); close(ifd); if (ipmuxid < 0) {#if defined(INET6) close(i6fd);#endif /* defined(INET6) */ fatal("Can't I_PLINK PPP device to IP: %m"); } memset(&ifr, 0, sizeof(ifr)); sprintf(ifr.ifr_name, "%s", ifname); ifr.ifr_ip_muxid = ipmuxid; /* * In Sol 8 and later, STREAMS dynamic module plumbing feature exists. * This is so that an arbitrary module can be inserted, or deleted, * between ip module and the device driver without tearing down the * existing stream. Such feature requires the mux ids, which is set * by SIOCSIFMUXID (or SIOCLSIFMUXID). */ if (ioctl(ipfd, SIOCSIFMUXID, &ifr) < 0) { ioctl(ipfd, I_PUNLINK, ipmuxid);#if defined(INET6) close(i6fd);#endif /* defined(INET6) */ fatal("SIOCSIFMUXID: %m"); }#else /* else if !defined(SOL2) */ if (dlpi_attach(ifd, ifunit) < 0 || dlpi_get_reply(ifd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0) { close(ifd); fatal("Can't attach to ppp%d: %m", ifunit); } ipmuxid = ioctl(ipfd, I_LINK, ifd); close(ifd); if (ipmuxid < 0) fatal("Can't link PPP device to IP: %m");#endif /* defined(SOL2) */#if defined(INET6) && defined(SOL2) ip6muxid = ioctl(ip6fd, I_PLINK, i6fd); close(i6fd); if (ip6muxid < 0) { ioctl(ipfd, I_PUNLINK, ipmuxid); fatal("Can't I_PLINK PPP device to IP (2): %m"); } memset(&lifr, 0, sizeof(lifr)); sprintf(lifr.lifr_name, "%s", ifname); lifr.lifr_ip_muxid = ip6muxid; /* * Let IP know of the mux id [see comment for SIOCSIFMUXID above] */ if (ioctl(ip6fd, SIOCSLIFMUXID, &lifr) < 0) { ioctl(ipfd, I_PUNLINK, ipmuxid); ioctl(ip6fd, I_PUNLINK, ip6muxid); fatal("Can't link PPP device to IP (2): %m"); }#endif /* defined(INET6) && defined(SOL2) */#if !defined(SOL2) /* Set the interface name for the link. */ slprintf(ifr.ifr_name, sizeof(ifr.ifr_name), PPP_DRV_NAME "%d", ifunit); ifr.ifr_metric = ipmuxid; if (strioctl(ipfd, SIOCSIFNAME, (char *)&ifr, sizeof ifr, 0) < 0) fatal("Can't set interface name %s: %m", ifr.ifr_name);#endif /* !defined(SOL2) */ 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 should call die() because it's called from die(). */voidsys_cleanup(){#if defined(SOL2) struct ifreq ifr;#if defined(INET6) struct lifreq lifr;#endif /* defined(INET6) */#endif /* defined(SOL2) */#if defined(SOL2) && defined(INET6) if (if6_is_up) sif6down(0);#endif /* defined(SOL2) && defined(INET6) */ if (if_is_up) sifdown(0); if (default_route_gateway) cifdefaultroute(0, default_route_gateway, default_route_gateway); if (proxy_arp_addr) cifproxyarp(0, proxy_arp_addr);#if defined(SOL2) /* * Make sure we ask ip what the muxid, because 'ifconfig modlist' will * unlink and re-link the modules, causing the muxid to change. */ memset(&ifr, 0, sizeof(ifr)); sprintf(ifr.ifr_name, "%s", ifname); if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) { error("SIOCGIFFLAGS: %m"); return; } if (ioctl(ipfd, SIOCGIFMUXID, &ifr) < 0) { error("SIOCGIFMUXID: %m"); return; } ipmuxid = ifr.ifr_ip_muxid; if (ioctl(ipfd, I_PUNLINK, ipmuxid) < 0) { error("Can't I_PUNLINK PPP from IP: %m"); return; }#if defined(INET6) /* * Make sure we ask ip what the muxid, because 'ifconfig modlist' will * unlink and re-link the modules, causing the muxid to change. */ memset(&lifr, 0, sizeof(lifr)); sprintf(lifr.lifr_name, "%s", ifname); if (ioctl(ip6fd, SIOCGLIFFLAGS, &lifr) < 0) { error("SIOCGLIFFLAGS: %m"); return; } if (ioctl(ip6fd, SIOCGLIFMUXID, &lifr) < 0) { error("SIOCGLIFMUXID: %m"); return; } ip6muxid = lifr.lifr_ip_muxid; if (ioctl(ip6fd, I_PUNLINK, ip6muxid) < 0) { error("Can't I_PUNLINK PPP from IP (2): %m"); }#endif /* defined(INET6) */#endif /* defined(SOL2) */}/* * sys_close - Clean up in a child process before execing. */voidsys_close(){ close(ipfd);#if defined(INET6) && defined(SOL2) close(ip6fd);#endif /* defined(INET6) && defined(SOL2) */ if (pppfd >= 0) close(pppfd);}/* * 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(PPP_DEV_NAME, &buf) >= 0;}/* * any_compressions - see if compression is enabled or not * * In the STREAMS implementation of kernel-portion pppd, * the comp STREAMS module performs the ACFC, PFC, as well * CCP and VJ compressions. However, if the user has explicitly * declare to not enable them from the command line, there is * no point of having the comp module be pushed on the stream. */static intany_compressions(){ if ((!lcp_wantoptions[0].neg_accompression) && (!lcp_wantoptions[0].neg_pcompression) && (!ccp_protent.enabled_flag) && (!ipcp_wantoptions[0].neg_vj)) { return 0; } return 1;}/* * tty_establish_ppp - Turn the serial port into a ppp interface. */inttty_establish_ppp(fd) int fd;{ int i; /* Pop any existing modules off the tty stream. */ for (i = 0;; ++i) if (ioctl(fd, I_LOOK, tty_modules[i]) < 0 || strcmp(tty_modules[i], "ptem") == 0 || ioctl(fd, I_POP, 0) < 0) break; tty_nmodules = i; /* Push the async hdlc module and the compressor module. */ tty_npushed = 0; if(!sync_serial) { if (ioctl(fd, I_PUSH, AHDLC_MOD_NAME) < 0) { error("Couldn't push PPP Async HDLC module: %m"); return -1; } ++tty_npushed; } if (kdebugflag & 4) { i = PPPDBG_LOG + PPPDBG_AHDLC; strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0); } /* * There's no need to push comp module if we don't intend * to compress anything */ if (any_compressions()) { if (ioctl(fd, I_PUSH, COMP_MOD_NAME) < 0) error("Couldn't push PPP compression module: %m"); else ++tty_npushed; } if (kdebugflag & 2) { i = PPPDBG_LOG; if (any_compressions()) i += PPPDBG_COMP; strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0); } /* Link the serial port under the PPP multiplexor. */ if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0) { error("Can't link tty to PPP mux: %m"); return -1; } return pppfd;}/* * tty_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(). */voidtty_disestablish_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; if (!hungup) { while (tty_npushed > 0 && ioctl(fd, I_POP, 0) >= 0) --tty_npushed; 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). */ kill(tty_sid, SIGHUP); } }}/* * 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 B76800 { 76800, B76800 },#endif#ifdef B115200 { 115200, B115200 },#endif#ifdef B153600 { 153600, B153600 },#endif#ifdef B230400 { 230400, B230400 },#endif#ifdef B307200 { 307200, B307200 },#endif#ifdef B460800 { 460800, B460800 },#endif { 0, 0 }};/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -