home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * BOOTP - Boot Protocol (RFC 854)
- *
- * These extensions get called if _bootphost is set to an IP address or
- * to 0xffffffff.
- *
- * Version
- *
- * 0.1 : May 9, 1991 : E. Engelke - made part of the library
- * 0.0 : May 3, 1991 : E. Engelke - original program as an application
- *
- */
-
- #include <copyright.h>
- #include <stdio.h>
- #include <wattcp.h>
- #include <bootp.h>
-
- /* global variables */
- longword _bootphost = 0L;
- word _bootptimeout = 30;
-
-
- extern longword set_timeout();
-
- /*
- * _dobootpc - Checks global variables _bootptimeout, _bootphost
- * if no host specified, the broadcast address
- * returns 0 on success and sets ip address
- */
- int _dobootp()
- {
- udp_Socket bsock;
- longword sendtimeout, bootptimeout;
- word magictimeout;
- word len, templen;
- struct bootp sendbootp; /* outgoing data */
- struct bootp _bootp; /* incoming data */
- int found;
- int status;
- longword xid;
-
- if ( _pktdevclass == PD_SLIP ) return( -1 );
-
- found = 0;
-
- /* We must get Waterloo TCP to use IP address 0 for sending */
- xid = my_ip_addr; /* a unique value coming from the ethernet card */
- my_ip_addr = 0;
-
- if (!udp_Open( &bsock, IPPORT_BOOTPC, _bootphost, IPPORT_BOOTPS, NULL )) {
- outs("\n\rUnable to resolve bootp server\n\r");
- return( -1 );
- }
-
- bootptimeout = set_timeout( _bootptimeout );
- magictimeout = (xid & 7) + 7; /* between 7 and 14 seconds */
-
- memset( &sendbootp, 0, sizeof( struct bootp ));
- sendbootp.bp_op = BOOTREQUEST;
- sendbootp.bp_htype = _pktdevclass;
-
- if (_pktdevclass == PD_ETHER) sendbootp.bp_hlen = 6;
-
- sendbootp.bp_xid = xid;
- sendbootp.bp_secs = intel16( 1 );
-
- movmem( _eth_addr, &sendbootp.bp_chaddr, sizeof(eth_address));
-
-
- while ( 1 ) {
- sock_FastWrite( &bsock, &sendbootp, sizeof( struct bootp ));
- sendbootp.bp_secs += magictimeout; /* for next time */
- sendtimeout = set_timeout( magictimeout += (xid > 5) & 7 );
-
- while ( !chk_timeout( sendtimeout )) {
-
- if (chk_timeout( bootptimeout))
- goto give_up;
-
- sock_tick( &bsock, &status );
- if (len = sock_DataReady( &bsock)) {
-
- /* got a response, lets consider it */
- templen = sock_FastRead( &bsock, &_bootp, sizeof( struct bootp ));
- if ( len < sizeof( struct bootp )) {
- /* too small, not a bootp packet */
- memset( _bootp, 0, sizeof( struct bootp ));
- continue;
- }
-
- /* we must see if this is for us */
- if (_bootp.bp_xid != sendbootp.bp_xid) {
- outs("Got someone else's xid ");
- continue;
- }
-
- /* we must have found it */
- my_ip_addr = intel( _bootp.bp_yiaddr );
- _bootphost = intel( _bootp.bp_siaddr );
- if (!sin_gate) sin_gate = intel( _bootp.bp_giaddr );
- goto give_up;
- }
- }
- }
- give_up:
-
- sock_Close( &bsock );
-
- return (my_ip_addr == 0 ); /* return 0 on success */
-
- sock_err:
- /* major network error if UDP fails */
- sock_Close( &bsock );
- return( -1 );
- }