1/* 2 * Copyright (c) 2003-2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#ifndef _S_BSDP_H 25#define _S_BSDP_H 26 27/* 28 * bsdp.h 29 * - Boot Server Discovery Protocol (BSDP) definitions 30 */ 31 32/* 33 * Modification History 34 * 35 * Dieter Siegmund (dieter@apple.com) November 24, 1999 36 * - created 37 */ 38 39#include <mach/boolean.h> 40#include <string.h> 41#include <sys/types.h> 42#include "dhcp.h" 43#include "dhcp_options.h" 44 45/* 46 * The boot_image_id consists of: (highest byte,bit to lowest bit,byte: 47 * struct boot_image_id { 48 * u_int16_t attributes; 49 * u_int16_t index; 50 * }; 51 * 52 * The attributes field contains: 53 * struct bsdp_image_attributes { 54 * u_int16_t install:1, 55 * kind:7, 56 * reserved:8; 57 */ 58#define BOOT_IMAGE_ID_NULL ((bsdp_image_id_t)0) 59#define BSDP_IMAGE_INDEX_MAX 0xffff 60#define BSDP_IMAGE_ATTRIBUTES_INSTALL ((u_int16_t)0x8000) 61#define BSDP_IMAGE_ATTRIBUTES_KIND_MASK ((u_int16_t)0x7f00) 62#define BSDP_IMAGE_ATTRIBUTES_KIND_MAX 0x7f 63 64#define BSDP_PRIORITY_MIN ((bsdp_priority_t) 0) 65#define BSDP_PRIORITY_MAX ((bsdp_priority_t) 65535) 66 67#define BSDP_PRIORITY_BASE ((bsdp_priority_t) 32768) 68 69#define BSDP_VENDOR_CLASS_ID "AAPLBSDPC" 70#define BSDP_VERSION_1_0 ((unsigned short)0x0100) 71#define BSDP_VERSION_1_1 ((unsigned short)0x0101) 72#define BSDP_VERSION_0_0 ((unsigned short)0x0) 73 74typedef enum { 75 bsdp_image_kind_MacOS9 = 0, 76 bsdp_image_kind_MacOSX = 1, 77 bsdp_image_kind_MacOSXServer = 2, 78 bsdp_image_kind_Diagnostics = 3, 79} bsdp_image_kind_t; 80 81/* 82 * the maximum length of name 83 * = DHCP_OPTION_SIZE_MAX - OPTION_OFFSET - OPTION_OFFSET 84 * - sizeof(bsdp_image_description_t) 85 * = 255 (max option size) 86 * - 2 (vendor specific option's tag/len) 87 * - 2 (this option's tag/len) 88 * - 5 (this struct's boot_image_id + length) 89 * = 246 90 */ 91#define BSDP_IMAGE_NAME_MAX (DHCP_OPTION_SIZE_MAX - 2 * OPTION_OFFSET - 5) 92typedef struct { 93 u_int8_t boot_image_id[4]; 94 u_int8_t name_length; 95 u_int8_t name[0]; 96} bsdp_image_description_t; 97 98typedef u_int16_t bsdp_priority_t; 99typedef u_int16_t bsdp_version_t; 100typedef u_int32_t bsdp_image_id_t; 101 102static __inline__ u_int16_t 103bsdp_image_index(bsdp_image_id_t image_id) 104{ 105 return (image_id & 0xffff); 106} 107 108static __inline__ u_int16_t 109bsdp_image_attributes(bsdp_image_id_t image_id) 110{ 111 return (image_id >> 16); 112} 113 114static __inline__ bsdp_image_id_t 115bsdp_image_id_make(u_int16_t index, u_int16_t attributes) 116{ 117 return (index | ((bsdp_image_id_t)attributes << 16)); 118} 119 120static __inline__ boolean_t 121bsdp_image_index_is_server_local(u_int16_t index) 122{ 123 return (index < 4096); 124} 125 126static __inline__ boolean_t 127bsdp_image_identifier_is_server_local(u_int32_t identifier) 128{ 129 return (bsdp_image_index_is_server_local(bsdp_image_index(identifier))); 130} 131 132static __inline__ boolean_t 133bsdp_image_identifier_is_install(u_int32_t identifier) 134{ 135 if ((bsdp_image_attributes(identifier) & BSDP_IMAGE_ATTRIBUTES_INSTALL) 136 != 0) { 137 return (TRUE); 138 } 139 return (FALSE); 140} 141 142static __inline__ bsdp_image_kind_t 143bsdp_image_kind_from_attributes(u_int16_t attr) 144{ 145 return ((attr & BSDP_IMAGE_ATTRIBUTES_KIND_MASK) >> 8); 146} 147 148static __inline__ u_int16_t 149bsdp_image_attributes_from_kind(bsdp_image_kind_t kind) 150{ 151 return ((kind << 8) & BSDP_IMAGE_ATTRIBUTES_KIND_MASK); 152} 153 154typedef enum { 155 /* protocol-specific */ 156 bsdptag_message_type_e = 1, 157 bsdptag_version_e = 2, 158 bsdptag_server_identifier_e = 3, 159 bsdptag_server_priority_e = 4, 160 bsdptag_reply_port_e = 5, 161 bsdptag_boot_image_list_path_e = 6, /* not used */ 162 bsdptag_default_boot_image_e = 7, 163 bsdptag_selected_boot_image_e = 8, 164 bsdptag_boot_image_list_e = 9, 165 bsdptag_netboot_1_0_firmware_e = 10, 166 bsdptag_image_attributes_filter_list_e = 11, 167 bsdptag_max_message_size_e = 12, 168 169 /* protocol-specific bounds */ 170 bsdptag_first_e = 1, 171 bsdptag_last_e = 12, 172 173 /* image-specific */ 174 bsdptag_shadow_mount_path_e = 128, /* string (URL) */ 175 bsdptag_shadow_file_path_e = 129, /* string (URL) */ 176 bsdptag_machine_name_e = 130, /* string */ 177} bsdptag_t; 178 179static __inline__ dhcptype_t 180bsdptag_type(bsdptag_t tag) 181{ 182 dhcptype_t type = dhcptype_none_e; 183 184 switch (tag) { 185 case bsdptag_message_type_e: 186 type = dhcptype_uint8_e; 187 break; 188 case bsdptag_server_identifier_e: 189 type = dhcptype_ip_e; 190 break; 191 case bsdptag_version_e: 192 case bsdptag_server_priority_e: 193 case bsdptag_reply_port_e: 194 type = dhcptype_uint16_e; 195 break; 196 case bsdptag_machine_name_e: 197 case bsdptag_boot_image_list_path_e: 198 case bsdptag_shadow_file_path_e: 199 case bsdptag_shadow_mount_path_e: 200 type = dhcptype_string_e; 201 break; 202 case bsdptag_default_boot_image_e: 203 case bsdptag_selected_boot_image_e: 204 type = dhcptype_uint32_e; 205 break; 206 case bsdptag_boot_image_list_e: 207 type = dhcptype_opaque_e; 208 break; 209 case bsdptag_netboot_1_0_firmware_e: 210 type = dhcptype_none_e; 211 break; 212 case bsdptag_image_attributes_filter_list_e: 213 type = dhcptype_uint16_mult_e; 214 break; 215 case bsdptag_max_message_size_e: 216 type = dhcptype_uint16_e; 217 break; 218 default: 219 break; 220 } 221 return (type); 222} 223 224static __inline__ const char * 225bsdptag_name(bsdptag_t tag) 226{ 227 static const char * names[] = { 228 NULL, 229 "message type", /* 1 */ 230 "version", /* 2 */ 231 "server identifier", /* 3 */ 232 "server priority", /* 4 */ 233 "reply port", /* 5 */ 234 "boot image list path", /* 6 */ 235 "default boot image", /* 7 */ 236 "selected boot image", /* 8 */ 237 "boot image list", /* 9 */ 238 "netboot 1.0 firmware", /* 10 */ 239 "image attributes filter list", /* 11 */ 240 "maximum message size", /* 12 */ 241 }; 242 if (tag >= bsdptag_first_e && tag <= bsdptag_last_e) { 243 return (names[tag]); 244 } 245 switch (tag) { 246 case bsdptag_shadow_mount_path_e: 247 return "shadow mount path"; 248 case bsdptag_shadow_file_path_e: 249 return "shadow file path"; 250 case bsdptag_machine_name_e: 251 return "machine name"; 252 default: 253 break; 254 } 255 return ("<unknown>"); 256} 257 258typedef enum { 259 bsdp_msgtype_none_e = 0, 260 bsdp_msgtype_list_e = 1, 261 bsdp_msgtype_select_e = 2, 262 bsdp_msgtype_failed_e = 3, 263} bsdp_msgtype_t; 264 265static __inline__ const char * 266bsdp_msgtype_names(bsdp_msgtype_t type) 267{ 268 static const char * names[] = { 269 "<none>", 270 "LIST", 271 "SELECT", 272 "FAILED", 273 }; 274 if (type >= bsdp_msgtype_none_e && type <= bsdp_msgtype_failed_e) 275 return (names[type]); 276 return ("<unknown>"); 277} 278 279/* 280 * Function: bsdp_parse_class_id 281 * 282 * Purpose: 283 * Parse the given option into the arch and system identifier 284 * fields. 285 * 286 * The format is "AAPLBSDPC/<arch>/<system_id>" for client-generated 287 * requests and "AAPLBSDPC" for server-generated responses. 288 */ 289static __inline__ boolean_t 290bsdp_parse_class_id(void * buf, int buf_len, char * arch, 291 char * sysid) 292{ 293 int len; 294 u_char * scan; 295 296 *arch = '\0'; 297 *sysid = '\0'; 298 299 len = strlen(BSDP_VENDOR_CLASS_ID); 300 if (buf_len < len || memcmp(buf, BSDP_VENDOR_CLASS_ID, len)) 301 return (FALSE); /* not a BSDP class identifier */ 302 303 buf_len -= len; 304 scan = (u_char *)buf + len; 305 if (buf_len == 0) 306 return (TRUE); /* server-generated */ 307 308 if (*scan != '/') 309 return (FALSE); 310 311 for (scan++, buf_len--; buf_len && *scan != '/'; scan++, buf_len--) { 312 switch (*scan) { 313 case '\n': 314 case '\0': 315 return (FALSE); 316 default: 317 break; 318 } 319 *arch++ = *scan; 320 } 321 *arch = '\0'; 322 if (*scan != '/') { 323 return (FALSE); 324 } 325 for (scan++, buf_len--; buf_len; scan++, buf_len--) { 326 switch (*scan) { 327 case '\n': 328 case '\0': 329 return (FALSE); 330 default: 331 break; 332 } 333 *sysid++ = *scan; 334 } 335 *sysid = '\0'; 336 return (TRUE); 337} 338 339#endif /* _S_BSDP_H */ 340