/* $Header:landump.c 12.0$ */
/* $ACIS:landump.c 12.0$ */
/* $Source: /ibm/acis/usr/src/etc/RCS/landump.c,v $ */

#ifndef lint
static char *rcsid = "$Header:landump.c 12.0$";
#endif

/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */

#include <stdio.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/signal.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/errno.h>
#include <net/if.h>
#include <machineif/if_lanio.h>

#define DEMON 1
struct lan_dump lan_dump;
struct ifreq ifr;
char *name;
char filename[30];
int s, fd;
int opmode;

/*
 * landump obtains a dump of the internal storage of the
 * lan adapter and writes it to file lanxcore in the current
 * directory, where x is the adapter interface number.
 * If invoked with no options, the named lan adapter
 * is frozen and dumped.  If invoked with -d option, landump
 * notifies the lan driver of its existence; if a dump is then
 * required  due to an external event (eg. adapter check)
 * the lan driver wakes up this process to request the dump.
 */


main(argc, argv)
	int argc;
	char *argv[];
{

	if (argc < 2) {
	usage:
		fprintf(stderr, "usage: landump [ -d ] interface\n");
		exit(1);
	}
	s = socket(AF_INET, SOCK_DGRAM, 0);
	if (s < 0) {
		perror("landump: socket");
		exit(1);
	}
	argc--, argv++;
	name = *argv;
	if (name[0] == '-' ) {
		switch (name[1]) {
		case 'd':
			opmode = DEMON;
			argc--, argv++;
			name = *argv;
			break;
		default:
			goto usage;
		}
	}
	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
		perror("landump: ioctl");   
		exit(1);
	}
	switch (opmode) {
	case DEMON:
		lan_demon();
		break;
	default:
		setifdump();
		break;
	}
	exit(0);
}

setifdump()
{
	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));  
		/* freeze adapter */
	if (ioctl(s,SIOCFLANDUMP, (caddr_t) &ifr) < 0) {
		perror("landump: setifdump: ioctl");
		exit(1);
	}
		/* request adapter dump and write to file */
	lan_get_dump();
}

lan_demon()
{
		/* notify driver in case of lan disaster */
	for (;;) {
		strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 
		if (ioctl(s,SIOCSLANDUMP, (caddr_t) &ifr) < 0) {
			perror("landump: lan_demon: ioctl");
			exit(1);
		}
		/* request adapter dump and write to file */
		lan_get_dump();
	}

}

lan_get_dump()
{
		/* request dump of adapter storage */
	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 
	lan_dump.lan_len = LAN_FREEZE_DUMP;
	ifr.ifr_data = (caddr_t) &lan_dump;
	if (ioctl(s,SIOCGLANDUMP, (caddr_t) &ifr) < 0) {
		perror("landump: lan_get_dump: ioctl");
		exit(1);
	}
		/* write dump date to lanxcore in cd */
	strcpy(filename,name);
	strcat(filename,"core");
	if ((fd = open(filename, O_RDWR+O_CREAT, 0x0666)) < 0) {
		perror("landump: lan_get_dump: open");
		exit(1);
	}
	if (write(fd, lan_dump.lan_dump_data, LAN_FREEZE_DUMP) < 0) {
		perror("landump: lan_get_dump: write");
		exit(1);
	}
	/* error to close before fsync */
	if (fsync(fd) < 0) {
		perror("landump: lan_get_dump: fsync");
		exit(1);
	}
	close(fd);
}



