params.c revision 50c83d09652262aba75a6182b3203c80b48b092b
/*
* 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
* 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.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <poll.h>
#include <errno.h>
#include <syslog.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 int ifUnit;
extern int ppanum;
extern int need_llc;
void usage(void);
int
{
int c;
int err = 0;
int ip_fd;
int numifs;
char *device;
int unit;
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;
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);
}
/*
* 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;
switch (c) {
case 'a':
aflag = 1;
break;
case 'f': /* alternate config file */
MAXPATHLEN) >= MAXPATHLEN) {
printf("Alternate config file too long\n");
return (-1);
}
break;
case '?':
usage();
return (-1);
}
}
if (!aflag) {
/* neither -a nor device name is specified */
usage();
return (-1);
} else {
/* potentially a correct device name is specified */
int i;
MAXPATHLEN) >= MAXPATHLEN) {
printf("Network interface name too long\n");
return (-1);
}
/* must have a PPA number */
usage();
return (-1);
}
/* extract the PPA number and device path */
while (i) {
break;
else
i--;
}
if (i) {
} else {
usage();
return (-1);
}
}
} else {
/* cannot have both -a and device */
usage();
return (-1);
}
}
/* Read the configuration file now */
#define NOTRUNNING 0
/* Now override any parameters with command line options */
optind = 1;
switch (c) {
case 'd': /* debug level */
break;
case 'D': /* debug output destination */
break;
case 'M': /* max clients */
break;
case 'b': /* background mode */
break;
case 'l': /* alt. log file name */
MAXPATHLEN) >= MAXPATHLEN) {
printf("Alternate log file too long\n");
return (-1);
}
break;
case 's': /* start delay count */
break;
case 'g': /* granularity */
break;
case 'z': /* frame size */
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 */
"Debug level out of range. Legal range is 0-9.\n");
err++;
}
if (debugLevel >= MSG_FATAL) {
"sending debug information to console.\n");
}
err++;
}
if ((long)delayGran < 0) {
if (debugLevel >= MSG_FATAL) {
"Cannot have negative delay granularity.\n");
}
err++;
}
if (err) {
usage();
return (-1);
}
if (aflag) {
/*
* Find all the network interfaces and start a server on
* each of them.
*/
if (debugLevel >= MSG_FATAL) {
"Failed to open IP, -a option failed.\n");
}
return (-1);
}
/* ask IP for the list of configured interfaces */
#ifdef SIOCGIFNUM
if (debugLevel >= MSG_FATAL) {
"Failed _ioctl(SIOCGIFNUM)\n");
}
return (-1);
}
#else
#endif
if (debugLevel >= MSG_FATAL) {
"to look up configured interfaces in IP.\n");
}
return (-1);
}
if (debugLevel >= MSG_FATAL) {
"SIOCGIFCONF failed, -a option failed.\n");
}
return (-1);
}
/*
* Fork and pass discovered interface name through the
* global variables ifName and ifUnit
*/
if (debugLevel >= MSG_FATAL) {
"ioctl SIOCGIFFLAGS failed.\n");
}
return (-1);
}
continue;
/*
* 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.
*/
if (debugLevel >= MSG_INFO_1) {
}
need_llc = 1;
} else
need_llc = 0;
if (more) {
switch (fork()) {
case -1: /* failure */
if (debugLevel >= MSG_FATAL) {
"failed to run rpld on "
"interface %s%d\n", ifName,
ifUnit);
}
return (-1);
break;
case 0: /* child */
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;
}
} /* for */
} /* aflag */
/* parent always use ppanum of 0 */
ppanum = 0;
if (debugLevel >= MSG_INFO_2)
dumpparams();
return (0);
}
/* returns 1 if need LLC, 0 if not, -1 if error occurs */
int
{
int if_fd;
unsigned char node_address[6];
int flags = 0;
/* open this device */
return (-1);
}
/* query information about this device */
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.
*/
return (1);
} else {
int rc;
if (debugLevel >= MSG_INFO_1) {
"Need to determine if LLC driver is needed\n");
}
/* attach to ifUnit */
return (-1);
}
/* find out own node address for use in test */
return (-1);
}
if (debugLevel >= MSG_FATAL) {
"putmsg() failed in DL_TEST_REQ, errno = %d\n", errno);
}
return (-1);
}
if (rc == 0) {
/* no reply message, assume LLC is available */
} else if (rc > 0) {
if (debugLevel >= MSG_FATAL) {
"getmsg() failed in DL_TEST_REQ, errno = %d\n", errno);
}
return (-1);
}
return (1);
}
} else {
/* error occurs */
return (-1);
}
}
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)
{
int i, n;
char line[80];
int lineno = 0;
int done = 0;
int debugDestChange;
unsigned int newDebugDest;
int logFileChange;
char newLogFile[MAXPATHLEN];
if (running) {
if (debugLevel >= MSG_ERROR_1) {
"Cannot open config file %s\n", configFile);
}
} else {
}
/*
* 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 */
printf("Using the default config file %s\n",
"default config file. Using "
"default values.\n");
} else {
printf("Cannot open default config "
"file. Using default values.\n");
}
return (0);
}
} else {
return (0);
}
}
}
do {
lineno++;
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;
i++;
i++;
if (!running) {
} else {
debugDestChange = 0;
continue;
/*
* Don't allow running in background to
* re-acquire the controlling terminal
*/
if (backGround &&
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;
}
/* can be -1 which means unlimited */
i--;
if (!running)
i--;
if (!running) {
} else {
logFileChange = 0;
continue;
else
logFileChange = 1;
}
done = 1;
} while (!done);
if (running) {
if (debugDestChange || logFileChange) {
switch (debugDest) {
case DEST_SYSLOGD:
closelog();
break;
case DEST_LOGFILE:
break;
}
switch (debugDest) {
case DEST_SYSLOGD:
break;
case DEST_LOGFILE:
/* cannot open the new log file */
/* reopen the old one and use that */
/* we are doomed */
;
}
if (debugLevel >= MSG_FATAL) {
"open new log file %s\n",
"old log file %s\n",
logFile);
}
} else {
}
break;
}
}
}
return (0);
}
int
{
int i = 0;
int done = 0;
int ch;
done = 1;
} else {
}
}
buf[i] = '\0';
return (i);
}
int
open_debug_dest(void)
{
if (debugDest == DEST_LOGFILE) {
if (debugLevel >= MSG_FATAL) {
logFile);
}
return (-1);
}
}
if (debugDest == DEST_SYSLOGD) {
}
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
{
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';
}