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 >
C/C++ Source or Header  |  1993-09-26  |  28KB  |  1,324 lines

  1. /* Main network program - provides both client and server functions */
  2.  
  3.  
  4. #define HOSTNAMELEN 64
  5. unsigned restricted_dev=1000;
  6. extern char *startup;    /* File to read startup commands from */
  7. #include <stdio.h>
  8. #include "config.h"
  9. #include "global.h"
  10. #include "mbuf.h"
  11. #include "netuser.h"
  12. #include "timer.h"
  13. #include "icmp.h"
  14. #include "iface.h"
  15. #include "ip.h"
  16. #include "tcp.h"
  17. #include "ax25.h"
  18. #include "netrom.h"
  19. #include "ftp.h"
  20. #include "telnet.h"
  21. #include "remote.h"
  22. #include "session.h"
  23. #include "cmdparse.h"
  24.  
  25. #ifdef    ASY
  26. #include "asy.h"
  27. #include "slip.h"
  28. #endif
  29.  
  30. #ifdef    NRS
  31. #include "nrs.h"
  32. #endif
  33.  
  34. #ifdef    SLFP
  35. #include "slfp.h"
  36. #endif
  37.  
  38. #ifdef UNIX        /* BSD or SYS5 */
  39. #include "unix.h"
  40. #include <memory.h>
  41. #include <string.h>
  42. #include <sys/types.h>
  43. time_t time();
  44. #endif
  45.  
  46. #ifdef AMIGA
  47. #include "amiga.h"
  48. #endif
  49.  
  50. #ifdef MAC
  51. #include "mac.h"
  52. #endif
  53.  
  54. #ifdef MSDOS
  55. #include "asy.h"
  56. #endif
  57.  
  58. #ifdef    ATARI_ST
  59. #include "st.h"
  60.  
  61. #ifdef    LATTICE
  62. long _MNEED = 100000L;        /* Reserve RAM for subshell... */
  63. long _32K = 0x8000;        /* For GST Linker (Don't ask me! -- hyc) */
  64. #endif
  65.  
  66. #ifdef    MWC
  67. long    _stksize = 16384L;    /* Fixed stack size... -- hyc */
  68. #endif
  69. #endif    /* ATARI_ST */
  70.  
  71. #ifdef    SYS5
  72. #include <signal.h>
  73. int    background = 0;
  74. #endif
  75.  
  76. #ifdef    TRACE
  77. #include "trace.h"
  78. /* Dummy structure for loopback tracing */
  79. struct interface loopback = { NULLIF, "loopback" };
  80. #endif
  81. int ntohip();
  82. extern struct interface *ifaces;
  83. extern char version[];
  84. extern struct mbuf *loopq;
  85. extern FILE *trfp;
  86. extern char trname[];
  87. extern int debug_options;
  88.  
  89.  
  90. static showtrace();
  91.  
  92. #ifdef MALLOC_DEBUG
  93. FILE *mall_deb;
  94. #endif
  95.  
  96. int mode;
  97. FILE *logfp;
  98. char badhost[] = "Unknown host %s\n";
  99. char hostname[HOSTNAMELEN];    
  100. unsigned nsessions = NSESSIONS;
  101. int32 resolve();
  102. int16 lport = 1001;
  103. char prompt[] = "net> ";
  104. char nospace[] = "No space!!\n";    /* Generic malloc fail message */
  105. #ifdef    SYS5
  106. int io_active = 0;
  107. void daemon();
  108. #endif
  109.  
  110. /* #if ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))    */
  111. /* PC/ST uses F-10 key always */
  112. unsigned char escape = 0x1d;    /* default escape character is ^] */
  113. /* #endif */
  114. /* so why does telnet use it ? */
  115. /* I'll put it back ! */
  116.  
  117.  
  118. /* Command lookup and branch table */
  119. int go(),doax25(),cmdmode(),doconnect(),dotelnet(),doexit(),doclose(),
  120.     dohostname(),doreset(),dotcp(),dotrace(),doescape(),dohelp(),
  121.     doroute(),doecho(),dolog(),doip(),dobootp(),dodomain(),dordate(),
  122.     memstat(),doarp(),dosession(),doftp(),dostart(),dostop(),doattach(),
  123.     dosmtp(),doudp(),doparam(),doeol(),dowait(),go_mode(),
  124.     dodump(),dorecord(),doupload(),dokick(),domode(),doshell(),
  125.     dodir(),docd(),doatstat(),doping(),doforward(),doremote(),donetrom(),
  126.     donrstat(), dombox(), mulport() ;
  127.  
  128. #ifdef ETHER
  129. int doetherstat();
  130. #endif
  131. #ifdef EAGLE
  132. int doegstat();
  133. #endif
  134. #ifdef HAPN
  135. int dohapnstat();
  136. #endif
  137. #ifdef _FINGER
  138. int dofinger();
  139. #endif
  140.  
  141. static struct cmds cmds[] = {
  142.     /* The "go" command must be first */
  143.     "",        go_mode,    0, NULLCHAR,    NULLCHAR,
  144.     "!",        doshell,    0, NULLCHAR,    NULLCHAR,
  145. #if    (MAC && APPLETALK)
  146.     "applestat",    doatstat,    0,    NULLCHAR,    NULLCHAR,
  147. #endif
  148. #if    (AX25 || ETHER || APPLETALK)
  149.     "arp",        doarp,        0, NULLCHAR,    NULLCHAR,
  150. #endif
  151. #ifdef    AX25
  152.     "ax25",        doax25,        0, NULLCHAR,    NULLCHAR,
  153. #endif    
  154.     "attach",    doattach,    2,
  155.         "attach <hardware> <hw specific options>", NULLCHAR,
  156.     "bootp",    dobootp,    0, NULLCHAR,    NULLCHAR,
  157. /* This one is out of alpabetical order to allow abbreviation to "c" */
  158. #ifdef    AX25
  159.     "connect",    doconnect,    3,"connect <interface> <callsign> [digipeaters]",
  160.         NULLCHAR,
  161. #endif
  162.     "cd",        docd,        0, NULLCHAR,    NULLCHAR,
  163.     "close",    doclose,    0, NULLCHAR,    NULLCHAR,
  164.     "disconnect",    doclose,    0, NULLCHAR,    NULLCHAR,
  165.     "dir",        dodir,        0, NULLCHAR,    NULLCHAR,
  166.     "domain",    dodomain,    0, NULLCHAR,    NULLCHAR,
  167. #ifdef    EAGLE
  168.     "eaglestat",    doegstat,    0, NULLCHAR,    NULLCHAR,
  169. #endif
  170.     "echo",        doecho,        0, NULLCHAR,    "echo [refuse|accept]",
  171.     "eol",        doeol,        0, NULLCHAR,
  172.         "eol options: unix, standard",
  173. #if    ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))
  174.     "escape",    doescape,    0, NULLCHAR,    NULLCHAR,   
  175. #endif
  176. #ifdef    PC_EC 
  177.     "etherstat",    doetherstat,    0, NULLCHAR,    NULLCHAR,
  178. #endif  /* PC_EC */
  179.     "exit",        doexit,        0, NULLCHAR,    NULLCHAR,
  180. #ifdef _FINGER
  181.     "finger",    dofinger,    0, NULLCHAR, NULLCHAR,
  182. #endif
  183.     "forward",    doforward,    0, NULLCHAR,    NULLCHAR,
  184.     "ftp",        doftp,        2, "ftp <address>",    NULLCHAR,
  185. #ifdef HAPN
  186.     "hapnstat",    dohapnstat,    0, NULLCHAR,    NULLCHAR,
  187. #endif
  188.     "help",        dohelp,        0, NULLCHAR,    NULLCHAR,
  189.     "hostname",    dohostname,    0, NULLCHAR,    NULLCHAR,
  190.     "kick",        dokick,        0, NULLCHAR,    NULLCHAR,
  191.     "log",        dolog,        0, NULLCHAR,    NULLCHAR,
  192.     "ip",        doip,        0, NULLCHAR,    NULLCHAR,
  193.     "memstat",    memstat,    0, NULLCHAR,    NULLCHAR,
  194. #ifdef    AX25
  195.     "mbox",        dombox,        0, NULLCHAR,    NULLCHAR,
  196.     "mode",        domode,        2, "mode <interface>",    NULLCHAR,
  197. #endif
  198. #ifdef    MULPORT
  199.     "mulport",    mulport,    2, "mulport <on|off>",    NULLCHAR,
  200. #endif
  201. #ifdef    NETROM
  202.     "netrom",    donetrom,    0, NULLCHAR,    NULLCHAR,
  203. #ifdef    NRS
  204.     "nrstat",    donrstat,    0, NULLCHAR,    NULLCHAR,
  205. #endif
  206. #endif
  207.     "param",    doparam,    2, "param <interface>", NULLCHAR,
  208.     "ping",        doping,        0, NULLCHAR,    NULLCHAR,
  209.     "pwd",        docd,        0, NULLCHAR,    NULLCHAR,
  210.     "rdate",    dordate,    0, NULLCHAR,    NULLCHAR,
  211.     "record",    dorecord,    0, NULLCHAR,    NULLCHAR,
  212.     "remote",    doremote,    4, "remote <address> <port> <command>",
  213.                             NULLCHAR,
  214.     "reset",    doreset,    0, NULLCHAR,    NULLCHAR,
  215.     "route",    doroute,    0, NULLCHAR,    NULLCHAR,
  216.     "session",    dosession,    0, NULLCHAR,    NULLCHAR,
  217.     "shell",    doshell,    0, NULLCHAR,    NULLCHAR,
  218.     "smtp",        dosmtp,        0, NULLCHAR,    NULLCHAR,
  219. #ifdef    SERVERS
  220.     "start",    dostart,    2, "start <servername>",NULLCHAR,
  221.     "stop",        dostop,        2, "stop <servername>",    NULLCHAR,
  222. #endif
  223.     "tcp",        dotcp,        0, NULLCHAR,    NULLCHAR,
  224.     "telnet",    dotelnet,    2, "telnet <address>",    NULLCHAR,
  225. #ifdef    TRACE
  226.     "trace",    dotrace,    0, NULLCHAR,    NULLCHAR,
  227. #endif
  228.     "udp",        doudp,        0, NULLCHAR,    NULLCHAR,
  229.     "upload",    doupload,    0, NULLCHAR,    NULLCHAR,
  230. #ifdef SYS5
  231.     "wait",        dowait,        0, NULLCHAR,     NULLCHAR,
  232. #endif
  233.  
  234.     "?",        dohelp,        0, NULLCHAR,    NULLCHAR,
  235.     NULLCHAR,    NULLFP,        0,
  236.         "Unknown command; type \"?\" for list",   NULLCHAR, 
  237. };
  238.  
  239. #ifdef    SERVERS
  240. /* "start" and "stop" subcommands */
  241. int dis1(),echo1(),ftp1(),smtp1(),tn1(),rem1();
  242.  
  243. #ifdef UNIX
  244. int tnix1();
  245. #endif
  246.  
  247. #ifdef _FINGER
  248. int finger1();
  249. #endif
  250.  
  251. static struct cmds startcmds[] = {
  252.     "discard",    dis1,        0, NULLCHAR, NULLCHAR,
  253.     "echo",        echo1,        0, NULLCHAR, NULLCHAR,
  254. #ifdef _FINGER
  255.     "finger",    finger1,    0, NULLCHAR, NULLCHAR,
  256. #endif
  257.     "ftp",        ftp1,        0, NULLCHAR, NULLCHAR,
  258.     "smtp",        smtp1,        0, NULLCHAR, NULLCHAR,
  259.     "telnet",    tn1,        0, NULLCHAR, NULLCHAR,
  260. #ifdef    UNIX
  261.     "telunix",    tnix1,        0, NULLCHAR, NULLCHAR,
  262. #endif
  263.     "remote",    rem1,        0, NULLCHAR, NULLCHAR,
  264.     NULLCHAR,    NULLFP,        0,
  265. #ifdef UNIX
  266. #ifdef _FINGER
  267.         "start options: discard, echo, finger, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  268. #else
  269.         "start options: discard, echo, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  270. #endif
  271. #else /* UNIX */
  272. #ifdef _FINGER
  273.         "start options: discard, echo, finger, ftp, remote, smtp, telnet", NULLCHAR,
  274. #else
  275.         "start options: discard, echo, ftp, remote, smtp, telnet", NULLCHAR,
  276. #endif
  277. #endif /* UNIX */
  278. };
  279. int ftp_stop(),smtp_stop(),echo_stop(),dis_stop(),tn_stop();
  280. int dis0(),echo0(),ftp0(),smtp0(),tn0(),rem0();
  281.  
  282. #ifdef UNIX
  283. int tnix0();
  284. #endif
  285.  
  286. #ifdef _FINGER
  287. int finger0();
  288. #endif
  289.  
  290. static struct cmds stopcmds[] = {
  291.     "discard",    dis0,        0, NULLCHAR, NULLCHAR,
  292.     "echo",        echo0,        0, NULLCHAR, NULLCHAR,
  293. #ifdef _FINGER
  294.     "finger",    finger0,    0, NULLCHAR, NULLCHAR,
  295. #endif
  296.     "ftp",        ftp0,        0, NULLCHAR, NULLCHAR,
  297.     "smtp",        smtp0,        0, NULLCHAR, NULLCHAR,
  298.     "telnet",    tn0,        0, NULLCHAR, NULLCHAR,
  299. #ifdef UNIX
  300.     "telunix",    tnix0,        0, NULLCHAR, NULLCHAR,
  301. #endif
  302.     "remote",    rem0,        0, NULLCHAR, NULLCHAR,
  303.     NULLCHAR,    NULLFP,        0,
  304. #ifdef UNIX
  305. #ifdef _FINGER
  306.         "stop options: discard, echo, finger, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  307. #else
  308.         "stop options: discard, echo, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  309. #endif
  310. #else /* UNIX */
  311. #ifdef _FINGER
  312.         "stop options: discard, echo, finger, ftp, remote, smtp, telnet", NULLCHAR,
  313. #else
  314.         "stop options: discard, echo, ftp, remote, smtp, telnet", NULLCHAR,
  315. #endif
  316. #endif /* UNIX */
  317. };
  318. #endif
  319.  
  320. void
  321. keep_things_going()
  322. {
  323.     void check_time(), ip_recv();
  324.     struct interface *ifp;
  325.     struct mbuf *bp;
  326.  
  327.     /* Service the loopback queue */
  328.     if((bp = dequeue(&loopq)) != NULLBUF){
  329.         struct ip ip;
  330. #ifdef    TRACE
  331.         dump(&loopback,IF_TRACE_IN,TRACE_IP,bp);        
  332. #endif
  333.         /* Extract IP header */
  334.         ntohip(&ip,&bp);
  335.         ip_recv(&ip,bp,0);
  336.     }
  337.     /* Service the interfaces */
  338. #ifdef    SYS5
  339.     do {
  340.     io_active = 0;
  341. #endif
  342.     for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next){
  343.         if(ifp->recv != NULLVFP)
  344.             (*ifp->recv)(ifp);
  345.     }
  346. #ifdef    SYS5
  347.     } while(io_active);
  348. #endif
  349.  
  350. #ifdef    XOBBS
  351.     /* service the W2XO PBBS code */
  352.     axchk();
  353. #endif
  354.  
  355.  
  356.  
  357.     /* Service the clock if it has ticked */
  358.     check_time();
  359.  
  360. #ifdef    MSDOS
  361.     /* Tell DoubleDos to let the other task run for awhile.
  362.      * If DoubleDos isn't active, this is a no-op
  363.      */
  364. #ifndef PLUS
  365.     giveup();
  366. #endif
  367. #else
  368.     /* Wait until interrupt, then do it all over again */
  369.     eihalt();
  370. #endif
  371. }
  372.  
  373. main(argc,argv)
  374. int argc;
  375. char *argv[];
  376. {
  377.   int nextarg;
  378.   static char inbuf[BUFSIZ];    /* keep it off the stack */
  379.   int c;
  380.   char *ttybuf,*fgets();
  381.     int16 cnt;
  382.     int ttydriv();
  383.     int cmdparse();
  384.     void check_time(),ip_recv();
  385.     FILE *fp;
  386. #ifdef    FLOW
  387.     extern int ttyflow;
  388. #endif
  389.  
  390. #ifdef MALLOC_DEBUG
  391.  
  392.   printf("**************** warning  MALLOC DEBUG is active **************\n");
  393.   mall_deb=fopen("malloc.deb","w");
  394.   if(!mall_deb) {
  395.     printf(" cannot open malloc.deb\n");
  396.     exit(1);
  397.   }
  398.   
  399. #endif
  400.  
  401. #ifdef    UNIX
  402.     fileinit(argv[0]);
  403. #endif
  404.     
  405.  
  406.  
  407. #ifdef    SYS5
  408.     if (signal(SIGINT, SIG_IGN) == SIG_IGN) {
  409.         background++;
  410.         daemon();
  411.     } else
  412.         ioinit();
  413. #else
  414.     ioinit();
  415. #endif
  416.  
  417. #ifdef PLUS
  418. /*
  419.  * set: cursor to block, attributes off, keyboard to ALT mode, 
  420.  *      transmit functions off, use HP fonts
  421.  */
  422.     printf(   "\033&d@"     /* display attributes off         */
  423.                   "\033[11m");  /* use ALT fonts                  */
  424. #endif
  425. #ifdef    MSDOS
  426. #ifndef PLUS
  427.     chktasker();
  428. #endif
  429. #endif
  430. #ifdef    MSDOS
  431.     printf("KA9Q Internet Protocol Package, v%s DS = %x\n",version,
  432.         getds());
  433. #else
  434. #ifdef    SYS5
  435.     if (!background) {
  436. #endif
  437.         printf("KA9Q Internet Protocol Package, v%s\n",version);
  438. #endif
  439.         printf("Copyright 1988 by Phil Karn, KA9Q\n");
  440. #ifdef NETROM
  441.         printf("NET/ROM Support Copyright 1989 by Dan Frank, W9NK\n") ;
  442. #endif
  443.         printf("Based on the version 890421.1a.linux.3 (n6xjj clh)\n");
  444.         printf("Bug reports for dje version can be mailed to:\n");
  445.         printf("Internet: devans@hclb.demon.co.uk\n");
  446.         printf("Cix:      devans@cix.compulink.co.uk ( from UK sites only!)\n");
  447.         nextarg=1;
  448.         if(argc>1)
  449.         if(!strcmp(argv[nextarg],"-x")){
  450.           display_file_names();
  451.           nextarg++;
  452.          }
  453. #ifdef    SYS5
  454.     }
  455. #endif
  456.     fflush(stdout);
  457.     sessions = (struct session *)calloc(nsessions,sizeof(struct session));
  458.     if(argc  > nextarg ){
  459.         /* Read startup file named on command line */
  460.         fp = fopen(argv[nextarg],"r");
  461.     } else {
  462.         fp = fopen(startup,"r");
  463.     }
  464.     if(fp != NULLFILE){
  465.         while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
  466.             cmdparse(cmds,inbuf);
  467.         }
  468.         fclose(fp);
  469.     }        
  470. #ifdef XOBBS
  471.     axinit();
  472. #endif
  473.     cmdmode();
  474.  
  475.     /* Main commutator loop */
  476.     for(;;){
  477.         /* Process any keyboard input */
  478. #ifdef    SYS5
  479.         while((background == 0) && ((c = kbread()) != -1)){
  480. #else
  481.         while((c = kbread()) != -1){
  482. #endif
  483. #if    (defined(MSDOS) || defined(ATARI_ST))
  484.             /* c == -2 means the command escape key (F10) */
  485.             if(c == -2){
  486.                 if(mode != CMD_MODE){
  487.                     printf("\n");
  488.                     cmdmode();
  489.                 }
  490.                 continue;
  491.             }
  492. #endif
  493. #ifdef undef
  494. /* #ifdef SYS5 */
  495.             if(c == escape && escape != 0){
  496.                 if(mode != CMD_MODE){
  497.                     printf("\r\n");
  498.                     cmdmode();
  499.                 }
  500.                 continue;
  501.             }
  502. #endif     /* SYS5 */
  503.  
  504. #ifndef    FLOW
  505.             if ((cnt = ttydriv(c, &ttybuf)) == 0)
  506.                 continue;
  507. #else
  508.             cnt = ttydriv(c, &ttybuf);
  509.             if (ttyflow && (mode != CMD_MODE))
  510.                 go();        /* display pending chars */
  511.             if (cnt == 0)
  512.                 continue;
  513. #endif    /* FLOW */
  514. #ifdef undef
  515. /* #if    (!defined(MSDOS) && !defined(ATARI_ST)) */
  516.             if((ttybuf[0] == escape) && (escape != 0)) {
  517.                 if(mode != CMD_MODE){
  518.                     printf("\r\n");
  519.                     cmdmode();
  520.                 }
  521.                 continue;
  522.             }
  523. #endif
  524.             switch(mode){
  525.             case CMD_MODE:
  526.                 (void)cmdparse(cmds,ttybuf);
  527.                 fflush(stdout);
  528.                 break;
  529.             case CONV_MODE:
  530. #ifdef undef
  531. /* #if    ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801)) */
  532.                 if(ttybuf[0] == escape && escape != 0){
  533.                     printf("\n");
  534.                     cmdmode();
  535.                 } else
  536. #endif    /* MSDOS */
  537.                     if(current->parse != NULLFP) 
  538.                         (*current->parse)(ttybuf,cnt);
  539.                 break;
  540.             }
  541.             if(mode == CMD_MODE){
  542.                 printf(prompt);
  543.                 fflush(stdout);
  544.             }
  545.         }
  546.         keep_things_going();
  547.     }
  548. }
  549. /* Standard commands called from main */
  550.  
  551. /* Enter command mode */
  552. int
  553. cmdmode()
  554. {
  555.     if(mode != CMD_MODE){
  556.         mode = CMD_MODE;
  557.         cooked();
  558.         flowdefault();
  559.         printf(prompt);
  560.         fflush(stdout);
  561.     }
  562.     return 0;
  563. }
  564. static
  565. doexit()
  566. {
  567.     void iostop();
  568.  
  569. #if    defined(PLUS)
  570. /*
  571.  * set: cursor to block, attributes off, keyboard to HP mode,
  572.  *      transmit functions off, use HP fonts
  573.  */
  574.     printf(/* "\033*dK"       cursor to block        */
  575.               "\033&d@"    /* display attributes off      */
  576.            /* "\033&k0\\"       KBD to HP mode        */
  577.            /* "\033&s0A"       transmit functions off    */
  578.               "\033[10m");    /* use HP fonts            */
  579. #endif
  580.     if(logfp != NULLFILE)
  581.         fclose(logfp);
  582. #ifdef    SYS5
  583.     if (!background)
  584.         iostop();
  585. #else
  586.     iostop();
  587. #endif
  588. #ifdef TRACE
  589.     if (trfp != stdout) 
  590.       fclose(trfp);
  591. #endif
  592.     exit(0);
  593. }
  594. static
  595. dohostname(argc,argv)
  596. int argc;
  597. char *argv[];
  598. {
  599.     char *strncpy();
  600.  
  601.     if(argc < 2)
  602.         printf("%s\n",hostname);
  603.     else 
  604.         strncpy(hostname,argv[1],HOSTNAMELEN);
  605.     return 0;
  606. }
  607. static
  608. int
  609. dolog(argc,argv)
  610. int argc;
  611. char *argv[];
  612. {
  613.     char *strncpy();
  614.  
  615. #ifdef    UNIX
  616.     static char logname[256];
  617. #else
  618.     static char logname[15];
  619. #endif
  620.     if(argc < 2){
  621.         if(logfp)
  622.             printf("Logging to %s\n",logname);
  623.         else
  624.             printf("Logging off\n");
  625.         return 0;
  626.     }
  627.     if(logfp){
  628.         fclose(logfp);
  629.         logfp = NULLFILE;
  630.     }
  631.     if(strcmp(argv[1],"stop") != 0){
  632. #ifdef    UNIX
  633.         strncpy(logname,argv[1],sizeof(logname));
  634. #else
  635.         strncpy(logname,argv[1],15);
  636. #endif
  637.         logfp = fopen(logname,"a+");
  638.     }
  639.     return 0;
  640. }
  641. static
  642. int
  643. dohelp()
  644. {
  645.     register struct cmds *cmdp;
  646.     int i,j;
  647.  
  648.     printf("Main commands:\n");
  649.     for(i=0,cmdp = cmds;cmdp->name != NULL;cmdp++,i++){
  650.         printf("%s",cmdp->name);
  651.         if((i % 4) == 3)
  652.             printf("\n");
  653.         else {
  654.             for(j=strlen(cmdp->name);j < 16; j++)
  655.                 putchar(' ');
  656.         }
  657.     }
  658.     if((i % 4) != 0)
  659.         printf("\n");
  660.     return 0;
  661. }
  662.  
  663. doecho(argc,argv)
  664. int argc;
  665. char *argv[];
  666. {
  667.     extern int refuse_echo;
  668.  
  669.     if(argc < 2){
  670.         if(refuse_echo)
  671.             printf("Refuse\n");
  672.         else
  673.             printf("Accept\n");
  674.     } else {
  675.         if(argv[1][0] == 'r')
  676.             refuse_echo = 1;
  677.         else if(argv[1][0] == 'a')
  678.             refuse_echo = 0;
  679.         else
  680.             return -1;
  681.     }
  682.     return 0;
  683. }
  684. /* set for unix end of line for remote echo mode telnet */
  685. doeol(argc,argv)
  686. int argc;
  687. char *argv[];
  688. {
  689.     extern int unix_line_mode;
  690.  
  691.     if(argc < 2){
  692.         if(unix_line_mode)
  693.             printf("Unix\n");
  694.         else
  695.             printf("Standard\n");
  696.     } else {
  697.         if(strcmp(argv[1],"unix") == 0)
  698.             unix_line_mode = 1;
  699.         else if(strcmp(argv[1],"standard") == 0)
  700.             unix_line_mode = 0;
  701.         else {
  702.             return -1;
  703.         }
  704.     }
  705.     return 0;
  706. }
  707. /* Attach an interface
  708.  * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
  709.  */
  710. doattach(argc,argv)
  711. int argc;
  712. char *argv[];
  713. {
  714.     extern struct cmds attab[];
  715.  
  716.     return subcmd(attab,argc,argv);
  717. }
  718. /* Manipulate I/O device parameters */
  719. doparam(argc,argv)
  720. int argc;
  721. char *argv[];
  722. {
  723.     register struct interface *ifp;
  724.  
  725.     for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  726.         if(strcmp(argv[1],ifp->name) == 0)
  727.             break;
  728.     }
  729.     if(ifp == NULLIF){
  730.         printf("Interface \"%s\" unknown\n",argv[1]);
  731.         return 1;
  732.     }
  733.     if(ifp->ioctl == NULLFP){
  734.         printf("Not supported\n");
  735.         return 1;
  736.     }
  737.     /* Pass rest of args to device-specific code */
  738.     return (*ifp->ioctl)(ifp,argc-2,argv+2);
  739. }
  740. /* Log messages of the form
  741.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  742.  */
  743. /*VARARGS2*/
  744. log(tcb,fmt,arg1,arg2,arg3,arg4)
  745. struct tcb *tcb;
  746. char *fmt;
  747. int32 arg1,arg2,arg3,arg4;
  748. {
  749.     char *cp;
  750.     long t;
  751. #if    (defined(MSDOS) || defined(ATARI_ST))
  752.     int fd;
  753. #endif
  754.  
  755.     if(logfp == NULLFILE)
  756.         return;
  757.     time(&t);
  758.     cp = ctime(&t);
  759.     rip(cp);
  760.     if (tcb)
  761.         fprintf(logfp,"%s %s - ",cp,psocket(&tcb->conn.remote));
  762.     else
  763.         fprintf(logfp,"%s - ",cp);
  764.     fprintf(logfp,fmt,arg1,arg2,arg3,arg4);
  765.     fprintf(logfp,"\n");
  766.     fflush(logfp);
  767. #if    (defined(MSDOS) || defined(ATARI_ST))
  768.     /* MS-DOS doesn't really flush files until they're closed */
  769.     fd = fileno(logfp);
  770.     if((fd = dup(fd)) != -1)
  771.         close(fd);
  772. #endif
  773. }
  774. /* Configuration-dependent code */
  775.  
  776. /* List of supported hardware devices */
  777. int modem_init(),asy_attach(),pc_attach(),at_attach(),nr_attach();
  778.  
  779. #ifdef    EAGLE
  780. int eg_attach();
  781. #endif
  782. #ifdef    HAPN
  783. int hapn_attach();
  784. #endif
  785. #ifdef    PC_EC
  786. int ec_attach();
  787. #endif
  788. #ifdef LINUX_ETH
  789. int linux_attach();
  790. #endif
  791. #ifdef    PACKET
  792. int pk_attach();
  793. #endif
  794.  
  795. struct cmds attab[] = {
  796. #ifdef    PC_EC
  797.     /* 3-Com Ethernet interface */
  798.     "3c500", ec_attach, 7, 
  799.     "attach 3c500 <address> <vector> arpa <label> <buffers> <mtu>",
  800.     "Could not attach 3c500",
  801. #endif
  802. #ifdef LINUX_ETH
  803.     /* linux Ethernet interface */
  804.     "linux", linux_attach, 5, 
  805.     "attach linux arpa <label> <mtu> <hex ether address as 1.2.3.4.5.6>",
  806.     "Could not attach linux ethernet",
  807. #endif
  808. #ifdef    ASY
  809.     /* Ordinary PC asynchronous adaptor */
  810.     "asy", asy_attach, 8, 
  811. #ifdef    UNIX
  812. #ifndef    SLFP
  813.     "attach asy 0 <ttyname> slip|ax25|nrs <label> <buffers> <mtu> <speed>",
  814. #else
  815.     "attach asy 0 <ttyname> slip|ax25|nrs|slfp <label> <buffers> <mtu> <speed>",
  816. #endif    /* SLFP */
  817. #else
  818. #ifndef    SLFP
  819.     "attach asy <address> <vector> slip|ax25|nrs <label> <buffers> <mtu> <speed>",
  820. #else
  821.     "attach asy <address> <vector> slip|ax25|nrs|slfp <label> <buffers> <mtu> <speed>",
  822. #endif    /* SLFP */
  823. #endif
  824.     "Could not attach asy",
  825. #endif
  826. #ifdef    PC100
  827.     /* PACCOMM PC-100 8530 HDLC adaptor */
  828.     "pc100", pc_attach, 8, 
  829.     "attach pc100 <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
  830.     "Could not attach pc100",
  831. #endif
  832. #ifdef    EAGLE
  833.     /* EAGLE RS-232C 8530 HDLC adaptor */
  834.     "eagle", eg_attach, 8,
  835.     "attach eagle <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
  836.     "Could not attach eagle",
  837. #endif
  838. #ifdef    HAPN
  839.     /* Hamilton Area Packet Radio (HAPN) 8273 HDLC adaptor */
  840.     "hapn", hapn_attach, 8,
  841.     "attach hapn <address> <vector> ax25 <label> <rx bufsize> <mtu> csma|full",
  842.     "Could not attach hapn",
  843. #endif
  844. #ifdef    APPLETALK
  845.     /* Macintosh AppleTalk */
  846.     "0", at_attach, 7,
  847.     "attach 0 <protocol type> <device> arpa <label> <rx bufsize> <mtu>",
  848.     "Could not attach Appletalk",
  849. #endif
  850. #ifdef NETROM
  851.     /* fake netrom interface */
  852.     "netrom", nr_attach, 1,
  853.     "attach netrom",
  854.     "Could not attach netrom",
  855. #endif
  856. #ifdef    PACKET
  857.     /* FTP Software's packet driver spec */
  858.     "packet", pk_attach, 4,
  859.     "attach packet <int#> <label> <buffers> <mtu>",
  860.     "Could not attach packet driver",
  861. #endif
  862.     NULLCHAR, NULLFP, 0,
  863.     "Unknown device",
  864.     NULLCHAR,
  865. };
  866.  
  867. /* Protocol tracing function pointers */
  868. #ifdef    TRACE
  869. int ax25_dump(),ether_dump(),ip_dump(),at_dump(),slfp_dump();
  870.  
  871. int (*tracef[])() = {
  872. #ifdef    AX25
  873.     ax25_dump,
  874. #else
  875.     NULLFP,
  876. #endif
  877.  
  878. #ifdef    ETHER
  879.     ether_dump,
  880. #else
  881.     NULLFP,
  882. #endif
  883.     ip_dump,
  884.  
  885. #ifdef    APPLETALK
  886.     at_dump,
  887. #else
  888.     NULLFP,
  889. #endif
  890.  
  891. #ifdef    SLFP
  892.     slfp_dump,
  893. #else
  894.     NULLFP,
  895. #endif
  896. };
  897. #else
  898. int (*tracef[])() = { NULLFP };    /* No tracing at all */
  899. dump(interface,direction,type,bp)
  900. struct interface *interface;
  901. int direction;
  902. unsigned type;
  903. struct mbuf *bp;
  904. {
  905. }
  906. #endif
  907.  
  908. #ifdef    ASY
  909.  
  910. /* Attach a serial interface to the system
  911.  * argv[0]: hardware type, must be "asy"
  912.  * argv[1]: I/O address, e.g., "0x3f8"
  913.  * argv[2]: vector, e.g., "4"
  914.  * argv[3]: mode, may be:
  915.  *        "slip" (point-to-point SLIP)
  916.  *        "ax25" (AX.25 frame format in SLIP for raw TNC)
  917.  *        "nrs" (NET/ROM format serial protocol)
  918.  *        "slfp" (point-to-point SLFP, as used by the Merit Network and MIT
  919.  * argv[4]: interface label, e.g., "sl0"
  920.  * argv[5]: receiver ring buffer size in bytes
  921.  * argv[6]: maximum transmission unit, bytes
  922.  * argv[7]: interface speed, e.g, "9600"
  923.  * argv[8]: optional ax.25 callsign (NRS only)
  924.  *        optional command string for modem (SLFP only)
  925.  *          optional modem L.sys style command (SLIP only)
  926.  */
  927. int
  928. asy_attach(argc,argv)
  929. int argc;
  930. char *argv[];
  931. {
  932.     register struct interface *if_asy;
  933.     extern struct interface *ifaces;
  934.     int16 dev;
  935.     int mode;
  936.     int asy_init();
  937.     int asy_send();
  938.     int asy_ioctl();
  939.     void doslip();
  940.     int asy_stop();
  941.     int ax_send();
  942.     int ax_output();
  943.     void kiss_recv();
  944.     int kiss_raw();
  945.     int kiss_ioctl();
  946.     int slip_send();
  947.     void slip_recv();
  948.     int slip_raw();
  949.  
  950. #ifdef    SLFP
  951.     int doslfp();
  952.     int slfp_raw();
  953.     int slfp_send();
  954.     int slfp_recv();
  955.     int slfp_init();
  956. #endif
  957.  
  958. #ifdef    AX25
  959.     struct ax25_addr addr ;
  960. #endif
  961.     int ax_send(),ax_output(),nrs_raw(),asy_ioctl();
  962.     void nrs_recv();
  963.  
  964.     if(nasy >= ASY_MAX){
  965.         printf("Too many asynch controllers\n");
  966.         return -1;
  967.     }
  968.     if(strcmp(argv[3],"slip") == 0 || strcmp(argv[3],"cslip") ==0)
  969.         mode = SLIP_MODE;
  970. #ifdef    AX25
  971.     else if(strcmp(argv[3],"ax25") == 0)
  972.         mode = AX25_MODE;
  973. #endif
  974. #ifdef    NRS
  975.     else if(strcmp(argv[3],"nrs") == 0)
  976.         mode = NRS_MODE;
  977. #endif
  978. #ifdef    SLFP
  979.     else if(strcmp(argv[3],"slfp") == 0)
  980.         mode = SLFP_MODE;
  981. #endif
  982.     else {
  983.         printf("Mode %s unknown for interface %s\n",
  984.             argv[3],argv[4]);
  985.         return(-1);
  986.     }
  987.  
  988.     dev = nasy++;
  989.  
  990.     /* Create interface structure and fill in details */
  991.     if_asy = (struct interface *)calloc(1,sizeof(struct interface));
  992.     if_asy->name = malloc((unsigned)strlen(argv[4])+1);
  993.     strcpy(if_asy->name,argv[4]);
  994.     if_asy->mtu = atoi(argv[6]);
  995.     if_asy->dev = dev;
  996.     if_asy->recv = doslip;
  997.     if_asy->stop = asy_stop;
  998.  
  999.     switch(mode){
  1000. #ifdef    SLIP
  1001.     case SLIP_MODE:
  1002.         if_asy->ioctl = asy_ioctl;
  1003.         if_asy->send = slip_send;
  1004.         if_asy->output = NULLFP;    /* ARP isn't used */
  1005.         if_asy->raw = slip_raw;
  1006.         if_asy->flags = 0;
  1007.         slip[dev].recv = slip_recv;
  1008.         if(strcmp(argv[3],"cslip") == 0) {
  1009.           if (! slip[dev].slcomp)
  1010.             slip[dev].slcomp = (char *)slhc_init(16, 16);
  1011.           if (slip[dev].slcomp)
  1012.             slip[dev].vjcomp = 1;
  1013.         } else
  1014.           slip[dev].vjcomp = 0;
  1015.         break;
  1016. #endif
  1017. #ifdef    AX25
  1018.     case AX25_MODE:  /* Set up a SLIP link to use AX.25 */
  1019.         axarp();
  1020.         if(mycall.call[0] == '\0'){
  1021.             printf("set mycall first\n");
  1022.             free(if_asy->name);
  1023.             free((char *)if_asy);
  1024.             nasy--;
  1025.             return -1;
  1026.         }
  1027.         if_asy->ioctl = kiss_ioctl;
  1028.         if_asy->send = ax_send;
  1029.         if_asy->output = ax_output;
  1030.         if_asy->raw = kiss_raw;
  1031.         if(if_asy->hwaddr == NULLCHAR)
  1032.             if_asy->hwaddr = malloc(sizeof(mycall));
  1033.         memcpy(if_asy->hwaddr,(char *)&mycall,sizeof(mycall));
  1034.         slip[dev].recv = kiss_recv;
  1035.         break;
  1036. #endif
  1037. #ifdef    NRS
  1038.     case NRS_MODE: /* Set up a net/rom serial interface */
  1039.         if(argc < 9){
  1040.             /* no call supplied? */
  1041.             if(mycall.call[0] == '\0'){
  1042.                 /* try to use default */
  1043.                 printf("set mycall first or specify in attach statement\n");
  1044.                 return -1;
  1045.             } else
  1046.                 addr = mycall;
  1047.         } else {
  1048.             /* callsign supplied on attach line */
  1049.             if(setcall(&addr,argv[8]) == -1){
  1050.                 printf ("bad callsign on attach line\n");
  1051.                 free(if_asy->name);
  1052.                 free((char *)if_asy);
  1053.                 nasy--;
  1054.                 return -1;
  1055.             }
  1056.         }
  1057.         if_asy->recv = nrs_recv;
  1058.         if_asy->ioctl = asy_ioctl;
  1059.         if_asy->send = ax_send;
  1060.         if_asy->output = ax_output;
  1061.         if_asy->raw = nrs_raw;
  1062.         if(if_asy->hwaddr == NULLCHAR)
  1063.             if_asy->hwaddr = malloc(sizeof(addr));
  1064.         memcpy(if_asy->hwaddr,(char *)&addr,sizeof(addr));
  1065.         nrs[dev].iface = if_asy;
  1066.         break;
  1067. #endif
  1068. #ifdef    SLFP
  1069.     case SLFP_MODE:
  1070.         if_asy->ioctl = asy_ioctl;
  1071.         if_asy->send = slfp_send;
  1072.         if_asy->recv = doslfp;
  1073.         if_asy->output = NULLFP;    /* ARP isn't used */
  1074.         if_asy->raw = slfp_raw;
  1075.         if_asy->flags = 0;
  1076.         slfp[dev].recv = slfp_recv;
  1077.         break;
  1078. #endif
  1079.     }
  1080.     if_asy->next = ifaces;
  1081.     ifaces = if_asy;
  1082.     asy_init(dev,argv[1],argv[2],(unsigned)atoi(argv[5]));
  1083.     asy_speed(dev,atoi(argv[7]));
  1084. /*
  1085.  * optional SLIP modem command?
  1086.  */
  1087. #if defined(SLIP) && defined(MODEM_CALL)
  1088.     if((mode == SLIP_MODE) && (argc > 8)) {
  1089.         restricted_dev=dev;
  1090.         if((modem_init(dev,argc-8,argv+8)) == -1) {
  1091.         printf("\nModem command sequence failed.\n");
  1092.         asy_stop(if_asy);
  1093.         ifaces = if_asy->next;
  1094.         free(if_asy->name);
  1095.         free((char *)if_asy);
  1096.         nasy--;
  1097.         restricted_dev=1000;
  1098.         return -1;
  1099.         }
  1100.         restricted_dev=1000;
  1101.         return 0;
  1102.     }
  1103. #endif
  1104. #ifdef    SLFP
  1105.     if(mode == SLFP_MODE)
  1106.         if(slfp_init(if_asy, argc>7?argv[8]:NULLCHAR) == -1) {
  1107.         printf("Request for IP address failed.\n");
  1108.         asy_stop(if_asy);
  1109.         ifaces = if_asy->next;
  1110.         free(if_asy->name);
  1111.         free((char *)if_asy);
  1112.         nasy--;
  1113.         return -1;
  1114.         }
  1115. #endif
  1116.     return 0;
  1117. }
  1118. #endif
  1119. #ifndef    NETROM
  1120. #ifdef    AX25
  1121. struct ax25_addr nr_nodebc;
  1122. #endif
  1123. nr_route(bp)
  1124. struct mbuf *bp;
  1125. {
  1126.     free_p(bp);
  1127. }
  1128. nr_nodercv(bp)
  1129. {
  1130.     free_p(bp);
  1131. }
  1132. #endif
  1133.  
  1134.  
  1135. /* Display or set IP interface control flags */
  1136. domode(argc,argv)
  1137. int argc;
  1138. char *argv[];
  1139. {
  1140.     register struct interface *ifp;
  1141.  
  1142.     for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  1143.         if(strcmp(argv[1],ifp->name) == 0)
  1144.             break;
  1145.     }
  1146.     if(ifp == NULLIF){
  1147.         printf("Interface \"%s\" unknown\n",argv[1]);
  1148.         return 1;
  1149.     }
  1150.     if(argc < 3){
  1151.         printf("%s: %s\n",ifp->name,
  1152.          (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
  1153.         return 0;
  1154.     }
  1155.     switch(argv[2][0]){
  1156.     case 'v':
  1157.     case 'c':
  1158.     case 'V':
  1159.     case 'C':
  1160.         ifp->flags = CONNECT_MODE;
  1161.         break;
  1162.     case 'd':
  1163.     case 'D':
  1164.         ifp->flags = DATAGRAM_MODE;
  1165.         break;
  1166.     default:
  1167.         printf("Usage: %s [vc | datagram]\n",argv[0]);
  1168.         return 1;
  1169.     }
  1170.     return 0;
  1171. }
  1172.  
  1173. #ifdef SERVERS
  1174. dostart(argc,argv)
  1175. int argc;
  1176. char *argv[];
  1177. {
  1178.     return subcmd(startcmds,argc,argv);
  1179. }
  1180. dostop(argc,argv)
  1181. int argc;
  1182. char *argv[];
  1183. {
  1184.     return subcmd(stopcmds,argc,argv);
  1185. }
  1186. #endif /* SERVERS */
  1187.  
  1188. #ifdef    TRACE
  1189. static
  1190. int
  1191. dotrace(argc,argv)
  1192. int argc;
  1193. char *argv[];
  1194. {
  1195.         extern int notraceall;  /* trace only in command mode? */
  1196.     struct interface *ifp;
  1197.  
  1198.     if(argc < 2){
  1199.          printf("trace mode is %s\n", (notraceall ? "cmdmode" : "allmode"));
  1200.             printf("trace to %s\n",trfp == stdout? "console" : trname);
  1201.         showtrace(&loopback);
  1202.         for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  1203.             showtrace(ifp);
  1204.         return 0;
  1205.     }
  1206.     if(strcmp("to",argv[1]) == 0){
  1207.         if(argc >= 3){
  1208.             if(trfp != stdout)
  1209.                 fclose(trfp);
  1210.             if(strncmp(argv[2],"con",3) == 0)
  1211.                 trfp = stdout;
  1212.             else {
  1213.                 if((trfp = fopen(argv[2],"a")) == NULLFILE){
  1214.                     printf("%s: cannot open\n",argv[2]);
  1215.                     trfp = stdout;
  1216.                     return 1;
  1217.                 }
  1218.             }
  1219.             strcpy(trname,argv[2]);
  1220.         } else {
  1221.             printf("trace to %s\n",trfp == stdout? "console" : trname);
  1222.         }
  1223.         return 0;
  1224.     }
  1225.     if(strcmp("loopback",argv[1]) == 0)
  1226.         ifp = &loopback;
  1227.      else if (strcmp("cmdmode", argv[1]) == 0) {
  1228.          notraceall = 1;
  1229.          return 0;
  1230.      } else if (strcmp("allmode", argv[1]) == 0) {
  1231.          notraceall = 0;
  1232.          return 0;
  1233.     } else if (strcmp("telnet", argv[1]) == 0) {
  1234.         if (argc >= 3) {
  1235.           if (strcmp(argv[2], "on") == 0)
  1236.             debug_options = 1;
  1237.           else
  1238.             debug_options = 0;
  1239.         }
  1240.         printf("telnet option trace is %s\n", 
  1241.                debug_options ? "on" : "off");
  1242.         return 0;
  1243.      } else
  1244.         for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  1245.             if(strcmp(ifp->name,argv[1]) == 0)
  1246.                 break;
  1247.  
  1248.     if(ifp == NULLIF){
  1249.         printf("Interface %s unknown\n",argv[1]);
  1250.         return 1;
  1251.     }
  1252.     if(argc >= 3)
  1253.         ifp->trace = htoi(argv[2]);
  1254.  
  1255.     showtrace(ifp);
  1256.     return 0;
  1257. }
  1258. /* Display the trace flags for a particular interface */
  1259. static
  1260. showtrace(ifp)
  1261. register struct interface *ifp;
  1262. {
  1263.     if(ifp == NULLIF)
  1264.         return;
  1265.     printf("%s:",ifp->name);
  1266.     if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT)){
  1267.         if(ifp->trace & IF_TRACE_IN)
  1268.             printf(" input");
  1269.         if(ifp->trace & IF_TRACE_OUT)
  1270.             printf(" output");
  1271.  
  1272.         if(ifp->trace & IF_TRACE_HEX)
  1273.             printf(" (Hex/ASCII dump)");
  1274.         else if(ifp->trace & IF_TRACE_ASCII)
  1275.             printf(" (ASCII dump)");
  1276.         else
  1277.             printf(" (headers only)");
  1278.         printf("\n");
  1279.     } else
  1280.         printf(" tracing off\n");
  1281.     fflush(stdout);
  1282. }
  1283. #endif
  1284.  
  1285. #if    ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))
  1286. static
  1287. int
  1288. doescape(argc,argv)
  1289. int argc;
  1290. char *argv[];
  1291. {
  1292.     if(argc < 2)
  1293.         printf("0x%x\n",escape);
  1294.     else 
  1295.         escape = *argv[1];
  1296.     return 0;
  1297. }
  1298. #endif    /* MSDOS */
  1299. /*ARGSUSED*/
  1300. static
  1301. doremote(argc,argv)
  1302. int argc;
  1303. char *argv[];
  1304. {
  1305.     struct socket fsock,lsock;
  1306.     struct mbuf *bp;
  1307.  
  1308.     lsock.address = ip_addr;
  1309.     fsock.address = resolve(argv[1]);
  1310.     lsock.port = fsock.port = atoi(argv[2]);
  1311.     bp = alloc_mbuf(1);
  1312.     if(strcmp(argv[3],"reset") == 0){
  1313.         *bp->data = SYS_RESET;
  1314.     } else if(strcmp(argv[3],"exit") == 0){
  1315.         *bp->data = SYS_EXIT;
  1316.     } else {
  1317.         printf("Unknown command %s\n",argv[3]);
  1318.         return 1;
  1319.     }
  1320.     bp->cnt = 1;
  1321.     send_udp(&lsock,&fsock,0,0,bp,0,0,0);
  1322.     return 0;
  1323. }
  1324.