home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msvp98b1.lzh / MSNTCP.C < prev    next >
Text File  |  1993-05-14  |  51KB  |  2,000 lines

  1. /* File MSNTCP.C
  2.  * Main TCP protocol code
  3.  *
  4.  * Copyright (C) 1991, University of Waterloo.
  5.  * Copyright (C) 1985, 1992, Trustees of Columbia University in the 
  6.  * City of New York.  Permission is granted to any individual or institution
  7.  * to use this software as long as it is not sold for profit.  This copyright
  8.  * notice must be retained.  This software may not be included in commercial
  9.  * products without written permission of Columbia University.
  10.  *
  11.  * Original version created by Erick Engelke of the University of
  12.  *  Waterloo, Waterloo, Ontario, Canada.
  13.  * Adapted and modified for MS-DOS Kermit by Joe R. Doupnik, 
  14.  *  Utah State University, jrd@cc.usu.edu, jrd@usu.Bitnet.
  15.  *
  16.  * Last edit
  17.  * 12 May 1992
  18.  *
  19.  *  PCTCP - the true worker of Waterloo TCP
  20.  *         - contains all opens, closes, major read/write routines and
  21.  *        basic IP handler for incomming packets
  22.  *      - NOTE: much of the TCP/UDP/IP layering is done at data structure
  23.  *        level, not in separate routines or tasks
  24.  *
  25.  */
  26.  
  27. #include "msntcp.h"
  28. #include "msnlib.h"
  29. /*
  30. #define OLD 1
  31. */
  32.  
  33. static void (*system_yield)() = NULL;
  34. static tcp_Retransmitter();
  35. static tcp_unthread(void * s);
  36. static tcp_handler(void * s);
  37. static udp_handler(void * s);
  38. extern int arp_handler(in_Header *);
  39. extern int icmp_handler(void * s);
  40. extern void icmp_noport(void * s);
  41. extern void server_hello(tcp_Socket *s);
  42. int tcp_rst(in_Header *his_ip, tcp_Header *oldtcpp);
  43. static tcp_ProcessData(void *s, void * tp, int len);
  44.  
  45. static initialized = 0;
  46. longword ipbcast = 0xffffffffL;        /* default IP broadcast address */
  47. word waittime = 2;    /* tcp_sendsoon, normal ticks to wait, ~0.1 sec */
  48.  
  49. #ifdef DEBUG
  50. void (*dbugxmit)() = NULL;
  51. void (*dbugrecv)() = NULL;
  52. #endif
  53. /*
  54.  * Local IP address
  55.  */
  56.  
  57. longword my_ip_addr = 0L;    /* for external references */
  58. longword sin_mask = 0xfffffe00L;
  59. longword sin_gate = 0L;
  60.  
  61. /*
  62.  * IP identification numbers
  63.  */
  64.  
  65. static int ip_id = 0;            /* packet number */
  66. static int next_tcp_port = 1024;    /* auto incremented */
  67. static int next_udp_port = 1024;
  68. static tcp_Socket *tcp_allsocs = NULL;    /* TCP socket linked list head */
  69. static udp_Socket *udp_allsocs = NULL;    /* UDP socket linked list head */
  70.  
  71. /* Timer definitions */
  72. #define RETRAN_STRAT_TIME  1     /* ticks, how often to check retransmitter*/
  73. #define tcp_RETRANSMITTIME 3     /* interval to call retransmitter */
  74. #define tcp_LONGTIMEOUT 31       /* timeout for opens */
  75. #define tcp_TIMEOUT 13           /* timeout during a connection */
  76.  
  77. word debug_on = 0;
  78. byte *hostname = "012345678901234567890123456789012345678901234567890";
  79. word mss = ETH_MSS;
  80. word sourcequench = 0;        /* non-zero if received ICMP Source Quench */
  81.  
  82. /*    TCP Header (and size in bits)
  83.     Source Port (16)
  84.     Destination Port (16)
  85.     Sequence Number (32)    First octet in this segment. If SYN then
  86.                 this is the initial seq num and first data
  87.                 octet is one larger.
  88.     Acknowledgment Number (32) Next octet expected to be received
  89.      Data Offset (4)        number of 32 bit words in this header so we
  90.                 know when options are present (and how large)
  91.      Reserved (6)
  92.      URG (1)            Urgent
  93.      ACK (1)            Acknowledgment
  94.      PSH (1)            Push function (expedite)
  95.      RST (1)            Reset the connection
  96.      SYN (1)            Synchronize sequence numbers
  97.      FIN (1)            Finish, no more data from sender
  98.      Window (16)        Octets willing to accept after Ack value
  99.      Checksum (16)        One's complement of header and Pseudo header
  100.      Urgent Pointer (16)    Points to octet following urgent data <sic>
  101.      Options & Padding (32)    Only Option is max segment size
  102.      Data (the rest)
  103. */
  104. /*
  105.  * tcp_Init - Initialize the tcp implementation
  106.  *        - may be called more than once without hurting
  107.  */
  108. int
  109. tcp_init()
  110. {
  111.     extern int arp_last_gateway;
  112.     extern int last_nameserver;
  113.     void    icmp_init();
  114.  
  115.     if (initialized != 0) return (1);    /* success, inited already */
  116.                 /* initialize ethernet interface */
  117.     arp_init();            /* clear ARP tables */
  118.     icmp_init();            /* clear ICMP material */
  119.     last_nameserver = 0;        /* reset the nameserver table */
  120.     *hostname = 0;            /* reset the host's name */
  121.     tcp_allsocs = NULL;        /* zero socket pointers */
  122.     udp_allsocs = NULL;
  123.     ip_id = 0;            /* packet number, convenient */
  124.     initialized = eth_init();    /* init the hardware, can fail */
  125.     if (my_ip_addr == 0L)         /* my_ap_addr is longword*/
  126.         bcopy(ð_addr[2], &my_ip_addr, 4); /* a pseudo long */
  127.                     /* next port numbers to choose */
  128.     next_udp_port = next_tcp_port = 1024 + (realclock() & 0x1ff);
  129.     eth_free (NULL);        /* clear all pkt rcv bufs */
  130.     return (initialized);        /* success (1) or failure (0) */
  131. }
  132.  
  133. /*
  134.  * Shut down the card and all services
  135.  */
  136. void
  137. tcp_shutdown()
  138. {
  139.     while (tcp_allsocs != NULL)
  140.         tcp_abort(tcp_allsocs);
  141.     eth_release();
  142.     initialized = 0;
  143. }
  144.  
  145. int 
  146. udp_open(s, lport, ina, port, datahandler)
  147. udp_Socket *s;
  148. longword ina;
  149. word lport, port;
  150. procref datahandler;
  151. {
  152.     if (s == NULL) return (0);
  153.  
  154.     memset(s, 0, sizeof(udp_Socket));
  155.     s->ip_type = UDP_PROTO;
  156.     if (lport == 0) lport = ++next_udp_port;  /* get a nonzero port val */
  157.     s->myport = lport;
  158.  
  159.     /* check for broadcast */
  160.     if (ina == 0xffffffffL || ina == 0L || ina == ipbcast)
  161.         memset(s->hisethaddr, 0xff, sizeof(eth_address));
  162.     else
  163.         if (arp_resolve(ina, &s->hisethaddr[0]) == 0)
  164.             return (0);
  165.     s->hisaddr = ina;
  166.     s->hisport = port;
  167.     s->dataHandler = datahandler;
  168.     s->usr_yield = system_yield;
  169.     s->next = udp_allsocs;
  170.     udp_allsocs = s;
  171.     return (1);
  172. }
  173.  
  174. /*
  175.  * Actively open a TCP connection to a particular destination.
  176.  *    - 0 on error
  177.  */
  178. int 
  179. tcp_open(s, lport, ina, port, datahandler)
  180. tcp_Socket *s;
  181. longword ina;
  182. word lport, port;
  183. procref datahandler;
  184. {
  185.     if (s == NULL) return (0);
  186.  
  187.     memset(s, 0, sizeof(tcp_Socket));    /* zero everything */
  188.     s->ip_type = TCP_PROTO;
  189.     s->mss = mss;
  190.     s->state = tcp_StateSYNSENT;
  191.     s->timeout = set_timeout(tcp_LONGTIMEOUT);
  192.     s->rmaxdatalen = tcp_MaxBufSize;
  193.     s->cwindow = 1;            /* slow start VJ algorithm */
  194.     s->vj_sa = 4;            /* about 250 ms (4/18.2 tics/sec) */
  195.     if (lport == 0)
  196.         lport = ++next_tcp_port;  /* get a nonzero port value */
  197.     s->myport = lport;
  198.     if (! arp_resolve(ina, &s->hisethaddr[0]))
  199.         return (0);        /* failed to get host Ethernet addr */
  200.     s->hisaddr = ina;
  201.     s->hisport = port;
  202.     s->seqnum = ntohl(set_timeout(0)) & 0xffff0000;
  203.     s->datalen = 0;
  204.     s->flags = tcp_FlagSYN;
  205.     s->unhappy = TRUE;
  206.     s->dataHandler = datahandler;
  207.     s->usr_yield = system_yield;
  208.     s->next = tcp_allsocs;
  209.     s->rtt_delay = s->rtt_smooth = 18;    /* one second startup */
  210.     tcp_allsocs = s;
  211.     return (tcp_send(s));        /* fail if send fails */
  212. }
  213.  
  214. /*
  215.  * Passive open: listen for a connection on a particular port
  216.  */
  217. tcp_listen(s, lport, ina, port, datahandler, timeout)
  218. tcp_Socket *s;
  219. word port, lport, timeout;
  220. longword ina;
  221. procref datahandler;
  222. {
  223.     if (s == NULL) return (0);
  224.  
  225.     memset(s, 0, sizeof(tcp_Socket));
  226.     s->ip_type = TCP_PROTO;
  227.     s->mss = mss;
  228.     s->rmaxdatalen = tcp_MaxBufSize;
  229.     s->cwindow = 1;            /* slow start VJ algorithm */
  230.     s->vj_sa = 4;            /* about 250 ms */
  231.     s->state = tcp_StateLISTEN;
  232.     if (timeout == 0)
  233.         s->timeout = 0;         /* no timeout */
  234.     else
  235.         s->timeout = set_timeout(timeout);
  236.     s->myport = lport;
  237.     s->hisport = port;
  238.     s->hisaddr = ina;
  239.     s->seqnum = ntohl(set_timeout(0)) & 0xffff0000;
  240.     s->datalen = 0;
  241.     s->flags = 0;
  242.     s->unhappy = FALSE;
  243.     s->dataHandler = datahandler;
  244.     s->usr_yield = system_yield;
  245.     s->next = tcp_allsocs;
  246.     tcp_allsocs = s;
  247.     return (1);
  248. }
  249.  
  250.  
  251. static int
  252. udp_close(ds)
  253. udp_Socket *ds;
  254. {
  255.     register udp_Socket *sp;
  256.  
  257.     sp = udp_allsocs;        /* ptr to first socket */
  258.     if (sp == NULL) return (0);    /* failure */
  259.     if (sp == ds) udp_allsocs = ds->next; /* if we are first, unlink */
  260.     while (sp != NULL)
  261.         {
  262.         if (sp->next == ds)    /* if current points to us */
  263.             {
  264.             sp->next = ds->next; /* point it to our successor */
  265.                break;
  266.             }
  267.         sp = sp->next;        /* look at next socket */
  268.         }
  269.     return (1);            /* success */
  270. }
  271.  
  272. /*
  273.  * Send a FIN on a particular port -- only works if it is open
  274.  * Must still allow receives
  275.  * Returns 0 for failure
  276.  */
  277. static 
  278. tcp_close(s)
  279. tcp_Socket *s;
  280. {
  281.     if (s == NULL) return (0);
  282.     if (s->ip_type != TCP_PROTO)
  283.         return (0);            /* failure */
  284.     if (s->state == tcp_StateESTAB || s->state == tcp_StateSYNREC)
  285.         {
  286.         if (s->err_msg == NULL)
  287.             s->err_msg = "TCP_Closed called";
  288.         s->flags = tcp_FlagACK | tcp_FlagFIN;
  289.         if (s->datalen)
  290.             s->flags |= tcp_FlagPUSH;
  291.         s->state = tcp_StateFINWT1;
  292.         s->timeout = set_timeout(4);
  293.                     /* should be a pretty lengthy time */
  294.         s->unhappy = TRUE;
  295.         tcp_send(s);
  296.         return (1);            /* success */
  297.         }
  298.     return (0);
  299. }
  300.  
  301. /*
  302.  * Abort a tcp connection
  303.  * Returns 0 if failure
  304.  */
  305. static int 
  306. tcp_abort(s)
  307. tcp_Socket *s;
  308. {
  309.     if (s == NULL) return (0);        /* failure */
  310.  
  311.     if (s->err_msg == NULL) s->err_msg = "TCP_ABORT";
  312.     if ((s->state != tcp_StateLISTEN) && (s->state != tcp_StateCLOSED))
  313.         {
  314.         s->flags = tcp_FlagRST | tcp_FlagACK;
  315.         s->unhappy = TRUE;
  316.         tcp_send(s);
  317.         }
  318.     s->unhappy = FALSE;
  319.     s->datalen = 0;
  320.     s->state = tcp_StateCLOSED;
  321.     if (s->dataHandler) s->dataHandler(s, 0, -1);
  322.     tcp_unthread(s);
  323.     return (1);                /* success */
  324. }
  325.  
  326. void 
  327. sock_abort(s)
  328. tcp_Socket *s;
  329. {
  330.     if (s == NULL) return;            /* do nothing */
  331.     if (s->ip_type == TCP_PROTO)
  332.         tcp_abort(s);
  333.     else
  334.         udp_close(s);
  335. }
  336.  
  337. /*
  338.  * tcp_sendsoon - schedule a transmission pretty soon
  339.  *        - this one has an imperfection at midnight, but it
  340.  *          is not significant to the connection performance
  341.  * Return 0 if failure.
  342.  */
  343. tcp_sendsoon(s)
  344. tcp_Socket *s;
  345. {
  346.     longword temp;
  347.  
  348.     if (s == NULL) return (0);
  349.  
  350.     if (s->ip_type != TCP_PROTO) return (0);
  351.  
  352.     s->karn_count = 1;
  353.     if (sourcequench != 0)            /* ICMP shutup message */
  354.         {
  355.         waittime += waittime;        /* double the timeout */
  356.         sourcequench = 0;        /* forget the reminder */
  357.         }
  358.  
  359.     temp = set_ttimeout(waittime);        /* Bios ticks into the future */
  360.     if ((s->rtt_time < temp))        /* if now is too soon */
  361.         return (1);            /* then wait some more */
  362.     if (waittime > 2)            /* if backing off already */
  363.         waittime = (waittime * 15) / 16; /* recover slowly */
  364.     s->rtt_time = temp;
  365.     return (1);
  366. }
  367.  
  368. /*
  369.  * Retransmitter - called periodically to perform tcp retransmissions
  370.  * Returns 0 if failure
  371.  */
  372. static 
  373. tcp_Retransmitter()
  374. {
  375.     register tcp_Socket *s;
  376.     static longword retran_strat = 0L;    /* timeout retran strategy */
  377.     extern word pktdevclass;
  378.  
  379.             /* do this only once per RETRAN_STRAT_TIME clock ticks */
  380.     if (!chk_timeout(retran_strat))
  381.         return (0L);
  382.     retran_strat = set_ttimeout( (pktdevclass == PD_SLIP)? 
  383.             4 * RETRAN_STRAT_TIME: RETRAN_STRAT_TIME);
  384.  
  385.     for (s = tcp_allsocs; s != NULL; s = s->next)
  386.         {
  387.         if ((s->datalen > 0) ||    (s->unhappy == TRUE) ||
  388.                 (s->karn_count == 1))
  389.                             /* retransmission strategy */
  390.                 if (chk_timeout(s->rtt_time)) /* if timeout */
  391.                 {
  392.                 if (s->karn_count == 0)
  393.                             s->karn_count = 2;
  394.                         /* if really did timeout */
  395.                         tcp_send(s);
  396.                     }
  397.  
  398.         if (s->timeout && chk_timeout(s->timeout))
  399.             {
  400.             if (s->state == tcp_StateTIMEWT)
  401.                 {
  402.                 s->flags = tcp_FlagACK;
  403.                 s->state = tcp_StateCLOSED;
  404.                 }
  405.             else if (s->state != tcp_StateESTAB)
  406.                 {
  407.                 s->err_msg = "Timeout, aborting";
  408.                 tcp_abort(s);
  409.                 }
  410.             }
  411.         }
  412.     return (1);        /* success */
  413. }
  414.  
  415. /*
  416.  * Unthread a socket from the socket list, if it's there. Return 0 on failure
  417.  */
  418. static int
  419. tcp_unthread(ds)
  420. tcp_Socket *ds;
  421. {
  422.     register tcp_Socket *sp;
  423.  
  424.     if (ds == NULL) return (0);        /* failure */
  425.  
  426.     if ((ds->rdatalen == 0) || (ds->state > tcp_StateESTAB))
  427.         ds->ip_type = 0;        /* fail io */
  428.     ds->state = tcp_StateCLOSED;           /* tcp_tick needs this */
  429.     if (tcp_allsocs == NULL) return (0);
  430.  
  431.     sp = tcp_allsocs;            /* ptr to first socket */
  432.     if (sp == ds) tcp_allsocs = ds->next; /* if we are first, unlink */
  433.     while (sp != NULL)
  434.         {
  435.         if (sp->next == ds)        /* if current points to us */
  436.             {
  437.             sp->next = ds->next; /* point it to our successor */
  438.                break;
  439.             }
  440.         sp = sp->next;            /* look at next socket */
  441.         }
  442.     return (1);                /* success */
  443. }
  444.  
  445. /*
  446.  * tcp_tick - called periodically by user application
  447.  *        - returns 0 when our socket closes
  448.  *        - called with socket parameter or NULL
  449.  */
  450. tcp_tick(s)
  451. sock_type *s;
  452. {
  453.     register in_Header *ip;
  454.     int packettype;
  455.  
  456.                 /* finish off dead sockets */
  457.     if (s != NULL)
  458.         if (s->tcp.ip_type == TCP_PROTO &&
  459.          s->tcp.state == tcp_StateCLOSED)
  460.              s->tcp.ip_type = 0;
  461.  
  462.                     /* read a packet */
  463.     while ((ip = (in_Header *)eth_arrived(&packettype)) != NULL)
  464.     {
  465.  
  466.     switch (ntohs(packettype))      /* big to little endian form */
  467.     {
  468.     case 0x0800:                /* do IP */
  469.         if (checksum(ip, in_GetHdrlenBytes(ip)) != 0xffff)
  470.             {
  471.             if (debug_on)
  472.                 outs("IP Received BAD Checksum \n\r");
  473.             break;
  474.             }
  475.         if ((my_ip_addr == 0L) || 
  476.             (htonl(ip->destination)    == my_ip_addr))
  477.             {
  478.             switch (ip->proto)
  479.                 {
  480.                 case TCP_PROTO:
  481.                     tcp_handler(ip);
  482.                     break;
  483.                 case UDP_PROTO:
  484.                     udp_handler(ip);
  485.                     break;
  486.                 case ICMP_PROTO:
  487.                     icmp_handler(ip);
  488.                     break;
  489.                 default:
  490.                     break;
  491.                 }    /* end of switch (ip->proto) */
  492.             }
  493.         break;
  494.  
  495.     case 0x0806:                /* do ARP */
  496.         arp_handler(ip);
  497.         break;
  498.     case 0x8035:                /* do RARP */
  499.         rarp_handler(ip);
  500.         break;
  501.     default:                /* unknown type */
  502.         break;
  503.     }                /* end of switch */
  504.     eth_free(ip);            /* free the processed packet */
  505.     }                    /* end of while */
  506.  
  507.     tcp_Retransmitter();        /* check on pending sends */
  508.     return ((s != NULL)? s->tcp.ip_type: 0); /* 0 means closed socket */
  509. }
  510.  
  511. void
  512. tcp_set_debug_state(x)
  513. word x;
  514. {
  515.     debug_on = x;
  516. }
  517.  
  518. /* returns 1 if connection is established, else 0 */
  519. int 
  520. tcp_established(s)
  521. tcp_Socket *s;
  522. {
  523.     if (s == NULL) return (0);        /* failure */
  524.     return (s->state == tcp_StateESTAB);
  525. }
  526.  
  527.  
  528. static int
  529. udp_Write(s, datap, len)
  530. udp_Socket *s;
  531. byte *datap;
  532. int len;
  533. {
  534.     tcp_PseudoHeader ph;
  535.     struct pkt
  536.         {
  537.         in_Header  in;
  538.         udp_Header udp;
  539.         int       data;
  540. /*        longword maxsegopt; */
  541.         } register *pkt;
  542.  
  543.     if (s == NULL || datap == NULL)
  544.         return (0);            /* failure */
  545.  
  546.     pkt = (struct pkt *)eth_formatpacket(&s->hisethaddr[0], 0x0008);
  547.     pkt->in.length = htons(sizeof(in_Header) + UDP_LENGTH + len);
  548.  
  549.                         /* UDP header */
  550.     pkt->udp.srcPort = htons(s->myport);
  551.     pkt->udp.dstPort = htons(s->hisport);
  552.     pkt->udp.checksum = 0;
  553.     pkt->udp.length = htons(UDP_LENGTH + len);
  554.     bcopy(datap, &pkt->data, len);
  555.                         /* Internet header */
  556.     pkt->in.hdrlen_ver = 0x45;        /* version 4, hdrlen 5 */
  557.     pkt->in.tos = 0;
  558.     pkt->in.identification = htons(++ip_id);    /* was post inc */
  559.     pkt->in.frag = 0;
  560. #ifdef KERMIT
  561.     pkt->in.ttl = 60;
  562. #else
  563.     pkt->in.ttl = 254;
  564. #endif
  565.     pkt->in.proto = UDP_PROTO;            /* UDP */
  566.     pkt->in.checksum = 0;
  567.     pkt->in.source = htonl(my_ip_addr);
  568.     pkt->in.destination = htonl(s->hisaddr);
  569.     pkt->in.checksum = ~checksum(&pkt->in, sizeof(in_Header));
  570.                     /* compute udp checksum if desired */
  571.     if (s->soc_mode & UDP_MODE_NOCHK)
  572.         pkt->udp.checksum = 0;
  573.     else
  574.         {
  575.         ph.src = pkt->in.source;        /* big endian now */
  576.         ph.dst = pkt->in.destination;
  577.         ph.mbz = 0;
  578.         ph.protocol = UDP_PROTO;        /* UDP */
  579.         ph.length = pkt->udp.length;        /* big endian now */
  580.         ph.checksum = checksum(&pkt->udp, htons(ph.length));
  581.         pkt->udp.checksum = ~checksum(&ph, sizeof(ph));
  582.         }
  583.  
  584. #ifdef DEBUG
  585.     if (dbugxmit) (*dbugxmit)(s,inp,udpp);
  586. #endif
  587.     if (eth_send(htons(pkt->in.length)) != 0)    /* send pkt */
  588.         return (len);
  589.     else    return (0);                /* failed */
  590. }
  591.  
  592. /*
  593.  * udp_read - read data from buffer, does large buffering.
  594.  * Return 0 on failure.
  595.  */
  596. static int 
  597. udp_read(s, datap, maxlen)
  598. udp_Socket *s;
  599. byte *datap;
  600. int maxlen;
  601. {
  602.     register int x;
  603.  
  604.     if (s == NULL || datap == NULL) return (0);        /* failure */
  605.     if ((x = s->rdatalen) > 0)
  606.         {
  607.         if (x > maxlen) x = maxlen;
  608.         if (x > 0)
  609.             {
  610.             bcopy(s->rdata, datap, x);
  611.             if (s->rdatalen -= x)
  612.                 bcopy(&s->rdata[x], s->rdata, s->rdatalen);
  613.             }
  614.             }
  615.     return (x);
  616. }
  617.  
  618. udp_cancel(in_Header *ip)
  619. {
  620.     int len;
  621.     register udp_Header *up;
  622.     register udp_Socket *s;
  623.  
  624.                         /* match to a udp socket */
  625.     len = in_GetHdrlenBytes(ip);
  626.     up = (udp_Header *)((byte *)ip + len);    /* udp frame pointer */
  627.  
  628.                         /* demux to active sockets */
  629.     for (s = udp_allsocs; s != NULL; s = s->next)
  630.             if (s->hisport != 0 &&
  631.              ntohs(up->dstPort) == s->myport &&
  632.              ntohs(up->srcPort) == s->hisport &&
  633.              ntohl(ip->source) == s->hisaddr)
  634.                  break;
  635.  
  636.     if (s == NULL)                /* demux to passive sockets */
  637.         for (s = udp_allsocs; s != NULL; s = s->next)
  638.                 if (s->hisport == 0 && 
  639.                 ntohs(up->dstPort) == s->myport)
  640.                     break;
  641.  
  642.     if (s != NULL)
  643.         {
  644.             s->rdatalen = 0;
  645.         s->ip_type = 0;
  646.         }
  647.     return (1);                /* success */
  648. }
  649.  
  650. int
  651. tcp_cancel(in_Header *ip)
  652. {
  653.     int len;
  654.     register tcp_Socket *s;
  655.     register tcp_Header *tp;
  656.  
  657.     if (ip == NULL) return (0);        /* failure */
  658.     len = in_GetHdrlenBytes(ip);        /* check work */
  659.  
  660.     tp = (tcp_Header *)((byte *)ip + len);    /* TCP frame pointer */
  661.  
  662.                         /* demux to active sockets */
  663.     for (s = tcp_allsocs; s != NULL; s = s->next)
  664.             if (s->hisport != 0 &&
  665.              ntohs(tp->dstPort) == s->myport &&
  666.              ntohs(tp->srcPort) == s->hisport &&
  667.              ntohl(ip->source) == s->hisaddr)
  668.                  break;
  669.  
  670.     if (s == NULL)            /* demux to passive sockets */
  671.         for (s = tcp_allsocs; s != NULL; s = s->next)
  672.                 if (s->hisport == 0 &&
  673.                 ntohs(tp->dstPort) == s->myport)
  674.                     break;
  675.     if (s != NULL)
  676.         {
  677.         s->rdatalen = 0;
  678.         s->state = tcp_StateCLOSED;
  679.             s->ip_type = 0;
  680.         if (s->dataHandler) s->dataHandler(s, 0, -1);
  681.         tcp_unthread(s);
  682.         }
  683.     return (1);                /* success */
  684. }
  685.  
  686. static int 
  687. tcp_read(s, datap, maxlen)
  688. tcp_Socket *s;
  689. byte *datap;
  690. int maxlen;
  691. {
  692.     register int x;
  693.  
  694.     if (s == NULL || datap == NULL || maxlen == 0)
  695.             return (0);        /* failure or read nothing */
  696.     if ((x = s->rdatalen) > 0)
  697.         {
  698.         if (x > maxlen) x = maxlen;
  699.         bcopy(s->rdata, datap, x);    /* copy out desired data */
  700.         if ((s->rdatalen -= x) < 0)
  701.             s->rdatalen = 0;    /* readjust socket buf */
  702.         bcopy(&s->rdata[x], s->rdata, s->rdatalen);
  703.         tcp_sendsoon(s);        /* update the window */
  704.         }
  705.     return (x);                /* return bytes read */
  706. }
  707.  
  708. /*
  709.  * Write data to a connection.
  710.  * Returns number of bytes written, == 0 when connection is not in
  711.  * established state.
  712.  */
  713. static int
  714. tcp_Write(s, dp, len)
  715. tcp_Socket *s;
  716. byte *dp;
  717. int len;
  718. {
  719.     register int x;
  720.  
  721.     if (s == NULL || dp == NULL) return (0);    /* failure */
  722.     if (s->state != tcp_StateESTAB) len = 0;
  723.     if (len > (x = tcp_MaxBufSize - s->datalen)) len = x;
  724.     if (len > 0)
  725.         {
  726.         bcopy(dp, &s->data[s->datalen], len);
  727.         s->datalen += len;
  728.         s->unhappy = TRUE;/* redundant because of outstanding data */
  729.  
  730.         if (s->soc_mode & TCP_MODE_NONAGLE)
  731.             tcp_send(s);
  732.         else    /* transmit if first data or reached MTU */
  733.                 /* not true MTU, but better than nothing */
  734.             /* Nagle's algorithm, RFC 896 */
  735.                 if ((s->datalen == len) || (s->datalen > (s->mss)))
  736.                 tcp_send(s);
  737.         }
  738.     return (len);
  739. }
  740.  
  741. /*
  742.  * Send pending data
  743.  */
  744. static int
  745. tcp_Flush(s)
  746.     tcp_Socket *s;
  747. {
  748.     if (s == NULL) return (0);        /* failure */
  749.     if (s->datalen > 0)
  750.         {
  751.             s->flags |= tcp_FlagPUSH;
  752.         tcp_send(s);
  753.             }
  754.     return (1);                    /* success */
  755. }
  756.  
  757. /*
  758.  * Handler for incoming UDP packets. If no socket tell the host via ICMP.
  759.  */
  760. static int
  761. udp_handler(ip)
  762. in_Header *ip;
  763. {
  764.     register udp_Header *up;
  765.     register udp_Socket *s;
  766.     tcp_PseudoHeader ph;
  767.     byte *dp;
  768.     word len;
  769.  
  770.     len = in_GetHdrlenBytes(ip);
  771.     up = (udp_Header *)((byte *)ip + len);    /* UDP segment pointer */
  772.     len = ntohs(up->length);
  773.  
  774.                 /* demux to active sockets */
  775.     for (s = udp_allsocs; s != NULL; s = s->next)
  776.         if (s->hisport != 0 &&
  777.             ntohs(up->dstPort) == s->myport &&
  778.             ntohs(up->srcPort) == s->hisport &&
  779.             ntohl(ip->source) == s->hisaddr)
  780.                 break;
  781. #ifdef DEBUG
  782.     if (dbugrecv) (*dbugrecv)(s,ip,up);
  783. #endif
  784.  
  785.     if (s == NULL)            /* demux to passive sockets */
  786.         for (s = udp_allsocs; s != NULL; s = s->next)
  787.             if (s->hisaddr == 0 && 
  788.                 ntohs(up->dstPort) == s->myport)
  789.                 {
  790.                 if (arp_resolve(htonl(ip->source),
  791.                     &s->hisethaddr[0]))
  792.                     {
  793.                        s->hisaddr = ntohl(ip->source);
  794.                         s->hisport = ntohs(up->srcPort);
  795.                     }
  796.                 break;
  797.                     }
  798.  
  799.     if (s == NULL)        /* demux to broadcast sockets */
  800.         for (s = udp_allsocs; s != NULL; s = s->next)
  801.             if (s->hisaddr == ipbcast && 
  802.                 ntohs(up->dstPort) == s->myport)
  803.                     break;
  804.  
  805.     if (s == NULL)
  806.         {
  807.         icmp_noport(ip);    /* tell host port is unreachable */
  808.         if (debug_on) outs("discarding...");
  809.         return (0);            /* say no socket */
  810.         }
  811.  
  812.     if (up->checksum)
  813.         {
  814.         ph.src = ip->source;        /* already bigend'd */
  815.         ph.dst = ip->destination;
  816.         ph.mbz = 0;
  817.         ph.protocol = UDP_PROTO;
  818.         ph.length = up->length;
  819.         ph.checksum = checksum(up, len);
  820.         if (checksum(&ph, sizeof(tcp_PseudoHeader)) != 0xffff)
  821.             return (0);        /* failure */
  822.         }
  823.  
  824.                         /* process user data */
  825.     if ((len -= UDP_LENGTH) > 0)
  826.         {
  827.         dp = (byte *)(up);
  828.         if (s->dataHandler != NULL)
  829.             s->dataHandler(s, &dp[UDP_LENGTH], len, &ph);
  830.         else
  831.             {
  832.             if (len > udp_MaxBufSize) len = udp_MaxBufSize;
  833.             bcopy(&dp[UDP_LENGTH], s->rdata, len);
  834.             s->rdatalen = len;
  835.             }
  836.         }
  837.     return (1);                /* success */
  838. }
  839.  
  840. /* Handle TCP packets. If no socket send an RST pkt. */
  841.  
  842. static 
  843. tcp_handler(ip)
  844. in_Header *ip;
  845. {
  846.     register tcp_Header *tp;
  847.     tcp_PseudoHeader ph;
  848.     int len;
  849.     int diff;                /* signed, please */
  850.     register tcp_Socket *s;
  851.     word flags;
  852.     long diffticks, ldiff;            /* must be signed */
  853.  
  854.     len = in_GetHdrlenBytes(ip);
  855.     tp = (tcp_Header *)((byte *)ip + len);    /* tcp frame pointer */
  856.     len = ntohs(ip->length) - len;    /* len of tcp data */
  857.     flags = ntohs(tp->flags);        /* flags from pkt */
  858.  
  859.                 /* demux to active sockets */
  860.     for (s = tcp_allsocs; s != NULL; s = s->next)
  861.         if (s->hisport != 0 &&
  862.             ntohs(tp->dstPort) == s->myport &&
  863.             ntohs(tp->srcPort) == s->hisport &&
  864.             ntohl(ip->source) == s->hisaddr)
  865.             break;
  866.  
  867.     if (s == NULL)    /* demux to passive sockets, must be a new session */
  868.         for (s = tcp_allsocs; s != NULL; s = s->next)
  869.             if ((s->hisport == 0) &&
  870.                 (ntohs(tp->dstPort) == s->myport))
  871.                 break;
  872.  
  873. #ifdef DEBUG
  874.     if (dbugrecv) (*dbugrecv)(s, ip, tp);
  875. #endif
  876.  
  877.     if (s == NULL)
  878.         {
  879.          /* no session seems to exist, nor is there desire to start 
  880.          one, so we must send a reset    */
  881.         tcp_rst(ip, tp);
  882.         return (0);        /* 0 to say socket is closed */
  883.         }
  884.  
  885.                 /* save his ethernet address */
  886.     bcopy(&((((eth_Header *)ip) - 1)->source[0]), &s->hisethaddr[0],
  887.             sizeof(eth_address));
  888.  
  889.     ph.src = ip->source;            /* network order now */
  890.     ph.dst = ip->destination;
  891.     ph.mbz = 0;
  892.     ph.protocol = TCP_PROTO;
  893.     ph.length = htons(len);
  894.     ph.checksum =  checksum(tp, len);
  895.     if (checksum(&ph, sizeof(ph)) != 0xffff)
  896.         {
  897.          if (debug_on) outs("bad tcp checksum \n\r");
  898.          return (1);
  899.         }
  900.  
  901.                     /* reset code */
  902.     if (flags & tcp_FlagRST)
  903.         {
  904.         if (debug_on) outs("\7\7connection reset\n");
  905.         s->rdatalen = 0;
  906.         s->state = tcp_StateCLOSED;
  907.         if (s->dataHandler) s->dataHandler(s, 0, -1);
  908.         tcp_unthread(s);
  909.         return (0);            /* say socket is closed */
  910.         }
  911.  
  912.                     /* update our retransmission stuff */
  913.     if (s->karn_count != 2)
  914.         if ((diffticks = set_ttimeout(0) - s->vj_last) >= 0)
  915.         {                /* we ignore the overnight case */
  916.         diffticks -= (s->vj_sa >> 3);
  917.         s->vj_sa += (word)diffticks;
  918.         if (diffticks < 0)
  919.             diffticks = -diffticks;
  920.         diffticks -= (s->vj_sd >> 2);
  921.         s->vj_sd += diffticks;
  922.         s->rto = ((s->vj_sa >> 2) + s->vj_sd) >> 1;
  923.         s->karn_count = 0;
  924.         }        /* else (== 2) use the backed off rto */
  925.  
  926.     switch (s->state) {
  927.  
  928.     case tcp_StateLISTEN:            /* accepting SYNs */
  929.         if (flags & tcp_FlagSYN)
  930.         {
  931.         s->acknum = ntohl(tp->seqnum) + 1;
  932.         s->hisport = ntohs(tp->srcPort);
  933.         s->hisaddr = ntohl(ip->source);
  934.         s->flags = tcp_FlagSYN | tcp_FlagACK;
  935.         server_hello(s);    /* put greeting msg in socket */
  936.         tcp_send(s);        /* we must respond immediately */
  937.         s->state = tcp_StateSYNREC;
  938.             s->unhappy = FALSE;
  939.         s->timeout = set_timeout(tcp_TIMEOUT);
  940.         }
  941.     else
  942.             tcp_rst(ip, tp);  /* send a reset */
  943.         break;
  944.  
  945.     case tcp_StateSYNSENT:        /* added ACK Section */
  946.     if (flags & tcp_FlagSYN)
  947.         {
  948.             s->flags = tcp_FlagACK;
  949.         s->timeout = set_timeout(tcp_TIMEOUT);
  950.  
  951.         /* FlagACK means connection established, else SYNREC */
  952.         if (flags & tcp_FlagACK)
  953.             {      /* but is it for the correct session? */
  954.             if (tp->acknum == htonl(s->seqnum + 1))
  955.                 {
  956.                 s->state = tcp_StateESTAB;
  957.                 s->seqnum++;        /* good increment */
  958.                 s->acknum = ntohl(tp->seqnum) + 1; /*32 bits*/
  959.                 s->unhappy = TRUE;
  960.                 tcp_ProcessData(s, tp, len);
  961.                 }
  962.             else
  963.                 { /* wrong ack, force a RST and resend SYN*/
  964.                 s->flags = tcp_FlagRST;
  965.                 s->unhappy = TRUE;
  966.                 tcp_send(s);
  967.                 s->unhappy = FALSE; /* no need to retransmit */
  968.                 s->flags = tcp_FlagSYN;
  969.                 tcp_send(s);
  970.                 }
  971.             }
  972.         else
  973.             {
  974.             s->acknum++;
  975.             s->state = tcp_StateSYNREC;
  976.             /* maybe check sequence number stuff too */
  977.             }
  978.         }
  979.     break;
  980.  
  981.     case tcp_StateSYNREC:    /* recSYNSENT, sentACK, waiting EST */
  982.     if (flags & tcp_FlagSYN)
  983.         {
  984.         s->flags = tcp_FlagSYN | tcp_FlagACK;
  985.             tcp_send(s);
  986.         s->timeout = set_timeout(tcp_TIMEOUT);
  987.         }
  988.     if ((flags & tcp_FlagACK) && (ntohl(tp->acknum) == (s->seqnum + 1)))
  989.         {
  990.         s->flags = tcp_FlagACK;
  991.         tcp_send(s);
  992.         s->seqnum++;
  993.         s->unhappy = FALSE;
  994.         s->state = tcp_StateESTAB;
  995.             s->timeout = 0;             /* never timeout */
  996.         tcp_ProcessData(s, tp, len);
  997.         }
  998.     break;
  999.  
  1000.     case tcp_StateESTAB:
  1001.     if ((flags & tcp_FlagACK) == 0) return (1); /* they must ack somthing*/
  1002.  
  1003.     s->timeout = 0L;    /* we do not timeout at this point */
  1004.                 /* process their ack value in packet */
  1005.     /* If their ack preceeds the window this is an old pkt. */
  1006.     /* If ack exceeds the window then they are lying, don't believe. */
  1007.     /* However, in all cases grab any useful data for us. */        
  1008.     ldiff = ntohl(tp->acknum) - s->seqnum; /* current - prev ack */
  1009.     if (ldiff >= 0 && ldiff <= s->datalen)
  1010.         {             /* their ack is in our window*/
  1011.         s->seqnum += ldiff;    /* update ACK'd file pointer */
  1012.         diff = ldiff;        /* 16 bits, bigger than our window */
  1013.         s->datalen -= diff;    /* deduct amount ACK'd */
  1014.                     /* move down residual in send buf */
  1015.          bcopy(&s->data[diff], s->data, s->datalen);
  1016.         }
  1017.     s->flags = tcp_FlagACK;        /* tell them thanks */
  1018.     tcp_ProcessData(s, tp, len);    /* process our data in the packet */
  1019.     if (ldiff != 0 || len != 0)
  1020.         tcp_sendsoon(s);
  1021.     break;
  1022.  
  1023.     case tcp_StateFINWT1:
  1024.                     /* process ack value in packet */
  1025.     ldiff = ntohl(tp->acknum) - s->seqnum; /* current - prev ack */
  1026.     if (ldiff >= 0 && ldiff <= s->datalen) /* their ack is in our window*/
  1027.         {
  1028.         s->seqnum += ldiff;    /* update ACK'd file counter */
  1029.         diff = ldiff;        /* 16 bits, more than our window */
  1030.         s->datalen -= diff;    /* deduct amount ACK'd */
  1031.         bcopy(&s->data[diff], s->data, s->datalen); /* move residual */
  1032.         }
  1033.     tcp_ProcessData(s, tp, len);    /* process our data in the packet */
  1034.  
  1035.     if (flags & tcp_FlagFIN)    /* trying to do simultaneous close */
  1036.         {
  1037.         if ((ntohl(tp->acknum) >= s->seqnum + 1) &&
  1038.             (ntohl(tp->seqnum) == s->acknum))
  1039.             {        /* other guy wishes to close too */
  1040.             s->seqnum++;
  1041.             s->acknum++;
  1042.             s->flags = tcp_FlagACK;
  1043.             s->unhappy = TRUE;
  1044.             s->timeout = set_timeout(3);
  1045.             s->state = tcp_StateCLOSING;
  1046.             }
  1047.         }
  1048.     else if (flags & tcp_FlagACK)
  1049.                    /* other side is legitimately acking our fin */
  1050.         if ((ntohl(tp->acknum) == s->seqnum + 1) &&
  1051.             (ntohl(tp->seqnum) == s->acknum) &&
  1052.             (s->datalen == 0))
  1053.             {
  1054.             s->seqnum++;
  1055.             s->datalen = 0;
  1056.             s->state = tcp_StateFINWT2;
  1057.                 s->timeout = set_timeout(3);
  1058.             s->unhappy = FALSE;
  1059.             }
  1060.     break;
  1061.  
  1062.     case tcp_StateFINWT2:        /* we can timeout of this state */
  1063.     if ((flags & (tcp_FlagACK | tcp_FlagFIN)) ==
  1064.         (tcp_FlagACK | tcp_FlagFIN))
  1065.         if ((ntohl(tp->acknum) == s->seqnum) &&
  1066.             (ntohl(tp->seqnum) == s->acknum))
  1067.             {
  1068.             s->acknum++;
  1069.             s->flags = tcp_FlagACK;
  1070.             tcp_send(s);
  1071.             s->unhappy = FALSE;
  1072.             s->timeout = set_timeout(2); /* max seg life 2 sec */
  1073.             s->state = tcp_StateTIMEWT;
  1074.             }
  1075.     break;
  1076.  
  1077.     case tcp_StateCLOSING:
  1078.         if ((flags & (tcp_FlagACK | tcp_FlagFIN)) == tcp_FlagACK)
  1079.         if ((tp->acknum == htonl(s->seqnum)) &&
  1080.             (tp->seqnum == htonl(s->acknum))) /* all agree */
  1081.         {
  1082.         s->state = tcp_StateTIMEWT;
  1083.         s->timeout = set_timeout(tcp_TIMEOUT);
  1084.         s->unhappy = FALSE;        /* no more retransmissions */
  1085.         }
  1086.     break;
  1087.  
  1088.     case tcp_StateLASTACK:
  1089.     if (flags & tcp_FlagFIN)    /* they lost our two packets, back up */
  1090.         {
  1091.         s->flags = tcp_FlagACK;
  1092.         tcp_send(s);
  1093.         s->flags = tcp_FlagACK | tcp_FlagFIN;
  1094.         tcp_send(s);
  1095.         s->unhappy = FALSE;
  1096.         }
  1097.     else
  1098.         {
  1099.         if ((ntohl(tp->acknum) == (s->seqnum + 1)) &&
  1100.             (ntohl(tp->seqnum) == s->acknum))
  1101.                 s->state = tcp_StateCLOSED;     /* no 2 msl */
  1102.         tcp_unthread(s);
  1103.         return (1);
  1104.         }
  1105.     break;
  1106.  
  1107.     case tcp_StateTIMEWT:
  1108.     s->flags = tcp_FlagACK;
  1109.     s->acknum = ntohl(tp->seqnum) + 1;
  1110.     tcp_send(s);
  1111.     break;
  1112.     }                        /* end switch */
  1113.     if (s->unhappy == TRUE) tcp_sendsoon(s);
  1114.     return (1);                    /* success */
  1115. }
  1116.  
  1117. /*
  1118.  * Process the data in an incoming packet.
  1119.  * Called from all states where incoming data can be received: established,
  1120.  * fin-wait-1, fin-wait-2
  1121.  */
  1122. static int
  1123. tcp_ProcessData(s, tp, len)
  1124. tcp_Socket *s;
  1125. tcp_Header *tp;
  1126. int len;
  1127. {
  1128.     register int diff, x;
  1129.     long ldiff;                    /* signed */
  1130.     byte *dp;
  1131.     word flags, *options, numoptions, opt_temp;
  1132.  
  1133.     if (s == NULL || tp == NULL) return (0);    /* failure */
  1134.  
  1135.     s->window = ntohs(tp->window);
  1136.     flags = ntohs(tp->flags);
  1137.     ldiff = s->acknum - ntohl(tp->seqnum);    /* signed long */
  1138.     if (flags & tcp_FlagSYN) ldiff--;    /* SYN counts as one unit */
  1139.     diff = ldiff;                /* 16 bit version */
  1140.  
  1141.                         /* find the data portion */
  1142.     x = tcp_GetDataOffset(tp) << 2;        /* quadword to byte format */
  1143.     dp = (byte *)tp + x;
  1144.  
  1145.                         /* process those options */
  1146.     if (numoptions = x - sizeof(tcp_Header))
  1147.         {
  1148.         options = (word *)(tp + sizeof(tcp_Header));
  1149.         while (numoptions-- > 0)
  1150.             switch (*options++)
  1151.                 {
  1152.                 case 0: numoptions = 0;    /* end of options */
  1153.                 case 1: break;        /* nop */
  1154.  
  1155.                   /* we are very liberal on MSS stuff */
  1156.                 case 2: if (*options == 2)
  1157.                         {
  1158.                 opt_temp = ntohs(*(word*)(&options[1]));
  1159.                         if (opt_temp < s->mss)
  1160.                             s->mss = opt_temp;
  1161.                         }
  1162.                     numoptions -= 2 + *options;
  1163.                     options += *options;
  1164.                       break;
  1165.                 }    /* end of switch and while */
  1166.         }            /* end of if */
  1167.                     /* done option processing */
  1168.  
  1169.     len -= x;            /* remove the header length */
  1170.     if (diff >= 0)            /* skip already received bytes */
  1171.         {
  1172.         dp += diff;
  1173.         len -= diff;
  1174.  
  1175.         if (s->dataHandler != NULL)
  1176.             s->acknum += s->dataHandler(s, dp, len);
  1177.         else
  1178.     /* no handler, just dump to buffer, should be indexed, handles goofs */
  1179.                     /* limit receive size to our window */
  1180.             if (s->rdatalen >= 0)
  1181.                 {
  1182.                 if (len > (x = tcp_MaxBufSize - s->rdatalen))
  1183.                     len = x;
  1184.                 if (len > 0)
  1185.                     {  /* new ack begins at end of data */
  1186.                     s->acknum += len;
  1187.                     bcopy(dp, &s->rdata[s->rdatalen], len);
  1188.                     s->rdatalen += len;
  1189.                     }
  1190.                 }    /* end of  if (s->datalen.. else */
  1191.         }                /* end of if (diff > 0) */
  1192.     s->unhappy = (s->datalen != 0)? TRUE: FALSE;
  1193.  
  1194.     if (flags & tcp_FlagFIN)
  1195.         {
  1196.         s->acknum++;
  1197.         switch (s->state)
  1198.             {
  1199.                 case tcp_StateESTAB:
  1200.                 s->err_msg = "Connection closed.";
  1201.                             /* tcp_StateCLOSWT ... here we go */
  1202.                 x = tcp_StateLASTACK;
  1203.                 s->flags |= tcp_FlagFIN;
  1204.                 s->unhappy = TRUE;    /* to send packet */
  1205.                 break;
  1206.  
  1207.             case tcp_StateFINWT1:    /* on ack should go to finwt2 */
  1208.                 s->flags |= tcp_FlagFIN;
  1209.                     /* not certain of this addition */
  1210.                 x = tcp_StateCLOSING;
  1211.                 break;
  1212.  
  1213.                 case tcp_StateFINWT2:
  1214.                 x = tcp_StateTIMEWT;
  1215.                 break;
  1216.             }            /* end of switch (s->state) */
  1217.         s->state = x;
  1218.         }            /* end of if (flags & tcp_FlagFIN) */
  1219.     s->timeout = set_timeout(tcp_TIMEOUT);
  1220.     return (1);                /* success */
  1221. }
  1222.  
  1223. /*
  1224.  * Format and send an outgoing segment
  1225.  */
  1226. static int
  1227. tcp_send(s)
  1228. tcp_Socket *s;
  1229. {
  1230.     tcp_PseudoHeader ph;
  1231.     struct pkt
  1232.         {
  1233.         in_Header in;
  1234.         tcp_Header tcp;
  1235.         word maxsegopt[2];
  1236.         } register *pkt;
  1237.     byte *dp;
  1238.     int senddatalen, sendtotlen, sendpktlen;
  1239.     register int ippkt;                /* 1..s->cwindow */
  1240.  
  1241.     if (s == NULL) return (0);        /* failure */
  1242.  
  1243.     pkt = (struct pkt *)eth_formatpacket(&s->hisethaddr[0], 0x0008);
  1244.     dp = (byte *)pkt->maxsegopt;  /* dp constant for multi-packet sends */
  1245.  
  1246.                     /* this is our total possible send size */
  1247.     if (s->window > 0)
  1248.         senddatalen = (s->datalen >= s->window)? 
  1249.             s->window - 1: s->datalen;
  1250.     else    senddatalen = 0;
  1251.  
  1252.     sendtotlen = 0;            /* running count of what we've sent */
  1253.  
  1254.                     /* step through our packets */
  1255.     for (ippkt = 1; ippkt <= s->cwindow; ippkt++)
  1256.         {            /* adjust size for each packet */
  1257.             if (senddatalen > s->mss)
  1258.             senddatalen = s->mss;
  1259.                     /* tcp header */
  1260.             pkt->tcp.srcPort = htons(s->myport);
  1261.             pkt->tcp.dstPort = htons(s->hisport);
  1262.             pkt->tcp.seqnum = htonl(s->seqnum + sendtotlen);
  1263.             pkt->tcp.acknum = htonl(s->acknum);
  1264.             pkt->tcp.window = htons(s->rmaxdatalen - s->rdatalen);
  1265.             pkt->tcp.flags = htons(s->flags | 0x5000);
  1266.             pkt->tcp.checksum = 0;
  1267.             pkt->tcp.urgentPointer = 0;
  1268.  
  1269.                 /* do options if this is our first packet */
  1270.             if ((s->flags & (tcp_FlagSYN | tcp_FlagACK)) == tcp_FlagSYN)
  1271.             {
  1272.             sendpktlen = sizeof(tcp_Header) + 
  1273.                     sizeof(in_Header) + 4;
  1274.             pkt->tcp.flags = htons(ntohs(pkt->tcp.flags) + 0x1000);
  1275.             pkt->maxsegopt[0] = 0x0402;
  1276.             pkt->maxsegopt[1] = htons(s->mss);
  1277.             dp += 4;
  1278.             }
  1279.         else
  1280.             {    
  1281.                 /* handle no-data, not-first-SYN packets */
  1282.                     sendpktlen = sizeof(tcp_Header) + sizeof(in_Header);
  1283.             if (senddatalen > 0)    /* handle packets with data */
  1284.                 {
  1285.                         sendpktlen += senddatalen;
  1286.                         bcopy(s->data, dp, senddatalen);
  1287.                 }
  1288.                 }
  1289.  
  1290.                     /* Internet header */
  1291.         pkt->in.hdrlen_ver = 0x45;    /* version 4, hdrlen 5 */
  1292.             pkt->in.tos = 0;        /* crummy service is ok */
  1293.             pkt->in.identification = htons(++ip_id); /* pre-inc req'd */
  1294.             pkt->in.frag = 0;        /* we can't do fragments */
  1295. #ifdef KERMIT
  1296.             pkt->in.ttl = 60;        /* seconds */
  1297. #else
  1298.             pkt->in.ttl = 254;
  1299. #endif
  1300.         pkt->in.proto = TCP_PROTO;
  1301.             pkt->in.checksum = 0;
  1302.             pkt->in.source = htonl(my_ip_addr);
  1303.             pkt->in.destination = htonl(s->hisaddr);
  1304.             pkt->in.length = htons(sendpktlen);
  1305.  
  1306.             pkt->in.checksum = ~checksum(&pkt->in, sizeof(in_Header));
  1307.  
  1308.             /* compute tcp checksum */
  1309.             ph.src = pkt->in.source;   /* already in network order */
  1310.             ph.dst = pkt->in.destination;
  1311.             ph.mbz = 0;
  1312.             ph.protocol = TCP_PROTO;
  1313.             ph.length = htons(sendpktlen - sizeof(in_Header));
  1314.             ph.checksum = checksum(&pkt->tcp,
  1315.                 (sendpktlen - sizeof(in_Header) + 1) & 0xfffe);
  1316.             pkt->tcp.checksum = ~checksum(&ph, sizeof(ph));
  1317.  
  1318. #ifdef DEBUG
  1319.             if (dbugxmit) (*dbugxmit)(s, &pkt->in, &pkt->tcp);
  1320. #endif
  1321.             if (eth_send(htons(pkt->in.length)) == 0)
  1322.             return (0);            /* sending failed */
  1323.             sendtotlen += senddatalen;
  1324.     }                    /* do next ip pkt */
  1325.  
  1326.     if (s->karn_count == 2)
  1327.         {
  1328.             if (s->rto) s->rto = (s->rto * 3) / 2;
  1329.         else s->rto = 4;
  1330.             }
  1331.     else
  1332.             {
  1333.         s->vj_last = set_ttimeout(0);
  1334.         s->karn_count = 0;
  1335.         }
  1336.     s->rtt_time = set_ttimeout(s->rto);
  1337.     return (1);                    /* success */
  1338. }
  1339. /*
  1340.  * Format and send a reset tcp packet
  1341.  */
  1342. int
  1343. tcp_rst(in_Header *his_ip, tcp_Header *oldtcpp)
  1344. {
  1345.     tcp_PseudoHeader ph;
  1346.     struct pkt
  1347.         {
  1348.             in_Header in;
  1349.             tcp_Header tcp;
  1350.         word maxsegopt[2];
  1351.         } register *pkt;
  1352.  
  1353.     eth_Header *eth;
  1354.     register int sendtotlen;            /* length of packet */
  1355.  
  1356.     if (his_ip == NULL || oldtcpp == NULL) return (0);    /* failure */
  1357.  
  1358.                     /* see RFC 793 page 65 for details */
  1359.     oldtcpp->flags = ntohs(oldtcpp->flags);        /* net to local */
  1360.  
  1361.     if (oldtcpp->flags & tcp_FlagRST)
  1362.         return (0);  
  1363.     if ((oldtcpp->flags & tcp_FlagACK) == 0)
  1364.             oldtcpp->flags = tcp_FlagACK;
  1365.     else
  1366.             oldtcpp->flags = 0;
  1367.  
  1368.                 /* reads his Ethernet address or garbage */
  1369.     eth = eth_hardware((byte *)his_ip);
  1370.  
  1371.     pkt = (struct pkt *)eth_formatpacket(eth, 0x0008);
  1372.     sendtotlen = sizeof(tcp_Header) + sizeof(in_Header);
  1373.     pkt->in.length = htons(sendtotlen);
  1374.                     /* TCP header */
  1375.     pkt->tcp.srcPort = oldtcpp->dstPort;
  1376.     pkt->tcp.dstPort = oldtcpp->srcPort;
  1377.     pkt->tcp.seqnum = oldtcpp->acknum;
  1378.     pkt->tcp.acknum = htonl(ntohl(oldtcpp->seqnum) + 1);
  1379.     pkt->tcp.window = 0;
  1380.     pkt->tcp.flags = htons(tcp_FlagRST | oldtcpp->flags | 0x5000);
  1381.     pkt->tcp.checksum = 0;
  1382.     pkt->tcp.urgentPointer = 0;
  1383.                     /* Internet header */
  1384.     pkt->in.hdrlen_ver = 0x45;        /* version 4, hdrlen 5 */
  1385.     pkt->in.tos = 0;
  1386.     pkt->in.identification = htons(++ip_id); /* use pre-inc here */
  1387.     pkt->in.frag = 0;
  1388. #ifdef KERMIT
  1389.     pkt->in.ttl = 60;            /* time to live */
  1390. #else
  1391.     pkt->in.ttl = 254;
  1392. #endif
  1393.     pkt->in.proto = TCP_PROTO;
  1394.     pkt->in.checksum = 0;
  1395.     pkt->in.source = his_ip->destination;
  1396.     pkt->in.destination = his_ip->source;
  1397.     pkt->in.checksum = ~checksum(&pkt->in, sizeof(in_Header));
  1398.                         /* compute TCP checksum */
  1399.     ph.src = pkt->in.source;        /* already big endian */
  1400.     ph.dst = pkt->in.destination;
  1401.     ph.mbz = 0;
  1402.     ph.protocol = TCP_PROTO;
  1403.     ph.length = htons(sendtotlen - sizeof(in_Header));
  1404.     ph.checksum = checksum(&pkt->tcp, (sendtotlen - sizeof(in_Header) + 1)
  1405.                                 & 0xfffe);
  1406.     pkt->tcp.checksum = ~checksum(&ph, sizeof(ph));
  1407.  
  1408. #ifdef DEBUG
  1409.     if (dbugxmit) (*dbugxmit)(NULL, &pkt->in, &pkt->tcp);
  1410. #endif
  1411.     return (eth_send(htons(pkt->in.length)));
  1412. }
  1413.  
  1414. /* Handle ICMP Redirects. ICMP processor yields new gateway IP number
  1415.    in "gateway" and pointer to offending IP header which we have sent.
  1416.    Find socket with destination IP address matching the gateway
  1417.    sending us the Redirect message, replace the socket's destination
  1418.    Ethernet address with that of the new gateway (use arp_resolve).
  1419.    For TCP resend the packet, for UDP give up all hope.
  1420. */
  1421. void
  1422. do_redirect(longword gateway, in_Header *ip)
  1423. {
  1424.     register udp_Socket *s_udp;
  1425.     register tcp_Socket *s_tcp;
  1426.     longword host;
  1427.  
  1428.     host = ntohl(ip->destination);        /* destination IP */
  1429.                         /* active TCP sockets */
  1430.     for (s_tcp = tcp_allsocs; s_tcp != NULL; s_tcp = s_tcp->next)
  1431.         if (host == s_tcp->hisaddr)    /* if same dest IP */
  1432.             {
  1433.             arp_resolve(gateway, &s_tcp->hisethaddr[0]);
  1434.             tcp_send(s_tcp);    /* resend the packet */
  1435.             }
  1436.                     /* active UDP sockets */
  1437.     for (s_udp = udp_allsocs; s_udp != NULL; s_udp = s_udp->next)
  1438.         if (host == s_udp->hisaddr)
  1439.             arp_resolve(gateway, &s_udp->hisethaddr[0]);
  1440. }
  1441.  
  1442. /**********************************************************************
  1443.  * socket functions
  1444.  **********************************************************************/
  1445.  
  1446. /* socket based procedures */
  1447.  
  1448. /*
  1449.  * sock_yield - enable user defined yield function
  1450.  */
  1451. void
  1452. sock_yield(tcp_Socket *s, void (*fn)())
  1453. {
  1454.     if (s != NULL)
  1455.         s->usr_yield = fn;
  1456.     else
  1457.         system_yield = fn;
  1458. }
  1459.  
  1460. /*
  1461.  * sock_mode - set binary or ascii - affects sock_gets, sock_dataready
  1462.  *         - set udp checksums
  1463.  */
  1464. int
  1465. sock_mode(tcp_Socket *s, word mode)
  1466. {
  1467.     if (s != NULL)
  1468.         {
  1469.         s->soc_mode = (s->soc_mode & 0xfffc) | mode;
  1470.         return (1);        /* success */
  1471.         }
  1472.     else
  1473.         return (0);        /* failure */
  1474. }
  1475.  
  1476. /*
  1477.  * sock_read - read a socket with maximum n bytes
  1478.  *         - busywaits until buffer is full but calls s->usr_yield
  1479.  *         - returns count also when connection gets closed
  1480.  */
  1481. int
  1482. sock_read(sock_type *s, byte *dp, int len)
  1483. {
  1484.     register int templen, count;
  1485.     count = 0;
  1486.  
  1487.     if (s == NULL || dp == NULL) return (0);        /* failure */
  1488.     do
  1489.             {
  1490.         if (s->udp.ip_type == UDP_PROTO)
  1491.             templen = udp_read(s, dp, len);
  1492.         else
  1493.             templen = tcp_read(s, dp, len);
  1494.         if (templen = 0)
  1495.             if (tcp_tick(s) == 0) return (count);
  1496.         if (s->tcp.usr_yield != NULL) (s->tcp.usr_yield)();
  1497.         count += templen;
  1498.         len -= templen;
  1499.             }
  1500.     while (len > 0);
  1501.        return (count);
  1502. }
  1503.  
  1504. /*
  1505.  * sock_fastread - read a socket with maximum n bytes
  1506.  *         - does not busywait until buffer is full
  1507.  */
  1508. int
  1509. sock_fastread(sock_type *s, byte *dp, int len)
  1510. {
  1511.     if (s == NULL || dp == NULL) return (0);    /* failure */
  1512.     if (s->udp.ip_type == UDP_PROTO)
  1513.         len = udp_read(s, dp, len);
  1514.     else
  1515.         len = tcp_read(s, dp, len);
  1516.     return (len);
  1517. }
  1518.  
  1519.  
  1520. /*
  1521.  * sock_write - writes data and returns length written
  1522.  *          - does not perform flush
  1523.  *          - repeatedly calls s->usr_yield
  1524.  */
  1525. int
  1526. sock_write(sock_type *s, byte *dp, int len)
  1527. {
  1528.     register int offset;
  1529.     int oldlen;        /* don't register since di gets clobbered */
  1530.                 /* by odipkt.com */
  1531.  
  1532.     oldlen = len;
  1533.     offset = 0;
  1534.     if (s == NULL || dp == NULL) return (0);    /* failure */
  1535.     while (len  > 0)
  1536.         {
  1537.         if (s->udp.ip_type == UDP_PROTO)
  1538.             offset += udp_Write(s, dp + offset, len);
  1539.         else
  1540.             offset += tcp_Write(s, dp + offset, len);
  1541.         len = oldlen - offset;
  1542.         if (s->udp.usr_yield != NULL) (s->udp.usr_yield)();
  1543.         if (tcp_tick(s) == 0) return (0);    /* no socket */
  1544.         }
  1545.     return (oldlen);
  1546. }
  1547.  
  1548. int
  1549. sock_fastwrite(sock_type *s, byte *dp, int len)
  1550. {
  1551.     tcp_tick(NULL);                /* updates our output buffer*/
  1552.     if (s == NULL) return (0);        /* failure */
  1553.  
  1554.     return ((s->udp.ip_type == UDP_PROTO)? 
  1555.         udp_Write(s, dp, len):
  1556.         tcp_Write(s, dp, len));
  1557. }
  1558.  
  1559. int
  1560. sock_flush(sock_type *s)
  1561. {
  1562.     if (s == NULL) return (0);            /* failure */
  1563.     if (s->tcp.ip_type == TCP_PROTO)
  1564.         tcp_Flush(s);
  1565.     return (1);
  1566. }
  1567. /*
  1568.  * sock_flushnext - cause next transmission to have a flush
  1569.  */
  1570. int
  1571. sock_flushnext(sock_type *s)
  1572. {
  1573.     if (s == NULL) return (0);            /* failure */
  1574.     if (s->tcp.ip_type == TCP_PROTO)
  1575.         s->tcp.flags |= tcp_FlagPUSH;
  1576.     return (1);                    /* success */
  1577. }
  1578. /*
  1579.  * sock_putc - put a character
  1580.  *         - no expansion but flushes on '\n'
  1581.  *         - returns character
  1582.  */
  1583. int
  1584. sock_putc(sock_type *s, byte c)
  1585. {
  1586.     byte ch;
  1587.  
  1588.     ch = c;
  1589.     if (s == NULL) return (-1);            /* failure */
  1590.     if ((ch == '\n') || (ch == '\r'))
  1591.         sock_flushnext(s);
  1592.     sock_write(s, &ch, 1);
  1593.     return (ch & 0xff);
  1594. }
  1595.  
  1596. int
  1597. sock_getc(sock_type *s)
  1598. {
  1599.     byte ch;
  1600.  
  1601.     if (s == NULL) return (-1);            /* failure */
  1602.     sock_read(s, &ch, 1);
  1603.     return (ch & 0xff);
  1604. }
  1605.  
  1606. #ifndef KERMIT
  1607. /*
  1608.  * sock_puts - does not append carriage return in binary mode
  1609.  *         - returns length
  1610.  */
  1611. int
  1612. sock_puts(sock_type *s, byte *dp)
  1613. {
  1614.     register int len;
  1615.  
  1616.     if (s == NULL || dp == NULL) return (0);    /* failure */
  1617.  
  1618.     len = strlen(dp);
  1619.     sock_flushnext(s);
  1620.     sock_write(s, dp, len);
  1621.     if (s->tcp.soc_mode & TCP_MODE_ASCII)
  1622.         sock_putc(s, '\n');
  1623.     return (len);
  1624. }
  1625. #endif    /* KERMIT */
  1626.  
  1627. /*
  1628.  * sock_update - update the socket window size to the other guy
  1629.  * Note: a better and safer criterion is s->rdatalen < mss
  1630.  *  which allows room for a full incoming segment without loss or overflow.
  1631.  */
  1632. static int
  1633. sock_update(tcp_Socket *s)
  1634. {
  1635.     if (s == NULL) return (0);            /* failure */
  1636.     if (s->ip_type == TCP_PROTO)
  1637.         {
  1638.         if (s->rdatalen < (3 * s->rmaxdatalen) / 4)
  1639.             tcp_send(s);        /* update the window */
  1640.         else
  1641.             tcp_sendsoon(s);
  1642.         }
  1643.     return (1);                    /* success */
  1644. }
  1645. #ifndef KERMIT
  1646. /*
  1647.  * sock_gets - read a string from any socket
  1648.  *         - return length of returned string
  1649.  *         - removes end of line terminator
  1650.  */
  1651. word 
  1652. sock_gets(sock_type *s, byte *dp, int n)
  1653. {
  1654.     int len, templen;
  1655.     byte *src_p, *temp, *temp2;
  1656.     word *np;
  1657.  
  1658.  
  1659.     if (s == NULL || dp == NULL) return (0);        /* failure */
  1660.  
  1661.     if (s->udp.ip_type == UDP_PROTO) {
  1662.         if (n > udp_MaxBufSize) n = udp_MaxBufSize;
  1663.     src_p = s->udp.rdata;
  1664.     np = &s->udp.rdatalen;
  1665.     } else {
  1666.        if (n > tcp_MaxBufSize) n = tcp_MaxBufSize;
  1667.     src_p = s->tcp.rdata;
  1668.     np = &s->tcp.rdatalen;
  1669.     }
  1670.  
  1671.     src_p[ *np ] = 0;         /* terminate string */
  1672.     strncpy(dp, src_p, n);    /* copy everything */
  1673.     dp[ n-1 ] = 0;        /* terminate */
  1674.  
  1675.     if (temp = strchr(dp, '\n')) *temp = 0;
  1676.     if (temp2= strchr(dp, '\r')) *temp2= 0;
  1677.     len = strlen(dp);
  1678.  
  1679.                 /* skip if there were no crs or lfs ??? */
  1680.     if ((temp2 == NULL) && (temp == NULL) && (strlen(dp) < n - 1)) {
  1681.     *dp = 0;
  1682.     return (0);
  1683.     }
  1684.  
  1685.                 /* skip over \n and \r but stop on end */
  1686. #ifndef OLD
  1687.     if (temp) templen = temp - (byte *)dp;
  1688.     else if (temp2) templen = temp2 - (byte *)dp;
  1689.     else templen = len + 1;
  1690.  
  1691.     if (templen) {
  1692.         templen++;
  1693.         bcopy(&src_p[ templen ], src_p, *np -= templen);
  1694.     } else
  1695.         *np = 0;
  1696. #else
  1697.     temp = &src_p[ len + 1 ];
  1698.     while (*temp && ((*temp == '\n') || (*temp == '\r')))
  1699.     temp++;
  1700.  
  1701.     if (*temp)
  1702.     bcopy(temp, src_p, *np = strlen(temp));
  1703.     else
  1704.     *np = 0;
  1705. #endif /* OLD */
  1706.  
  1707.     sock_update((tcp_Socket *)s);    /* new window */
  1708.     return (len);
  1709. }
  1710. #endif    /* KERMIT */
  1711.  
  1712. /*
  1713.  * sock_dataready - returns number of bytes waiting to be read
  1714.  *          - if in ASCII mode, return 0 until a line is present
  1715.  *            or the buffer is full
  1716.  */
  1717. word 
  1718. sock_dataready(sock_type *s)
  1719. {
  1720.     register int len;
  1721.     register byte *p;
  1722.  
  1723.     if (s == NULL) return (0);            /* failure */
  1724.     if ((len = s->tcp.rdatalen) == 0) return (0);
  1725.  
  1726.     if (s->tcp.soc_mode & TCP_MODE_ASCII)
  1727.         {
  1728.         if (len == tcp_MaxBufSize)
  1729.             return (tcp_MaxBufSize);
  1730.                 /* check for terminating \n \r */
  1731.         p = s->tcp.rdata;
  1732.         if ((strchr(p, '\n') == NULL) || (strchr(p, '\r') == NULL))
  1733.             return (len);
  1734.         return (0);
  1735.         }
  1736.         return (len);
  1737. }
  1738.  
  1739. int
  1740. sock_established(sock_type *s)
  1741. {
  1742.     if (s == NULL) return (0);            /* failure */
  1743.     switch (s->tcp.ip_type)
  1744.         {
  1745.         case UDP_PROTO:
  1746.             return (1);
  1747.         case TCP_PROTO:
  1748.             return (s->tcp.state == tcp_StateESTAB);
  1749.         default:
  1750.             return (0);
  1751.         }
  1752. }
  1753.  
  1754. int
  1755. sock_close(s)
  1756. sock_type *s;
  1757. {
  1758.     register int status;
  1759.  
  1760.     if (s == NULL) return (0);            /* failure */
  1761.     switch (s->udp.ip_type)
  1762.         {
  1763.         case UDP_PROTO :
  1764.             status = udp_close(s);
  1765.             break;
  1766.         case TCP_PROTO :
  1767.             status = tcp_close(s);
  1768.             tcp_tick(s);
  1769.             break;
  1770.         }
  1771.     return (status);                    /* success */
  1772. }
  1773.  
  1774. /* return count of chars in socket receive buffer which lie before char ch */
  1775. word
  1776. sock_findch(sock_type *s, byte ch)
  1777. {
  1778.     int i;
  1779.     int len;
  1780.     register byte c = ch;
  1781.     register byte * p;
  1782.  
  1783.     tcp_tick(s);                /* update socket buffer */
  1784.     if ((len = sock_dataready(s)) == 0)    /* get qty available */
  1785.         return (-1);            /* say no char available */
  1786.     p = s->tcp.rdata;        /* point to start of socket buffer */
  1787.     for (i = 0; i < len; i++)        /* scan for byte ch */
  1788.         if (*p++ == ch) break;        /* stop when found */
  1789.     return (i);
  1790. }
  1791.     
  1792.  
  1793. /*
  1794.  * ip user level timer stuff
  1795.  *   void ip_timer_init(void *s, int delayseconds)
  1796.  *   int  ip_timer_expired(void *s)
  1797.  *    - 0 if not expired
  1798.  */
  1799.  
  1800.  
  1801. void 
  1802. ip_timer_init(s, delayseconds)
  1803. udp_Socket *s;
  1804. int delayseconds;
  1805. {
  1806.     if (s == NULL)
  1807.         return;
  1808.     if (delayseconds != 0)
  1809.         s->usertimer = set_timeout(delayseconds);
  1810.     else
  1811.         s->usertimer = 0;
  1812. }
  1813.  
  1814. int 
  1815. ip_timer_expired(s)
  1816. udp_Socket *s;
  1817. {
  1818.     if (s == NULL) return (1);            /* say time out */
  1819.     if (s->usertimer == 0)                /* cannot expire */
  1820.         return (0);
  1821.  
  1822.     return (chk_timeout(s->usertimer));
  1823. }
  1824.  
  1825. long 
  1826. make_timeout(word timeout)
  1827. {
  1828.     if (timeout) return (set_timeout(timeout));
  1829.     return (0);
  1830. }
  1831.  
  1832. /*
  1833.  * check_timeout - test agains timeout clock - account for overflow
  1834.  */
  1835. int 
  1836. check_timeout(unsigned long timeout)
  1837. {
  1838.     if (timeout) return (chk_timeout(timeout));
  1839.     return (0);
  1840. }
  1841.  
  1842. /*
  1843.  * ip_delay0 called by macro sock_wait_established()
  1844.  * ip_delay1 called by macro sock_wait_intput()
  1845.  * ip_delay2 called by macro sock_wait_closed();
  1846.  *
  1847.  */
  1848.  
  1849. ip_delay0(s, timeoutseconds, fn, statusptr)
  1850. sock_type *s;
  1851. int timeoutseconds;
  1852. procref fn;
  1853. int *statusptr;
  1854. {
  1855.     register int status;
  1856.  
  1857.     if (s == NULL)
  1858.         {
  1859.         status = -1;        /* failure */
  1860.             if (statusptr != NULL) *statusptr = status;
  1861.         return (status);
  1862.         }
  1863.     ip_timer_init(s, timeoutseconds);
  1864.  
  1865.     do
  1866.         {
  1867.         if (s->tcp.ip_type == TCP_PROTO)
  1868.             if (tcp_established(s))
  1869.                 {
  1870.                 status = 0;
  1871.                 break;
  1872.                 }
  1873.  
  1874.         if (tcp_tick(s) == 0)
  1875.             {
  1876.             s->tcp.err_msg = "Host refused connection";
  1877.             status = -1;    /* get an early reset */
  1878.             break;
  1879.             }
  1880.  
  1881.         if (ip_timer_expired(s))
  1882.             {
  1883.             sock_close(s);
  1884.             status = -1;
  1885.             break;
  1886.             }
  1887.         if (fn != NULL) if (status = fn(s)) break;
  1888.         if (s->tcp.usr_yield != NULL) (s->tcp.usr_yield)();
  1889.         if (s->tcp.ip_type == UDP_PROTO)
  1890.             {
  1891.             status = 0;
  1892.             break;
  1893.             }
  1894.         } while (1 == 1);
  1895.     if (statusptr != NULL) *statusptr = status;
  1896.     return (status);
  1897. }
  1898.  
  1899. int
  1900. ip_delay1(s, timeoutseconds, fn, statusptr)
  1901. sock_type *s;
  1902. int timeoutseconds;
  1903. procref fn;
  1904. int *statusptr;
  1905. {
  1906.     register int status;
  1907.  
  1908.     if (s == NULL)
  1909.         {
  1910.         status = -1;        /* failure */
  1911.             if (statusptr != NULL) *statusptr = status;
  1912.         return (status);
  1913.         }
  1914.  
  1915.     ip_timer_init(s, timeoutseconds);
  1916.     sock_flush(s);        /* new enhancement */
  1917.  
  1918.     do
  1919.         {
  1920.         if (sock_dataready(s))
  1921.             {
  1922.             status = 0;
  1923.             break;
  1924.             }
  1925.  
  1926.         if (tcp_tick(s) == 0)
  1927.             {
  1928.             status = 1;
  1929.             break;
  1930.             }
  1931.         if (ip_timer_expired(s))
  1932.             {
  1933.             sock_close(s);
  1934.             status = -1;
  1935.             break;
  1936.             }
  1937.         if (fn != NULL)
  1938.             if (status = fn(s)) break;
  1939.         if (s->tcp.usr_yield != NULL) (s->tcp.usr_yield)();
  1940.         } while (1 == 1);
  1941.  
  1942.     if (statusptr != NULL) *statusptr = status;
  1943.     return (status);
  1944. }
  1945.  
  1946. int
  1947. ip_delay2(s, timeoutseconds, fn, statusptr)
  1948. sock_type *s;
  1949. int timeoutseconds;
  1950. procref fn;
  1951. int *statusptr;
  1952. {
  1953.     register int status;
  1954.  
  1955.     if (s == NULL)
  1956.         {
  1957.         status = 0;        /* failure */
  1958.             if (statusptr != NULL) *statusptr = status;
  1959.         return (status);
  1960.         }
  1961.  
  1962.     ip_timer_init(s, timeoutseconds);
  1963.  
  1964.     if (s->tcp.ip_type != TCP_PROTO) return (1);
  1965.  
  1966.     do
  1967.         {
  1968.         if (tcp_tick(s) == 0)        /* 0 means no socket */
  1969.             {
  1970.             status = 1;
  1971.             break;
  1972.             }
  1973.         if (ip_timer_expired(s))
  1974.             {
  1975.             sock_abort(s);
  1976.             status = 0;
  1977.             break;
  1978.             }
  1979.         if (fn != NULL)
  1980.             if (status = fn(s)) break;
  1981.         if (s->tcp.usr_yield != NULL) (s->tcp.usr_yield)();
  1982.         } while (1 == 1);
  1983.  
  1984.     if (statusptr != NULL) *statusptr = status;
  1985.     return (status);
  1986. }
  1987.  
  1988.  
  1989. byte *
  1990. rip(byte *s)    /* put null terminator on CR or LF */
  1991. {
  1992.     register byte *temp;
  1993.  
  1994.     if (s == NULL) return (NULL);            /* failure */
  1995.     if (temp = strchr(s, '\n')) *temp = 0;
  1996.     if (temp = strchr(s, '\r')) *temp = 0;
  1997.     return (s);
  1998. }
  1999.  
  2000.