/*-1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright (c) 1988, 1992 The University of Utah and the Center4* for Software Science (CSS).5* Copyright (c) 1992, 19936* The Regents of the University of California. All rights reserved.7*8* This code is derived from software contributed to Berkeley by9* the Center for Software Science of the University of Utah Computer10* Science Department. CSS requests users of this software to return11* to [email protected] any improvements that they make and grant12* CSS redistribution rights.13*14* Redistribution and use in source and binary forms, with or without15* modification, are permitted provided that the following conditions16* are met:17* 1. Redistributions of source code must retain the above copyright18* notice, this list of conditions and the following disclaimer.19* 2. Redistributions in binary form must reproduce the above copyright20* notice, this list of conditions and the following disclaimer in the21* documentation and/or other materials provided with the distribution.22* 3. Neither the name of the University nor the names of its contributors23* may be used to endorse or promote products derived from this software24* without specific prior written permission.25*26* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND27* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE28* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE29* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE30* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL31* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS32* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)33* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT34* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY35* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF36* SUCH DAMAGE.37*38* from: Utah Hdr: rmp_var.h 3.1 92/07/0639* Author: Jeff Forys, University of Utah CSS40*/4142/*43* Possible values for "rmp_type" fields.44*/4546#define RMP_BOOT_REQ 1 /* boot request packet */47#define RMP_BOOT_REPL 129 /* boot reply packet */48#define RMP_READ_REQ 2 /* read request packet */49#define RMP_READ_REPL 130 /* read reply packet */50#define RMP_BOOT_DONE 3 /* boot complete packet */5152/*53* Useful constants.54*/5556#define RMP_VERSION 2 /* protocol version */57#define RMP_TIMEOUT 600 /* timeout connection after ten minutes */58#define RMP_PROBESID 0xffff /* session ID for probes */59#define RMP_HOSTLEN 13 /* max length of server's name */60#define RMP_MACHLEN 20 /* length of machine type field */6162/*63* RMP error codes64*/6566#define RMP_E_OKAY 067#define RMP_E_EOF 2 /* read reply: returned end of file */68#define RMP_E_ABORT 3 /* abort operation */69#define RMP_E_BUSY 4 /* boot reply: server busy */70#define RMP_E_TIMEOUT 5 /* lengthen time out (not implemented) */71#define RMP_E_NOFILE 16 /* boot reply: file does not exist */72#define RMP_E_OPENFILE 17 /* boot reply: file open failed */73#define RMP_E_NODFLT 18 /* boot reply: default file does not exist */74#define RMP_E_OPENDFLT 19 /* boot reply: default file open failed */75#define RMP_E_BADSID 25 /* read reply: bad session ID */76#define RMP_E_BADPACKET 27 /* Bad packet detected */7778/*79* RMPDATALEN is the maximum number of data octets that can be stuffed80* into an RMP packet. This excludes the 802.2 LLC w/HP extensions.81*/82#define RMPDATALEN (RMP_MAX_PACKET - (sizeof(struct hp_hdr) + \83sizeof(struct hp_llc)))8485/*86* Define sizes of packets we send. Boot and Read replies are variable87* in length depending on the length of `s'.88*89* Also, define how much space `restofpkt' can take up for outgoing90* Boot and Read replies. Boot Request packets are effectively91* limited to 255 bytes due to the preceding 1-byte length field.92*/9394#define RMPBOOTSIZE(s) (sizeof(struct hp_hdr) + sizeof(struct hp_llc) + \95sizeof(struct rmp_boot_repl) + s - sizeof(restofpkt))96#define RMPREADSIZE(s) (sizeof(struct hp_hdr) + sizeof(struct hp_llc) + \97sizeof(struct rmp_read_repl) + s - sizeof(restofpkt) \98- sizeof(u_int8_t))99#define RMPDONESIZE (sizeof(struct hp_hdr) + sizeof(struct hp_llc) + \100sizeof(struct rmp_boot_done))101#define RMPBOOTDATA 255102#define RMPREADDATA (RMPDATALEN - \103(2*sizeof(u_int8_t)+sizeof(u_int16_t)+sizeof(u_word)))104105/*106* This protocol defines some field sizes as "rest of ethernet packet".107* There is no easy way to specify this in C, so we use a one character108* field to denote it, and index past it to the end of the packet.109*/110111typedef char restofpkt;112113/*114* Due to the RMP packet layout, we'll run into alignment problems115* on machines that can't access (or don't, by default, align) words116* on half-word boundaries. If you know that your machine does not suffer117* from this problem, add it to the vax/tahoe/m68k #define below.118*119* The following macros are used to deal with this problem:120* WORDZE(w) Return True if u_word `w' is zero, False otherwise.121* ZEROWORD(w) Set u_word `w' to zero.122* COPYWORD(w1,w2) Copy u_word `w1' to `w2'.123* GETWORD(w,i) Copy u_word `w' into int `i'.124* PUTWORD(i,w) Copy int `i' into u_word `w'.125*126* N.B. Endianness is handled by use of ntohl/htonl127*/128#if defined(__vax__) || defined(__tahoe__) || defined(__m68k__)129130typedef u_int32_t u_word;131132#define WORDZE(w) ((w) == 0)133#define ZEROWORD(w) (w) = 0134#define COPYWORD(w1,w2) (w2) = (w1)135#define GETWORD(w, i) (i) = ntohl(w)136#define PUTWORD(i, w) (w) = htonl(i)137138#else139140#define _WORD_HIGHPART 0141#define _WORD_LOWPART 1142143typedef struct _uword { u_int16_t val[2]; } u_word;144145#define WORDZE(w) \146((w.val[_WORD_HIGHPART] == 0) && (w.val[_WORD_LOWPART] == 0))147#define ZEROWORD(w) \148(w).val[_WORD_HIGHPART] = (w).val[_WORD_LOWPART] = 0149#define COPYWORD(w1, w2) \150{ (w2).val[_WORD_HIGHPART] = (w1).val[_WORD_HIGHPART]; \151(w2).val[_WORD_LOWPART] = (w1).val[_WORD_LOWPART]; \152}153#define GETWORD(w, i) \154(i) = (((u_int32_t)ntohs((w).val[_WORD_HIGHPART])) << 16) | ntohs((w).val[_WORD_LOWPART])155#define PUTWORD(i, w) \156{ (w).val[_WORD_HIGHPART] = htons((u_int16_t) ((i >> 16) & 0xffff)); \157(w).val[_WORD_LOWPART] = htons((u_int16_t) (i & 0xffff)); \158}159160#endif161162/*163* Packet structures.164*/165166struct rmp_raw { /* generic RMP packet */167u_int8_t rmp_type; /* packet type */168u_int8_t rmp_rawdata[RMPDATALEN-1];169};170171struct rmp_boot_req { /* boot request */172u_int8_t rmp_type; /* packet type (RMP_BOOT_REQ) */173u_int8_t rmp_retcode; /* return code (0) */174u_word rmp_seqno; /* sequence number (real time clock) */175u_int16_t rmp_session; /* session id (normally 0) */176u_int16_t rmp_version; /* protocol version (RMP_VERSION) */177char rmp_machtype[RMP_MACHLEN]; /* machine type */178u_int8_t rmp_flnmsize; /* length of rmp_flnm */179restofpkt rmp_flnm; /* name of file to be read */180};181182struct rmp_boot_repl { /* boot reply */183u_int8_t rmp_type; /* packet type (RMP_BOOT_REPL) */184u_int8_t rmp_retcode; /* return code (normally 0) */185u_word rmp_seqno; /* sequence number (from boot req) */186u_int16_t rmp_session; /* session id (generated) */187u_int16_t rmp_version; /* protocol version (RMP_VERSION) */188u_int8_t rmp_flnmsize; /* length of rmp_flnm */189restofpkt rmp_flnm; /* name of file (from boot req) */190};191192struct rmp_read_req { /* read request */193u_int8_t rmp_type; /* packet type (RMP_READ_REQ) */194u_int8_t rmp_retcode; /* return code (0) */195u_word rmp_offset; /* file relative byte offset */196u_int16_t rmp_session; /* session id (from boot repl) */197u_int16_t rmp_size; /* max no of bytes to send */198};199200struct rmp_read_repl { /* read reply */201u_int8_t rmp_type; /* packet type (RMP_READ_REPL) */202u_int8_t rmp_retcode; /* return code (normally 0) */203u_word rmp_offset; /* byte offset (from read req) */204u_int16_t rmp_session; /* session id (from read req) */205restofpkt rmp_data; /* data (max size from read req) */206u_int8_t rmp_unused; /* padding to 16-bit boundary */207};208209struct rmp_boot_done { /* boot complete */210u_int8_t rmp_type; /* packet type (RMP_BOOT_DONE) */211u_int8_t rmp_retcode; /* return code (0) */212u_word rmp_unused; /* not used (0) */213u_int16_t rmp_session; /* session id (from read repl) */214};215216struct rmp_packet {217struct hp_hdr hp_hdr;218struct hp_llc hp_llc;219union {220struct rmp_boot_req rmp_brq; /* boot request */221struct rmp_boot_repl rmp_brpl; /* boot reply */222struct rmp_read_req rmp_rrq; /* read request */223struct rmp_read_repl rmp_rrpl; /* read reply */224struct rmp_boot_done rmp_done; /* boot complete */225struct rmp_raw rmp_raw; /* raw data */226} rmp_proto;227};228229/*230* Make life easier...231*/232233#define r_type rmp_proto.rmp_raw.rmp_type234#define r_data rmp_proto.rmp_raw.rmp_rawdata235#define r_brq rmp_proto.rmp_brq236#define r_brpl rmp_proto.rmp_brpl237#define r_rrq rmp_proto.rmp_rrq238#define r_rrpl rmp_proto.rmp_rrpl239#define r_done rmp_proto.rmp_done240241242