ftp.nice.ch/peanuts/GeneralData/Documents/user-groups/rmNUG/dialupip.tar.gz#/dialupip/src/dumisc/dudisc.c

This is dudisc.c in view mode; [Download] [Up]

/*
**  Copyright (c) 1991 Bolt Beranek and Newman, Inc.
**  All rights reserved.
**
**  Redistribution and use in source and binary forms are permitted
**  provided that: (1) source distributions retain this entire copyright
**  notice and comment, and (2) distributions including binaries display
**  the following acknowledgement:  ``This product includes software
**  developed by Bolt Beranek and Newman, Inc. and CREN/CSNET'' in the
**  documentation or other materials provided with the distribution and in
**  all advertising materials mentioning features or use of this software.
**  Neither the name of Bolt Beranek and Newman nor CREN/CSNET may be used
**  to endorse or promote products derived from this software without
**  specific prior written permission.
**
**  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
**  WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <stdio.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sgtty.h>
#include "dialupip.h"

#define CORE_DIRECTORY	"/usr/tmp"

/*
** Local Variables
*/
static char		device[128];
static long		endipkts;
static long		endopkts;
static int		dialfd;
static struct sgttyb	osgtty;
static long		startipkts;
static long		startopkts;
static time_t		starttime;
static char		TTY[] = "/dev/tty";
static char		*WHERE = "dudisc";


/*
**  External declarations.
*/
extern int		optind;
extern char		*optarg;
extern unsigned int	sleep();
extern time_t		time();
extern char		*strcpy();
extern char		*strrchr();


/*
**  Print error message and exit.
*/
static void
fatal(format, arg1)
    char	*format;
    char	*arg1;
{
    d_log(DLOG_GENERAL, WHERE, format, arg1);
    (void)fprintf(stderr, format, arg1);
    (void)fprintf(stderr, "\n\r");
    (void)fflush(stderr);
    exit(1);
}


/*
**  Get the packet counts.
*/
static int
getpacketcounts(ipkts, opkts)
    long		*ipkts;
    long		*opkts;
{
    struct ifreq	ifr;
    int			s;
    int			status;

    /* Setup and open the socket */
    status = 0;
    (void)strcpy(ifr.ifr_name, device);
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
	d_log(DLOG_GENERAL, WHERE, "Can't allocate socket, %m");
	status = -1;
    }

    /* Get the input counts */
    if (ioctl(s, SIOCGIPKTS, (caddr_t)&ifr) < 0) {
	d_log(DLOG_GENERAL, WHERE, "Can't SIOCGIPKTS, %m");
	status = -1;
    }
    *ipkts = (long)GETDATAVAL(ifr);

    /* Get the output counts */
    if (ioctl(s, SIOCGOPKTS, (caddr_t)&ifr) < 0) {
	d_log(DLOG_GENERAL, WHERE, "Can't SIOCGOPKTS, %m");
	status = -1;
    }
    *opkts = (long)GETDATAVAL(ifr);

    /* Close the socket, return status. */
    (void)close(s);
    return status;
}


/*
**  Catch a signal and exit.
*/
static void
hangup()
{
    long	totalpkts;
    time_t	total_time;
    int		disc;

    /* Get the ending packets, time and print the statistics */
    if (getpacketcounts(&endipkts, &endopkts) < 0)
	fatal("Can't get packet counts for \"%s\"", device);

    total_time = time((time_t *)NULL) - starttime;
    totalpkts = (endipkts - startipkts) + (endopkts - startopkts);
    d_log(DLOG_GENERAL, WHERE, "Incoming interface \"%s\" up %ld seconds",
	device, (long)total_time);
    d_log(DLOG_GENERAL, WHERE,
	"Inpackets = %ld, Outpackets = %ld, Average = %.2f packets/sec",
	endipkts - startipkts, endopkts - startopkts,
	totalpkts ? ((float)totalpkts) / ((float)total_time) : 0);

    /* Set things back */
    disc = NTTYDISC;
    if (ioctl(dialfd, TIOCSETD, (caddr_t)&disc) < 0)
	fatal("Can't TIOCSETD for \"%s\"", device);
    if (ioctl(dialfd, TIOCSETP, (caddr_t)&osgtty) < 0)
	fatal("Can't TIOCSETP for \"%s\"", device);

    exit(0);
}


main(argc, argv)
    int			argc;
    char		*argv[];
{
    char		*cp;
    char		name[64];
    int			c;
    int			unit;
    int			pid;
    struct ifreq	ifr;
    struct sgttyb	sgtty;
    int			uid;

    /* Set up. */
    setprogname(argv[0]);
    WHERE = progname;
    pid = getpid();

#ifdef    CORE_DIRECTORY
    {
	struct rlimit	rlp;

	if (chdir(CORE_DIRECTORY) < 0)
	    d_log(DLOG_GENERAL, WHERE, "Can't chdir, %m");

	if (getrlimit(RLIMIT_CORE, &rlp) < 0)
	    d_log(DLOG_GENERAL, WHERE, "Can't get getrlimit, %m");

	rlp.rlim_cur = rlp.rlim_max;
	if (setrlimit(RLIMIT_CORE, &rlp) < 0)
	    d_log(DLOG_GENERAL, WHERE, "Can't setrlimit RLIMIT_CORE, %m");
    }
#endif	/* CORE_DIRECTORY */

    /* Parse the command line */
    while ((c = getopt(argc, argv, "d:")) != EOF)
	switch (c) {
	default:
	    fatal("Usage error -- unknown flag", (char *)NULL);
	    /* NOTREACHED */
	case 'd':			/* Set the debug level		 */
	    log_level =  atoi(optarg);
	    break;
	}
    argc -= optind;
    argv += optind;
    if (argc)
	fatal("Usage error -- too many arguments", (char *)NULL);

    /* Set UID to root so we can attach to DIP and boost run time priority
     * until DIP is up and running */
    d_log(DLOG_DIAG, WHERE, "Setting uid to root");
    uid = getuid();
    if (setuid(0) < 0)
	fatal("Can't set uid to root", (char *)NULL);

    if (setpriority(PRIO_PROCESS, pid, -10))
	fatal("Can't set process priority", (char *)NULL);

    /* Pick off the device for DIP */
    if ((cp = strrchr(progname, '_')) == NULL)
	fatal("Can't find device name in program name (\"%s\")", progname);
    if (sscanf(cp, "_%[A-Za-z]%d", name, &unit) != 2)
	fatal("Can't parse device name \"%s\"", cp);
    (void)sprintf(ifr.ifr_name, "%s%d", name, unit);
    (void)strcpy(device, ifr.ifr_name);

    /* Leave the user the Process ID for easy kill */
    if (record_pid(device) < 0)
	fatal("Can't record PID for \"%s\"", device);
    d_log(DLOG_INFO, WHERE, "Device is \"%s\"", device);

#ifdef	ifr_metric
    ifr.ifr_metric = unit;
#endif	/* ifr_metric */

    /* Set the new tty mode */
    if ((dialfd = open(TTY, O_RDWR | O_NDELAY)) < 0)
	fatal("Can't open TTY for \"%s\"", device);
    d_log(DLOG_DIAG, WHERE, "Doing TIOCGETP for \"%s\"", device);
    if (ioctl(dialfd, TIOCGETP, (caddr_t)&sgtty) < 0)
	fatal("Can't TIOCGETP for \"%s\"", device);
    osgtty = sgtty;
    sgtty.sg_flags = RAW | ANYP;
    d_log(DLOG_DIAG, WHERE, "Doing TIOCSETP for \"%s\"", device);
    if (ioctl(dialfd, TIOCSETP, (caddr_t)&sgtty) < 0)
	fatal("Can't TIOCSETP for \"%s\"", device);

    /* Get the starting statistics. */
    d_log(DLOG_DIAG, WHERE, "Reading packet counts for \"%s\"",
	device);
    if (getpacketcounts(&startipkts, &startopkts) < 0)
	fatal("Can't get packet counts for \"%s\"", device);
    d_log(DLOG_GENERAL, WHERE,
	"Incoming interface \"%s\" starting ipkts = %ld, okpts = %ld",
	device, startipkts, startopkts);

    /* Turn on DIP mode */
    d_log(DLOG_DIAG, WHERE, "Doing TIOCSETD for \"%s\"", device);
    c = DUDISC;
    if (ioctl(dialfd, TIOCSETD, (caddr_t)&c) < 0)
	fatal("Can't TIOCSETD for \"%s\"", device);

    /* Set the interface address */
    d_log(DLOG_DIAG, WHERE, "Doing TIOCHPCL for \"%s\"", device);
    if (ioctl(dialfd, TIOCHPCL, (caddr_t)0) < 0)
	fatal("Can't TIOCHPCL for \"%s\"", device);

    d_log(DLOG_DIAG, WHERE, "Doing SIOCSIFADDR for \"%s\"", device);
    if (ioctl(dialfd, SIOCSIFADDR, (caddr_t)&ifr) < 0)
	fatal("Can't SIOCSIFADDR for \"%s\"", device);

    /* DIP is now up.  Log it, set up exit handler. */
    (void)time(&starttime);
    (void)printf("%s connected to \"%s\"\n", dip_release(), device);
    d_log(DLOG_GENERAL, WHERE, "Setup finished -- now running DIP.");
    (void)signal(SIGHUP, hangup);
    (void)signal(SIGINT, hangup);

    /* Reset priority and identity. */
    if (setpriority(PRIO_PROCESS, pid, 0) < 0)
	fatal("Can't reset priority for \"%s\"", device);
    (void)setuid(uid);

    /* Periodically make log entries. */
    for (c = 0; ; ) {
	(void)sleep(UPTIME_INTERVAL * 60);
	c += UPTIME_INTERVAL;
	d_log(DLOG_GENERAL, WHERE,
	    "Incoming interface \"%s\" up %d minutes", device, c);
    }

    /* NOTREACHED */
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.