diff options
Diffstat (limited to 'usr/src/cmd/cvcd/sparc')
| -rw-r--r-- | usr/src/cmd/cvcd/sparc/Makefile | 5 | ||||
| -rw-r--r-- | usr/src/cmd/cvcd/sparc/sun4u/Makefile | 7 | ||||
| -rw-r--r-- | usr/src/cmd/cvcd/sparc/sun4u/starfire/Makefile | 61 | ||||
| -rw-r--r-- | usr/src/cmd/cvcd/sparc/sun4u/starfire/cvcd.c | 930 |
4 files changed, 5 insertions, 998 deletions
diff --git a/usr/src/cmd/cvcd/sparc/Makefile b/usr/src/cmd/cvcd/sparc/Makefile index 1be28bcac0..e5c629cfc3 100644 --- a/usr/src/cmd/cvcd/sparc/Makefile +++ b/usr/src/cmd/cvcd/sparc/Makefile @@ -20,12 +20,11 @@ # CDDL HEADER END # # -# ident "%Z%%M% %I% %E% SMI" -# # Copyright (c) 1997 by Sun Microsystems, Inc. # All rights reserved. +# Copyright 2019 Peter Tribble. # -# Makefile definitions for Starfire's Network Console related items. +# Makefile definitions for Starcat's Network Console related items. # # cmd/cvcd/sparc/Makefile # diff --git a/usr/src/cmd/cvcd/sparc/sun4u/Makefile b/usr/src/cmd/cvcd/sparc/sun4u/Makefile index ca4dcf086f..e9bbcd1148 100644 --- a/usr/src/cmd/cvcd/sparc/sun4u/Makefile +++ b/usr/src/cmd/cvcd/sparc/sun4u/Makefile @@ -20,17 +20,16 @@ # CDDL HEADER END # # -#ident "%Z%%M% %I% %E% SMI" -# # Copyright 2004 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2019 Peter Tribble. # -# Makefile definitions for Starfire and Starcat Network Console related items. +# Makefile definitions for Starcat Network Console related items. # # cmd/cvcd/sparc/sun4u/Makefile # -SUBDIRS = starfire starcat +SUBDIRS = starcat all := TARGET= all install := TARGET= install diff --git a/usr/src/cmd/cvcd/sparc/sun4u/starfire/Makefile b/usr/src/cmd/cvcd/sparc/sun4u/starfire/Makefile deleted file mode 100644 index 1ec26f96d7..0000000000 --- a/usr/src/cmd/cvcd/sparc/sun4u/starfire/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/cvcd/sparc/sun4u/starfire/cvcd -# -PROG= cvcd -ROOTFS_PROG= $(PROG) -PLATFORM= SUNW,Ultra-Enterprise-10000 - -# Create default so empty rules don't confuse make -CLASS= 32 - -SRCS= $(PROG:%=%.c) -OBJS= $(PROG:%=%.o) - -include ../../../../Makefile.cmd -include ../../../../../Makefile.psm - -FILEMODE= 0700 - -ROOTPSMPROG = $(ROOT_PSM_LIB_DIR)/$(PROG) - -CPPFLAGS = -I$(USR_PSM_INCL_DIR) $(CPPFLAGS.master) -CERRWARN += -_gcc=-Wno-unused-variable - -LDLIBS += -lsocket -lnsl - -.KEEP_STATE: - -all: $(ROOTFS_PROG) - -install: all .WAIT $(ROOTPSMPROG) - -clean: - $(RM) $(PROG) $(OBJS) - -lint: lint_PROG - -include ../../../../Makefile.targ -include ../../../../../Makefile.psm.targ diff --git a/usr/src/cmd/cvcd/sparc/sun4u/starfire/cvcd.c b/usr/src/cmd/cvcd/sparc/sun4u/starfire/cvcd.c deleted file mode 100644 index 008d33af99..0000000000 --- a/usr/src/cmd/cvcd/sparc/sun4u/starfire/cvcd.c +++ /dev/null @@ -1,930 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - - -/* - * This code implements the Starfire Virtual Console host daemon - * (see cvcd(1M)). It accepts a connection from netcon_server - * and transfers console I/O to/from the SSP across the - * network via TLI. The I/O is sent to the cvcredir device - * on the host (see cvc(7) and cvcredir(7)). It also sends - * disconnect and break ioctl's to the kernel CVC drivers. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - - -#include <stdio.h> -#include <stdarg.h> -#include <syslog.h> -#include <stdlib.h> -#include <tiuser.h> -#include <sys/timod.h> -#include <fcntl.h> -#include <sys/param.h> -#include <sys/utsname.h> -#include <sys/stat.h> -#include <unistd.h> -#include <stropts.h> -#include <sys/conf.h> -#include <pwd.h> -#include <errno.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <locale.h> -#include <termio.h> -#include <signal.h> -#include <sys/cvc.h> - -#include <string.h> - -#include <sys/ioctl.h> -#include <sys/file.h> -#include <sys/sockio.h> - -#include <sys/tihdr.h> - -#include <netdb.h> -#include <net/if.h> -#include <netinet/if_ether.h> - -#include <inet/common.h> -#include <sys/systeminfo.h> - -/* Process priority control */ -#include <sys/priocntl.h> -#include <sys/tspriocntl.h> -#include <sys/rtpriocntl.h> - -/* - * Misc. defines. - */ -#define CONREF "connection request from illegal host" -#define SSPHOSTNAMEFILE "/etc/ssphostname" -#define NODENAME "/etc/nodename" -#define MAXIFS 256 - -/* - * Function prototypes - */ -static void cvcd_connect(int fd, struct pollfd *); -static void cvcd_reject(int fd); -static void cvcd_read(struct pollfd *); -static void cvcd_write(char *data, int size); -static void cvcd_status(int fd); -static void cvcd_winch(int, char *, int); -static void cvcd_ioctl(int fd, int cmd); -static void cvcd_err(int code, char *format, ...); -static void usage(void); -static id_t schedinfo(char *name, short *maxpri); -static void cvcd_setopt(int fd, int name); - -/* - * Globals - */ -static int rconsfd; /* Console redirection driver */ -static char progname[MAXPATHLEN]; -static char ssphostname[MAXPATHLEN]; -static int debug = 0; -static int connected = 0; -static int peercheck = 1; -static char nic_name[32]; - -int -main(int argc, char **argv) -{ - int opt; - int tport = 0; - char *hostname; - struct utsname utsname; - struct t_info tinfo; - int cvcd_ssp; - int nfd; - struct pollfd *cvcd_pfd; - int i; - int j; - struct servent *se; - struct sockaddr_in *sin; - struct t_bind *reqb; - struct t_bind *retb; - struct t_optmgmt *topt, *tropt; - struct opthdr *sockopt; - int on = 1; - int tmperr = 0; - int event; - char prefix[256]; - pcparms_t pcparms; - tsparms_t *tsparmsp; - id_t pid, tsID; - short tsmaxpri; - static int netcon_fail = 0; - - (void) setlocale(LC_ALL, ""); - (void) strcpy(progname, argv[0]); - (void) memset(ssphostname, 0, MAXPATHLEN); - - if ((cvcd_ssp = open(SSPHOSTNAMEFILE, O_RDONLY)) < 0) { - /* - * If there is no /etc/ssphostname disable peer check after - * issuing warning. - */ - tmperr = errno; - peercheck = 0; - } else { - if ((i = read(cvcd_ssp, ssphostname, MAXPATHLEN)) < 0) { - cvcd_err(LOG_ERR, "failed to read ssphostname"); - } - /* - * The ssp-config(1M) command newline terminates the - * ssphostname in the /etc/ssphostname file - */ - ssphostname[i-1] = '\0'; - (void) close(cvcd_ssp); - - (void) memset(nic_name, 0, sizeof (nic_name)); - } - -#if defined(DEBUG) - while ((opt = getopt(argc, argv, "dp:r:")) != EOF) { -#else - while ((opt = getopt(argc, argv, "r:")) != EOF) { -#endif /* DEBUG */ - switch (opt) { - -#if defined(DEBUG) - case 'd' : debug = 1; - break; - - case 'p' : tport = atoi(optarg); - break; -#endif /* DEBUG */ - - case 'r' : (void) strcpy(ssphostname, optarg); - break; - - default : usage(); - exit(1); - } - } - - if (uname(&utsname) == -1) { - perror("HOSTNAME not defined"); - exit(1); - } - hostname = utsname.nodename; - - /* - * hostname may still be NULL, depends on when cvcd was started - * in the boot sequence. If it is NULL, try one more time - * to get a hostname -> look in the /etc/nodename file. - */ - if (!strlen(hostname)) { - /* - * try to get the hostname from the /etc/nodename file - * we reuse the utsname.nodename buffer here! hostname - * already points to it. - */ - if ((nfd = open(NODENAME, O_RDONLY)) > 0) { - if ((i = read(nfd, utsname.nodename, SYS_NMLN)) <= 0) { - cvcd_err(LOG_WARNING, - "failed to acquire hostname"); - } - utsname.nodename[i-1] = '\0'; - (void) close(nfd); - } - } - - /* - * Must be root. - */ - if (debug == 0 && geteuid() != 0) { - fprintf(stderr, "cvcd: Must be root"); - exit(1); - } - - /* - * Daemonize... - */ - if (debug == 0) { - for (i = 0; i < NOFILE; i++) { - (void) close(i); - } - (void) chdir("/"); - (void) umask(0); - if (fork() != 0) { - exit(0); - } - (void) setpgrp(); - (void) sprintf(prefix, "%s-(HOSTNAME:%s)", progname, hostname); - openlog(prefix, LOG_CONS | LOG_NDELAY, LOG_LOCAL0); - } - if (peercheck == 0) { - cvcd_err(LOG_ERR, "open(SSPHOSTNAMEFILE):%s", - strerror(tmperr)); - } - - cvcd_pfd = (struct pollfd *)malloc(3*sizeof (struct pollfd)); - if (cvcd_pfd == (struct pollfd *)NULL) { - cvcd_err(LOG_ERR, "malloc:", strerror(errno)); - exit(1); - } - (void) memset((void *)cvcd_pfd, 0, 3*sizeof (struct pollfd)); - cvcd_pfd[0].fd = -1; - cvcd_pfd[1].fd = -1; - cvcd_pfd[2].fd = -1; - - /* SPR 94004 */ - (void) sigignore(SIGTERM); - - /* - * SPR 83644: cvc and kadb are not compatible under heavy loads. - * Fix: will give cvcd highest TS priority at execution time. - */ - pid = getpid(); - pcparms.pc_cid = PC_CLNULL; - tsparmsp = (tsparms_t *)pcparms.pc_clparms; - - /* Get scheduler properties for this PID */ - if (priocntl(P_PID, pid, PC_GETPARMS, (caddr_t)&pcparms) == -1L) { - cvcd_err(LOG_ERR, - "cvcd: GETPARMS failed. Warning: can't get ", - "TS priorities."); - } else { - /* Get class IDs and maximum priorities for a TS process */ - if ((tsID = schedinfo("TS", &tsmaxpri)) == -1) { - cvcd_err(LOG_ERR, "cvcd: Warning, can't get ", - "TS scheduler info."); - } else { - if (debug) { /* Print priority info */ - if (pcparms.pc_cid == tsID) { - cvcd_err(LOG_DEBUG, "%s%d%s%d%s%d\n", - "cvcd:: PID:", pid, - ", TS priority:", - tsparmsp->ts_upri, - ", TS max_pri:", tsmaxpri); - } - } - /* Change proc's priority to maxtspri */ - pcparms.pc_cid = tsID; - tsparmsp = (struct tsparms *)pcparms.pc_clparms; - tsparmsp->ts_upri = tsmaxpri; - tsparmsp->ts_uprilim = tsmaxpri; - - if (priocntl(P_PID, pid, PC_SETPARMS, - (caddr_t)&pcparms) == -1L) { - cvcd_err(LOG_ERR, "cvcd: Warning, ", - "can't set TS maximum priority."); - } - /* Done */ - if (debug) { /* Get new scheduler properties for PID */ - if (priocntl(P_PID, pid, PC_GETPARMS, - (caddr_t)&pcparms) == -1L) { - cvcd_err(LOG_DEBUG, "GETPARMS failed"); - exit(1); - } else { - cvcd_err(LOG_DEBUG, "%s%d%s%d%s%d\n", - "cvcd:: PID:", pid, - ", New TS priority:", - tsparmsp->ts_upri, - ", TS max_pri:", tsmaxpri); - } - } - } - } - - if (debug == 1) { - cvcd_err(LOG_DEBUG, "tport = %d, debug = %d", tport, debug); - } - - if (tport == 0) { - if ((se = getservbyname(CVCD_SERVICE, "tcp")) == NULL) { - cvcd_err(LOG_ERR, "getservbyname(%s) not found", - CVCD_SERVICE); - exit(1); - } - tport = se->s_port; - } - - cvcd_ssp = t_open(TCP_DEV, O_RDWR, &tinfo); - if (cvcd_ssp == -1) { - cvcd_err(LOG_ERR, "t_open: %s", t_errlist[t_errno]); - exit(1); - } - - /* - * Set the SO_REUSEADDR option for this TLI endpoint. - */ - cvcd_setopt(cvcd_ssp, SO_REUSEADDR); - - /* - * Set the SO_DONTROUTE option for this TLI endpoint, if - * /etc/ssphostname exists. - */ - if (peercheck == 1) - cvcd_setopt(cvcd_ssp, SO_DONTROUTE); - - /* - * Bind it. - */ - if (((reqb = (struct t_bind *)t_alloc(cvcd_ssp, T_BIND, T_ALL)) - == (struct t_bind *)NULL)) { - cvcd_err(LOG_ERR, "%s", t_errlist[t_errno]); - exit(1); - } - if (((retb = (struct t_bind *)t_alloc(cvcd_ssp, T_BIND, T_ALL)) - == (struct t_bind *)NULL)) { - cvcd_err(LOG_ERR, "%s", t_errlist[t_errno]); - exit(1); - } - reqb->qlen = 1; - reqb->addr.len = sizeof (struct sockaddr_in); - sin = (struct sockaddr_in *)reqb->addr.buf; - (void) memset((void *)sin, 0, sizeof (struct sockaddr_in)); - sin->sin_family = AF_INET; - - - sin->sin_addr.s_addr = htonl(INADDR_ANY); - sin->sin_port = htons(tport); - if (t_bind(cvcd_ssp, reqb, retb) == -1) { - cvcd_err(LOG_ERR, "t_bind: %s", t_errlist[t_errno]); - exit(1); - } - sin = (struct sockaddr_in *)retb->addr.buf; - if (sin->sin_port != htons(tport)) { - cvcd_err(LOG_ERR, "t_bind: bound to wrong port"); - cvcd_err(LOG_ERR, "Wanted %d, got %d", tport, - ntohs(sin->sin_port)); - exit(1); - } - - t_free((char *)reqb, T_BIND); - t_free((char *)retb, T_BIND); - - - /* - * Wait for connect from OBP. - */ - cvcd_pfd[2].fd = cvcd_ssp; - cvcd_pfd[2].events = POLLIN|POLLPRI; - if ((event = poll(&cvcd_pfd[2], 1, -1)) == -1) { - cvcd_err(LOG_ERR, "poll: %s", strerror(errno)); - exit(1); - } - /* - * cvcd_connect sets global - * connected = 1 if successful. - */ - cvcd_connect(cvcd_ssp, cvcd_pfd); - - /* - * Now set up the Network Console redirection driver. - */ - rconsfd = open(CVCREDIR_DEV, O_RDWR|O_NDELAY); - if (rconsfd < 0) { - cvcd_err(LOG_ERR, "open: %s", strerror(errno)); - exit(1); - } - - /* - * cvcd_pfd holds three file descriptors we need to poll from: - * 0 will be connected to in_cvcd; 1 is the CVC Redirection driver; - * and 2 is the listen endpoint for new connections. - */ - cvcd_pfd[1].fd = rconsfd; - cvcd_pfd[1].events = POLLIN; - /* - * Loop through main service routine. We check for inbound in.cvcd - * connection and data xfer between host and in.cvcd. - */ - for (;;) { - - char buf[MAXPKTSZ]; - - /* - * Check for in_cvcd connect requests. - */ - switch ((event = t_look(cvcd_ssp))) { - case -1 : - cvcd_err(LOG_ERR, "%s", t_errlist[t_errno]); - exit(1); - /* NOTREACHED */ - break; - case 0 : /* Nothing to do */ - break; - case T_LISTEN : - if (connected == 1) { - /* - * Someone already connected. - */ - cvcd_reject(cvcd_ssp); - } else { - /* - * cvcd_connect sets global - * connected = 1 if successful. - */ - cvcd_connect(cvcd_ssp, cvcd_pfd); - - /* - * Re-open the cvcredir driver if - * the netcon_fail is true. This - * indicates there was a previous - * network connection that got closed. - */ - if (netcon_fail) { - rconsfd = open(CVCREDIR_DEV, - O_RDWR|O_NDELAY); - if (rconsfd < 0) { - cvcd_err(LOG_ERR, - "open: %s", - strerror(errno)); - exit(1); - } - cvcd_pfd[1].fd = rconsfd; - cvcd_pfd[1].events = POLLIN; - netcon_fail = 0; - } - } - break; - default : - cvcd_err(LOG_ERR, - "Illegal event %d for cvcd_ssp", event); - exit(1); - } - /* - * Take a look for console I/O or connect request. - */ - if ((event = poll(cvcd_pfd, 3, -1)) == -1) { - cvcd_err(LOG_ERR, "poll: %s", strerror(errno)); - exit(1); - } - - /* - * The following for loop is to detect any bad - * things(ie hangup,errors,invalid fd) have happened - * to the file descriptors we're interested in. - * If so, disconnect current network console connection. - */ - for (j = 0; j < 3; j++) { - if (cvcd_pfd[j].revents & (POLLERR|POLLHUP|POLLNVAL)) { - cvcd_err(LOG_WARNING, - "poll: status on %s fd:%s%s%s", - ((j == 2) ? "listen" : - ((j == 0) ? "network" : "redir")), - (cvcd_pfd[j].revents & POLLERR) ? - " error" : "", - (cvcd_pfd[j].revents & POLLHUP) ? - " hangup" : "", - (cvcd_pfd[j].revents & POLLNVAL) ? - " bad fd" : ""); - - (void) t_close(cvcd_pfd[0].fd); - cvcd_pfd[0].fd = -1; - - (void) close(cvcd_pfd[1].fd); - cvcd_pfd[1].fd = -1; - connected = 0; - netcon_fail = 1; - break; - } - } - - /* - * Check if dummy netcon_fail flag is set, if set returns - * to the beginning of the main service routine. - */ - if (netcon_fail) - continue; - - if (event != 0) { - if (cvcd_pfd[0].revents == POLLIN) { - /* - * Process cvcd_ssp data and commands. - */ - cvcd_read(cvcd_pfd); - } - if (cvcd_pfd[1].revents == POLLIN) { - int s; - - if ((s = read(rconsfd, buf, MAXPKTSZ)) == -1) { - cvcd_err(LOG_ERR, "read: %s", - strerror(errno)); - exit(1); - } - if ((s > 0) && (connected == 1)) { - if (write(cvcd_pfd[0].fd, buf, s) != - s) { - cvcd_err(LOG_ERR, - "lost data output"); - } - } - } - } - } /* End forever loop */ - -#ifdef lint - /* NOTREACHED */ - return (1); -#endif /* lint */ -} - -static void -cvcd_reject(int fd) -{ - struct t_call *tcall; - - tcall = (struct t_call *)t_alloc(fd, T_CALL, T_ALL); - if (tcall == (struct t_call *)NULL) { - cvcd_err(LOG_ERR, "cvcd_reject: t_alloc: %s", - t_errlist[t_errno]); - return; - } - if (t_listen(fd, tcall) == -1) { - if (t_errno == TNODATA) { - cvcd_err(LOG_ERR, "cvcd_reject: No client data!"); - } - cvcd_err(LOG_ERR, "cvcd_reject: t_listen: %s", - t_errlist[t_errno]); - t_free((char *)tcall, T_CALL); - return; - } - if (t_snddis(fd, tcall) < 0) { - cvcd_err(LOG_ERR, "cvcd_reject: t_snddis: %s", - t_errlist[t_errno]); - } - t_free((char *)tcall, T_CALL); -} - -static void -cvcd_connect(int fd, struct pollfd *pfd) -{ - struct t_call *tcall; - int newfd; - struct sockaddr_in *peer; - int badpeer = 1; - struct hostent *he; - struct netbuf netbuf; - char addr[100]; - ulong_t tmpaddr; /* network byte order */ - char **pp; - - tcall = (struct t_call *)t_alloc(fd, T_CALL, T_ALL); - if (tcall == (struct t_call *)NULL) { - cvcd_err(LOG_ERR, "cvcd_connect: t_alloc: %s", - t_errlist[t_errno]); - return; - } - if (t_listen(fd, tcall) == -1) { - if (t_errno == TNODATA) { - cvcd_err(LOG_ERR, "cvcd_connect: No client data!"); - } - cvcd_err(LOG_ERR, "cnctip_connect: t_listen: %s", - t_errlist[t_errno]); - t_free((char *)tcall, T_CALL); - return; - } - if (pfd[0].fd != -1) { - cvcd_err(LOG_ERR, "cvcd_connect: no free file descriptors!"); - t_free((char *)tcall, T_CALL); - return; - } - newfd = t_open(TCP_DEV, O_RDWR|O_NDELAY, NULL); - if (newfd == -1) { - cvcd_err(LOG_ERR, "cvcd_connect: t_open: %s", - t_errlist[t_errno]); - t_free((char *)tcall, T_CALL); - return; - } - if (t_accept(fd, newfd, tcall) < 0) { - cvcd_err(LOG_ERR, "cvcd_connect: t_accept: %s", - t_errlist[t_errno]); - t_close(newfd); - t_free((char *)tcall, T_CALL); - return; - } - t_free((char *)tcall, T_CALL); - - /* - * If /etc/ssphostname doesnt exists, dont bother verifying - * peer since we cant do gethostbyname. - */ - if (peercheck == 1) { - he = gethostbyname(ssphostname); - if (he == NULL) { - cvcd_err(LOG_ERR, "gethostbyname: %s", - strerror(h_errno)); - cvcd_err(LOG_ERR, "unable to get SSP name %s!", - ssphostname); - exit(1); - } - /* - * Verify peer is from specified host by comparing the - * address (in network byte order) of the TLI endpoint - * and the address (in network byte order) of the ssp - * (using the hostname found in /etc/ssphostname). - */ - (void) memset(addr, 0, 100); - netbuf.buf = addr; - netbuf.len = 0; - netbuf.maxlen = 100; - if (ioctl(newfd, TI_GETPEERNAME, &netbuf) < 0) { - cvcd_err(LOG_ERR, "ioctl(TI_GETPEERNAME): %s", - strerror(errno)); - t_close(newfd); - return; - } - - /* - * cvcd doesn't check multi-homed ssphostname - * properly (only checks 1st address) - */ - peer = (struct sockaddr_in *)addr; - for (pp = he->h_addr_list; *pp != 0; pp++) { - tmpaddr = htonl(*(ulong_t *)*pp); - if (memcmp(&peer->sin_addr.s_addr, &tmpaddr, - he->h_length) == 0) { - badpeer = 0; - break; - } - } - - if (badpeer) { - cvcd_err(LOG_ERR, CONREF); - cvcd_err(LOG_ERR, "remote host = %s.", - inet_ntoa(peer->sin_addr)); - t_close(newfd); - return; - } - } - pfd[0].fd = newfd; - pfd[0].events = POLLIN; - connected = 1; -} - -/* - * Read in data from client. - */ -static void -cvcd_read(struct pollfd *pd) -{ - register char *data; - register int fd = pd[0].fd; - char buf[MAXPKTSZ]; - int flags = 0; - - data = buf; - - if (pd[0].revents & POLLIN) { - int n; - - if ((n = t_rcv(fd, data, MAXPKTSZ, &flags)) == -1) { - cvcd_err(LOG_ERR, "cvcd_read: t_rcv: %s", - t_errlist[t_errno]); - (void) t_close(pd[0].fd); - pd[0].fd = -1; - connected = 0; - return; - } - if (flags & T_EXPEDITED) { - if (n != 1) { - cvcd_err(LOG_ERR, - "cvcd_read: %d bytes EXD!!", - n); - } - /* - * Deal with cvcd_ssp_commands. - */ - switch (data[n-1]) { - case CVC_CONN_BREAK : - cvcd_ioctl(rconsfd, CVC_BREAK); - break; - - case CVC_CONN_DIS : - (void) t_close(pd[0].fd); - pd[0].fd = -1; - cvcd_ioctl(rconsfd, CVC_DISCONNECT); - connected = 0; - break; - - case CVC_CONN_STAT : - cvcd_status(fd); - break; - - default : - cvcd_err(LOG_ERR, - "Illegal cmd 0x%x", buf[n-1]); - break; - } - } else { - if (((data[0] & 0377) == 0377) && - ((data[1] & 0377) == 0377)) { - /* - * Pass on window size changes (TIOCSWINSZ). - */ - cvcd_winch(rconsfd, data, n); - (void) memset(data, 0, n); - } else { - cvcd_write(buf, n); - } - } - } - -} - -static void -cvcd_ioctl(int fd, int flags) -{ - struct strioctl cmd; - - cmd.ic_cmd = flags; - cmd.ic_timout = 0; - cmd.ic_len = 0; - cmd.ic_dp = NULL; - - if (ioctl(fd, I_STR, &cmd) == -1) { - cvcd_err(LOG_ERR, "cvcd_ioctl: %s", strerror(errno)); - exit(1); - } -} - - -/* ARGSUSED */ -static void -cvcd_status(int fd) -{ -} - - -/* - * Write input to console - called from cvcd_read. - */ -static void -cvcd_write(char *data, int size) -{ - int n; - - if ((n = write(rconsfd, data, size)) == -1) { - cvcd_err(LOG_ERR, "cvcd_write: write: %s", strerror(errno)); - exit(1); - } - if (n != size) { - cvcd_err(LOG_ERR, "cvcd_write: wrote %d of %d bytes", n, size); - } -} - -static void -usage() -{ -#if defined(DEBUG) - (void) printf("%s [-d] [-p port]\n", progname); -#else - (void) printf("%s -r [ssp host]\n", progname); -#endif /* DEBUG */ -} - -/* - * cvcd_err () - * - * Description: - * Log messages via syslog daemon. - * - * Input: - * code - logging code - * format - messages to log - * - * Output: - * void - * - */ -static void -cvcd_err(int code, char *format, ...) -{ - va_list varg_ptr; - char buf[MAXPKTSZ]; - - va_start(varg_ptr, format); - (void) vsprintf(buf, format, varg_ptr); - va_end(varg_ptr); - - if (debug == 0) - syslog(code, buf); - else - (void) fprintf(stderr, "%s: %s\n", progname, buf); -} - -/* - * Handle a "control" request (signaled by magic being present) - * in the data stream. For now, we are only willing to handle - * window size changes. - */ -void -cvcd_winch(int pty, char *cp, int n) -{ - struct winsize w; - - if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's') - return; - (void) memcpy(&w, cp + 4, sizeof (w)); - w.ws_row = ntohs(w.ws_row); - w.ws_col = ntohs(w.ws_col); - w.ws_xpixel = ntohs(w.ws_xpixel); - w.ws_ypixel = ntohs(w.ws_ypixel); - (void) ioctl(pty, TIOCSWINSZ, &w); -} - - -/* - * Return class ID and maximum priority of it. - * Input: - * name: is class name (either TS or RT). - * maxpri: maximum priority for the class, returned in *maxpri. - * Output: - * pc_cid: class ID - */ -static id_t -schedinfo(char *name, short *maxpri) -{ - pcinfo_t info; - tsinfo_t *tsinfop; - rtinfo_t *rtinfop; - - (void) strcpy(info.pc_clname, name); - if (priocntl(0L, 0L, PC_GETCID, (caddr_t)&info) == -1L) { - return (-1); - } - if (strcmp(name, "TS") == 0) { /* Time Shared */ - tsinfop = (struct tsinfo *)info.pc_clinfo; - *maxpri = tsinfop->ts_maxupri; - } else if (strcmp(name, "RT") == 0) { /* Real Time */ - rtinfop = (struct rtinfo *)info.pc_clinfo; - *maxpri = rtinfop->rt_maxpri; - } else { - return (-1); - } - return (info.pc_cid); -} - - -/* - * set the tli options for the given endpoint represented by fd - */ -static void -cvcd_setopt(int fd, int name) -{ - struct t_optmgmt *topt, *tropt; - struct opthdr *sockopt; - int on = 1; - - topt = (struct t_optmgmt *)t_alloc(fd, T_OPTMGMT, 0); - if (topt == NULL) { - cvcd_err(LOG_ERR, "t_alloc: %s", t_errlist[t_errno]); - exit(1); - } - tropt = (struct t_optmgmt *)t_alloc(fd, T_OPTMGMT, 0); - if (tropt == NULL) { - cvcd_err(LOG_ERR, "t_alloc: %s", t_errlist[t_errno]); - exit(1); - } - topt->opt.buf = (char *)malloc(sizeof (struct opthdr) + sizeof (int)); - topt->opt.maxlen = 0; - topt->opt.len = sizeof (struct opthdr) + sizeof (int); - topt->flags = T_NEGOTIATE; - sockopt = (struct opthdr *)topt->opt.buf; - sockopt->level = SOL_SOCKET; - sockopt->name = name; - sockopt->len = sizeof (int); - (void) memcpy((char *)(topt->opt.buf + sizeof (struct opthdr)), - (char *)&on, sizeof (on)); - tropt->opt.buf = (char *)malloc(sizeof (struct opthdr) + sizeof (int)); - tropt->opt.maxlen = sizeof (struct opthdr) + sizeof (int); - - if (t_optmgmt(fd, topt, tropt) == -1) { - t_error("t_optmgmt"); - exit(1); - } - - t_free((char *)topt, T_OPTMGMT); - t_free((char *)tropt, T_OPTMGMT); -} |
