summaryrefslogtreecommitdiffstats
path: root/sys/i386/boot/netboot
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1994-10-19 20:25:37 +0000
committerphk <phk@FreeBSD.org>1994-10-19 20:25:37 +0000
commite55b0fa62fdb3d44ba0a6aa243d83b3d48238880 (patch)
treeca6f35237586c08f19fd6fe641bc1346c54d5fa9 /sys/i386/boot/netboot
parent9ee8afd3d61349795596b88864c0580ac1ad8cde (diff)
downloadFreeBSD-src-e55b0fa62fdb3d44ba0a6aa243d83b3d48238880.zip
FreeBSD-src-e55b0fa62fdb3d44ba0a6aa243d83b3d48238880.tar.gz
Martins latest changes. RFC1048 and swap-file should be in the game now.
Submitted by: Martin Renters.
Diffstat (limited to 'sys/i386/boot/netboot')
-rw-r--r--sys/i386/boot/netboot/bootmenu.c22
-rw-r--r--sys/i386/boot/netboot/main.c85
-rw-r--r--sys/i386/boot/netboot/netboot.h8
3 files changed, 98 insertions, 17 deletions
diff --git a/sys/i386/boot/netboot/bootmenu.c b/sys/i386/boot/netboot/bootmenu.c
index c4b7a4d..19c13d8 100644
--- a/sys/i386/boot/netboot/bootmenu.c
+++ b/sys/i386/boot/netboot/bootmenu.c
@@ -13,7 +13,7 @@ extern unsigned long netmask;
int cmd_ip(), cmd_server(), cmd_kernel(), cmd_help(), exit();
int cmd_rootfs(), cmd_swapfs(), cmd_interface(), cmd_hostname();
-int cmd_netmask();
+int cmd_netmask(), cmd_swapsize();
#ifdef SMALL_ROM
struct bootcmds_t {
@@ -40,10 +40,11 @@ struct bootcmds_t {
{"ip", cmd_ip, "<addr> set my IP addr"},
{"server", cmd_server, "<addr> set TFTP server IP addr"},
{"netmask", cmd_netmask, "<addr> set network mask"},
- {"hostname", cmd_hostname, " set hostname"},
+ {"hostname", cmd_hostname, "<name> set hostname"},
{"kernel", cmd_kernel, "<file> set boot filename"},
- {"rootfs", cmd_rootfs, " set root filesystem"},
- {"swapfs", cmd_swapfs, " set swap filesystem"},
+ {"rootfs", cmd_rootfs, "ip:/fs set root filesystem"},
+ {"swapfs", cmd_swapfs, "ip:/fs set swap filesystem"},
+ {"swapsize", cmd_swapsize, "<nblks> set swap size"},
{"diskboot", exit, " boot from disk"},
{"autoboot", NULL, " continue"},
{NULL, NULL, NULL}
@@ -73,7 +74,7 @@ cmd_ip(p)
if (!setip(p, &arptable[ARP_CLIENT].ipaddr)) {
printf("IP address is %I\r\n",
arptable[ARP_CLIENT].ipaddr);
- }
+ } else default_netmask();
}
/**************************************************************************
@@ -104,6 +105,17 @@ cmd_netmask(p)
netmask = htonl(netmask);
}
+/**************************************************************************
+CMD_SWAPSIZE - Set number of blocks for swap
+**************************************************************************/
+cmd_swapsize(p)
+ char *p;
+{
+ int blks = getdec(&p);
+ if (blks > 0) nfsdiskless.swap_nblks = blks;
+ else printf("Swap size is: %d blocks\r\n",nfsdiskless.swap_nblks);
+}
+
extern char kernel_buf[], *kernel;
/**************************************************************************
CMD_KERNEL - set kernel filename
diff --git a/sys/i386/boot/netboot/main.c b/sys/i386/boot/netboot/main.c
index 0f4e842..0046208 100644
--- a/sys/i386/boot/netboot/main.c
+++ b/sys/i386/boot/netboot/main.c
@@ -126,19 +126,14 @@ load()
nfsdiskless.myif.ifra_addr.sa_family = AF_INET;
addr = htonl(arptable[ARP_CLIENT].ipaddr);
bcopy(&addr, &nfsdiskless.myif.ifra_addr.sa_data[2], 4);
- if (!netmask) {
- int net = nfsdiskless.myif.ifra_addr.sa_data[2];
- if (net <= 127)
- netmask = htonl(0xff000000);
- else if (net < 192)
- netmask = htonl(0xffff0000);
- else
- netmask = htonl(0xffffff00);
- }
broadcast = (addr & netmask) | ~netmask;
- nfsdiskless.myif.ifra_broadaddr.sa_len = sizeof(struct sockaddr);
- nfsdiskless.myif.ifra_broadaddr.sa_family = AF_INET;
+ nfsdiskless.myif.ifra_broadaddr.sa_len = sizeof(struct sockaddr);
+ nfsdiskless.myif.ifra_broadaddr.sa_family = AF_INET;
bcopy(&broadcast, &nfsdiskless.myif.ifra_broadaddr.sa_data[2], 4);
+ addr = htonl(arptable[ARP_GATEWAY].ipaddr);
+ nfsdiskless.mygateway.sin_len = sizeof(struct sockaddr);
+ nfsdiskless.mygateway.sin_family = AF_INET;
+ bcopy(&addr, &nfsdiskless.mygateway.sin_addr, 4);
nfsdiskless.myif.ifra_mask.sa_len = sizeof(struct sockaddr);
nfsdiskless.myif.ifra_mask.sa_family = AF_UNSPEC;
bcopy(&netmask, &nfsdiskless.myif.ifra_mask.sa_data[2], 4);
@@ -147,15 +142,29 @@ load()
/* Lookup NFS/MOUNTD ports for SWAP using PORTMAP */
if (arptable[ARP_SWAPSERVER].ipaddr) {
+ char swapfs_fh[32], swapfile[32];
swap_nfs_port = rpclookup(ARP_SWAPSERVER, PROG_NFS, 2);
swap_mount_port = rpclookup(ARP_SWAPSERVER, PROG_MOUNT, 1);
if ((swap_nfs_port == -1) || (swap_mount_port == -1)) {
printf("Unable to get SWAP NFS/MOUNT ports\r\n");
longjmp(jmp_bootmenu,1);
}
+ if (err = nfs_mount(ARP_SWAPSERVER, swap_mount_port,
+ nfsdiskless.swap_hostnam, &swapfs_fh)) {
+ printf("Unable to mount SWAP filesystem: ");
+ nfs_err(err);
+ longjmp(jmp_bootmenu,1);
+ }
+ sprintf(swapfile,"swap.%I",arptable[ARP_CLIENT].ipaddr);
+ if (err = nfs_lookup(ARP_SWAPSERVER, swap_nfs_port,
+ &swapfs_fh, swapfile, &nfsdiskless.swap_fh)) {
+ printf("Unable to open %s: ",swapfile);
+ nfs_err(err);
+ longjmp(jmp_bootmenu,1);
+ }
nfsdiskless.swap_saddr.sin_len = sizeof(struct sockaddr_in);
nfsdiskless.swap_saddr.sin_family = AF_INET;
- nfsdiskless.swap_saddr.sin_port = root_nfs_port;
+ nfsdiskless.swap_saddr.sin_port = swap_nfs_port;
nfsdiskless.swap_saddr.sin_addr.s_addr =
htonl(arptable[ARP_SWAPSERVER].ipaddr);
nfsdiskless.swap_args.sotype = SOCK_DGRAM;
@@ -272,6 +281,19 @@ pollkbd()
}
/**************************************************************************
+DEFAULT_NETMASK - Set a default netmask for IP address
+**************************************************************************/
+default_netmask()
+{
+ int net = arptable[ARP_CLIENT].ipaddr >> 24;
+ if (net <= 127)
+ netmask = htonl(0xff000000);
+ else if (net < 192)
+ netmask = htonl(0xffff0000);
+ else
+ netmask = htonl(0xffffff00);
+}
+/**************************************************************************
UDP_TRANSMIT - Send a UDP datagram
**************************************************************************/
udp_transmit(destip, srcsock, destsock, len, buf)
@@ -307,6 +329,12 @@ udp_transmit(destip, srcsock, destsock, len, buf)
if (destip == IP_BROADCAST) {
eth_transmit(broadcast, IP, len, buf);
} else {
+ long h_netmask = ntohl(netmask);
+ /* Check to see if we need gateway */
+ if (((destip & h_netmask) !=
+ (arptable[ARP_CLIENT].ipaddr & h_netmask)) &&
+ arptable[ARP_GATEWAY].ipaddr)
+ destip = arptable[ARP_GATEWAY].ipaddr;
for(arpentry = 0; arpentry<MAX_ARP; arpentry++)
if (arptable[arpentry].ipaddr == destip) break;
if (arpentry == MAX_ARP) {
@@ -469,15 +497,21 @@ await_reply(type, ival, ptr)
(bootpreply->bp_op == BOOTP_REPLY)) {
convert_ipaddr(&arptable[ARP_CLIENT].ipaddr,
bootpreply->bp_yiaddr);
+ default_netmask();
convert_ipaddr(&arptable[ARP_SERVER].ipaddr,
bootpreply->bp_siaddr);
bzero(arptable[ARP_SERVER].node,
ETHER_ADDR_SIZE); /* Kill arp */
+ convert_ipaddr(&arptable[ARP_GATEWAY].ipaddr,
+ bootpreply->bp_giaddr);
+ bzero(arptable[ARP_GATEWAY].node,
+ ETHER_ADDR_SIZE); /* Kill arp */
if (bootpreply->bp_file[0]) {
bcopy(bootpreply->bp_file,
kernel_buf, 128);
kernel = kernel_buf;
}
+ decode_rfc1048(bootpreply->bp_vend);
return(1);
}
@@ -500,6 +534,33 @@ await_reply(type, ival, ptr)
}
/**************************************************************************
+DECODE_RFC1048 - Decodes RFC1048 header
+**************************************************************************/
+decode_rfc1048(p)
+ unsigned char *p;
+{
+ static char rfc1048_cookie[4] = RFC1048_COOKIE;
+ unsigned char *end = p + BOOTP_VENDOR_LEN;
+ if (bcompare(p, rfc1048_cookie, 4)) { /* RFC 1048 header */
+ p += 4;
+ while(p < end) {
+ if (*p == RFC1048_PAD) {
+ p++;
+ continue;
+ }
+ if (*p == RFC1048_END) break;
+ if (*p == RFC1048_NETMASK)
+ bcopy(p+2,&netmask,4);
+ if (*p == RFC1048_HOSTNAME) {
+ bcopy(p+2, &nfsdiskless.my_hostnam, TAG_LEN(p));
+ hostnamelen = (TAG_LEN(p) + 3) & ~3;
+ }
+ p += TAG_LEN(p) + 2;
+ }
+ }
+}
+
+/**************************************************************************
IPCHKSUM - Checksum IP Header
**************************************************************************/
ipchksum(ip, len)
diff --git a/sys/i386/boot/netboot/netboot.h b/sys/i386/boot/netboot/netboot.h
index e6d949d..e60c8f7 100644
--- a/sys/i386/boot/netboot/netboot.h
+++ b/sys/i386/boot/netboot/netboot.h
@@ -79,6 +79,14 @@ Author: Martin Renters
#define BOOTP_REQUEST 1
#define BOOTP_REPLY 2
+#define TAG_LEN(p) (*((p)+1))
+#define RFC1048_COOKIE { 99, 130, 83, 99 }
+#define RFC1048_PAD 0
+#define RFC1048_NETMASK 1
+#define RFC1048_HOSTNAME 12
+#define RFC1048_END 255
+#define BOOTP_VENDOR_LEN 64
+
#define TFTP_RRQ 1
#define TFTP_WRQ 2
#define TFTP_DATA 3
OpenPOWER on IntegriCloud