/* 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 #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 #include #include 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 int background = 0; #endif #ifdef TRACE #include "trace.h" /* Dummy structure for loopback tracing */ struct interface loopback = { NULLIF, "loopback" }; #endif extern struct interface *ifaces; extern char version[]; extern struct mbuf *loopq; extern FILE *trfp; extern char trname[]; extern int debug_options; 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 /* 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(), xserv0(), xserv1(); #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 ", NULLCHAR, "bootp", dobootp, 0, NULLCHAR, NULLCHAR, /* This one is out of alpabetical order to allow abbreviation to "c" */ #ifdef AX25 "connect", doconnect, 3,"connect [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
", 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 ", NULLCHAR, #endif #ifdef MULPORT "mulport", mulport, 2, "mulport ", NULLCHAR, #endif #ifdef NETROM "netrom", donetrom, 0, NULLCHAR, NULLCHAR, #ifdef NRS "nrstat", donrstat, 0, NULLCHAR, NULLCHAR, #endif #endif "param", doparam, 2, "param ", 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
", 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 ",NULLCHAR, "stop", dostop, 2, "stop ", NULLCHAR, #endif "tcp", dotcp, 0, NULLCHAR, NULLCHAR, "telnet", dotelnet, 2, "telnet
", NULLCHAR, #ifdef TRACE "trace", dotrace, 0, NULLCHAR, NULLCHAR, #endif "udp", doudp, 0, NULLCHAR, NULLCHAR, "upload", doupload, 0, NULLCHAR, NULLCHAR, "wait", dowait, 0, NULLCHAR, NULLCHAR, "?", 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, "x", xserv1, 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, x", NULLCHAR, #else "start options: discard, echo, ftp, remote, smtp, telnet, telunix, x", 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, "x", xserv0, 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[]; { 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 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 #ifdef SYS5 } #endif fflush(stdout); sessions = (struct session *)calloc(nsessions,sizeof(struct session)); if(argc > 1){ /* Read startup file named on command line */ fp = fopen(argv[1],"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