home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1 / HamRadio.cdr / misc / tcpipsrc / pppcmd.c < prev    next >
C/C++ Source or Header  |  1990-12-09  |  22KB  |  840 lines

  1. /*
  2.  *  PPPCMD.C    -- PPP related user commands
  3.  *
  4.  *    12-89    -- Katie Stevens (dkstevens@ucdavis.edu)
  5.  *           UC Davis, Computing Services
  6.  *    PPP.07    04-90    [ks] new storage for peer addr for IPCP
  7.  *    PPP.08  05-90    [ks] improve PPP trace reporting
  8.  *    PPP.09    05-90    [ks] add commands to set PPP Auth protocol
  9.  *                 (UPAP server) and UPAP peerID (UPAP client)
  10.  *    PPP.10    6-90    [ks] improve keybd input of UPAP password
  11.  *                 make ppp open/close/reset work properly
  12.  *                 add peer IP lookup pool
  13.  *    PPP.13    8-90    [ks] report PPP open timestamp with stats
  14.  *    PPP.14    8-90    [ks] change UPAP to PAP for consistency with RFC1172
  15.  *                 add RLSD physical link up/down handling
  16.  *                 add autobaud handling to set link speed
  17.  *                 make LCP/IPCP timeout configurable
  18.  *    PPP.15    09-90    [ks] update to KA9Q NOS v900828
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <time.h>
  23. #include "global.h"
  24. #include "mbuf.h"
  25. #include "iface.h"
  26. #include "timer.h"
  27. #include "pktdrvr.h"
  28. #include "asy.h"
  29. #include "slcompre.h"
  30. #include "ppp.h"
  31. #include "slip.h"
  32. #include "commands.h"
  33. #include "netuser.h"
  34. /*#include "internet.h"*/
  35. #include "cmdparse.h"
  36. #include "config.h"
  37.  
  38. extern char Badhost[];
  39.  
  40. int16 Ppptrace = 0;
  41. int16 Npool = 0;        /* Number of pools for PPP interfaces */
  42.  
  43. #ifdef notdef /*MUXASY*/
  44. struct ipcppool PPPpool[ASY_MAX*PORTS_PER_MUX];    /* For pooling peer IP addrs */
  45. #else
  46. struct ipcppool PPPpool[ASY_MAX];        /* For pooling peer IP addrs */
  47. #endif
  48.  
  49. static int dopppaccomp __ARGS((int argc, char *argv[], void *p));
  50. static int dopppactive __ARGS((int argc, char *argv[], void *p));
  51. static int dopppauth __ARGS((int argc, char *argv[], void *p));
  52. static int dopppclose __ARGS((int argc, char *argv[], void *p));
  53. static int dopppctlmap __ARGS((int argc, char *argv[], void *p));
  54. static int dopppmru __ARGS((int argc, char *argv[], void *p));
  55. static int dopppipcomp __ARGS((int argc, char *argv[], void *p));
  56. static int doppppassive __ARGS((int argc, char *argv[], void *p));
  57. static int doppppeer __ARGS((int argc, char *argv[], void *p));
  58. static int doppppool __ARGS((int argc, char *argv[], void *p));
  59. static int dopppprotcomp __ARGS((int argc, char *argv[], void *p));
  60. static int dopppreset __ARGS((int argc, char *argv[], void *p));
  61. static int dopppstat __ARGS((int argc, char *argv[], void *p));
  62. static int doppptrace __ARGS((int argc, char *argv[], void *p));
  63. static int doppptimeout __ARGS((int argc, char *argv[], void *p));
  64. static int dopapuser __ARGS((int argc, char *argv[], void *p));
  65.  
  66. static void genstat __ARGS((struct slip *sp));
  67. static void pppstat __ARGS((struct slip *sp));
  68. static void lcpstat __ARGS((struct lcpctl *lcpiop));
  69. static void ipcpstat __ARGS((struct ipcpctl *ipcpiop));
  70. static struct iface *ppplookup __ARGS((char *ifname));
  71. static void dumppool __ARGS((void));
  72. static char *uptime __ARGS((long first, long second));
  73.  
  74. /* "ppp" subcommands */
  75. static struct cmds Pppcmds[] = {
  76.     "accompr",    dopppaccomp,    0,    2,
  77.         "ppp accompr <iface> <int>",
  78.     "activeopen",    dopppactive,    0,    2,
  79.         "ppp activeopen <iface>",
  80.     "authprot",    dopppauth,    0,    2,
  81.         "ppp authprot <authtype>",
  82.     "close",    dopppclose,    512,    2,
  83.         "ppp close <iface>",
  84.     "ctlmap",    dopppctlmap,    0,    2,
  85.         "ppp ctlmap <iface> <int>",
  86.     "ipcompr",    dopppipcomp,    0,    2,
  87.         "ppp ipcompr <iface> <comprtype>",
  88.     "mru",        dopppmru,    0,    2,
  89.         "ppp mru <iface> <int>",
  90.     "passiveopen",    doppppassive,    0,    2,
  91.         "ppp passiveopen <iface>",
  92.     "peeraddr",    doppppeer,    0,    2,
  93.         "ppp peeraddr <iface> <addr>",
  94.     "peerid",    dopapuser,    0,    2,
  95.         "ppp peerid <iface> <peer ID code>",
  96.     "pooladdr",    doppppool,    0,    1,
  97.         "ppp pooladdr <addr>:<# addr in pool> [ <iface> ... ]",
  98.     "protcompr",    dopppprotcomp,    0,    2,
  99.         "ppp protcompr <iface> <int>",
  100.     "reset",    dopppreset,    0,    2,
  101.         "ppp reset <iface>",
  102.     "status",    dopppstat,    0,    0,    NULLCHAR,
  103.     "timeout",    doppptimeout,    0,    2,
  104.         "ppp timeout <iface> <#sec>",
  105.     "trace",    doppptrace,    0,    0,    NULLCHAR,
  106.     NULLCHAR,
  107. };
  108.  
  109. static char *PPPStatus[] = {
  110.     "physical layer down",
  111.     "waiting for link speed assignment message",
  112.     "Closed",
  113.     "waiting for LCP negotiation",
  114.     "waiting for PAP verfication",
  115.     "waiting for IPCP negotiation",
  116.     "Open"
  117. };
  118. static char *LCPStatus[] = {
  119.     "Closed",
  120.     "Listen; waiting for remote host to attempt open",
  121.     "Req Sent: Attempting to start configuration exchange",
  122.     "Ack Rcvd: Remote host accepted our request; waiting for remote request",
  123.     "Ack Sent: Waiting for reply to our request; accepted remote request",
  124.     "Open; configuration negotiation complete",
  125.     "Terminate request sent to remote host"
  126. };
  127.  
  128. /****************************************************************************/
  129.  
  130. int
  131. dopppcontrol(argc,argv,p)
  132. int argc;
  133. char *argv[];
  134. void *p;
  135. {
  136.     return subcmd(Pppcmds,argc,argv,p);
  137. }
  138.  
  139. /****************************************************************************/
  140.  
  141. /* Initiate active open on a PPP interface */
  142. static int
  143. dopppactive(argc,argv,p)
  144. int argc;
  145. char *argv[];
  146. void *p;
  147. {
  148.     struct iface *ifp;
  149.     struct pppctl *pppiop;
  150.     struct lcpctl *lcpiop;
  151.  
  152.     /* Look for the PPP interface */
  153.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  154.         return -1;
  155.  
  156.     /* Start LCP configuration negotiation on interface */
  157.     pppiop = Slip[ifp->xdev].pppio;
  158.     lcpiop = &(pppiop->lcpio);
  159.     lcpiop->active = 1;
  160.     if ((pppiop->state == PPP_PL_DOWN) || (pppiop->state == PPP_AUTOBAUD))
  161.         return 0;
  162.     else
  163.         return(lcp_start(&Slip[ifp->xdev]));
  164. }
  165.  
  166. /* Close connection on PPP interface */
  167. static int
  168. dopppclose(argc,argv,p)
  169. int argc;
  170. char *argv[];
  171. void *p;
  172. {
  173.     struct iface *ifp;
  174.  
  175.     /* Look for the PPP interface */
  176.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  177.         return -1;
  178.  
  179.     /* Close PPP connection */
  180.     return(ppp_close(&Slip[ifp->xdev],1));
  181. }
  182.  
  183. /* Set PPP interface to passive open; will revert to LISTEN on next close */
  184. static int
  185. doppppassive(argc,argv,p)
  186. int argc;
  187. char *argv[];
  188. void *p;
  189. {
  190.     struct iface *ifp;
  191.     struct pppctl *pppiop;
  192.     struct lcpctl *lcpiop;
  193.  
  194.     /* Look for the PPP interface */
  195.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  196.         return -1;
  197.  
  198.     /* Start LCP configuration negotiation on interface */
  199.     pppiop = Slip[ifp->xdev].pppio;
  200.     lcpiop = &(pppiop->lcpio);
  201.     lcpiop->active = 0;
  202.     return 0;
  203. }
  204.  
  205. /* Close and reopen connection on PPP interface */
  206. static int
  207. dopppreset(argc,argv,p)
  208. int argc;
  209. char *argv[];
  210. void *p;
  211. {
  212.     struct iface *ifp;
  213.     struct slip *sp;
  214.     struct pppctl *pp;
  215.     struct slcompress *slp;
  216.  
  217.     /* Look for the PPP interface */
  218.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  219.         return -1;
  220.     sp = &Slip[ifp->xdev];
  221.     pp = sp->pppio;
  222.  
  223.     /* Close PPP connection */
  224.     ppp_close(&Slip[ifp->xdev],0);
  225.  
  226. #ifndef PPP_NO_STATS
  227.     /* Zero PPP packet counters */
  228.     pp->sndpkt = 0L;        /* # packets sent on PPP interface */
  229.     pp->snderr = 0;            /* # pkts with PPP error on send */
  230.     pp->rcvpkt = 0L;        /* # packets rcvd on PPP interface */
  231.     pp->rcverr = 0;            /* # pkts with error */
  232.     pp->csumerr = 0;        /* # rcv pkts with bad PPP checksum */
  233.  
  234.     pp->sndlcp = 0;            /* # LCP packets sent */
  235.     pp->sndpap = 0;            /* # PAP packets sent */
  236.     pp->sndipcp = 0;        /* # IPCP packets sent */
  237.     pp->sndip = 0L;            /* # IP packets sent */
  238.     pp->rcvlcp = 0;            /* # LCP packets received */
  239.     pp->rcvpap = 0;            /* # PAP packets received */
  240.     pp->rcvipcp = 0;        /* # IPCP packets received */
  241.     pp->rcvip = 0L;            /* # IP packets received */
  242.     pp->rcvunk = 0;            /* # unknown packets received */
  243. #endif
  244.  
  245. #ifndef SL_NO_STATS
  246.     slp = sp->slcomp;
  247.     slp->sls_nontcp = 0L;        /* outbound non-TCP packets */
  248.     slp->sls_asistcp = 0L;        /* outbound TCP packets */
  249.     slp->sls_compressed = 0L;    /* outbound compressed packets */
  250.     slp->sls_uncompressed = 0L;    /* outbound uncompressed packets */
  251.     slp->sls_searches = 0L;        /* searches for connection state */
  252.     slp->sls_misses = 0L;        /* times couldn't find conn. state */
  253.     slp->sls_nontcpin = 0L;        /* inbound non-TCP packets */
  254.     slp->sls_tcpin = 0L;        /* inbound TCP packets */
  255.     slp->sls_uncompressedin = 0L;    /* inbound uncompressed packets */
  256.     slp->sls_compressedin = 0L;    /* inbound compressed packets */
  257.     slp->sls_errorin = 0L;        /* inbound unknown type packets */
  258.     slp->sls_tossed = 0L;        /* inbound tossed because of error */
  259. #endif
  260.  
  261.     /* Always restart as active open when PPP reset */
  262.     pp->lcpio.active = 1;
  263.     tprintf("Attempting to reopen PPP interface  %s\n",ifp->name);
  264.     return(lcp_start(&Slip[ifp->xdev]));
  265. }
  266.  
  267. /*******************************************/
  268.  
  269. /* Set Address/Control Compression for a PPP interface */
  270. static int
  271. dopppaccomp(argc,argv,p)
  272. int argc;
  273. char *argv[];
  274. void *p;
  275. {
  276.     struct iface *ifp;
  277.     struct pppctl *pppiop;
  278.     struct lcpctl *lcpiop;
  279.     struct lcpparm *localp;
  280.  
  281.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  282.         return -1;
  283.     --argc;++argv;
  284.  
  285.     pppiop = Slip[ifp->xdev].pppio;
  286.     lcpiop = &(pppiop->lcpio);
  287.     localp = &(lcpiop->initparm);
  288.     localp->neg_ac_compress = 1;
  289.     return setbool(&(localp->ac_compress),
  290.             "Addr/Ctl Field Compression",argc,argv);
  291. }
  292.  
  293. /* Set authentication type for PPP interface */
  294. static int
  295. dopppauth(argc,argv,p)
  296. int argc;
  297. char *argv[];
  298. void *p;
  299. {
  300.     struct iface *ifp;
  301.     struct pppctl *pppiop;
  302.     struct lcpctl *lcpiop;
  303.     struct lcpparm *localp;
  304.  
  305.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  306.         return -1;
  307.  
  308.     pppiop = Slip[ifp->xdev].pppio;
  309.     lcpiop = &(pppiop->lcpio);
  310.     localp = &(lcpiop->initparm);
  311.     if (argc < 3) {
  312.         tprintf("%s\n",((localp->auth_type == PAP_AUTH_TYPE) ? "PAP" : "None"));
  313.     } else if ((strnicmp("pap",argv[2],2) == 0)
  314.             || ((int16)strtol(argv[2],NULLCHARP,0)==PAP_AUTH_TYPE)) {
  315.         localp->neg_auth_type = 1;
  316.         localp->auth_type = PAP_AUTH_TYPE;
  317.     } else if ((stricmp("none",argv[2]) == 0)
  318.             || ((int16)strtol(argv[2],NULLCHARP,0) == 0)) {
  319.         localp->neg_auth_type = 0;
  320.         localp->auth_type = DEF_AUTH_TYPE;
  321.     } else {
  322.         tprintf("unknown Authentication Protocol type; command ignored\n");
  323.         return 1;
  324.     }
  325.     return 0;
  326. }
  327.  
  328. /* Set Async Control Map for a PPP interface */
  329. static int
  330. dopppctlmap(argc,argv,p)
  331. int argc;
  332. char *argv[];
  333. void *p;
  334. {
  335.     long lx;
  336.     struct iface *ifp;
  337.     struct pppctl *pppiop;
  338.     struct lcpctl *lcpiop;
  339.     struct lcpparm *localp;
  340.  
  341.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  342.         return -1;
  343.  
  344.     pppiop = Slip[ifp->xdev].pppio;
  345.     lcpiop = &(pppiop->lcpio);
  346.     localp = &(lcpiop->initparm);
  347.     if (argc < 3) {
  348.         tprintf("0x%08lx\n",localp->ctl_map);
  349.     } else {
  350.         lx = strtol(argv[2], NULLCHARP, 0);
  351.         localp->neg_ctl_map = 1;
  352.         localp->ctl_map = lx;
  353.     }
  354.     return 0;
  355. }
  356.  
  357. /* Set preferred Maximum Receive Unit for a PPP interface */
  358. static int
  359. dopppmru(argc,argv,p)
  360. int argc;
  361. char *argv[];
  362. void *p;
  363. {
  364.     int x;
  365.     struct iface *ifp;
  366.     struct pppctl *pppiop;
  367.     struct lcpctl *lcpiop;
  368.     struct lcpparm *localp;
  369.  
  370.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  371.         return -1;
  372.  
  373.     pppiop = Slip[ifp->xdev].pppio;
  374.     lcpiop = &(pppiop->lcpio);
  375.     localp = &(lcpiop->initparm);
  376.     if (argc < 3) {
  377.         tprintf("%d\n",localp->mru);
  378.     } else {
  379.         x = atoi(argv[2]);
  380.         if ((x < MIN_MRU)||(x > DEF_MRU)) {
  381.             tprintf("Command rejected; MRU out of range: Min MRU: %d  Max MRU: %d\n",
  382.                 MIN_MRU,DEF_MRU);
  383.             return -1;
  384.         } else {
  385.             localp->neg_mru = 1;
  386.             localp->mru = x;
  387.         }
  388.     }
  389.     return 0;
  390. }
  391.  
  392. /* Set Protocol Compression for a PPP interface */
  393. static int
  394. dopppprotcomp(argc,argv,p)
  395. int argc;
  396. char *argv[];
  397. void *p;
  398. {
  399.     struct iface *ifp;
  400.     struct pppctl *pppiop;
  401.     struct lcpctl *lcpiop;
  402.     struct lcpparm *localp;
  403.  
  404.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  405.         return -1;
  406.     --argc;++argv;
  407.  
  408.     pppiop = Slip[ifp->xdev].pppio;
  409.     lcpiop = &(pppiop->lcpio);
  410.     localp = &(lcpiop->initparm);
  411.     localp->neg_prot_compress = 1;
  412.     return setbool(&(localp->prot_compress),
  413.             "Protocol Field Compression",argc,argv);
  414. }
  415.  
  416. /* Set timeout interval when waiting for response from remote peer */
  417. static int
  418. doppptimeout(argc,argv,p)
  419. int argc;
  420. char *argv[];
  421. void *p;
  422. {
  423.     int x;
  424.     struct iface *ifp;
  425.     struct pppctl *pppiop;
  426.     struct lcpctl *lcpiop;
  427.     struct ipcpctl *ipcpiop;
  428.     struct timer *t;
  429.  
  430.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  431.         return -1;
  432.  
  433.     pppiop = Slip[ifp->xdev].pppio;
  434.     lcpiop = &(pppiop->lcpio);
  435.     t = &(lcpiop->lcp_tm);
  436.     if (argc < 3) {
  437.         tprintf("%d\n",(dur_timer(t)/1000L));
  438.     } else {
  439.         x = atoi(argv[2]);
  440.         if (x <= 0) {
  441.             tprintf("Command rejected; timeout value must be > 0\n");
  442.             return -1;
  443.         } else {
  444.             set_timer(t,x*1000L);
  445.             ipcpiop = &(pppiop->ipcpio);
  446.             t = &(ipcpiop->ipcp_tm);
  447.             set_timer(t,x*1000L);
  448.         }
  449.     }
  450.     return 0;
  451. }
  452.  
  453. /* Set peer ID string to send with PAP AUTH_REQ */
  454. static int
  455. dopapuser(argc,argv,p)
  456. int argc;
  457. char *argv[];
  458. void *p;
  459. {
  460.     struct iface *ifp;
  461.     struct pppctl *pppiop;
  462.     struct lcpctl *lcpiop;
  463.  
  464.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  465.         return -1;
  466.  
  467.     pppiop = Slip[ifp->xdev].pppio;
  468.     lcpiop = &(pppiop->lcpio);
  469.     if (argc < 3) {
  470.         tprintf("%s\n",((lcpiop->pap_user==NULLCHAR)?"None":lcpiop->pap_user));
  471.     } else if (strnicmp("none",argv[2],2) == 0) {
  472.         if (lcpiop->pap_user != NULLCHAR)
  473.             free(lcpiop->pap_user);
  474.     } else {
  475.         if (lcpiop->pap_user != NULLCHAR)
  476.             free(lcpiop->pap_user);
  477.         if (lcpiop->pap_pass != NULLCHAR)
  478.             free(lcpiop->pap_pass);
  479.         lcpiop->pap_user = mallocw(strlen(argv[2])+1);
  480.         strcpy(lcpiop->pap_user,argv[2]);
  481.         pap_getpass(&Slip[ifp->xdev],0);
  482.     }
  483.     return 0;
  484. }
  485.  
  486.  
  487. /*******************************************/
  488.  
  489. /* Set IP compression type for PPP interface */
  490. static int
  491. dopppipcomp(argc,argv,p)
  492. int argc;
  493. char *argv[];
  494. void *p;
  495. {
  496.     struct iface *ifp;
  497.     struct pppctl *pppiop;
  498.     struct ipcpctl *ipcpiop;
  499.  
  500.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  501.         return -1;
  502.  
  503.     pppiop = Slip[ifp->xdev].pppio;
  504.     ipcpiop = &(pppiop->ipcpio);
  505.     if (argc < 3) {
  506.         if (ipcpiop->ip_compr_type == IPCP_VJCOMPR)
  507.             tprintf("Van Jacobson TCP header compression enabled\n");
  508.         else
  509.             tprintf("IP compression disabled\n");
  510.     } else if ((strnicmp("vj",argv[2],2) == 0)
  511.             || ((int16)strtol(argv[2],NULLCHARP,0) == IPCP_VJCOMPR)) {
  512.         ipcpiop->neg_ip_compr = 1;
  513.         ipcpiop->ip_compr_type = IPCP_VJCOMPR;
  514.     } else if ((int16)strtol(argv[2],NULLCHARP,0) == 0) {
  515.         ipcpiop->neg_ip_compr = 1;
  516.         ipcpiop->ip_compr_type = 0;
  517.     } else {
  518.         tprintf("unknown IP compression type; command ignored\n");
  519.         return 1;
  520.     }
  521.     return 0;
  522. }
  523.  
  524. /* Set peer address for PPP interface */
  525. static int
  526. doppppeer(argc,argv,p)
  527. int argc;
  528. char *argv[];
  529. void *p;
  530. {
  531.     int32 x32;
  532.     struct iface *ifp;
  533.     struct pppctl *pppiop;
  534.     struct ipcpctl *ipcpiop;
  535.  
  536.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  537.         return -1;
  538.  
  539.     pppiop = Slip[ifp->xdev].pppio;
  540.     ipcpiop = &(pppiop->ipcpio);
  541.     if (argc < 3) {
  542.         tprintf("%s\n",inet_ntoa(ipcpiop->peer_addr));
  543.     } else if ((x32 = resolve(argv[2])) == 0L) {
  544.         tprintf(Badhost,argv[2]);
  545.         return 1;
  546.     } else {
  547.         ipcpiop->peer_addr = x32;
  548.     }
  549.     return 0;
  550. }
  551.  
  552. /* Set a pool of peer addresses for PPP interface */
  553. static int
  554. doppppool(argc,argv,p)
  555. int argc;
  556. char *argv[];
  557. void *p;
  558. {
  559.     int pool;
  560.     int pool_cnt;
  561.     char *bitp;
  562.     int32 pool_addr;
  563.     struct ipcppool *poolp;
  564.     struct iface *ifp;
  565.     struct pppctl *pppiop;
  566.  
  567.     if (argc < 2) {
  568.         dumppool();
  569.         return 0;
  570.     }
  571.  
  572.     if (Npool > ASY_MAX) {
  573.         tprintf("Too many PPP address pools -- command rejected\n");
  574.         return -1;
  575.     }
  576.  
  577.     /* Need at least one IP address for the pool */
  578.     if((pool_addr = resolve(argv[1])) == 0){
  579.         tprintf("Must specify an IP address pool\n");
  580.         return -1;
  581.     }
  582.     /* May specify a consecutive range of addresses; otherwise assume 1 */
  583.     if((bitp = strchr(argv[1],':')) != NULLCHAR){
  584.         bitp++;
  585.         pool_cnt = atoi(bitp);
  586.     } else
  587.         pool_cnt = 1;
  588.     if (pool_cnt < 0) {
  589.         tprintf("Unreasonable address range  --  command rejected\n");
  590.         return -1;
  591.     }
  592.  
  593.     if (argc < 3) {
  594.         printf("Must specify a PPP interface\n");
  595.         return -1;
  596.     }
  597.  
  598.     pool = Npool++;
  599.     poolp = &(PPPpool[pool]);
  600.     poolp->peer_min = pool_addr;
  601.     poolp->peer_max = pool_addr + pool_cnt - 1;
  602.     poolp->peer_next = pool_addr;
  603.  
  604.     argc -= 2;argv++;
  605.     while (argc--) {
  606.         argv++;
  607.         if ((ifp = ppplookup(*argv)) == NULLIF)
  608.             continue;
  609.         pppiop = Slip[ifp->xdev].pppio;
  610.         pppiop->ipcpio.peer_pool = &(PPPpool[pool]);
  611.     }
  612.     return 0;
  613. }
  614.  
  615. /****************************************************************************/
  616.  
  617. static int
  618. doppptrace(argc,argv,p)
  619. int argc;
  620. char *argv[];
  621. void *p;
  622. {
  623.     return setshort(&Ppptrace,"PPP tracing",argc,argv);
  624. }
  625.  
  626. /****************************************************************************/
  627.  
  628. static int
  629. dopppstat(argc,argv,p)
  630. int argc;
  631. char *argv[];
  632. void *p;
  633. {
  634.     register struct slip *sp;
  635.     struct iface *ifp;
  636.  
  637.     if (argc < 2) {
  638.         for (sp = Slip;sp < &Slip[ASY_MAX];sp++) {
  639.             if (sp->type != CL_PPP)
  640.                 continue;
  641.             genstat(sp);
  642.         }
  643.     } else {
  644.         if ((ifp = ppplookup(argv[1])) == NULLIF)
  645.             return -1;
  646.         sp = &Slip[ifp->xdev];
  647.         genstat(sp);
  648.         pppstat(sp);
  649.         lcpstat(&(sp->pppio->lcpio));
  650.         ipcpstat(&(sp->pppio->ipcpio));
  651.     }
  652.     return 0;
  653. }
  654.  
  655. static void
  656. genstat(sp)
  657. struct slip *sp;
  658. {
  659.     register struct pppctl *pp;
  660.  
  661.     pp = sp->pppio;
  662.     tprintf("%s:\t",sp->iface->name);
  663.     tprintf("SndPkt: %ld  SndErr: %d  RcvPkt: %ld  RcvErr: %d  ChksumErr: %d\n",
  664.         pp->sndpkt,pp->snderr,pp->rcvpkt,pp->rcverr,pp->csumerr);
  665.     return;
  666. }
  667.  
  668. static void
  669. pppstat(sp)
  670. struct slip *sp;
  671. {
  672.     register struct pppctl *pp;
  673.     register struct slcompress *scp;
  674.  
  675.     pp = sp->pppio;
  676.     scp = sp->slcomp;
  677.     tprintf("\tOverall PPP state: %s",
  678.         PPPStatus[pp->state]);
  679.     if (pp->state == PPP_OPEN) {
  680.         tprintf("   (open for %s)\n",uptime(pp->upsince,time(0L)));
  681.     } else {
  682.         tprintf("\n");
  683.     }
  684.     tprintf("\t    SndIP: %ld  SndLCP: %d  SndPAP: %d  SndIPCP: %d\n",
  685.         pp->sndip,pp->sndlcp,pp->sndpap,pp->sndipcp);
  686.     if (sp->escaped & PPP_XMT_VJCOMPR) {
  687.         tprintf("\t      (IP) NotTCP: %ld  AsIsTCP: %ld  CmpTCP: %ld  UncmpTCP: %ld\n",
  688.             scp->sls_nontcp,scp->sls_asistcp,scp->sls_compressed,scp->sls_uncompressed);
  689.     }
  690.     tprintf("\t    RcvIP: %ld  RcvLCP: %d  RcvPAP: %d  RcvIPCP: %d  RcvUnknown: %d\n",
  691.         pp->rcvip,pp->rcvlcp,pp->rcvpap,pp->rcvipcp,pp->rcvunk);
  692.     if (sp->escaped & PPP_RCV_VJCOMPR) {
  693.         tprintf("\t      (IP) NotTCP: %ld  AsIsTCP: %ld  CmpTCP: %ld  UncmpTCP: %ld\n",
  694.             scp->sls_nontcpin,scp->sls_tcpin,scp->sls_compressedin,scp->sls_uncompressedin);
  695.         tprintf("\t           Unknown: %ld  CmpError: %ld\n",
  696.             scp->sls_errorin,scp->sls_tossed);
  697.     }
  698.     return;
  699. }
  700.  
  701. static void
  702. lcpstat(lcpiop)
  703. struct lcpctl *lcpiop;
  704. {
  705.     struct lcpparm *localp, *remotep;
  706.  
  707.     localp = &(lcpiop->lclparm);
  708.     remotep = &(lcpiop->remparm);
  709.  
  710.     tprintf("\tLCP state: %s\n",LCPStatus[lcpiop->lcp_state]);
  711.     tprintf("\t\t\t\tLocal options\tRemote options\n");
  712.     tprintf("\t    MRU:\t\t%d\t\t%d\n",
  713.         localp->mru,remotep->mru);
  714.     tprintf("\t    Ctl Map:\t\t0x%08lx\t0x%08lx\n",
  715.         localp->ctl_map,remotep->ctl_map);
  716.     tprintf("\t    Auth Prot:\t\t%s\t\t%s\n",
  717.         ((localp->auth_type == PAP_AUTH_TYPE) ? "PAP" : "None"),
  718.         ((remotep->auth_type == PAP_AUTH_TYPE) ? "PAP" : "None"));
  719.     tprintf("\t    Protocol Compr:\t%s\t\t%s\n",
  720.         (localp->prot_compress ? "ON" : "OFF"),
  721.         (remotep->prot_compress ? "ON" : "OFF"));
  722.     tprintf("\t    Addr/Ctl Compr:\t%s\t\t%s\n",
  723.         (localp->ac_compress ? "ON" : "OFF"),
  724.         (remotep->ac_compress ? "ON" : "OFF"));
  725. }
  726.  
  727. static void
  728. ipcpstat(ipcpiop)
  729. struct ipcpctl *ipcpiop;
  730. {
  731.     tprintf("\tIPCP state: %s\n",LCPStatus[ipcpiop->ipcp_state]);
  732.     tprintf("\t    IPCP local IP address:\t%s\n",
  733.         inet_ntoa(ipcpiop->attempt_src));
  734.     tprintf("\t    IPCP remote IP address:\t%s\n",
  735.         inet_ntoa(ipcpiop->attempt_dest));
  736.     if (ipcpiop->lcl_ip_compr == IPCP_VJCOMPR)
  737.         tprintf("\t    Rcv: Van Jacobson TCP header compression enabled\n");
  738.     else
  739.         tprintf("\t    Rcv: IP compression disabled\n");
  740.     if (ipcpiop->rem_ip_compr == IPCP_VJCOMPR)
  741.         tprintf("\t    Snd: Van Jacobson TCP header compression enabled\n");
  742.     else
  743.         tprintf("\t    Snd: IP compression disabled\n");
  744.  
  745.     return;
  746. }
  747.  
  748. /****************************************************************************/
  749.  
  750. static void
  751. dumppool()
  752. {
  753.     struct iface *ifp;
  754.     struct pppctl *pppiop;
  755.     struct ipcppool *poolp;
  756.  
  757.     tprintf("Interface        Pool Base/Count\tNext Address\n");
  758.     for (ifp=Ifaces; ifp != NULLIF; ifp = ifp->next) {
  759.         if ((Slip[ifp->xdev].iface == ifp) &&
  760.             (Slip[ifp->xdev].type == CL_PPP)) {
  761.             pppiop = Slip[ifp->xdev].pppio;
  762.             poolp = pppiop->ipcpio.peer_pool;
  763.             if (poolp == NULLPOOL)
  764.                 continue;
  765.             tprintf("%-11s%19s/%-2d",
  766.                 ifp->name,inet_ntoa(poolp->peer_min),
  767.                 (poolp->peer_max - poolp->peer_min + 1));
  768.             tprintf("\t%s\n",inet_ntoa(poolp->peer_next));
  769.         }
  770.     }
  771.     return;
  772. }
  773.  
  774. static struct iface *
  775. ppplookup(ifname)
  776. char *ifname;
  777. {
  778.     struct iface *ifp;
  779.  
  780.     for (ifp=Ifaces;ifp != NULLIF;ifp = ifp->next) {
  781.         if (!strcmp(ifname,ifp->name))
  782.             break;
  783.     }
  784.     if (ifp == NULLIF) {
  785.         tprintf("Interface %s unknown\n",ifname);
  786.         return(NULLIF);
  787.     } else if (ifp->type != CL_PPP) {
  788.         tprintf("Interface %s not a PPP interface\n",ifp->name);
  789.         return(NULLIF);
  790.     } else {
  791.         return(ifp);
  792.     }
  793. }
  794.  
  795.  
  796. /* Break a time differential, measured in seconds, into weeks, days      */
  797. /* hours, minutes, and seconds. Store ASCII description in static buffer */
  798. #define SECS_MIN    60L
  799. #define SECS_HR        3600L
  800. #define SECS_DAY    86400L
  801. #define SECS_WEEK    604800L
  802.  
  803. static char utbuf[128];
  804.  
  805. static char *
  806. uptime(first, second)
  807. long first;
  808. long second;
  809. {
  810.     int found = 0;
  811.     long diff;
  812.     long part;
  813.  
  814.     utbuf[0] = '\0';
  815.     diff = second - first;
  816.     if ((diff > SECS_DAY)||(found)) {
  817.         part = diff / SECS_DAY;
  818.         sprintf(&(utbuf[strlen(utbuf)]),
  819.             "%ld day%s ",part,((part==1)?",":"s,"));
  820.         diff -= (part * SECS_DAY);
  821.         found = 100;
  822.     }
  823.     if ((diff > SECS_HR)||(found)) {
  824.         part = diff / SECS_HR;
  825.         sprintf(&(utbuf[strlen(utbuf)]),
  826.             "%ld hr%s ",part,((part==1)?",":"s,"));
  827.         diff -= (part * SECS_HR);
  828.         ++found;
  829.     }
  830.     if ((diff > SECS_MIN)||(found)) {
  831.         part = diff / SECS_MIN;
  832.         sprintf(&(utbuf[strlen(utbuf)]),"%ld mi%s",part,
  833.             ((found < 100)?"n, ":"n"));
  834.         diff -= (part * SECS_MIN);
  835.     }
  836.     if (found < 100)
  837.         sprintf(&(utbuf[strlen(utbuf)]),"%ld sec",diff);
  838.     return(utbuf);
  839. }
  840.