home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / WATTCP / MSWATTCP.ZIP / SRC / SOCKET.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-08  |  15.5 KB  |  625 lines

  1. /***
  2.  *
  3.  * File: socket.c
  4.  *
  5.  * 27-Aug-93 fr
  6.  *    cleanup
  7.  * 16-Jul-93 fr
  8.  *
  9.  ***/
  10.  
  11.  
  12. #include <tcp.h>
  13.  
  14. #define SOCKET
  15.  
  16.  
  17. #define MAXPORT      32
  18. #define MAXNUMPORT   2000
  19. #define MAXLISTEN    8    
  20. #define MAXTICKS     32500    /* about 30 minutes */
  21.  
  22. #define NO      0    /* should move to tcp.h -- also from tcp.c */
  23.  
  24. static int    ports[MAXPORT] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  25.                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  26.  
  27. static int 
  28. get_port(void)
  29. {
  30.     int i;
  31.     for (i=0 ; i<MAXPORT ; i++)
  32.         if(!(ports[i])){
  33.             ports[i] = i+1;
  34.             return(i+1);    
  35.             }
  36.     return(-1);
  37. } /* end get_port */
  38.  
  39. int 
  40. socket(int af, int type, int protocol) {
  41.     int i;
  42.     udp_Socket *s;
  43.  
  44.     if(af != AF_INET  || type > SOCK_DGRAM || type < SOCK_STREAM) 
  45.         return(-1);
  46.     if( (type==SOCK_STREAM) && (protocol != 0) && (protocol != IPPROTO_TCP) ) 
  47.         return(-1);
  48.     if( (type==SOCK_DGRAM) && (protocol != 0) && (protocol != IPPROTO_UDP) ) 
  49.         return(-1);
  50.     for(i = 0; i< MAXSOCK ;i++ )
  51.         if (!(sockarr[i].valid)){
  52.         sockarr[i].valid = 1;
  53.         sockarr[i].type = type;
  54.         if(type == SOCK_DGRAM){   /* must allocate space for UDP socket */
  55.             if((s=(udp_Socket *)malloc((int)sizeof(udp_Socket)))==NULL)
  56.             return(-1);
  57.         if(!udp_open(s, 0, 0, 0, NULL)){
  58.             DB3((stderr,"socket(): can't open UDP socket\n"));
  59.             return(-1);
  60.             }        
  61.         sockarr[i].sockp = (sock_type *)s;
  62.         }
  63.         return(i+MAXFILE);
  64.         }
  65.     return(-1);
  66.     } /* end socket */
  67.  
  68.  
  69.  
  70.  
  71. int 
  72. bind(int s, struct sockaddr *name, int namelen){
  73.  
  74.     unsigned short j;
  75.     int i;
  76.  
  77.     if( (name->sa_family)!= AF_INET )
  78.         return(-1);
  79.     if( namelen != sizeof(struct sockaddr) )
  80.         return(-1);
  81.     if( ( ((struct sockaddr_in *)name)->sin_addr.s_addr ) &&
  82.         ( ((struct sockaddr_in *)name)->sin_addr.s_addr ) != 
  83.                         htonl(my_ip_addr) )
  84.         return(-1);    
  85.     
  86.     if( j = ntohs(((struct sockaddr_in *)name)->sin_port) ) {
  87.         if( (j > MAXNUMPORT) || j <= 0 ) 
  88.             return(-1);
  89.         for(i = 0; i < MAXPORT; i++){
  90.             if(ports[i]==(int)j)
  91.                 return(-1);
  92.             }
  93.         for(i = 0; i < MAXPORT; i++){
  94.             if(!ports[i]){
  95.                 ports[i] = j;
  96.                 break;
  97.                 }
  98.             }
  99.         if(i==MAXPORT) return(-1);        
  100.         
  101.         sockarr[s-MAXFILE].my_port = j;
  102.         }
  103.     return(0);
  104.     } /* end bind */
  105.  
  106.  
  107.  
  108.  
  109. int
  110. listen(int sock, int numsock ) {
  111.  
  112.   tcp_Socket   *s[MAXLISTEN], *sret = NULL, *bsp=NULL; 
  113.   int i;
  114.  
  115.   if( (numsock > MAXLISTEN) || (numsock < 1 ) )
  116.     return(-1);
  117.  
  118.   if((sockarr[sock-MAXFILE].type)!=SOCK_STREAM){ 
  119.      DB3((stderr,"listen(): Can't do it on this type of socket!\n"));
  120.     return(-1);
  121.     }
  122.   if( !(sockarr[sock-MAXFILE].my_port) ){ 
  123.      DB3((stderr,"listen(): Must execute bind() before!\n"));
  124.     return(-1);
  125.     }
  126.  
  127.   for( i=0 ; i<numsock ; i++){
  128.     if ( (s[i] = (tcp_Socket *) malloc( (int) sizeof( tcp_Socket ) )) == NULL){
  129.     DB3((stderr,"%d sockets allocated\n",i));
  130.     break;
  131.     }
  132.     
  133.     largecheck( s[i], sizeof( tcp_Socket ));
  134.     memset( s[i], 0, sizeof( tcp_Socket));
  135.     s[i]->ip_type = TCP_PROTO;
  136.     s[i]->mss = _mss;
  137.     s[i]->state = tcp_StateLISTEN;
  138.     DB2((FDB,"tcp_listen(): going to LISTEN\n"));
  139.     s[i]->myport = sockarr[sock-MAXFILE].my_port;
  140.     s[i]->hisport = 0;    /* you can't choose in BSD */
  141.     s[i]->hisaddr = 0L;    /* the same as above */
  142.     s[i]->sock_mode = (s[i]->sock_mode & 0xfffc) | TCP_MODE_BINARY;    
  143.     s[i]->seqnum = intel( (longword)s[i] ); /* not a good idea, but works */
  144.     s[i]->datalen = 0;
  145.     s[i]->flags = 0;
  146.     s[i]->rto= 9; /* start 1/2 sec. rto */
  147.     s[i]->unhappy = NO; /* this is a PASSIVE open */
  148.     s[i]->dataHandler = NULL;
  149.     s[i]->usr_yield = system_yield;
  150.     s[i]->safetysig = SAFETYTCP;
  151.     s[i]->next = tcp_allsocs;
  152.     s[i]->brother = bsp;
  153.     s[i]->rxbufsize = RxMaxBufSize;
  154.     s[i]->txbufsize = TxMaxBufSize;
  155.  
  156.     tcp_allsocs = s[i];
  157.     bsp=s[i];
  158.     sret = s[i];
  159.     if(!(sockarr[sock-MAXFILE].sockp))
  160.        sockarr[sock-MAXFILE].sockp=(sock_type *)s[i]; /* will it work? */
  161.     }    /*end for*/
  162.   ((tcp_Socket *)(sockarr[sock-MAXFILE].sockp))->brother = sret;
  163.                      /* now we have a cyclic list */
  164.   sockarr[sock-MAXFILE].sockp = (sock_type *)sret;
  165.                      /* begin from the beginning */
  166.   return(0);
  167.   } /* end listen */
  168.  
  169.  
  170.  
  171.  
  172. int 
  173. accept(int s, struct sockaddr *addr, int *addrlen)
  174. {
  175.     tcp_Socket *ws, *ns;
  176.     int i;
  177.     char *cp;
  178.  
  179.     if(!(sockarr[s-MAXFILE].sockp)){
  180.     DB3((stderr,"accept(): must call listen() first\n"));
  181.     return(-1);
  182.     }
  183.     if( ( *addrlen < 0 ) || ( *addrlen > sizeof(struct sockaddr) ) )
  184.     return(-1);
  185.     ws = (tcp_Socket *)sockarr[s-MAXFILE].sockp;
  186.     for(;;){
  187.     if(!tcp_tick((sock_type *)ws)){
  188.         DB3((stderr,"accept(): Working on non-existing socket\n"));
  189.         return( -1 );
  190.     }
  191.     if(!ws->brother){
  192.         DB4((stderr,"*** PANIC *** accept(): You're in the wrong place!\n"));
  193.         exit(4);
  194.     }
  195.     kbhit();
  196.     if( tcp_established(ws)){
  197.             
  198.         for(i = 0; i< MAXSOCK ;i++ ){
  199.         if (!(sockarr[i].valid)) break;
  200.         }
  201.         if(i==MAXSOCK){
  202.         DB3((stderr,"accept(): No available sockets\n"));
  203.         return(-1);
  204.         }
  205.         if((ns = malloc( (int) sizeof(tcp_Socket) )) == NULL){
  206.         DB3((stderr,"accept(): No room for new socket\n"));
  207.         return(-1);
  208.         }
  209.         memcpy(ns, ws, sizeof(tcp_Socket));    
  210.         ns->next = tcp_allsocs;
  211.         ns->brother = NULL;
  212.  
  213.         if ((ns->rdata = (byte *) malloc((int)RxMaxBufSize)) == NULL) {
  214.            DB3((stderr,"accept(): not enough space for rdata buffer\n"));
  215.            return(-1);
  216.         }
  217.  
  218.         if ((ns->data = (byte *) malloc((int)TxMaxBufSize)) == NULL) {
  219.               DB3((stderr,"ACCEPT: not enough space for data buffer\n"));
  220.            return(-1);
  221.         }
  222.  
  223.         sockarr[i].sockp = (sock_type *)ns;
  224.         tcp_allsocs=((tcp_Socket *)sockarr[i].sockp);
  225.  
  226.         sockarr[i].type = sockarr[s-MAXFILE].type;
  227.         sockarr[i].my_port = sockarr[s-MAXFILE].my_port;
  228.         sockarr[s-MAXFILE].sockp=((sock_type *)ws->brother);    
  229.         sockarr[i].valid = 1;
  230.  
  231.         ((struct sockaddr_in *)addr)->sin_family = AF_INET;
  232.                      /* as it's obvious */    
  233.         ((struct sockaddr_in *)addr)->sin_addr.s_addr = 
  234.                         htonl(ws->hisaddr);
  235.         ((struct sockaddr_in *)addr)->sin_port = htons(ws->hisport);
  236.  
  237.         cp = &(addr->sa_data[*addrlen]);
  238.         memset( cp, 0, sizeof(struct sockaddr) - *addrlen );
  239.  
  240.         ws->state = tcp_StateLISTEN; /*   will .... */
  241.         ws->hisaddr = 0L;         /* ...these....*/
  242.         ws->hisport = 0;          /*    ...suffice? */
  243.         
  244.         return(i+MAXFILE);
  245.     }
  246.         ws = ws->brother;   /* I loop but it's no use! */            
  247.    }    /* end for(;;) */
  248. }
  249.  
  250.  
  251. int 
  252. select(int maxfdp, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
  253.             struct timeval *timeout){
  254.     fd_set wkread, wkexcept, wkwrite;
  255.     sock_type *s;
  256.     int i, count = 0;
  257.     long endtime = 0L, ttime = 0L;
  258.  
  259.     if(maxfdp > FD_SETSIZE) return(-1);
  260.     if(timeout){
  261.         if( (ttime = ( (18 * timeout->tv_sec )
  262.             +(timeout->tv_usec / 55000) )) > MAXTICKS )
  263.             return(-1);
  264.         endtime = set_ttimeout((int)ttime);    
  265.         }
  266.     FD_ZERO( &wkread );
  267.     FD_ZERO( &wkwrite );
  268.     FD_ZERO( &wkexcept );
  269.     for(;;){
  270.         kbhit();    
  271.         if(exceptfds){
  272.             for( i=0 ; i < maxfdp ; i++ ){
  273.             if( ( i>= MAXFILE) && FD_ISSET(i, exceptfds) ){
  274.                 tcp_tick(NULL);
  275.                 s=sockarr[i-MAXFILE].sockp;
  276.                 if( (!s) || ( (s->tcp.ip_type == TCP_PROTO) && 
  277.                       (s->tcp.state >= tcp_StateCLOSWT) ) ){
  278.                 count++;
  279.                 FD_SET(i, &wkexcept);
  280.                 if(!timeout) goto end;    
  281.                 }
  282.             }
  283.             }
  284.         }    
  285.         if(readfds){    
  286.             for( i=0 ; i < maxfdp ; i++ ){
  287.             tcp_tick(NULL);
  288.             if( ( i>= MAXFILE) && FD_ISSET(i, readfds) &&
  289.                 (sockarr[i-MAXFILE].sockp) ){
  290.             s=sockarr[i-MAXFILE].sockp;
  291.             if( (   (s->tcp.ip_type == TCP_PROTO) && 
  292.                 (s->tcp.brother) && 
  293.                 (tcp_established((tcp_Socket *)s)) ) ||
  294.                 (   (s->tcp.ip_type == TCP_PROTO) &&
  295.                 (!s->tcp.brother) && 
  296.                 (sock_dataready(s)) )  ||
  297.                 (   (s->tcp.ip_type == UDP_PROTO)  &&
  298.                 (s->udp.rdatalen) ) ){
  299.         /* opened with LISTEN or waiting for data read */
  300.                 count++;
  301.                 FD_SET(i, &wkread);
  302.                 if( !timeout )   goto end; 
  303.                 }
  304.                 }
  305.             } /* end for */
  306.         }  /* end readfds */
  307.         if(writefds){
  308.             for( i=0 ; i < maxfdp ; i++ ){
  309.             if( ( i>= MAXFILE) && FD_ISSET(i, writefds) ){
  310.                 tcp_tick(NULL);
  311.                 s=sockarr[i-MAXFILE].sockp;
  312.                 if( (s->tcp.ip_type == UDP_PROTO ) ||
  313.                ((s->tcp.ip_type == TCP_PROTO) && 
  314.                 (s->tcp.datalen < s->tcp.txbufsize)) ){
  315.                 count++;
  316.                 FD_SET(i, &wkwrite);
  317.                 if(!timeout) goto end;    
  318.                 }
  319.             }
  320.             }
  321.         }
  322.         if( timeout && ( (ttime == 0) || (chk_timeout(endtime)) ) ){
  323. end:            if(readfds)
  324.                  memcpy(readfds, &wkread, sizeof(fd_set) );
  325.             if(exceptfds)
  326.             memcpy(exceptfds, &wkexcept, sizeof(fd_set) );
  327.             if(writefds)
  328.             memcpy(writefds, &wkwrite, sizeof(fd_set) );
  329.         return(count);
  330.         }
  331.         } /* end for(;;) */
  332.     }       
  333.  
  334.  
  335.  
  336. int 
  337. connect(int sock, struct sockaddr *name, int namelen){
  338.  
  339.     int myport;
  340.     longword ina;
  341.     word hisport;
  342.     sock_type *s;
  343.  
  344.     if ((sockarr[sock-MAXFILE].type)!=SOCK_STREAM){
  345.         DB3((stderr,"connect(): %d is not a SOCK_STREAM socket\n",sock));
  346.         return(-1);
  347.         }
  348.     if( namelen != sizeof(struct sockaddr) )
  349.         return(-1);
  350.     if( (name->sa_family) != AF_INET )
  351.         return(-1);
  352.     if( (myport = get_port()) <0 )
  353.         return(-1);
  354.     
  355.     sockarr[sock-MAXFILE].my_port = myport;
  356.  
  357.         if ( (s = (sock_type *)malloc( (int) sizeof( tcp_Socket ) )) == NULL)
  358.         return(-1);
  359.  
  360.     sockarr[sock-MAXFILE].sockp = s;
  361.     ina = ntohl((longword)((struct sockaddr_in *)name)->sin_addr.s_addr);    
  362.     hisport = ntohs( ((struct sockaddr_in *)name)->sin_port );
  363.  
  364.     if( !(tcp_open( (tcp_Socket *)s, (word)myport, ina, hisport, NULL) ) ){
  365.         DB3((stderr,"open failed\n"));
  366.         return(-1); 
  367.         }
  368.     return(0);
  369.     } /* end connect */
  370.         
  371.  
  372.  
  373. struct hostent *
  374. gethostbyname(char *name) {
  375.     struct hostent *p;
  376.     u_long    ul;
  377.  
  378.     if ((p = (struct hostent *)malloc((int)sizeof(struct hostent))) == NULL)
  379.         return(NULL);
  380.     p->h_name= (char *)malloc(64);
  381.     strcpy(p->h_name,name);
  382.     p->h_aliases = NULL;
  383.     p->h_addrtype = AF_INET;
  384.     p->h_length = 4;
  385.     p->h_addr_list = ((char **)calloc(3,sizeof(char *)));
  386.     p->h_addr = (char *)malloc(sizeof(struct in_addr));
  387.     if(!(ul = resolve(name)))
  388.         return(NULL);
  389.     ul = htonl(ul);        
  390.     movmem(&ul,p->h_addr,4);
  391.     p->h_addr_list[1] = NULL;
  392.     return(p);
  393.     } /* end gethostbyname */
  394.  
  395.  
  396. int 
  397. getsockname(int s, struct sockaddr *name, int *lenp){
  398.     udp_Socket *us;
  399.     char *cp;
  400.     int j;
  401.  
  402.     if(!(sockarr[s-MAXFILE].valid))
  403.         return(-1);
  404.     if( *lenp < 0 )
  405.         return(-1);
  406.     if(!(((struct sockaddr_in *)name)->sin_port)){
  407.         sockarr[s-MAXFILE].my_port = get_port();
  408.              ((struct sockaddr_in *)name)->sin_port = 
  409.                     htons(sockarr[s-MAXFILE].my_port);
  410.         }    
  411.     if( (sockarr[s-MAXFILE].type) == SOCK_DGRAM ){
  412.         us=((udp_Socket *)sockarr[s-MAXFILE].sockp);
  413.         us->myport = (word)sockarr[s-MAXFILE].my_port;
  414.         }
  415.     if( (j = *lenp) < 2 )
  416.         j = 2;
  417.         cp = &(name->sa_data[j]);
  418.         memset( cp, 0, sizeof(struct sockaddr) - j );
  419.     return(sockarr[s-MAXFILE].my_port);
  420.     } /* end getsockname */
  421.  
  422.  
  423. int 
  424. gethostname(char *buf, int len){
  425.     if(!(_hostname) || !(buf) )
  426.         return(-1);
  427.     buf[0]=0;
  428.     if ( (len < 0) || (len > (int)strlen(_hostname) ) )  
  429.         len = 1 + (int)strlen(_hostname); 
  430.     strncpy(buf,_hostname,len);
  431.     return(0);
  432.     } /* end gethostname */
  433.  
  434.  
  435. char *
  436. inet_ntoa(struct in_addr in){
  437.     longword x;
  438.     static char s[128];
  439.  
  440.     x = ntohl((longword)in.s_addr);
  441.         s[0]='\0';
  442.         itoa((int) (x >> 24), s, 10 );
  443.        strcat( s, ".");
  444.         itoa((int)(( x >> 16) & 0xff), strchr( s, 0), 10);
  445.         strcat( s, ".");
  446.         itoa((int)( x >> 8) & 0xff, strchr( s, 0), 10);
  447.         strcat( s, ".");
  448.         itoa((int)(x) & 0xff, strchr( s, 0), 10);
  449.         return( s );
  450.     } /* end inet_ntoa */
  451.  
  452.  
  453.  
  454. int 
  455. n_read(int fd, char *dp, int len){
  456.     tcp_Socket *s;
  457.     int x;
  458.     
  459.     s = ((tcp_Socket *)sockarr[fd-MAXFILE].sockp);
  460.     if ( (sockarr[fd-MAXFILE].type)!=SOCK_STREAM ){
  461.         DB3((stderr,"Error: N_READ applied to a non tcp socket\n"));
  462.         return(-1);
  463.         }
  464.     for(;;){
  465.         kbhit();    
  466.         if(!tcp_tick((sock_type *)s))
  467.             return(0);
  468.         if(x=sock_dataready((sock_type *)s )){
  469.             x = sock_fastread((sock_type *)s,(byte *)dp,len);
  470.             dp[x] = 0;    /* you can't never say.... */
  471.             if( (x > 0) && (x < len) ) 
  472.                 x = len;
  473.             return(x);
  474.             }
  475.         if(s->state >= tcp_StateCLOSWT)
  476.             return(0);
  477.         }
  478.     }
  479.  
  480.  
  481.  
  482. int 
  483. n_write(int fd, char *dp, int len){
  484.     tcp_Socket *s;
  485.     
  486.     s = ((tcp_Socket *)sockarr[fd-MAXFILE].sockp);
  487.     if( !(tcp_tick( (sock_type *)s )) )
  488.         return(-1);
  489.     return(sock_fastwrite((sock_type *)s,(byte *)dp,len));
  490.     }
  491.  
  492.  
  493. int 
  494. n_close(int sock) {
  495.     tcp_Socket *s, *ps, *ts, *ys, **xs;
  496.     int i, n;
  497.  
  498.     if(!(sockarr[sock-MAXFILE].valid)){
  499.         DB3((stderr,"N_CLOSE: socket %d was already closed\n", sock));
  500.         return(-1);
  501.         }
  502.  
  503.     if((sockarr[sock-MAXFILE].type)==SOCK_DGRAM){
  504.         sock_close(sockarr[sock-MAXFILE].sockp);
  505.         free( ((udp_Socket *)sockarr[sock-MAXFILE].sockp) );        
  506.         goto end;
  507.         }
  508.     
  509.     ps = (tcp_Socket *)sockarr[sock-MAXFILE].sockp;
  510.     if ( (ps->ip_type==TCP_PROTO) && (ps->brother) ){
  511.         s = ps;
  512.         for(;;){
  513.         xs = &tcp_allsocs;
  514.         for(;;){
  515.             ys = *xs;
  516.             if (ys == s){
  517.                 *xs = ys->next;
  518.                 break;
  519.                 }
  520.             if(!ys) break;
  521.             xs = &ys->next;
  522.             }
  523.         ts = s;
  524.         s = s->brother;
  525.         free(ts);
  526.         DB3((stderr,"Freeing LISTEN socket\n"));
  527.         if (s == ps) break;
  528.         }        
  529.          /* freed all sockets allocated with LISTEN */
  530.         goto end;
  531.         } 
  532.     
  533.     /* must be a normal tcp socket */
  534.     sock_close((sock_type *)ps);
  535.     _ip_delay2( (sock_type *)ps, 3, NULL, NULL);
  536.     free(ps);
  537.  
  538. end:    sockarr[sock-MAXFILE].valid = 0;
  539.     sockarr[sock-MAXFILE].type = 0;
  540.     i = sockarr[sock-MAXFILE].my_port;
  541.     for(n=0; n<MAXPORT; n++){
  542.         if(ports[n] == i){
  543.             ports[n]=0;
  544.             break;
  545.             }
  546.         }
  547.     sockarr[sock-MAXFILE].my_port = 0;
  548.     sockarr[sock-MAXFILE].sockp = NULL;
  549.     return(0);
  550.     } /* end n_close */
  551.  
  552.  
  553.  
  554. int 
  555. sendto(int sock, char *buf, int nbytes, int flags, 
  556.                 struct sockaddr *to, int addrlen) {
  557.     udp_Socket *s;
  558.  
  559.     if( addrlen < sizeof(struct sockaddr) )
  560.         return(-1);
  561.     if( ((sockarr[sock-MAXFILE].type)!=SOCK_DGRAM) || (flags) )
  562.         return(-1);
  563.     s = ((udp_Socket *)sockarr[sock-MAXFILE].sockp);
  564.     kbhit();
  565.     tcp_tick(NULL);
  566.     s->hisaddr = ntohl(((struct sockaddr_in *)to)->sin_addr.s_addr); 
  567.     if(! _arp_resolve(s->hisaddr, &(s->hisethaddr)) )
  568.         return(-1);
  569.     s->hisport = ntohs( ((struct sockaddr_in *)to)->sin_port ); 
  570.     return( sock_fastwrite( (sock_type *)s, buf, nbytes ) );
  571.     } /* end sendto */
  572.  
  573.  
  574.  
  575. int 
  576. recvfrom(int sock, char *buf, int nbytes, int flags, 
  577.                 struct sockaddr *from, int *addrlen) {
  578.     udp_Socket *s;
  579.     int num;
  580.     char *cp;
  581.  
  582.     if( ((sockarr[sock-MAXFILE].type)!=SOCK_DGRAM) || (flags) )
  583.         return(-1);
  584.     if( ( *addrlen < 0 ) || ( *addrlen > sizeof(struct sockaddr) ))
  585.         return(-1);   
  586.     s = ((udp_Socket *)sockarr[sock-MAXFILE].sockp);
  587.     for(;;){
  588.         kbhit();
  589.         tcp_tick(NULL);
  590.         if( s->rdatalen ){
  591.             num = sock_fastread( (sock_type *)s, buf, nbytes );
  592.             ((struct sockaddr_in *)from)->sin_family = AF_INET; 
  593.                              /* obviously */
  594.             ((struct sockaddr_in *)from)->sin_addr.s_addr = 
  595.                         htonl(s->hisaddr); 
  596.             ((struct sockaddr_in *)from)->sin_port = htons(s->hisport);
  597.  
  598.             cp = &(from->sa_data[*addrlen]);
  599.             memset( cp, 0, sizeof(struct sockaddr) - *addrlen );
  600.             
  601.             s->hisaddr = 0L;  /* washing! */
  602.             s->hisport = 0;
  603.             memset( s->hisethaddr, 0xff, sizeof(eth_address) );    
  604.             return(num);
  605.             } 
  606.         }
  607.     } /* end recvfrom */
  608.  
  609.  
  610. void
  611. sleep(int sec){
  612.     int ttime;
  613.     long endtime;
  614.  
  615.     if( (sec > 0) && (sec < 1800) ){
  616.         ttime=(18 * sec);
  617.         endtime = set_ttimeout(ttime);
  618.         while( !(chk_timeout(endtime)) ){
  619.             tcp_tick(NULL);
  620.             }
  621.         }
  622.     }
  623.  
  624.  
  625.