1*0Sstevel@tonic-gate# 2*0Sstevel@tonic-gate# CDDL HEADER START 3*0Sstevel@tonic-gate# 4*0Sstevel@tonic-gate# The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate# (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate# with the License. 8*0Sstevel@tonic-gate# 9*0Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate# See the License for the specific language governing permissions 12*0Sstevel@tonic-gate# and limitations under the License. 13*0Sstevel@tonic-gate# 14*0Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate# 20*0Sstevel@tonic-gate# CDDL HEADER END 21*0Sstevel@tonic-gate# 22*0Sstevel@tonic-gateCopyright (c) 2001 by Sun Microsystems, Inc. 23*0Sstevel@tonic-gateAll rights reserved. 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gateInittab Purpose, Goals, and Functionality 26*0Sstevel@tonic-gatePeter Memishian 27*0Sstevel@tonic-gateident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gatePROBLEM STATEMENT 30*0Sstevel@tonic-gate================= 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gateCurrently, each DHCP-related utility that needs to handle DHCP options 33*0Sstevel@tonic-gateuses ad-hoc methods for learning and using them, ranging from using 34*0Sstevel@tonic-gatehard-coded internal tables to providing published (but distinct) 35*0Sstevel@tonic-gateconfiguration files describing these options. 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gateOriginally, when only the DHCP server needed to be concerned with DHCP 38*0Sstevel@tonic-gateoptions, not having a standard API for managing and parsing DHCP 39*0Sstevel@tonic-gateoptions was understandable. Now, with four consumers of DHCP options 40*0Sstevel@tonic-gatein core Solaris (in.dhcpd, dhcpinfo, snoop, and dhcpmgr), the 41*0Sstevel@tonic-gatesituation has spiraled out of control. In addition to the obvious 42*0Sstevel@tonic-gatemaintenance headache caused by the redundant code, it has also become 43*0Sstevel@tonic-gatea burden to our customers, who already have to cope with multiple 44*0Sstevel@tonic-gateplaces where DHCP option information is stored (dhcptags(4), 45*0Sstevel@tonic-gatedhcptab(4)). 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gateThe inittab API is designed to reduce the confusion, both for the 48*0Sstevel@tonic-gatecustomer and the application developer. Its goal is to provide a 49*0Sstevel@tonic-gatesingle configuration for applications to receive their DHCP option 50*0Sstevel@tonic-gateknowledge from and general routines for encoding and decoding DHCP 51*0Sstevel@tonic-gateoptions. 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gateINITTAB 54*0Sstevel@tonic-gate======= 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gateThe inittab file contains information regarding the syntax and (to 57*0Sstevel@tonic-gatesome degree) the semantics of DHCP options. It is primarily a 58*0Sstevel@tonic-gateread-only file (like /etc/termcap) and should not need to be changed 59*0Sstevel@tonic-gateby users. Experienced sysadmins may need to update this file to add 60*0Sstevel@tonic-gatenew DHCP options, but this should be rare. 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gateThe inittab file consists of inittab records, each being one line long 63*0Sstevel@tonic-gateand describing a particular option. The format is based heavily on 64*0Sstevel@tonic-gatethe format for defining symbols in dhcptab(4). Each line has the 65*0Sstevel@tonic-gatefollowing syntax: 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate option_name category, code, type, granularity, maximum, consumers 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gatewhere: 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate `option_name' is user-interpretable name of the option (for use with 72*0Sstevel@tonic-gate dhcpinfo(1M) for instance). This field should at least be per- 73*0Sstevel@tonic-gate category unique and ideally should be unique across all categories. 74*0Sstevel@tonic-gate Of particular note is that options names in the STANDARD, SITE, and 75*0Sstevel@tonic-gate VENDOR spaces should not overlap, or the behavior is undefined. 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate `category' is one of STANDARD, SITE, VENDOR, FIELD, or INTERNAL and 78*0Sstevel@tonic-gate identifies the namespace in which the option falls. 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate `code' is the code of this option when it is sent over the 81*0Sstevel@tonic-gate wire. (note: in most cases, `code' uniquely identifies the 82*0Sstevel@tonic-gate option, without a category. however, in the case of internal 83*0Sstevel@tonic-gate categories like FIELD or INTERNAL, `code' may be used for 84*0Sstevel@tonic-gate other purposes and thus may not be globally unique). This field 85*0Sstevel@tonic-gate should be per-category unique and the STANDARD and SITE fields 86*0Sstevel@tonic-gate should not have overlapping code fields or the behavior is 87*0Sstevel@tonic-gate undefined. 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate `type' describes the payload associated with this option. Valid 90*0Sstevel@tonic-gate types are IP, ASCII, OCTET, NUMBER, BOOL, UNUMBER8, UNUMBER16, 91*0Sstevel@tonic-gate UNUMBER32, SNUMBER8, SNUMBER16, and SNUMBER32. For numbers, 92*0Sstevel@tonic-gate a preceding `U' or `S' indicates whether the number is unsigned 93*0Sstevel@tonic-gate or signed, and the trailing number indicates the number of bits 94*0Sstevel@tonic-gate in the number. 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate `granularity' describes how many units of `type' payload make 97*0Sstevel@tonic-gate up a whole value for this option. In the case of `NUMBER', 98*0Sstevel@tonic-gate granularity describes the number of bytes in the number. Note 99*0Sstevel@tonic-gate that `NUMBER' is preserved for compatibility, but the more 100*0Sstevel@tonic-gate descriptive [SU]NUMBER{8,16,32,64} types should preferred. 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate `maximum' describes how many whole values are allowed for this 103*0Sstevel@tonic-gate option. 0 indicates an infinite number. 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate `consumers' describe which programs make use of this information. 106*0Sstevel@tonic-gate (`i' for dhcpinfo, `s' for snoop, `d' for in.dhcpd, and 107*0Sstevel@tonic-gate `m' for dhcpmgr). 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gateA sample entry would be 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate StaticRt STANDARD, 33, IP, 2, 0, isdm 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gatewhich describes an option named `StaticRt', that is in the STANDARD 114*0Sstevel@tonic-gatecategory (i.e., defined by the DHCP standard), and is option code 115*0Sstevel@tonic-gate33, which is of type `IP Address', consisting of a potentially 116*0Sstevel@tonic-gateinfinite number of pairs of IP addresses. Lastly, the consumers of 117*0Sstevel@tonic-gateoption are dhcpinfo, snoop, in.dhcpd and dhcpmgr. 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gateComments in the inittab file begin with `#', and end with a newline. 120*0Sstevel@tonic-gateComments need not start at the beginning of a line. Lines cannot be 121*0Sstevel@tonic-gatecontinued (with `\' for instance). 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gateThe inittab file becomes the authoritative source for all DHCP options 124*0Sstevel@tonic-gatefor all DHCP option consumers, with the following exceptions and notes: 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gate o The DHCP agent and DHCP server both have their core protocol- 127*0Sstevel@tonic-gate related functionality hardcoded into them, so changes to the 128*0Sstevel@tonic-gate inittab file do not generally affect their inner workings. 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate o A program can specify which entries it wants from the inittab. 131*0Sstevel@tonic-gate This means that some DHCP options will never be used by some 132*0Sstevel@tonic-gate programs, even if they are listed as a `consumer' of the given 133*0Sstevel@tonic-gate option. An example of this is that the DHCP server never 134*0Sstevel@tonic-gate requests any fields with the VENDOR category. (VENDOR information 135*0Sstevel@tonic-gate for the DHCP server comes from dhcptab(4) instead). 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate o In general, changing provided information in a released inittab 138*0Sstevel@tonic-gate file is ill-advised. Adding new entries should be the extent 139*0Sstevel@tonic-gate of the modifications that are performed. 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate o The inittab C API also provides functions which allow programs 142*0Sstevel@tonic-gate to verify that a given entry in the inittab file is correct 143*0Sstevel@tonic-gate (which it does by consulting a compiled-in database of current 144*0Sstevel@tonic-gate options). In general, this functionality is only used where 145*0Sstevel@tonic-gate absolutely necessary, since it nullifies some of the advantages 146*0Sstevel@tonic-gate of having an inittab. 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate o Where a symbol is defined both in the inittab and in dhcptab(4), 149*0Sstevel@tonic-gate inittab is authoritative. EXTEND symbol definitions in 150*0Sstevel@tonic-gate dhcptab(4) will be deprecated in a future release of Solaris. 151*0Sstevel@tonic-gate 152*0Sstevel@tonic-gateC-LEVEL API 153*0Sstevel@tonic-gate=========== 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gateEach inittab entry describes a specific DHCP option and is defined as 156*0Sstevel@tonic-gatea dhcp_symbol_t (as defined in usr/src/lib/libdhcputil/common/dhcp_symbol.h). 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gateIn general, it is expected that inittab entries are acquired via 159*0Sstevel@tonic-gateinittab_load(), inittab_getbyname(), or inittab_getbycode() and passed 160*0Sstevel@tonic-gateas needed to the remaining inittab_XXX functions. If consumers need 161*0Sstevel@tonic-gateto convert the inittab entries into a different format, then the 162*0Sstevel@tonic-gatefields inside the inittab entry may be read directly. Some inittab 163*0Sstevel@tonic-gatefunctions return dynamically allocated parameters; all such parameters 164*0Sstevel@tonic-gatecan be freed with free(3c). 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gateTo get an inittab entry, one of the following API's must be used: 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate dhcp_symbol_t * 169*0Sstevel@tonic-gate inittab_load(uchar_t categories, char consumer, size_t *n_entries); 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate dhcp_symbol_t * 172*0Sstevel@tonic-gate inittab_getbyname(uchar_t categories, char consumer, const char *name); 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate dhcp_symbol_t * 175*0Sstevel@tonic-gate inittab_getbycode(uchar_t categories, char consumer, unsigned int code); 176*0Sstevel@tonic-gate 177*0Sstevel@tonic-gatewhere the `categories' parameter consists of the following values OR'd 178*0Sstevel@tonic-gatetogether: 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate #define ITAB_CAT_STANDARD 0x01 181*0Sstevel@tonic-gate #define ITAB_CAT_FIELD 0x02 182*0Sstevel@tonic-gate #define ITAB_CAT_INTERNAL 0x04 183*0Sstevel@tonic-gate #define ITAB_CAT_VENDOR 0x08 184*0Sstevel@tonic-gate #define ITAB_CAT_SITE 0x10 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gateand the `consumer' field consists of one of the following: 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate #define ITAB_CONS_INFO 'i' 189*0Sstevel@tonic-gate #define ITAB_CONS_SERVER 'd' 190*0Sstevel@tonic-gate #define ITAB_CONS_SNOOP 's' 191*0Sstevel@tonic-gate #define ITAB_CONS_MANAGER 'm' 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gateinittab_load() creates and returns an array of dhcp_symbol_t's made 194*0Sstevel@tonic-gateup of all the entries of the specified categories that are available 195*0Sstevel@tonic-gateto the provided consumer. Note that there is no specified order to 196*0Sstevel@tonic-gatethe entries returned. The array is dynamically allocated, and the 197*0Sstevel@tonic-gatenumber of items in the array is returned in the `n_entries' parameter. 198*0Sstevel@tonic-gate 199*0Sstevel@tonic-gateinittab_getbyname()/inittab_getbycode() return an dhcp_symbol_t 200*0Sstevel@tonic-gatematching the given name or code for the provided category and the 201*0Sstevel@tonic-gateprovided consumer. The dhcp_symbol_t is dynamically allocated. 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gateSome inittab consumers may need to make sure that a given inittab 204*0Sstevel@tonic-gateentry has not been corrupted in the inittab file. For those cases, 205*0Sstevel@tonic-gateinittab_verify() can be used to validate an inittab_entry against an 206*0Sstevel@tonic-gateinternal table compiled into the inittab API: 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate int 209*0Sstevel@tonic-gate inittab_verify(dhcp_symbol_t *inittab_ent, 210*0Sstevel@tonic-gate dhcp_symbol_t *internal_ent); 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gatewhere `inittab_ent' is an dhcp_symbol_t previously returned from 213*0Sstevel@tonic-gateinittab_load() or inittab_getbyX(). inittab_verify() returns 214*0Sstevel@tonic-gateITAB_SUCCESS if `inittab_ent' is verified to be correct, ITAB_FAILURE 215*0Sstevel@tonic-gateif `inittab_ent' is incorrect, and ITAB_UNKNOWN if inittab_verify() 216*0Sstevel@tonic-gatedoesn't know. If `internal_ent' is non-NULL, it is filled in with the 217*0Sstevel@tonic-gatevalue of the option known internally to the inittab API. Entries are 218*0Sstevel@tonic-gateverified using the `ds_category' and `ds_code' fields from the 219*0Sstevel@tonic-gatedhcp_symbol_t. For ITAB_SUCCESS to be returned, the entry passed in 220*0Sstevel@tonic-gateand the internal entry both must have the same ds_gran, ds_max, and 221*0Sstevel@tonic-gateds_type values. 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gateTo perform encoding and decoding of DHCP options, the following 224*0Sstevel@tonic-gateroutines are provided: 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate uchar_t * 227*0Sstevel@tonic-gate inittab_encode(dhcp_symbol_t *inittab_ent, const char *data, 228*0Sstevel@tonic-gate uint16_t *lengthp, boolean_t just_payload); 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate const char * 231*0Sstevel@tonic-gate inittab_decode(dhcp_symbol_t *inittab_ent, uchar_t *data, 232*0Sstevel@tonic-gate uint16_t length, boolean_t just_payload); 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gateBoth of these routines take an `inittab_ent' that was previously 235*0Sstevel@tonic-gatereturned from inittab_load() or inittab_getbyX(). 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gateFor inittab_encode(), `data' is an ASCII string to encode, and a 238*0Sstevel@tonic-gatepointer to a dynamically allocated byte-array representing the encoded 239*0Sstevel@tonic-gateoption is returned. The size of the resulting data returned is stored 240*0Sstevel@tonic-gatein `lengthp'. Note that if the `just_payload' option is set, then 241*0Sstevel@tonic-gateonly the payload of the option is returned (i.e., the option code and 242*0Sstevel@tonic-gateoption length is left off the returned data). To encode multiple 243*0Sstevel@tonic-gateitems of a given type, separate the items by spaces, such as 244*0Sstevel@tonic-gate"109.108.21.1 148.232.2.1". Octal data should be of the form "0xNN" 245*0Sstevel@tonic-gatewhere NN is a hexadecimal digit representing the byte. 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gateFor inittab_decode(), `data' is a byte-array representing an encoded 248*0Sstevel@tonic-gateoption, which is `length' bytes long. A pointer to a dynamically 249*0Sstevel@tonic-gateallocated string representing the option's value in ASCII is returned. 250*0Sstevel@tonic-gateNote that if the `data' byte-array consists of just the payload of the 251*0Sstevel@tonic-gateoption, then the `just_payload' option should be set. 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gateIn addition, the following routines return extended error information 254*0Sstevel@tonic-gatefor reporting parsing errors: 255*0Sstevel@tonic-gate 256*0Sstevel@tonic-gate uchar_t * 257*0Sstevel@tonic-gate inittab_encode_e(dhcp_symbol_t *inittab_ent, const char *data, 258*0Sstevel@tonic-gate uint16_t *lengthp, boolean_t just_payload, int *eerrno); 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate const char * 261*0Sstevel@tonic-gate inittab_decode_e(dhcp_symbol_t *inittab_ent, uchar_t *data, 262*0Sstevel@tonic-gate uint16_t length, boolean_t just_payload, int *eerrno); 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gateThe extended codes: 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gate/* 268*0Sstevel@tonic-gate * DHCP Extended error codes 269*0Sstevel@tonic-gate */ 270*0Sstevel@tonic-gate#define ITAB_SYNTAX_ERROR (-1) 271*0Sstevel@tonic-gate#define ITAB_BAD_IPADDR (-2) 272*0Sstevel@tonic-gate#define ITAB_BAD_STRING (-3) 273*0Sstevel@tonic-gate#define ITAB_BAD_OCTET (-4) 274*0Sstevel@tonic-gate#define ITAB_BAD_NUMBER (-5) 275*0Sstevel@tonic-gate#define ITAB_BAD_BOOLEAN (-6) 276*0Sstevel@tonic-gate#define ITAB_NOT_ENOUGH_IP (-7) 277*0Sstevel@tonic-gate#define ITAB_BAD_GRAN (-8) 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate 280*0Sstevel@tonic-gateENVIRONMENT VARIABLES 281*0Sstevel@tonic-gate===================== 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gateIn order to aid in debugging inittab-related problems, two environment 284*0Sstevel@tonic-gatevariables, DHCP_INITTAB_DEBUG, and DHCP_INITTAB_PATH, can be set 285*0Sstevel@tonic-gatebefore starting a program which uses the inittab API. 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gateIf DHCP_INITTAB_DEBUG is an exported environment variable, then the 288*0Sstevel@tonic-gateinittab API will print useful diagnostic messages handy in tracking 289*0Sstevel@tonic-gatedown problems in the inittab file. If DHCP_INITTAB_PATH is an 290*0Sstevel@tonic-gateexported environment variable, then its value is used as the location 291*0Sstevel@tonic-gateof the inittab file, instead of /etc/dhcp/inittab. 292*0Sstevel@tonic-gate 293*0Sstevel@tonic-gate-- 294*0Sstevel@tonic-gatePeter Memishian, Internet Engineering, Solaris Software (meem@east.sun.com) 295