summaryrefslogtreecommitdiff
path: root/usr/src/cmd/cvcd/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/cvcd/sparc')
-rw-r--r--usr/src/cmd/cvcd/sparc/Makefile5
-rw-r--r--usr/src/cmd/cvcd/sparc/sun4u/Makefile7
-rw-r--r--usr/src/cmd/cvcd/sparc/sun4u/starfire/Makefile61
-rw-r--r--usr/src/cmd/cvcd/sparc/sun4u/starfire/cvcd.c930
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);
-}