Subject: Early working version of bootpc for NetBSD (using bpf ...NOT!)
To: John C. Hayward <johnh@david.wheaton.edu>
From: Gordon W. Ross <gwr@mc.com>
List: current-users
Date: 08/18/1995 11:56:00
> Date: Thu, 17 Aug 1995 17:13:50 -0500 (CDT)
> From: "John C. Hayward" <johnh@david.wheaton.edu>
> Subject: Early working version of bootpc for NetBSD using bpf
> Dear NetBSDers,
> On the issue of getting NetBSD version of bootpc up several people
> mentioned that "bpf" could be used to grab packets before the IP number
> of an interface was known.
> Using this I have a working version of bootpc. It is a bit of a hack in
> that you have to know the network number your computer is on. I first
> configure the network interface to use the network address (with a host
> of 0) of that network then bootpc sends out a bootp request (using
> sendto). It then waits for packets which are filtered by bpf. Bootpc
> then outputs the various parameters it picks up from the server.
Here is an easier way to do this: (No BPF required)
# ifconfig ie0 inet 255.255.255.255
# ifconfig ie0
ie0: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST>
inet 255.255.255.255 netmask 0xffffff00 broadcast 255.255.255.255
# ./bootptest -i ie0 -h
bootptest: version 2.4.1
Sending to 255.255.255.255 (request) xid:131 vend-rfc1395
Recvd from 192.233.17.32 (reply) xid:131 Y:192.233.17.119 S:192.233.17.32 \
sname:"merlin" vend-rfc1395 SM:255.255.255.0 GW:192.233.17.32 TZ:18000 \
DNS:192.233.16.15,192.233.16.4 DNAM:"mc.com" HN:"venus"
#
All the info you need is in the bootp reply printed by bootptest.
I had to hack on bootptest slightly to get it to do the above;
attached are my changes against src/usr.sbin/bootpd/bootptest.c
(note that you build this program in src/usr.sbin/bootptest).
Have fun!
Gordon Ross
*** bootptest.c.~1~ Sat May 20 06:13:54 1995
--- bootptest.c Fri Aug 18 11:41:48 1995
***************
*** 125,130 ****
--- 125,131 ----
char *servername = NULL;
char *vendor_file = NULL;
char *bp_file = NULL;
+ char *ifname = NULL;
int s; /* Socket file descriptor */
int n, tolen, fromlen, recvcnt;
int use_hwa = 0;
***************
*** 175,180 ****
--- 176,188 ----
use_hwa = 1;
break;
+ case 'i': /* interface name */
+ if (argc < 2)
+ goto error;
+ argc--; argv++;
+ ifname = *argv;
+ break;
+
case 'm': /* Magic number value. */
if (argc < 2)
goto error;
***************
*** 204,214 ****
--- 212,227 ----
argc--;
argv++;
}
+
+ #if 0
+ /* if not specified, assume 255.255.255.255 */
if (!servername) {
printf("missing server name.\n");
puts(usage);
exit(1);
}
+ #endif
+
/*
* Create a socket.
*/
***************
*** 242,250 ****
sizeof(sin_server.sin_addr));
}
} else {
! /* Get broadcast address */
! /* XXX - not yet */
! sin_server.sin_addr.s_addr = INADDR_ANY;
}
sin_server.sin_family = AF_INET;
sin_server.sin_port = htons(bootps_port);
--- 255,268 ----
sizeof(sin_server.sin_addr));
}
} else {
! /* XXX - Get broadcast address? */
! int on = 1;
! servername = "255.255.255.255";
! sin_server.sin_addr.s_addr = INADDR_BROADCAST;
! if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on))) {
! perror("setsockopt broadcast");
! exit(1);
! }
}
sin_server.sin_family = AF_INET;
sin_server.sin_port = htons(bootps_port);
***************
*** 294,305 ****
if (use_hwa) {
struct ifreq *ifr;
! ifr = getif(s, &sin_server.sin_addr);
! if (!ifr) {
! printf("No interface for %s\n", servername);
! exit(1);
}
! if (getether(ifr->ifr_name, eaddr)) {
printf("Can not get ether addr for %s\n", ifr->ifr_name);
exit(1);
}
--- 312,326 ----
if (use_hwa) {
struct ifreq *ifr;
! if (!ifname) {
! ifr = getif(s, &sin_server.sin_addr);
! if (!ifr) {
! printf("No interface for %s\n", servername);
! exit(1);
! }
! ifname = ifr->ifr_name;
}
! if (getether(ifname, eaddr)) {
printf("Can not get ether addr for %s\n", ifr->ifr_name);
exit(1);
}