/* BOOTP - resident BOOTP service. written by Bruce Campbell, WATSTAR Office, Engineering Computing, University of Waterloo. This program is a TSR that watches for any packet driver application sending out a BOOTP request. When it is seen, this program fakes the upcalls to make it seem like a real BOOTP response. Usage: BOOTP options... where options can be: QUIET - so that is loads without screen activity MYIP=ip_number MY=ip_number PC_IP=ip_number - these 3 do the same thing, that is, set your local IP number SERV=ip_number - sets the IP number of the server supposedly responding SIP=ip_number - sets the IP number of a gateway HW=hardware_address - physical address of the server supposedly responding MASK=subnet_mask - sets the subnet mask on magic cookie (63.82.53.63) BOOTPs NAME=ip_number - sets the name server on magic cookie (63.82.53.63) BOOTPs GATE=ip_number - sets the gateway on magic cookie (63.82.53.63) BOOTPs EXTRA=xx,xx,xx,xx etc - fills in the vendor field with more stuff on magic cookie (63.82.53.63) BOOTPs @filename - a filename full of more options like above (not recursive!) - multiple @filename options can be specified on the command line if the SERV, SIP, NAME or GATE are set to 255.255.255.255, an ip number is created for the field automatically which consists of the local ip anded with the subnet mask plus 1. The ip_number, hardware_address, and subnet_mask are specified as nnn.nnn.nnn.nnn or a hexadecimal address like x628462FE Questions etc. mail to BRUCE@DEVELOPMENT.WATSTAR.uwaterloo.ca Other issues: The upcalls are done during the transmit. So if an application sends a BOOTP and immediately clears all received packets, it will not see the BOOTP response. This could be fixed by deferring the upcalls to a timer tick mechanism, however, it works for everything I've tried so far anyway. Example usage: bootp my=129.97.20.102 @defaults where the file 'defaults' contains: serv=129.97.20.1 sip=129.97.20.1 hw=xc800c700 gate=129.97.20.1 name=129.97.129.140 name=129.97.128.152 mask=255.255.254.0 extra=8,4,129.97.128.152 Notice how 2 name servers are given. Also, a quote server has been given using the "extra" option. See RFC1084 and RFC 951 for more information on BOOTP Source code freely available. Distribute freely. Make any changes. Please leave my name on it though. */ extern unsigned long rdvct(); extern newpack(); extern char *strstr(); extern unsigned long oldpack; extern char *nval(); extern unsigned long your_ip; extern unsigned long server_ip; extern unsigned long gateway_ip; extern unsigned long server_hw; extern unsigned char vendor[]; #define CMDLEN 2048 unsigned char tmpcmd[CMDLEN]; #define MAXG 7 unsigned long auto_create( inip, msk ) unsigned long inip; unsigned long msk; { if( inip == 0x0FFFFFFFFl ) return( (your_ip & msk) + 0x001000000l ); else return( inip ); } install_wpack( cmd ) char *cmd; { unsigned int vec; char *ts; unsigned long tmpl; char *tp; int i, j; int numgates = 0; int numnames = 0; unsigned long gates[MAXG]; unsigned long names[MAXG]; unsigned long *llp; unsigned long submask = 0x000FEFFFFl; int quiet = 0; int handle; strupr( cmd ); strcpy( tmpcmd, cmd ); strcat( tmpcmd, " " ); tp = cmd; while( tp = strstr( tp, "@" ) ) { tp++; if( ts = strstr( tp, " " ) ) *ts = 0; handle = bopen( tp ); if( handle == -1 ) { pmsg( "Unable to open " ); pmsg( tp ); pmsg( "\r\n" ); if( ts ) *ts = 0x020; continue; } if( ts ) *ts = 0x020; i = strlen( tmpcmd ); while( i < (CMDLEN-1) ) { j = bread( handle ); if( j == -1 ) break; j = toupper( j & 0x07F ); if( j == 0x01A ) break; if( iscntrl( j ) ) j = 0x020; tmpcmd[i++] = j; tmpcmd[i] = 0; } bclose( handle ); } if( strstr( tmpcmd, "QUIET" ) ) quiet = 1; do_one_arg( tmpcmd, "MY=", &your_ip, 4 ); do_one_arg( tmpcmd, "MYIP=", &your_ip, 4 ); do_one_arg( tmpcmd, "PC_IP=", &your_ip, 4 ); do_one_arg( tmpcmd, "SERV=", &server_ip, 4 ); do_one_arg( tmpcmd, "SIP=", &gateway_ip, 4 ); do_one_arg( tmpcmd, "HW=", &server_hw, 4 ); do_one_arg( tmpcmd, "MASK=", &submask, 4 ); server_ip = auto_create( server_ip, submask ); gateway_ip = auto_create( gateway_ip, submask ); while( tp = strstr( tmpcmd, "NAME=" ) ) { do_one_arg( tmpcmd, "NAME=", &tmpl, 4 ); tmpl = auto_create( tmpl, submask ); names[numnames++] = tmpl; if( numnames >= MAXG ) break; tp[0] = 'n'; } while( tp = strstr( tmpcmd, "GATE=" ) ) { do_one_arg( tmpcmd, "GATE=", &tmpl, 4 ); tmpl = auto_create( tmpl, submask ); gates[numgates++] = tmpl; if( numgates >= MAXG ) break; tp[0] = 'g'; } i = 0; vendor[i+0] = 1; vendor[i+1] = 4; llp = &vendor[i+2]; llp[0] = submask; i += (2 + vendor[i+1]); if( numgates ) { vendor[i+0] = 3; vendor[i+1] = numgates*4; llp = &vendor[i+2]; for( j=0; j