home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / WATTCP / UNZIPPED / MSWATTCP / SRC / PCBOOTP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-28  |  5.7 KB  |  179 lines

  1. /****
  2.  *
  3.  * File: pcbootp.c
  4.  *
  5.  * 01-Jul-92 lr
  6.  *
  7.  *   BOOTP - Boot Protocol (RFC 854)
  8.  *
  9.  *   These extensions get called if _bootphost is set to an IP address or
  10.  *   to 0xffffffff.
  11.  *
  12.  *   Version
  13.  *
  14.  *   0.2 : May 22, 1991 : E.J. Sutcliffe - added RFC_1048 vendor fields
  15.  *   0.1 : May  9, 1991 : E. Engelke - made part of the library
  16.  *   0.0 : May  3, 1991 : E. Engelke - original program as an application
  17.  *
  18.  */
  19.  
  20.  
  21. #define WATTCP_KERNEL
  22. #define PCBOOTP
  23. #include <tcp.h>
  24. #include <bootp.h>
  25.  
  26. /*
  27.  * _dobootp - Checks global variables _bootptimeout, _bootphost
  28.  *            if no host specified, the broadcast address
  29.  *            returns 0 on success and sets ip address
  30.  */
  31. int
  32. _dobootp(void)
  33. {
  34.     udp_Socket bsock;
  35.     longword sendtimeout, bootptimeout;
  36.     longword magictimeout;
  37.     word len, templen;
  38.     struct bootp sendbootp;     /* outgoing data */
  39.     struct bootp _bootp;        /* incoming data */
  40.     int status;
  41.     longword xid;
  42.     unsigned char *p /* ,*t */ ;
  43.  
  44.     if ( _pktdevclass == PD_SLIP ) return( -1 );
  45.  
  46.  
  47.     /* We must get Waterloo TCP to use IP address 0 for sending */
  48.     xid = my_ip_addr;   /* a unique value coming from the ethernet card */
  49.     my_ip_addr = 0;
  50.  
  51.     if (!udp_open( &bsock, IPPORT_BOOTPC, _bootphost, IPPORT_BOOTPS, NULL )) {
  52.         outs("\n\rUnable to resolve bootp server\n\r");
  53.         return( -1 );
  54.     }
  55.  
  56.     bootptimeout = set_timeout( _bootptimeout );
  57.     magictimeout = (xid & 7) + 7;  /* between 7 and 14 seconds */
  58.  
  59.     memset( &sendbootp, 0, sizeof( struct bootp ));
  60.     sendbootp.bp_op = BOOTREQUEST;
  61.     sendbootp.bp_htype =(byte) _pktdevclass;
  62.     /* Copy into position the Magic Number used by Bootp */
  63.     /* avoid static storage and pushf/call assembler instructions */
  64.     *(longword *)(&sendbootp.bp_vend) = VM_RFC1048;
  65.  
  66.     if (_pktdevclass == PD_ETHER) sendbootp.bp_hlen = 6;
  67.  
  68.     sendbootp.bp_xid = xid;
  69.     sendbootp.bp_secs = intel16( 1 );
  70.  
  71.     movmem( _eth_addr, &sendbootp.bp_chaddr, sizeof(eth_address));
  72.  
  73.     while ( 1 ) {
  74.     sock_fastwrite( (sock_type *)&bsock, (byte *)&sendbootp, sizeof( struct bootp ));
  75.         sendbootp.bp_secs += magictimeout;      /* for next time */
  76.         sendtimeout = set_timeout( magictimeout += (xid >> 5) & 7 );
  77.  
  78.         while ( !chk_timeout( sendtimeout )) {
  79.  
  80.             if (chk_timeout( bootptimeout))
  81.                 goto give_up;
  82.             kbhit();
  83.             sock_tick((sock_type *)&bsock, &status );
  84.             if (len = sock_dataready((sock_type *) &bsock)) {
  85.  
  86.                 /* got a response, lets consider it */
  87.                 templen = sock_fastread((sock_type *) &bsock,(byte *)&_bootp, sizeof( struct bootp ));
  88.                 if ( templen < sizeof( struct bootp )) {
  89.                     /* too small, not a bootp packet */
  90.             memset( &_bootp, 0, sizeof( struct bootp ));
  91.                     continue;
  92.                 }
  93.  
  94.                 /* we must see if this is for us */
  95.         if (_bootp.bp_xid != sendbootp.bp_xid) {
  96.             memset( &_bootp, 0, sizeof( struct bootp ));
  97.                     continue;
  98.                 }
  99.  
  100.                 /* we must have found it */
  101.         my_ip_addr = intel( _bootp.bp_yiaddr );
  102.  
  103.  
  104.         if ( intel( *(longword*)(&_bootp.bp_vend)) == VM_RFC1048 ) {
  105.             /*RFC1048 complient BOOTP vendor field */
  106.             /* Based heavily on NCSA Telnet BOOTP */
  107.  
  108.             p = &_bootp.bp_vend[4]; /* Point just after vendor field */
  109.  
  110.             while (*p!=255) {
  111.             switch(*p) {
  112.                           case 0: /* Nop Pad character */
  113.                                  p++;
  114.                                  break;
  115.                           case 1: /* Subnet Mask */
  116.                  sin_mask = intel( *(longword *)( &p[2] ));
  117.                  /* and fall through */
  118.               case 2: /* Time offset */
  119.                  p += *(p+1) + 2;
  120.                  break;
  121.               case 3: /* gateways */
  122.                   /* only add first */
  123.                   _arp_add_gateway( NULL,
  124.                      intel( *(longword*)(&p[2])));
  125.                   /* and fall through */
  126.               case 4: /*time servers */
  127.                   /* fall through */
  128.                           case 5: /* IEN=116 name server */
  129.                                  p +=*(p+1)+2;
  130.                                  break;
  131.               case 6: /* Domain Name Servers (BIND) */
  132.                 for ( len = 0; len < *(p+1) ; len += 4 )
  133.                     _add_server( &_last_nameserver,
  134.                     MAX_NAMESERVERS, def_nameservers,
  135.                         intel( *(longword*)(&p[2+len])));
  136.                 /* and fall through */
  137.               case 7: /* log server */
  138.                  p += *(p+1)+2;
  139.                  break;
  140.               case 8: /* cookie server */
  141.                  for ( len = 0; len < *(p+1) ; len += 4 )
  142.                      _add_server( &_last_cookie, MAX_COOKIES,
  143.                     _cookie, intel( *(longword*)(&p[2+len])));
  144.                  /* and fall through */
  145.                           case 9: /* lpr server */
  146.                           case 10: /* impress server */
  147.                           case 11: /* rlp server */
  148.                    p +=*(p+1)+2;
  149.                                    break;
  150.               case 12: /* Client Hostname */
  151.                   movmem( &p[2] , _hostname, MAX_STRING );
  152.                   _hostname[ MAX_STRING - 1 ] = 0;
  153.                   p += *(p+1)+2;
  154.                                   break;
  155.                           case 255:
  156.                                    break;
  157.                           default:
  158.                                    p +=*(p+1)+2;
  159.                                    break;
  160.                         } /* end of switch */
  161.                      } /* end of while */
  162.                 }/* end of RFC_1048 if */
  163.                 goto give_up;
  164.             }
  165.         }
  166.     }
  167. give_up:
  168.  
  169.     sock_close((sock_type *) &bsock );
  170.  
  171.     return (my_ip_addr == 0 );  /* return 0 on success */
  172.  
  173. sock_err:
  174.     /* major network error if UDP fails */
  175.     sock_close((sock_type *) &bsock );
  176.     return( -1 );
  177. }
  178. /*** end of file pcbootp.c ***/
  179.