home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1 / HamRadio.cdr / misc / tcpipsrc / tcpcmd.c < prev    next >
C/C++ Source or Header  |  1991-01-26  |  7KB  |  318 lines

  1. /* TCP control and status routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "timer.h"
  7. #include "mbuf.h"
  8. #include "netuser.h"
  9. #include "internet.h"
  10. #include "tcp.h"
  11. #include "cmdparse.h"
  12. #include "commands.h"
  13.  
  14. static int doirtt __ARGS((int argc,char *argv[],void *p));
  15. static int domss __ARGS((int argc,char *argv[],void *p));
  16. static int dortt __ARGS((int argc,char *argv[],void *p));
  17. static int dotcpkick __ARGS((int argc,char *argv[],void *p));
  18. static int dotcpreset __ARGS((int argc,char *argv[],void *p));
  19. static int dotcpstat __ARGS((int argc,char *argv[],void *p));
  20. static int dotcptr __ARGS((int argc,char *argv[],void *p));
  21. static int dowindow __ARGS((int argc,char *argv[],void *p));
  22. static int dosyndata __ARGS((int argc,char *argv[],void *p));
  23. static int tstat __ARGS((void));
  24.  
  25. /* TCP subcommand table */
  26. static struct cmds Tcpcmds[] = {
  27.     "irtt",        doirtt,        0, 0,    NULLCHAR,
  28.     "kick",        dotcpkick,    0, 2,    "tcp kick <tcb>",
  29.     "mss",        domss,        0, 0,    NULLCHAR,
  30.     "reset",    dotcpreset,    0, 2,    "tcp reset <tcb>",
  31.     "rtt",        dortt,        0, 3,    "tcp rtt <tcb> <val>",
  32.     "status",    dotcpstat,    0, 0,    NULLCHAR,
  33.     "syndata",    dosyndata,    0, 0,    NULLCHAR,
  34.     "trace",    dotcptr,    0, 0,    NULLCHAR,
  35.     "window",    dowindow,    0, 0,    NULLCHAR,
  36.     NULLCHAR,
  37. };
  38. int
  39. dotcp(argc,argv,p)
  40. int argc;
  41. char *argv[];
  42. void *p;
  43. {
  44.     return subcmd(Tcpcmds,argc,argv,p);
  45. }
  46. static int
  47. dotcptr(argc,argv,p)
  48. int argc;
  49. char *argv[];
  50. void *p;
  51. {
  52.     return setbool(&Tcp_trace,"TCP state tracing",argc,argv);
  53. }
  54.  
  55. /* Eliminate a TCP connection */
  56. static int
  57. dotcpreset(argc,argv,p)
  58. int argc;
  59. char *argv[];
  60. void *p;
  61. {
  62.     register struct tcb *tcb;
  63.  
  64.     tcb = (struct tcb *)ltop(htol(argv[1]));
  65.     if(!tcpval(tcb)){
  66.         tprintf(Notval);
  67.         return 1;
  68.     }
  69.     close_self(tcb,RESET);
  70.     return 0;
  71. }
  72.  
  73. /* Set initial round trip time for new connections */
  74. static int
  75. doirtt(argc,argv,p)
  76. int argc;
  77. char *argv[];
  78. void *p;
  79. {
  80.     struct tcp_rtt *tp;
  81.  
  82.     setlong(&Tcp_irtt,"TCP default irtt",argc,argv);
  83.     if(argc < 2){
  84.         for(tp = &Tcp_rtt[0];tp < &Tcp_rtt[RTTCACHE];tp++){
  85.             if(tp->addr != 0){
  86.                 if(tprintf("%s: srtt %lu mdev %lu\n",
  87.                  inet_ntoa(tp->addr),
  88.                  tp->srtt,tp->mdev) == EOF)
  89.                     break;
  90.             }
  91.         }
  92.     }
  93.     return 0;
  94. }
  95.  
  96. /* Set smoothed round trip time for specified TCB */
  97. static int
  98. dortt(argc,argv,p)
  99. int argc;
  100. char *argv[];
  101. void *p;
  102. {
  103.     register struct tcb *tcb;
  104.  
  105.     tcb = (struct tcb *)ltop(htol(argv[1]));
  106.     if(!tcpval(tcb)){
  107.         tprintf(Notval);
  108.         return 1;
  109.     }
  110.     tcb->srtt = atol(argv[2]);
  111.     return 0;
  112. }
  113.  
  114. /* Force a retransmission */
  115. static int
  116. dotcpkick(argc,argv,p)
  117. int argc;
  118. char *argv[];
  119. void *p;
  120. {
  121.     register struct tcb *tcb;
  122.  
  123.     tcb = (struct tcb *)ltop(htol(argv[1]));
  124.     if(kick_tcp(tcb) == -1){
  125.         tprintf(Notval);
  126.         return 1;
  127.     }
  128.     return 0;
  129. }
  130.  
  131. /* Set default maximum segment size */
  132. static int
  133. domss(argc,argv,p)
  134. int argc;
  135. char *argv[];
  136. void *p;
  137. {
  138.     return setshort(&Tcp_mss,"TCP MSS",argc,argv);
  139. }
  140.  
  141. /* Set default window size */
  142. static int
  143. dowindow(argc,argv,p)
  144. int argc;
  145. char *argv[];
  146. void *p;
  147. {
  148.     return setshort(&Tcp_window,"TCP window",argc,argv);    
  149. }
  150.  
  151. static int
  152. dosyndata(argc,argv,p)
  153. int argc;
  154. char *argv[];
  155. void *p;
  156. {
  157.     return setbool(&Tcp_syndata,"TCP syn+data piggybacking",argc,argv);
  158. }
  159.  
  160.  
  161. /* Display status of TCBs */
  162. static int
  163. dotcpstat(argc,argv,p)
  164. int argc;
  165. char *argv[];
  166. void *p;
  167. {
  168.     register struct tcb *tcb;
  169.  
  170.     if(argc < 2){
  171.         tstat();
  172.     } else {
  173.         tcb = (struct tcb *)ltop(htol(argv[1]));
  174.         if(tcpval(tcb))
  175.             st_tcp(tcb);
  176.         else
  177.             tprintf(Notval);
  178.     }
  179.     return 0;
  180. }
  181.  
  182. /* Dump TCP stats and summary of all TCBs
  183. /*     &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State
  184.  *     1234     0     0  xxx.xxx.xxx.xxx:xxxxx  xxx.xxx.xxx.xxx:xxxxx  Established
  185.  */
  186. static int
  187. tstat()
  188. {
  189.     register int i;
  190.     register struct tcb *tcb;
  191.     int j;
  192.  
  193.     for(j=i=1;i<=NUMTCPMIB;i++){
  194.         if(Tcp_mib[i].name == NULLCHAR)
  195.             continue;
  196.         tprintf("(%2u)%-20s%10lu",i,Tcp_mib[i].name,
  197.          Tcp_mib[i].value.integer);
  198.         if(j++ % 2)
  199.             tprintf("     ");
  200.         else
  201.             tprintf("\n");
  202.     }
  203.     if((j % 2) == 0)
  204.         tprintf("\n");
  205.  
  206.     tprintf("    &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State\n");
  207.     for(i=0;i<NTCB;i++){
  208.         for(tcb=Tcbs[i];tcb != NULLTCB;tcb = tcb->next){
  209.             tprintf("%8lx%6u%6u  ",ptol(tcb),tcb->rcvcnt,tcb->sndcnt);
  210.             tprintf("%-23s",pinet(&tcb->conn.local));
  211.             tprintf("%-23s",pinet(&tcb->conn.remote));
  212.             tprintf("%-s",Tcpstates[tcb->state]);
  213.             if(tcb->state == TCP_LISTEN && tcb->flags.clone)
  214.                 tprintf(" (S)");
  215.             if(tprintf("\n") == EOF)
  216.                 return 0;
  217.         }
  218.     }
  219.     return 0;
  220. }
  221. /* Dump a TCP control block in detail */
  222. void
  223. st_tcp(tcb)
  224. struct tcb *tcb;
  225. {
  226.     int32 sent,recvd;
  227.  
  228.     if(tcb == NULLTCB)
  229.         return;
  230.     /* Compute total data sent and received; take out SYN and FIN */
  231.     sent = tcb->snd.una - tcb->iss;    /* Acknowledged data only */
  232.     recvd = tcb->rcv.nxt - tcb->irs;
  233.     switch(tcb->state){
  234.     case TCP_LISTEN:
  235.     case TCP_SYN_SENT:    /* Nothing received or acked yet */
  236.         sent = recvd = 0;    
  237.         break;
  238.     case TCP_SYN_RECEIVED:
  239.         recvd--;    /* Got SYN, no data acked yet */
  240.         sent = 0;
  241.         break;
  242.     case TCP_ESTABLISHED:    /* Got and sent SYN */
  243.     case TCP_FINWAIT1:    /* FIN not acked yet */
  244.         sent--;
  245.         recvd--;
  246.         break;
  247.     case TCP_FINWAIT2:    /* Our SYN and FIN both acked */
  248.         sent -= 2;
  249.         recvd--;
  250.         break;
  251.     case TCP_CLOSE_WAIT:    /* Got SYN and FIN, our FIN not yet acked */
  252.     case TCP_CLOSING:
  253.     case TCP_LAST_ACK:
  254.         sent--;
  255.         recvd -= 2;
  256.         break;
  257.     case TCP_TIME_WAIT:    /* Sent and received SYN/FIN, all acked */
  258.         sent -= 2;
  259.         recvd -= 2;
  260.         break;
  261.     }
  262.     tprintf("Local: %s",pinet(&tcb->conn.local));
  263.     tprintf(" Remote: %s",pinet(&tcb->conn.remote));
  264.     tprintf(" State: %s\n",Tcpstates[tcb->state]);
  265.     tprintf("      Init seq    Unack     Next Resent CWind Thrsh  Wind  MSS Queue      Total\n");
  266.     tprintf("Send:");
  267.     tprintf("%9lx",tcb->iss);
  268.     tprintf("%9lx",tcb->snd.una);
  269.     tprintf("%9lx",tcb->snd.nxt);
  270.     tprintf("%7lu",tcb->resent);
  271.     tprintf("%6u",tcb->cwind);
  272.     tprintf("%6u",tcb->ssthresh);
  273.     tprintf("%6u",tcb->snd.wnd);
  274.     tprintf("%5u",tcb->mss);
  275.     tprintf("%6u",tcb->sndcnt);
  276.     tprintf("%11lu\n",sent);
  277.  
  278.     tprintf("Recv:");
  279.     tprintf("%9lx",tcb->irs);
  280.     tprintf("         ");
  281.     tprintf("%9lx",tcb->rcv.nxt);
  282.     tprintf("%7lu",tcb->rerecv);
  283.     tprintf("      ");
  284.     tprintf("      ");
  285.     tprintf("%6u",tcb->rcv.wnd);
  286.     tprintf("     ");
  287.     tprintf("%6u",tcb->rcvcnt);
  288.     tprintf("%11lu\n",recvd);
  289.  
  290.     if(tcb->reseq != (struct reseq *)NULL){
  291.         register struct reseq *rp;
  292.  
  293.         tprintf("Reassembly queue:\n");
  294.         for(rp = tcb->reseq;rp != (struct reseq *)NULL; rp = rp->next){
  295.             if(tprintf("  seq x%lx %u bytes\n",
  296.              rp->seg.seq,rp->length) == EOF)
  297.                 return;
  298.         }
  299.     }
  300.     if(tcb->backoff > 0)
  301.         tprintf("Backoff %u ",tcb->backoff);
  302.     if(tcb->flags.retran)
  303.         tprintf("Retrying ");
  304.     switch(tcb->timer.state){
  305.     case TIMER_STOP:
  306.         tprintf("Timer stopped ");
  307.         break;
  308.     case TIMER_RUN:
  309.         tprintf("Timer running (%ld/%ld ms) ",
  310.          (long)read_timer(&tcb->timer),
  311.          (long)dur_timer(&tcb->timer));
  312.         break;
  313.     case TIMER_EXPIRE:
  314.         tprintf("Timer expired ");
  315.     }
  316.     tprintf("SRTT %ld ms Mean dev %ld ms\n",tcb->srtt,tcb->mdev);
  317. }
  318.