home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
telecomm
/
nhclb120
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-26
|
28KB
|
1,324 lines
/* Main network program - provides both client and server functions */
#define HOSTNAMELEN 64
unsigned restricted_dev=1000;
extern char *startup; /* File to read startup commands from */
#include <stdio.h>
#include "config.h"
#include "global.h"
#include "mbuf.h"
#include "netuser.h"
#include "timer.h"
#include "icmp.h"
#include "iface.h"
#include "ip.h"
#include "tcp.h"
#include "ax25.h"
#include "netrom.h"
#include "ftp.h"
#include "telnet.h"
#include "remote.h"
#include "session.h"
#include "cmdparse.h"
#ifdef ASY
#include "asy.h"
#include "slip.h"
#endif
#ifdef NRS
#include "nrs.h"
#endif
#ifdef SLFP
#include "slfp.h"
#endif
#ifdef UNIX /* BSD or SYS5 */
#include "unix.h"
#include <memory.h>
#include <string.h>
#include <sys/types.h>
time_t time();
#endif
#ifdef AMIGA
#include "amiga.h"
#endif
#ifdef MAC
#include "mac.h"
#endif
#ifdef MSDOS
#include "asy.h"
#endif
#ifdef ATARI_ST
#include "st.h"
#ifdef LATTICE
long _MNEED = 100000L; /* Reserve RAM for subshell... */
long _32K = 0x8000; /* For GST Linker (Don't ask me! -- hyc) */
#endif
#ifdef MWC
long _stksize = 16384L; /* Fixed stack size... -- hyc */
#endif
#endif /* ATARI_ST */
#ifdef SYS5
#include <signal.h>
int background = 0;
#endif
#ifdef TRACE
#include "trace.h"
/* Dummy structure for loopback tracing */
struct interface loopback = { NULLIF, "loopback" };
#endif
int ntohip();
extern struct interface *ifaces;
extern char version[];
extern struct mbuf *loopq;
extern FILE *trfp;
extern char trname[];
extern int debug_options;
static showtrace();
#ifdef MALLOC_DEBUG
FILE *mall_deb;
#endif
int mode;
FILE *logfp;
char badhost[] = "Unknown host %s\n";
char hostname[HOSTNAMELEN];
unsigned nsessions = NSESSIONS;
int32 resolve();
int16 lport = 1001;
char prompt[] = "net> ";
char nospace[] = "No space!!\n"; /* Generic malloc fail message */
#ifdef SYS5
int io_active = 0;
void daemon();
#endif
/* #if ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801)) */
/* PC/ST uses F-10 key always */
unsigned char escape = 0x1d; /* default escape character is ^] */
/* #endif */
/* so why does telnet use it ? */
/* I'll put it back ! */
/* Command lookup and branch table */
int go(),doax25(),cmdmode(),doconnect(),dotelnet(),doexit(),doclose(),
dohostname(),doreset(),dotcp(),dotrace(),doescape(),dohelp(),
doroute(),doecho(),dolog(),doip(),dobootp(),dodomain(),dordate(),
memstat(),doarp(),dosession(),doftp(),dostart(),dostop(),doattach(),
dosmtp(),doudp(),doparam(),doeol(),dowait(),go_mode(),
dodump(),dorecord(),doupload(),dokick(),domode(),doshell(),
dodir(),docd(),doatstat(),doping(),doforward(),doremote(),donetrom(),
donrstat(), dombox(), mulport() ;
#ifdef ETHER
int doetherstat();
#endif
#ifdef EAGLE
int doegstat();
#endif
#ifdef HAPN
int dohapnstat();
#endif
#ifdef _FINGER
int dofinger();
#endif
static struct cmds cmds[] = {
/* The "go" command must be first */
"", go_mode, 0, NULLCHAR, NULLCHAR,
"!", doshell, 0, NULLCHAR, NULLCHAR,
#if (MAC && APPLETALK)
"applestat", doatstat, 0, NULLCHAR, NULLCHAR,
#endif
#if (AX25 || ETHER || APPLETALK)
"arp", doarp, 0, NULLCHAR, NULLCHAR,
#endif
#ifdef AX25
"ax25", doax25, 0, NULLCHAR, NULLCHAR,
#endif
"attach", doattach, 2,
"attach <hardware> <hw specific options>", NULLCHAR,
"bootp", dobootp, 0, NULLCHAR, NULLCHAR,
/* This one is out of alpabetical order to allow abbreviation to "c" */
#ifdef AX25
"connect", doconnect, 3,"connect <interface> <callsign> [digipeaters]",
NULLCHAR,
#endif
"cd", docd, 0, NULLCHAR, NULLCHAR,
"close", doclose, 0, NULLCHAR, NULLCHAR,
"disconnect", doclose, 0, NULLCHAR, NULLCHAR,
"dir", dodir, 0, NULLCHAR, NULLCHAR,
"domain", dodomain, 0, NULLCHAR, NULLCHAR,
#ifdef EAGLE
"eaglestat", doegstat, 0, NULLCHAR, NULLCHAR,
#endif
"echo", doecho, 0, NULLCHAR, "echo [refuse|accept]",
"eol", doeol, 0, NULLCHAR,
"eol options: unix, standard",
#if ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))
"escape", doescape, 0, NULLCHAR, NULLCHAR,
#endif
#ifdef PC_EC
"etherstat", doetherstat, 0, NULLCHAR, NULLCHAR,
#endif /* PC_EC */
"exit", doexit, 0, NULLCHAR, NULLCHAR,
#ifdef _FINGER
"finger", dofinger, 0, NULLCHAR, NULLCHAR,
#endif
"forward", doforward, 0, NULLCHAR, NULLCHAR,
"ftp", doftp, 2, "ftp <address>", NULLCHAR,
#ifdef HAPN
"hapnstat", dohapnstat, 0, NULLCHAR, NULLCHAR,
#endif
"help", dohelp, 0, NULLCHAR, NULLCHAR,
"hostname", dohostname, 0, NULLCHAR, NULLCHAR,
"kick", dokick, 0, NULLCHAR, NULLCHAR,
"log", dolog, 0, NULLCHAR, NULLCHAR,
"ip", doip, 0, NULLCHAR, NULLCHAR,
"memstat", memstat, 0, NULLCHAR, NULLCHAR,
#ifdef AX25
"mbox", dombox, 0, NULLCHAR, NULLCHAR,
"mode", domode, 2, "mode <interface>", NULLCHAR,
#endif
#ifdef MULPORT
"mulport", mulport, 2, "mulport <on|off>", NULLCHAR,
#endif
#ifdef NETROM
"netrom", donetrom, 0, NULLCHAR, NULLCHAR,
#ifdef NRS
"nrstat", donrstat, 0, NULLCHAR, NULLCHAR,
#endif
#endif
"param", doparam, 2, "param <interface>", NULLCHAR,
"ping", doping, 0, NULLCHAR, NULLCHAR,
"pwd", docd, 0, NULLCHAR, NULLCHAR,
"rdate", dordate, 0, NULLCHAR, NULLCHAR,
"record", dorecord, 0, NULLCHAR, NULLCHAR,
"remote", doremote, 4, "remote <address> <port> <command>",
NULLCHAR,
"reset", doreset, 0, NULLCHAR, NULLCHAR,
"route", doroute, 0, NULLCHAR, NULLCHAR,
"session", dosession, 0, NULLCHAR, NULLCHAR,
"shell", doshell, 0, NULLCHAR, NULLCHAR,
"smtp", dosmtp, 0, NULLCHAR, NULLCHAR,
#ifdef SERVERS
"start", dostart, 2, "start <servername>",NULLCHAR,
"stop", dostop, 2, "stop <servername>", NULLCHAR,
#endif
"tcp", dotcp, 0, NULLCHAR, NULLCHAR,
"telnet", dotelnet, 2, "telnet <address>", NULLCHAR,
#ifdef TRACE
"trace", dotrace, 0, NULLCHAR, NULLCHAR,
#endif
"udp", doudp, 0, NULLCHAR, NULLCHAR,
"upload", doupload, 0, NULLCHAR, NULLCHAR,
#ifdef SYS5
"wait", dowait, 0, NULLCHAR, NULLCHAR,
#endif
"?", dohelp, 0, NULLCHAR, NULLCHAR,
NULLCHAR, NULLFP, 0,
"Unknown command; type \"?\" for list", NULLCHAR,
};
#ifdef SERVERS
/* "start" and "stop" subcommands */
int dis1(),echo1(),ftp1(),smtp1(),tn1(),rem1();
#ifdef UNIX
int tnix1();
#endif
#ifdef _FINGER
int finger1();
#endif
static struct cmds startcmds[] = {
"discard", dis1, 0, NULLCHAR, NULLCHAR,
"echo", echo1, 0, NULLCHAR, NULLCHAR,
#ifdef _FINGER
"finger", finger1, 0, NULLCHAR, NULLCHAR,
#endif
"ftp", ftp1, 0, NULLCHAR, NULLCHAR,
"smtp", smtp1, 0, NULLCHAR, NULLCHAR,
"telnet", tn1, 0, NULLCHAR, NULLCHAR,
#ifdef UNIX
"telunix", tnix1, 0, NULLCHAR, NULLCHAR,
#endif
"remote", rem1, 0, NULLCHAR, NULLCHAR,
NULLCHAR, NULLFP, 0,
#ifdef UNIX
#ifdef _FINGER
"start options: discard, echo, finger, ftp, remote, smtp, telnet, telunix", NULLCHAR,
#else
"start options: discard, echo, ftp, remote, smtp, telnet, telunix", NULLCHAR,
#endif
#else /* UNIX */
#ifdef _FINGER
"start options: discard, echo, finger, ftp, remote, smtp, telnet", NULLCHAR,
#else
"start options: discard, echo, ftp, remote, smtp, telnet", NULLCHAR,
#endif
#endif /* UNIX */
};
int ftp_stop(),smtp_stop(),echo_stop(),dis_stop(),tn_stop();
int dis0(),echo0(),ftp0(),smtp0(),tn0(),rem0();
#ifdef UNIX
int tnix0();
#endif
#ifdef _FINGER
int finger0();
#endif
static struct cmds stopcmds[] = {
"discard", dis0, 0, NULLCHAR, NULLCHAR,
"echo", echo0, 0, NULLCHAR, NULLCHAR,
#ifdef _FINGER
"finger", finger0, 0, NULLCHAR, NULLCHAR,
#endif
"ftp", ftp0, 0, NULLCHAR, NULLCHAR,
"smtp", smtp0, 0, NULLCHAR, NULLCHAR,
"telnet", tn0, 0, NULLCHAR, NULLCHAR,
#ifdef UNIX
"telunix", tnix0, 0, NULLCHAR, NULLCHAR,
#endif
"remote", rem0, 0, NULLCHAR, NULLCHAR,
NULLCHAR, NULLFP, 0,
#ifdef UNIX
#ifdef _FINGER
"stop options: discard, echo, finger, ftp, remote, smtp, telnet, telunix", NULLCHAR,
#else
"stop options: discard, echo, ftp, remote, smtp, telnet, telunix", NULLCHAR,
#endif
#else /* UNIX */
#ifdef _FINGER
"stop options: discard, echo, finger, ftp, remote, smtp, telnet", NULLCHAR,
#else
"stop options: discard, echo, ftp, remote, smtp, telnet", NULLCHAR,
#endif
#endif /* UNIX */
};
#endif
void
keep_things_going()
{
void check_time(), ip_recv();
struct interface *ifp;
struct mbuf *bp;
/* Service the loopback queue */
if((bp = dequeue(&loopq)) != NULLBUF){
struct ip ip;
#ifdef TRACE
dump(&loopback,IF_TRACE_IN,TRACE_IP,bp);
#endif
/* Extract IP header */
ntohip(&ip,&bp);
ip_recv(&ip,bp,0);
}
/* Service the interfaces */
#ifdef SYS5
do {
io_active = 0;
#endif
for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next){
if(ifp->recv != NULLVFP)
(*ifp->recv)(ifp);
}
#ifdef SYS5
} while(io_active);
#endif
#ifdef XOBBS
/* service the W2XO PBBS code */
axchk();
#endif
/* Service the clock if it has ticked */
check_time();
#ifdef MSDOS
/* Tell DoubleDos to let the other task run for awhile.
* If DoubleDos isn't active, this is a no-op
*/
#ifndef PLUS
giveup();
#endif
#else
/* Wait until interrupt, then do it all over again */
eihalt();
#endif
}
main(argc,argv)
int argc;
char *argv[];
{
int nextarg;
static char inbuf[BUFSIZ]; /* keep it off the stack */
int c;
char *ttybuf,*fgets();
int16 cnt;
int ttydriv();
int cmdparse();
void check_time(),ip_recv();
FILE *fp;
#ifdef FLOW
extern int ttyflow;
#endif
#ifdef MALLOC_DEBUG
printf("**************** warning MALLOC DEBUG is active **************\n");
mall_deb=fopen("malloc.deb","w");
if(!mall_deb) {
printf(" cannot open malloc.deb\n");
exit(1);
}
#endif
#ifdef UNIX
fileinit(argv[0]);
#endif
#ifdef SYS5
if (signal(SIGINT, SIG_IGN) == SIG_IGN) {
background++;
daemon();
} else
ioinit();
#else
ioinit();
#endif
#ifdef PLUS
/*
* set: cursor to block, attributes off, keyboard to ALT mode,
* transmit functions off, use HP fonts
*/
printf( "\033&d@" /* display attributes off */
"\033[11m"); /* use ALT fonts */
#endif
#ifdef MSDOS
#ifndef PLUS
chktasker();
#endif
#endif
#ifdef MSDOS
printf("KA9Q Internet Protocol Package, v%s DS = %x\n",version,
getds());
#else
#ifdef SYS5
if (!background) {
#endif
printf("KA9Q Internet Protocol Package, v%s\n",version);
#endif
printf("Copyright 1988 by Phil Karn, KA9Q\n");
#ifdef NETROM
printf("NET/ROM Support Copyright 1989 by Dan Frank, W9NK\n") ;
#endif
printf("Based on the version 890421.1a.linux.3 (n6xjj clh)\n");
printf("Bug reports for dje version can be mailed to:\n");
printf("Internet: devans@hclb.demon.co.uk\n");
printf("Cix: devans@cix.compulink.co.uk ( from UK sites only!)\n");
nextarg=1;
if(argc>1)
if(!strcmp(argv[nextarg],"-x")){
display_file_names();
nextarg++;
}
#ifdef SYS5
}
#endif
fflush(stdout);
sessions = (struct session *)calloc(nsessions,sizeof(struct session));
if(argc > nextarg ){
/* Read startup file named on command line */
fp = fopen(argv[nextarg],"r");
} else {
fp = fopen(startup,"r");
}
if(fp != NULLFILE){
while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
cmdparse(cmds,inbuf);
}
fclose(fp);
}
#ifdef XOBBS
axinit();
#endif
cmdmode();
/* Main commutator loop */
for(;;){
/* Process any keyboard input */
#ifdef SYS5
while((background == 0) && ((c = kbread()) != -1)){
#else
while((c = kbread()) != -1){
#endif
#if (defined(MSDOS) || defined(ATARI_ST))
/* c == -2 means the command escape key (F10) */
if(c == -2){
if(mode != CMD_MODE){
printf("\n");
cmdmode();
}
continue;
}
#endif
#ifdef undef
/* #ifdef SYS5 */
if(c == escape && escape != 0){
if(mode != CMD_MODE){
printf("\r\n");
cmdmode();
}
continue;
}
#endif /* SYS5 */
#ifndef FLOW
if ((cnt = ttydriv(c, &ttybuf)) == 0)
continue;
#else
cnt = ttydriv(c, &ttybuf);
if (ttyflow && (mode != CMD_MODE))
go(); /* display pending chars */
if (cnt == 0)
continue;
#endif /* FLOW */
#ifdef undef
/* #if (!defined(MSDOS) && !defined(ATARI_ST)) */
if((ttybuf[0] == escape) && (escape != 0)) {
if(mode != CMD_MODE){
printf("\r\n");
cmdmode();
}
continue;
}
#endif
switch(mode){
case CMD_MODE:
(void)cmdparse(cmds,ttybuf);
fflush(stdout);
break;
case CONV_MODE:
#ifdef undef
/* #if ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801)) */
if(ttybuf[0] == escape && escape != 0){
printf("\n");
cmdmode();
} else
#endif /* MSDOS */
if(current->parse != NULLFP)
(*current->parse)(ttybuf,cnt);
break;
}
if(mode == CMD_MODE){
printf(prompt);
fflush(stdout);
}
}
keep_things_going();
}
}
/* Standard commands called from main */
/* Enter command mode */
int
cmdmode()
{
if(mode != CMD_MODE){
mode = CMD_MODE;
cooked();
flowdefault();
printf(prompt);
fflush(stdout);
}
return 0;
}
static
doexit()
{
void iostop();
#if defined(PLUS)
/*
* set: cursor to block, attributes off, keyboard to HP mode,
* transmit functions off, use HP fonts
*/
printf(/* "\033*dK" cursor to block */
"\033&d@" /* display attributes off */
/* "\033&k0\\" KBD to HP mode */
/* "\033&s0A" transmit functions off */
"\033[10m"); /* use HP fonts */
#endif
if(logfp != NULLFILE)
fclose(logfp);
#ifdef SYS5
if (!background)
iostop();
#else
iostop();
#endif
#ifdef TRACE
if (trfp != stdout)
fclose(trfp);
#endif
exit(0);
}
static
dohostname(argc,argv)
int argc;
char *argv[];
{
char *strncpy();
if(argc < 2)
printf("%s\n",hostname);
else
strncpy(hostname,argv[1],HOSTNAMELEN);
return 0;
}
static
int
dolog(argc,argv)
int argc;
char *argv[];
{
char *strncpy();
#ifdef UNIX
static char logname[256];
#else
static char logname[15];
#endif
if(argc < 2){
if(logfp)
printf("Logging to %s\n",logname);
else
printf("Logging off\n");
return 0;
}
if(logfp){
fclose(logfp);
logfp = NULLFILE;
}
if(strcmp(argv[1],"stop") != 0){
#ifdef UNIX
strncpy(logname,argv[1],sizeof(logname));
#else
strncpy(logname,argv[1],15);
#endif
logfp = fopen(logname,"a+");
}
return 0;
}
static
int
dohelp()
{
register struct cmds *cmdp;
int i,j;
printf("Main commands:\n");
for(i=0,cmdp = cmds;cmdp->name != NULL;cmdp++,i++){
printf("%s",cmdp->name);
if((i % 4) == 3)
printf("\n");
else {
for(j=strlen(cmdp->name);j < 16; j++)
putchar(' ');
}
}
if((i % 4) != 0)
printf("\n");
return 0;
}
doecho(argc,argv)
int argc;
char *argv[];
{
extern int refuse_echo;
if(argc < 2){
if(refuse_echo)
printf("Refuse\n");
else
printf("Accept\n");
} else {
if(argv[1][0] == 'r')
refuse_echo = 1;
else if(argv[1][0] == 'a')
refuse_echo = 0;
else
return -1;
}
return 0;
}
/* set for unix end of line for remote echo mode telnet */
doeol(argc,argv)
int argc;
char *argv[];
{
extern int unix_line_mode;
if(argc < 2){
if(unix_line_mode)
printf("Unix\n");
else
printf("Standard\n");
} else {
if(strcmp(argv[1],"unix") == 0)
unix_line_mode = 1;
else if(strcmp(argv[1],"standard") == 0)
unix_line_mode = 0;
else {
return -1;
}
}
return 0;
}
/* Attach an interface
* Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
*/
doattach(argc,argv)
int argc;
char *argv[];
{
extern struct cmds attab[];
return subcmd(attab,argc,argv);
}
/* Manipulate I/O device parameters */
doparam(argc,argv)
int argc;
char *argv[];
{
register struct interface *ifp;
for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
if(strcmp(argv[1],ifp->name) == 0)
break;
}
if(ifp == NULLIF){
printf("Interface \"%s\" unknown\n",argv[1]);
return 1;
}
if(ifp->ioctl == NULLFP){
printf("Not supported\n");
return 1;
}
/* Pass rest of args to device-specific code */
return (*ifp->ioctl)(ifp,argc-2,argv+2);
}
/* Log messages of the form
* Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
*/
/*VARARGS2*/
log(tcb,fmt,arg1,arg2,arg3,arg4)
struct tcb *tcb;
char *fmt;
int32 arg1,arg2,arg3,arg4;
{
char *cp;
long t;
#if (defined(MSDOS) || defined(ATARI_ST))
int fd;
#endif
if(logfp == NULLFILE)
return;
time(&t);
cp = ctime(&t);
rip(cp);
if (tcb)
fprintf(logfp,"%s %s - ",cp,psocket(&tcb->conn.remote));
else
fprintf(logfp,"%s - ",cp);
fprintf(logfp,fmt,arg1,arg2,arg3,arg4);
fprintf(logfp,"\n");
fflush(logfp);
#if (defined(MSDOS) || defined(ATARI_ST))
/* MS-DOS doesn't really flush files until they're closed */
fd = fileno(logfp);
if((fd = dup(fd)) != -1)
close(fd);
#endif
}
/* Configuration-dependent code */
/* List of supported hardware devices */
int modem_init(),asy_attach(),pc_attach(),at_attach(),nr_attach();
#ifdef EAGLE
int eg_attach();
#endif
#ifdef HAPN
int hapn_attach();
#endif
#ifdef PC_EC
int ec_attach();
#endif
#ifdef LINUX_ETH
int linux_attach();
#endif
#ifdef PACKET
int pk_attach();
#endif
struct cmds attab[] = {
#ifdef PC_EC
/* 3-Com Ethernet interface */
"3c500", ec_attach, 7,
"attach 3c500 <address> <vector> arpa <label> <buffers> <mtu>",
"Could not attach 3c500",
#endif
#ifdef LINUX_ETH
/* linux Ethernet interface */
"linux", linux_attach, 5,
"attach linux arpa <label> <mtu> <hex ether address as 1.2.3.4.5.6>",
"Could not attach linux ethernet",
#endif
#ifdef ASY
/* Ordinary PC asynchronous adaptor */
"asy", asy_attach, 8,
#ifdef UNIX
#ifndef SLFP
"attach asy 0 <ttyname> slip|ax25|nrs <label> <buffers> <mtu> <speed>",
#else
"attach asy 0 <ttyname> slip|ax25|nrs|slfp <label> <buffers> <mtu> <speed>",
#endif /* SLFP */
#else
#ifndef SLFP
"attach asy <address> <vector> slip|ax25|nrs <label> <buffers> <mtu> <speed>",
#else
"attach asy <address> <vector> slip|ax25|nrs|slfp <label> <buffers> <mtu> <speed>",
#endif /* SLFP */
#endif
"Could not attach asy",
#endif
#ifdef PC100
/* PACCOMM PC-100 8530 HDLC adaptor */
"pc100", pc_attach, 8,
"attach pc100 <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
"Could not attach pc100",
#endif
#ifdef EAGLE
/* EAGLE RS-232C 8530 HDLC adaptor */
"eagle", eg_attach, 8,
"attach eagle <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
"Could not attach eagle",
#endif
#ifdef HAPN
/* Hamilton Area Packet Radio (HAPN) 8273 HDLC adaptor */
"hapn", hapn_attach, 8,
"attach hapn <address> <vector> ax25 <label> <rx bufsize> <mtu> csma|full",
"Could not attach hapn",
#endif
#ifdef APPLETALK
/* Macintosh AppleTalk */
"0", at_attach, 7,
"attach 0 <protocol type> <device> arpa <label> <rx bufsize> <mtu>",
"Could not attach Appletalk",
#endif
#ifdef NETROM
/* fake netrom interface */
"netrom", nr_attach, 1,
"attach netrom",
"Could not attach netrom",
#endif
#ifdef PACKET
/* FTP Software's packet driver spec */
"packet", pk_attach, 4,
"attach packet <int#> <label> <buffers> <mtu>",
"Could not attach packet driver",
#endif
NULLCHAR, NULLFP, 0,
"Unknown device",
NULLCHAR,
};
/* Protocol tracing function pointers */
#ifdef TRACE
int ax25_dump(),ether_dump(),ip_dump(),at_dump(),slfp_dump();
int (*tracef[])() = {
#ifdef AX25
ax25_dump,
#else
NULLFP,
#endif
#ifdef ETHER
ether_dump,
#else
NULLFP,
#endif
ip_dump,
#ifdef APPLETALK
at_dump,
#else
NULLFP,
#endif
#ifdef SLFP
slfp_dump,
#else
NULLFP,
#endif
};
#else
int (*tracef[])() = { NULLFP }; /* No tracing at all */
dump(interface,direction,type,bp)
struct interface *interface;
int direction;
unsigned type;
struct mbuf *bp;
{
}
#endif
#ifdef ASY
/* Attach a serial interface to the system
* argv[0]: hardware type, must be "asy"
* argv[1]: I/O address, e.g., "0x3f8"
* argv[2]: vector, e.g., "4"
* argv[3]: mode, may be:
* "slip" (point-to-point SLIP)
* "ax25" (AX.25 frame format in SLIP for raw TNC)
* "nrs" (NET/ROM format serial protocol)
* "slfp" (point-to-point SLFP, as used by the Merit Network and MIT
* argv[4]: interface label, e.g., "sl0"
* argv[5]: receiver ring buffer size in bytes
* argv[6]: maximum transmission unit, bytes
* argv[7]: interface speed, e.g, "9600"
* argv[8]: optional ax.25 callsign (NRS only)
* optional command string for modem (SLFP only)
* optional modem L.sys style command (SLIP only)
*/
int
asy_attach(argc,argv)
int argc;
char *argv[];
{
register struct interface *if_asy;
extern struct interface *ifaces;
int16 dev;
int mode;
int asy_init();
int asy_send();
int asy_ioctl();
void doslip();
int asy_stop();
int ax_send();
int ax_output();
void kiss_recv();
int kiss_raw();
int kiss_ioctl();
int slip_send();
void slip_recv();
int slip_raw();
#ifdef SLFP
int doslfp();
int slfp_raw();
int slfp_send();
int slfp_recv();
int slfp_init();
#endif
#ifdef AX25
struct ax25_addr addr ;
#endif
int ax_send(),ax_output(),nrs_raw(),asy_ioctl();
void nrs_recv();
if(nasy >= ASY_MAX){
printf("Too many asynch controllers\n");
return -1;
}
if(strcmp(argv[3],"slip") == 0 || strcmp(argv[3],"cslip") ==0)
mode = SLIP_MODE;
#ifdef AX25
else if(strcmp(argv[3],"ax25") == 0)
mode = AX25_MODE;
#endif
#ifdef NRS
else if(strcmp(argv[3],"nrs") == 0)
mode = NRS_MODE;
#endif
#ifdef SLFP
else if(strcmp(argv[3],"slfp") == 0)
mode = SLFP_MODE;
#endif
else {
printf("Mode %s unknown for interface %s\n",
argv[3],argv[4]);
return(-1);
}
dev = nasy++;
/* Create interface structure and fill in details */
if_asy = (struct interface *)calloc(1,sizeof(struct interface));
if_asy->name = malloc((unsigned)strlen(argv[4])+1);
strcpy(if_asy->name,argv[4]);
if_asy->mtu = atoi(argv[6]);
if_asy->dev = dev;
if_asy->recv = doslip;
if_asy->stop = asy_stop;
switch(mode){
#ifdef SLIP
case SLIP_MODE:
if_asy->ioctl = asy_ioctl;
if_asy->send = slip_send;
if_asy->output = NULLFP; /* ARP isn't used */
if_asy->raw = slip_raw;
if_asy->flags = 0;
slip[dev].recv = slip_recv;
if(strcmp(argv[3],"cslip") == 0) {
if (! slip[dev].slcomp)
slip[dev].slcomp = (char *)slhc_init(16, 16);
if (slip[dev].slcomp)
slip[dev].vjcomp = 1;
} else
slip[dev].vjcomp = 0;
break;
#endif
#ifdef AX25
case AX25_MODE: /* Set up a SLIP link to use AX.25 */
axarp();
if(mycall.call[0] == '\0'){
printf("set mycall first\n");
free(if_asy->name);
free((char *)if_asy);
nasy--;
return -1;
}
if_asy->ioctl = kiss_ioctl;
if_asy->send = ax_send;
if_asy->output = ax_output;
if_asy->raw = kiss_raw;
if(if_asy->hwaddr == NULLCHAR)
if_asy->hwaddr = malloc(sizeof(mycall));
memcpy(if_asy->hwaddr,(char *)&mycall,sizeof(mycall));
slip[dev].recv = kiss_recv;
break;
#endif
#ifdef NRS
case NRS_MODE: /* Set up a net/rom serial interface */
if(argc < 9){
/* no call supplied? */
if(mycall.call[0] == '\0'){
/* try to use default */
printf("set mycall first or specify in attach statement\n");
return -1;
} else
addr = mycall;
} else {
/* callsign supplied on attach line */
if(setcall(&addr,argv[8]) == -1){
printf ("bad callsign on attach line\n");
free(if_asy->name);
free((char *)if_asy);
nasy--;
return -1;
}
}
if_asy->recv = nrs_recv;
if_asy->ioctl = asy_ioctl;
if_asy->send = ax_send;
if_asy->output = ax_output;
if_asy->raw = nrs_raw;
if(if_asy->hwaddr == NULLCHAR)
if_asy->hwaddr = malloc(sizeof(addr));
memcpy(if_asy->hwaddr,(char *)&addr,sizeof(addr));
nrs[dev].iface = if_asy;
break;
#endif
#ifdef SLFP
case SLFP_MODE:
if_asy->ioctl = asy_ioctl;
if_asy->send = slfp_send;
if_asy->recv = doslfp;
if_asy->output = NULLFP; /* ARP isn't used */
if_asy->raw = slfp_raw;
if_asy->flags = 0;
slfp[dev].recv = slfp_recv;
break;
#endif
}
if_asy->next = ifaces;
ifaces = if_asy;
asy_init(dev,argv[1],argv[2],(unsigned)atoi(argv[5]));
asy_speed(dev,atoi(argv[7]));
/*
* optional SLIP modem command?
*/
#if defined(SLIP) && defined(MODEM_CALL)
if((mode == SLIP_MODE) && (argc > 8)) {
restricted_dev=dev;
if((modem_init(dev,argc-8,argv+8)) == -1) {
printf("\nModem command sequence failed.\n");
asy_stop(if_asy);
ifaces = if_asy->next;
free(if_asy->name);
free((char *)if_asy);
nasy--;
restricted_dev=1000;
return -1;
}
restricted_dev=1000;
return 0;
}
#endif
#ifdef SLFP
if(mode == SLFP_MODE)
if(slfp_init(if_asy, argc>7?argv[8]:NULLCHAR) == -1) {
printf("Request for IP address failed.\n");
asy_stop(if_asy);
ifaces = if_asy->next;
free(if_asy->name);
free((char *)if_asy);
nasy--;
return -1;
}
#endif
return 0;
}
#endif
#ifndef NETROM
#ifdef AX25
struct ax25_addr nr_nodebc;
#endif
nr_route(bp)
struct mbuf *bp;
{
free_p(bp);
}
nr_nodercv(bp)
{
free_p(bp);
}
#endif
/* Display or set IP interface control flags */
domode(argc,argv)
int argc;
char *argv[];
{
register struct interface *ifp;
for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
if(strcmp(argv[1],ifp->name) == 0)
break;
}
if(ifp == NULLIF){
printf("Interface \"%s\" unknown\n",argv[1]);
return 1;
}
if(argc < 3){
printf("%s: %s\n",ifp->name,
(ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
return 0;
}
switch(argv[2][0]){
case 'v':
case 'c':
case 'V':
case 'C':
ifp->flags = CONNECT_MODE;
break;
case 'd':
case 'D':
ifp->flags = DATAGRAM_MODE;
break;
default:
printf("Usage: %s [vc | datagram]\n",argv[0]);
return 1;
}
return 0;
}
#ifdef SERVERS
dostart(argc,argv)
int argc;
char *argv[];
{
return subcmd(startcmds,argc,argv);
}
dostop(argc,argv)
int argc;
char *argv[];
{
return subcmd(stopcmds,argc,argv);
}
#endif /* SERVERS */
#ifdef TRACE
static
int
dotrace(argc,argv)
int argc;
char *argv[];
{
extern int notraceall; /* trace only in command mode? */
struct interface *ifp;
if(argc < 2){
printf("trace mode is %s\n", (notraceall ? "cmdmode" : "allmode"));
printf("trace to %s\n",trfp == stdout? "console" : trname);
showtrace(&loopback);
for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
showtrace(ifp);
return 0;
}
if(strcmp("to",argv[1]) == 0){
if(argc >= 3){
if(trfp != stdout)
fclose(trfp);
if(strncmp(argv[2],"con",3) == 0)
trfp = stdout;
else {
if((trfp = fopen(argv[2],"a")) == NULLFILE){
printf("%s: cannot open\n",argv[2]);
trfp = stdout;
return 1;
}
}
strcpy(trname,argv[2]);
} else {
printf("trace to %s\n",trfp == stdout? "console" : trname);
}
return 0;
}
if(strcmp("loopback",argv[1]) == 0)
ifp = &loopback;
else if (strcmp("cmdmode", argv[1]) == 0) {
notraceall = 1;
return 0;
} else if (strcmp("allmode", argv[1]) == 0) {
notraceall = 0;
return 0;
} else if (strcmp("telnet", argv[1]) == 0) {
if (argc >= 3) {
if (strcmp(argv[2], "on") == 0)
debug_options = 1;
else
debug_options = 0;
}
printf("telnet option trace is %s\n",
debug_options ? "on" : "off");
return 0;
} else
for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
if(strcmp(ifp->name,argv[1]) == 0)
break;
if(ifp == NULLIF){
printf("Interface %s unknown\n",argv[1]);
return 1;
}
if(argc >= 3)
ifp->trace = htoi(argv[2]);
showtrace(ifp);
return 0;
}
/* Display the trace flags for a particular interface */
static
showtrace(ifp)
register struct interface *ifp;
{
if(ifp == NULLIF)
return;
printf("%s:",ifp->name);
if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT)){
if(ifp->trace & IF_TRACE_IN)
printf(" input");
if(ifp->trace & IF_TRACE_OUT)
printf(" output");
if(ifp->trace & IF_TRACE_HEX)
printf(" (Hex/ASCII dump)");
else if(ifp->trace & IF_TRACE_ASCII)
printf(" (ASCII dump)");
else
printf(" (headers only)");
printf("\n");
} else
printf(" tracing off\n");
fflush(stdout);
}
#endif
#if ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))
static
int
doescape(argc,argv)
int argc;
char *argv[];
{
if(argc < 2)
printf("0x%x\n",escape);
else
escape = *argv[1];
return 0;
}
#endif /* MSDOS */
/*ARGSUSED*/
static
doremote(argc,argv)
int argc;
char *argv[];
{
struct socket fsock,lsock;
struct mbuf *bp;
lsock.address = ip_addr;
fsock.address = resolve(argv[1]);
lsock.port = fsock.port = atoi(argv[2]);
bp = alloc_mbuf(1);
if(strcmp(argv[3],"reset") == 0){
*bp->data = SYS_RESET;
} else if(strcmp(argv[3],"exit") == 0){
*bp->data = SYS_EXIT;
} else {
printf("Unknown command %s\n",argv[3]);
return 1;
}
bp->cnt = 1;
send_udp(&lsock,&fsock,0,0,bp,0,0,0);
return 0;
}