diff options
Diffstat (limited to 'usr/src/cmd/rpld/params.c')
| -rw-r--r-- | usr/src/cmd/rpld/params.c | 808 |
1 files changed, 0 insertions, 808 deletions
diff --git a/usr/src/cmd/rpld/params.c b/usr/src/cmd/rpld/params.c deleted file mode 100644 index 5c59e60327..0000000000 --- a/usr/src/cmd/rpld/params.c +++ /dev/null @@ -1,808 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <sys/fcntl.h> -#include <sys/socket.h> -#include <sys/sockio.h> -#include <poll.h> -#include <errno.h> -#include <sys/dlpi.h> -#include <sys/stropts.h> -#include <syslog.h> -#include <net/if.h> -#include "rpld.h" -#include "dluser.h" - -#define MAXIFS 256 - -extern char configFile[]; -extern int debugLevel; -extern int debugDest; -extern int maxClients; -extern int backGround; -extern char logFile[]; -extern unsigned long delayGran; -extern unsigned long startDelay; -extern int frameSize; -extern char ifName[]; -extern char debugmsg[]; -extern FILE *log_str; -extern int ifUnit; -extern int ppanum; -extern int need_llc; - -void usage(void); -void getdevice(uchar_t *, uchar_t *); - -int -parseargs(int argc, char *argv[], char *envp[]) -{ - int c; - int err = 0; - int ip_fd; - int numifs; - struct ifreq *reqbuf; - struct ifreq *ifr; - char *device; - int unit; - struct ifconf ifconf; - unsigned bufsize; - char devbuf[MAXPATHLEN]; - int aflag = 0; - int curr_ppa = 0; - extern char *optarg; - extern int optind; - extern int opterr; - int n; - int more = 0; - char _ifName[MAXPATHLEN] = ""; - int _ifUnit = 0; - int _need_llc; - - opterr = 0; - - /* - * Expects at least 2 arguments: program name and the network - * interface name, or the program name with -a option. - */ - if (argc < 2) { - usage(); - return (-1); - } - - debugLevel = MSG_ERROR_1; /* at least when it fails, we know */ - debugDest = DEST_CONSOLE; /* why at the console */ - - /* - * Check if either the -a option or a /dev/deviceN path is specified. - * At the same time look for an alternate config file. - * After this checking, optind is positioned to the next thing on - * the command line after all the options. - */ - optind = 1; - while ((c = getopt(argc, argv, "af:d:D:M:b:l:s:g:z:")) != -1) { - switch (c) { - case 'a': - aflag = 1; - break; - case 'f': /* alternate config file */ - if (strlcpy(configFile, optarg, - MAXPATHLEN) >= MAXPATHLEN) { - printf("Alternate config file too long\n"); - return (-1); - } - break; - case '?': - usage(); - return (-1); - } - } - - if (!aflag) { - if ((argv[optind] == NULL) || (argv[optind][0] == '\0')) { - /* neither -a nor device name is specified */ - usage(); - return (-1); - } else { - /* potentially a correct device name is specified */ - int i; - - if (strlcpy(ifName, argv[optind], - MAXPATHLEN) >= MAXPATHLEN) { - printf("Network interface name too long\n"); - return (-1); - } - - /* must have a PPA number */ - i = strlen(ifName) - 1; - if ((ifName[i] < '0') || (ifName[i] > '9')) { - usage(); - return (-1); - } - - /* extract the PPA number and device path */ - while (i) { - if ((ifName[i] < '0') || (ifName[i] > '9')) - break; - else - i--; - } - - if (i) { - ifUnit = atoi(&ifName[i+1]); - ifName[i+1] = '\0'; - } else { - usage(); - return (-1); - } - } - } else { - /* cannot have both -a and device */ - if (argv[optind] && argv[optind][0]) { - usage(); - return (-1); - } - } - - - /* Read the configuration file now */ -#define NOTRUNNING 0 - readconfig(NOTRUNNING); - - /* Now override any parameters with command line options */ - optind = 1; - while ((c = getopt(argc, argv, "af:d:D:M:b:l:s:g:z:")) != -1) { - switch (c) { - case 'd': /* debug level */ - debugLevel = atoi(optarg); - break; - case 'D': /* debug output destination */ - debugDest = atoi(optarg); - break; - case 'M': /* max clients */ - maxClients = atoi(optarg); - break; - case 'b': /* background mode */ - backGround = atoi(optarg); - break; - case 'l': /* alt. log file name */ - if (strlcpy(logFile, optarg, - MAXPATHLEN) >= MAXPATHLEN) { - printf("Alternate log file too long\n"); - return (-1); - } - break; - case 's': /* start delay count */ - startDelay = atol(optarg); - break; - case 'g': /* granularity */ - delayGran = atol(optarg); - break; - case 'z': /* frame size */ - frameSize = atoi(optarg); - break; - case '?': - err++; - } - } - - if (debugLevel && (open_debug_dest() < 0)) { - printf("Cannot open specified debug destination\n"); - return (-1); - } - - /* debugLevel and debugDest finally has meaning now */ - - if (debugLevel < MSG_NONE || debugLevel > MSG_ALWAYS) { - sprintf(debugmsg, - "Debug level out of range. Legal range is 0-9.\n"); - senddebug(MSG_FATAL); - err++; - } - - if (backGround && debugDest == DEST_CONSOLE) { - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, "Cannot run in background while " - "sending debug information to console.\n"); - senddebug(MSG_FATAL); - } - err++; - } - - if ((long)delayGran < 0) { - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, - "Cannot have negative delay granularity.\n"); - senddebug(MSG_FATAL); - } - err++; - } - - if (err) { - usage(); - return (-1); - } - - if (aflag) { - /* - * Find all the network interfaces and start a server on - * each of them. - */ - if ((ip_fd = open("/dev/ip", 0)) < 0) { - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, - "Failed to open IP, -a option failed.\n"); - senddebug(MSG_FATAL); - } - return (-1); - } - - /* ask IP for the list of configured interfaces */ -#ifdef SIOCGIFNUM - if (ioctl(ip_fd, SIOCGIFNUM, (char *)&numifs) < 0) { - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, - "Failed ioctl(SIOCGIFNUM)\n"); - senddebug(MSG_FATAL); - } - close(ip_fd); - return (-1); - } -#else - numifs = MAXIFS; -#endif - bufsize = numifs*sizeof (struct ifreq); - reqbuf = (struct ifreq *)malloc(bufsize); - if (reqbuf == NULL) { - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, "Failed to allocate memory " - "to look up configured interfaces in IP.\n"); - senddebug(MSG_FATAL); - sprintf(debugmsg, "-a option failed.\n"); - senddebug(MSG_FATAL); - } - close(ip_fd); - return (-1); - } - ifconf.ifc_len = bufsize; - ifconf.ifc_buf = (caddr_t)reqbuf; - if (ioctl(ip_fd, SIOCGIFCONF, (char *)&ifconf) < 0) { - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, - "SIOCGIFCONF failed, -a option failed.\n"); - senddebug(MSG_FATAL); - } - close(ip_fd); - free(reqbuf); - return (-1); - } - - /* - * Fork and pass discovered interface name through the - * global variables ifName and ifUnit - */ - for (ifr = ifconf.ifc_req; ifconf.ifc_len > 0; - ifr++, ifconf.ifc_len -= sizeof (struct ifreq)) { - if (ioctl(ip_fd, SIOCGIFFLAGS, (char *)ifr) < 0) { - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, - "ioctl SIOCGIFFLAGS failed.\n"); - senddebug(MSG_FATAL); - } - free(reqbuf); - close(ip_fd); - return (-1); - } - if ((ifr->ifr_flags & IFF_LOOPBACK) || - !(ifr->ifr_flags & IFF_BROADCAST) || - !(ifr->ifr_flags & IFF_UP) || - (ifr->ifr_flags & IFF_NOARP) || - (ifr->ifr_flags & IFF_POINTOPOINT)) - continue; - - if (strchr(ifr->ifr_name, ':') != NULL) - /* - * rpld only cares about DLPI devices and only - * the physical IP interfaces correspond to - * a DLPI device. - */ - continue; - - /* - * check if this interface needs LLC and if so, - * remember which PPA in LLC to use. Assume that - * only llc1 is used. - */ - (void) strlcpy(devbuf, "/dev/", MAXPATHLEN); - getdevice((uchar_t *)ifr->ifr_name, - (uchar_t *)&devbuf[5]); - (void) strlcpy(ifName, devbuf, MAXPATHLEN); - ifUnit = unit = getunit(ifr->ifr_name); - if (debugLevel >= MSG_INFO_1) { - sprintf(debugmsg, "found interface = %s%d\n", - ifName, ifUnit); - senddebug(MSG_INFO_1); - } - - if (llc_is_needed(ifName, ifUnit)) { - need_llc = 1; - } else - need_llc = 0; - - if (more) { - switch (fork()) { - case -1: /* failure */ - free(reqbuf); - close(ip_fd); - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, "Fork() " - "failed to run rpld on " - "interface %s%d\n", ifName, - ifUnit); - senddebug(MSG_FATAL); - } - return (-1); - break; - case 0: /* child */ - free(reqbuf); - close(ip_fd); - if (debugLevel >= MSG_INFO_2) - dumpparams(); - return (0); - default: /* parent */ - break; - } - - /* prepare for next ppanum for LLC */ - ppanum++; - } - - /* - * retain the first found interface for the - * parent process - */ - if (!more) { - more = 1; - (void) strlcpy(_ifName, ifName, MAXPATHLEN); - _ifUnit = ifUnit; - _need_llc = need_llc; - } - } /* for */ - - free(reqbuf); - close(ip_fd); - - } /* aflag */ - - /* parent always use ppanum of 0 */ - ppanum = 0; - (void) strlcpy(ifName, _ifName, MAXPATHLEN); - ifUnit = _ifUnit; - need_llc = _need_llc; - - if (debugLevel >= MSG_INFO_2) - dumpparams(); - - return (0); -} - -/* returns 1 if need LLC, 0 if not, -1 if error occurs */ -int -llc_is_needed(char *devname, int ifUnit) -{ - int if_fd; - dl_info_t if_info; - struct strbuf ctl; - char resultbuf[MAXPRIMSZ]; - union DL_primitives *dlp = (union DL_primitives *)resultbuf; - unsigned char node_address[6]; - int flags = 0; - - /* open this device */ - if ((if_fd = dl_open(ifName, O_RDWR, NULL)) < 0) { - return (-1); - } - - /* query information about this device */ - if (dl_info(if_fd, &if_info) < 0) { - dl_close(if_fd); - return (-1); - } - - /* - * Check if we need to use the LLC module. This is needed if: - * 1. a DL_INFO_REQ determines that the device is of type DL_ETHER - * 2. an attempt to do a DL_TEST_REQ to yourself does not return - * an error ack for non-DL_ETHER devices. - */ - if (if_info.mac_type == DLTYPE_ETHER) { - dl_close(if_fd); - return (1); - } else { - struct pollfd pfd; - int rc; - - if (debugLevel >= MSG_INFO_1) { - sprintf(debugmsg, - "Need to determine if LLC driver is needed\n"); - senddebug(MSG_INFO_1); - } - - /* attach to ifUnit */ - if (dl_attach(if_fd, ifUnit) < 0) { - dl_close(if_fd); - return (-1); - } - - /* find out own node address for use in test */ - if (dlpi_get_phys(if_fd, node_address) != 0) { - dl_close(if_fd); - return (-1); - } - - dlp->test_req.dl_primitive = DL_TEST_REQ; - dlp->test_req.dl_flag = 0; - dlp->test_req.dl_dest_addr_length = 7; - dlp->test_req.dl_dest_addr_offset = DL_TEST_REQ_SIZE; - memcpy(&resultbuf[DL_TEST_REQ_SIZE], node_address, 6); - resultbuf[DL_TEST_REQ_SIZE+6] = (unsigned char)0xfc; - - ctl.len = DL_TEST_REQ + 7; - ctl.buf = resultbuf; - if (putmsg(if_fd, &ctl, NULL, 0) < 0) { - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, - "putmsg() failed in DL_TEST_REQ, errno = %d\n", errno); - senddebug(MSG_FATAL); - } - dl_close(if_fd); - return (-1); - } - - pfd.fd = if_fd; - pfd.events = POLLIN | POLLPRI | POLLERR; - rc = poll(&pfd, 1, 10); /* 10 millisec timeout */ - if (rc == 0) { - /* no reply message, assume LLC is available */ - } else if (rc > 0) { - ctl.maxlen = MAXPRIMSZ; - ctl.buf = resultbuf; - if (getmsg(if_fd, &ctl, NULL, &flags) < 0) { - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, - "getmsg() failed in DL_TEST_REQ, errno = %d\n", errno); - senddebug(MSG_FATAL); - } - dl_close(if_fd); - return (-1); - } - if (dlp->dl_primitive == DL_ERROR_ACK) { - dl_close(if_fd); - return (1); - } - } else { - /* error occurs */ - dl_close(if_fd); - return (-1); - } - } - dl_close(if_fd); - return (0); -} - -/* - * Read the configuration parameters in the config file. - * Different actions are required if the server is already running or not - */ -int -readconfig(int running) -{ - FILE *fstr; - int i, n; - char line[80]; - int lineno = 0; - int done = 0; - int debugDestChange; - unsigned int newDebugDest; - int logFileChange; - char newLogFile[MAXPATHLEN]; - - if ((fstr = fopen(configFile, "r")) == NULL) { - if (running) { - if (debugLevel >= MSG_ERROR_1) { - sprintf(debugmsg, - "Cannot open config file %s\n", configFile); - senddebug(MSG_ERROR_1); - } - } else { - printf("Cannot open config file %s.\n", configFile); - } - - /* - * If already running, do not fall back to use the default - * config file. - */ - if (running) - return (0); - - /* Try to use default config file if not already done so */ - if (strcmp(configFile, DFT_CONFIGFILE) != 0) { - printf("Using the default config file %s\n", - DFT_CONFIGFILE); - (void) strlcpy(configFile, DFT_CONFIGFILE, MAXPATHLEN); - if ((fstr = fopen(configFile, "r")) == NULL) { - if (running && debugLevel >= MSG_ERROR_1) { - sprintf(debugmsg, "Cannot open " - "default config file. Using " - "default values.\n"); - senddebug(MSG_ERROR_1); - } else { - printf("Cannot open default config " - "file. Using default values.\n"); - } - return (0); - } - } else { - return (0); - } - } - - if (running && (debugLevel >= MSG_INFO_1)) { - sprintf(debugmsg, "Reading config file %s\n", configFile); - senddebug(MSG_INFO_1); - } - - do { - lineno++; - n = readline(fstr, line, 80); - - if (line[0] == '\0' || line[0] == COMMENT_CHAR) - continue; - /* - * We now scan the input line and put a NULL at the - * end of the keyword token. This way, we can compare - * the keyword token by strcmp(line, "...") - * - * At the same time, we find the start of the value - * token so that we can retrieve the value by something - * like atoi(&line[i]) - */ - i = 0; - while (line[i] != ' ' && line[i] != TAB) - i++; - line[i++] = '\0'; /* put NULL after keyword token */ - - while (line[i] < '0' || line[i] > 'z' || - (line[i] > '9' && line[i] < 'A') || - (line[i] > 'Z' && line[i] < 'a')) - i++; - - if (strcmp(line, "DebugLevel") == 0) - debugLevel = atoi(&line[i]); - else if (strcmp(line, "DebugDest") == 0) { - if (!running) { - debugDest = atoi(&line[i]); - } else { - debugDestChange = 0; - newDebugDest = atoi(&line[i]); - - if (debugDest == atoi(&line[i])) - continue; - /* - * Don't allow running in background to - * re-acquire the controlling terminal - */ - if (backGround && - atoi(&line[i]) == DEST_CONSOLE) - continue; - /* - * We have determined that there is a - * legal change of the debug destination. - * However, we cannot do the actual change - * now because the log file may also change. - * So we set a flag and do it later. - */ - debugDestChange = 1; - } - } else if (strcmp(line, "MaxClients") == 0) { - /* can be -1 which means unlimited */ - if (line[i-1] == '-') - i--; - maxClients = atoi(&line[i]); - } else if (strcmp(line, "BackGround") == 0) { - if (!running) - backGround = atoi(&line[i]); - } else if (strcmp(line, "LogFile") == 0) { - if (line[i-1] == '/') - i--; - if (!running) { - (void) strlcpy(logFile, &line[i], MAXPATHLEN); - } else { - logFileChange = 0; - (void) strlcpy(newLogFile, &line[i], - MAXPATHLEN); - if (strcmp(newLogFile, logFile) == 0) - continue; - else - logFileChange = 1; - } - } else if (strcmp(line, "DelayGran") == 0) - delayGran = atol(&line[i]); - else if (strcmp(line, "StartDelay") == 0) - startDelay = atol(&line[i]); - else if (strcmp(line, "FrameSize") == 0) - frameSize = atoi(&line[i]); - else if (strcmp(line, "end") == 0) - done = 1; - } while (!done); - - fclose(fstr); - - if (running) { - if (debugDestChange || logFileChange) { - switch (debugDest) { - case DEST_SYSLOGD: - closelog(); - break; - case DEST_LOGFILE: - if (log_str != NULL) - fclose(log_str); - log_str = NULL; - break; - } - debugDest = newDebugDest; - switch (debugDest) { - case DEST_SYSLOGD: - openlog("rpld", LOG_PID, LOG_DAEMON); - break; - case DEST_LOGFILE: - log_str = fopen(newLogFile, "a+"); - if (log_str == NULL) { - /* cannot open the new log file */ - /* reopen the old one and use that */ - log_str = fopen(logFile, "a+"); - if (log_str == NULL) { - /* we are doomed */ - ; - } - setbuf(log_str, (char *)NULL); - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, "Cannot " - "open new log file %s\n", - newLogFile); - senddebug(MSG_FATAL); - sprintf(debugmsg, "Re-using " - "old log file %s\n", - logFile); - senddebug(MSG_FATAL); - } - } else { - (void) strlcpy(logFile, newLogFile, - MAXPATHLEN); - setbuf(log_str, (char *)NULL); - } - break; - } - } - } - return (0); -} - -int -readline(FILE *str, char *buf, int count) -{ - int i = 0; - int done = 0; - int ch; - - while (!done && i < count) { - ch = getc(str); - if (ch == LF || ch == CR || ch == EOF) { - done = 1; - } else { - buf[i++] = ch; - } - } - buf[i] = '\0'; - return (i); -} - -int -open_debug_dest(void) -{ - if (debugDest == DEST_LOGFILE) { - if (log_str != NULL) - fclose(log_str); - log_str = fopen(logFile, "a+"); - if (log_str == NULL) { - if (debugLevel >= MSG_FATAL) { - sprintf(debugmsg, "Cannot open log file %s\n", - logFile); - senddebug(MSG_FATAL); - } - return (-1); - } - setbuf(log_str, (char *)NULL); - } - - if (debugDest == DEST_SYSLOGD) { - openlog("rpld", LOG_PID, LOG_DAEMON); - } - - return (0); -} - -void -usage(void) -{ - printf("\n"); - printf("Usage: rpld [options] <network_interface_name>\n"); - printf(" rpld -a [options]\n"); - printf("Options:\n"); - printf(" -f file # set alternate config file\n"); - printf(" -d num # set debug level (0-9), 0=nil, 9=most\n"); - printf(" -D num # set debug destination, 0=console, " - "1=syslogd, 2=logfile\n"); - printf(" -M num # set max simultaneous clients, " - "-1=unlimited\n"); - printf(" -b num # set background mode, 1=background, " - "0=not\n"); - printf(" -l file # set alternate log file\n"); - printf(" -s num # set start delay count\n"); - printf(" -g num # set delay granularity\n"); - printf("\n"); -} - -/* - * Pick out leading alphabetic part of string 's'. - */ -void -getdevice(uchar_t *s, uchar_t *dev) -{ - while (isalpha(*s)) - *dev++ = *s++; - *dev = '\0'; -} - -/* - * Pick out trailing numeric part of string 's' and return int. - */ -int -getunit(char *s) -{ - char intbuf[128]; - char *p = intbuf; - - while (isalpha(*s)) - s++; - while (isdigit(*s)) - *p++ = *s++; - *p = '\0'; - return (atoi(intbuf)); -} |
