Subject: rbootd works on SunOS4's NIT
To: None <port-hp300@NetBSD.ORG>
From: YAMAMORI Takenori <yamamori@kt.rim.or.jp>
List: port-hp300
Date: 05/28/1998 21:00:31
Hello, this is my first mail.
I've just succeeded in diskless booting NetBSD/hp300 by rbootd
running on SunOS4's NIT (not BPF).
I shall send this "rbootd on SunOS4's NIT" named "sun-rbootd.c"
for someone who might need it.
And I made some changes on this sun-rbootd as follows:
* not use /etc/rbootd.conf but use /etc/ethers (or NIS ethers map)
* put SYS_UBOOT on /tftpboot instead of /usr/mdec/rbootd,
and symlink to C0A8XXXX if client IP is 192.168.xx.xx.
(like Sun's rarp/tftp)
You can make sun-rbootd with some additional files.
* etherlib.tar.gz
This contains functions ether_open(), ether_read(), ether_write()
etc., and I can use NIT by these.
(Please find it by archie, ftpsearch etc.)
* rmp.h rmp_var.h
These are from the original rbootd source.
(This source is somewhat "quick hack" but it works fine)
Now, I can boot diskless NetBSD/hp300 by SunOS4 boot-server without BPF!!
# OpenBSD/hp300 also boots.
----- sun-rbootd.c --(begin)------------------------------------------------
/* sun-rbootd.c yamamori@kt.rim.or.jp */
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netdb.h>
#include "ether.h"
/* typedef unsigned char u_int8_t; */
/* typedef unsigned short u_int16_t; */
#include "rmp.h"
#undef RMP_MAX_PACKET
#define RMP_MAX_PACKET 1514
#include "rmp_var.h"
#define TFTPBOOT "/tftpboot"
static union {
char buf[2048];
struct {
struct hp_llc llc;
union {
struct rmp_raw raw;
struct rmp_boot_req boot_req;
struct rmp_boot_repl boot_repl;
struct rmp_read_req read_req;
struct rmp_read_repl read_repl;
} proto;
} rmp;
} pb;
static ether_addr rmp_addr = {RMP_ADDR};
static int
my_ether_write(ether_packet *packetp)
{
int fd;
if (
packetp->pktlen > 1500 ||
(fd = ether_open(0, packetp->pktlen, &rmp_addr)) < 0
) {
return 1;
}
ether_write(fd, packetp);
close(fd);
return 0;
}
int
main()
{
int fd_r, fd_boot;
ether_packet packet;
ether_addr dest;
int size;
struct hostent *hp;
char boot_file[8+1];
char hostname[MAXHOSTNAMELEN];
if (chdir(TFTPBOOT) < 0) {
perror(TFTPBOOT);
return 1;
}
if ((fd_r = ether_open(0, -1, &rmp_addr)) < 0) {
perror("ether_open");
return 1;
}
packet.pktbuf = pb.buf;
for (;;) {
packet.pktlen = 60;
ether_read(fd_r, &packet);
if (
!(
*(unsigned short *)packet.type <= 1500 &&
pb.rmp.llc.dsap == IEEE_DSAP_HP &&
pb.rmp.llc.ssap == IEEE_SSAP_HP &&
pb.rmp.llc.cntrl == IEEE_CNTL_HP &&
pb.rmp.llc.filler == 0 &&
pb.rmp.llc.dxsap == HPEXT_DXSAP &&
pb.rmp.llc.sxsap == HPEXT_SXSAP
)
) {
continue;
}
dest = *(ether_addr *)packet.dest;
*(ether_addr *)packet.dest = *(ether_addr *)packet.src;
pb.rmp.llc.dxsap = HPEXT_SXSAP;
pb.rmp.llc.sxsap = HPEXT_DXSAP;
switch (pb.rmp.proto.raw.rmp_type) {
case RMP_BOOT_REQ:
pb.rmp.proto.boot_repl.rmp_type = RMP_BOOT_REPL;
pb.rmp.proto.boot_repl.rmp_retcode = 0;
pb.rmp.proto.boot_repl.rmp_session = 0;
pb.rmp.proto.boot_repl.rmp_version = RMP_VERSION;
if (memcmp(&dest, &rmp_addr, sizeof (ether_addr)) == 0) {
pb.rmp.proto.boot_repl.rmp_flnmsize = 6;
strcpy(&pb.rmp.proto.boot_repl.rmp_flnm, "server");
} else {
pb.rmp.proto.boot_repl.rmp_flnmsize = 4;
strcpy(&pb.rmp.proto.boot_repl.rmp_flnm, "BOOT");
}
packet.pktlen = 46;
my_ether_write(&packet);
break;
case RMP_READ_REQ:
size = pb.rmp.proto.read_req.rmp_size;
pb.rmp.proto.read_repl.rmp_type = RMP_READ_REPL;
pb.rmp.proto.read_repl.rmp_retcode = 0;
if (ether_ntohost(hostname, *(ether_addr *)packet.src) != 0) {
fprintf(stderr, "%x:%x:%x:%x:%x:%x unknown\n",
packet.src[0], packet.src[1], packet.src[2],
packet.src[3], packet.src[4], packet.src[5]
);
break;
}
if ((hp = gethostbyname(hostname)) == NULL) {
fprintf(stderr, "%s: unknown\n", hostname);
break;
}
sprintf(boot_file, "%08X", *(long *)hp->h_addr);
if ((fd_boot = open(boot_file, O_RDONLY, 0)) < 0) {
perror(boot_file);
break;
}
lseek(fd_boot,
*(unsigned long *)&pb.rmp.proto.read_req.rmp_offset,
SEEK_SET);
read(fd_boot, &pb.rmp.proto.read_repl.rmp_data, size);
close(fd_boot);
packet.pktlen = size + 18;
my_ether_write(&packet);
break;
}
}
}
----- sun-rbootd.c --(end)--------------------------------------------------
----------------------------------------
YAMAMORI Takenori yamamori@kt.rim.or.jp
----------------------------------------