1/* 2 * Copyright (c) 2009-2013 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/* 25 * DHCPv6Options.h 26 * - definitions and API's to handle DHCPv6 options 27 */ 28 29/* 30 * Modification History 31 * 32 * September 18, 2009 Dieter Siegmund (dieter@apple.com) 33 * - created 34 */ 35 36#ifndef _S_DHCPV6OPTIONS_H 37#define _S_DHCPV6OPTIONS_H 38 39#include <stdint.h> 40#include <stdbool.h> 41#include <string.h> 42#include "symbol_scope.h" 43#include "DHCPv6.h" 44 45enum { 46 kDHCPv6OPTION_CLIENTID = 1, 47 kDHCPv6OPTION_SERVERID = 2, 48 kDHCPv6OPTION_IA_NA = 3, 49 kDHCPv6OPTION_IA_TA = 4, 50 kDHCPv6OPTION_IAADDR = 5, 51 kDHCPv6OPTION_ORO = 6, 52 kDHCPv6OPTION_PREFERENCE = 7, 53 kDHCPv6OPTION_ELAPSED_TIME = 8, 54 kDHCPv6OPTION_RELAY_MSG = 9, 55 kDHCPv6OPTION_AUTH = 11, 56 kDHCPv6OPTION_UNICAST = 12, 57 kDHCPv6OPTION_STATUS_CODE = 13, 58 kDHCPv6OPTION_RAPID_COMMIT = 14, 59 kDHCPv6OPTION_USER_CLASS = 15, 60 kDHCPv6OPTION_VENDOR_CLASS = 16, 61 kDHCPv6OPTION_VENDOR_OPTS = 17, 62 kDHCPv6OPTION_INTERFACE_ID = 18, 63 kDHCPv6OPTION_RECONF_MSG = 19, 64 kDHCPv6OPTION_RECONF_ACCEPT = 20, 65 kDHCPv6OPTION_DNS_SERVERS = 23, 66 kDHCPv6OPTION_DOMAIN_LIST = 24, 67}; 68 69typedef struct { 70 uint8_t code[2]; 71 uint8_t len[2]; 72 uint8_t data[1]; /* variable length */ 73} DHCPv6Option, * DHCPv6OptionRef; 74 75#define DHCPV6_OPTION_HEADER_SIZE offsetof(DHCPv6Option, data) 76 77INLINE int 78DHCPv6OptionGetLength(DHCPv6OptionRef option) 79{ 80 return (net_uint16_get(option->len)); 81} 82 83INLINE void 84DHCPv6OptionSetLength(DHCPv6OptionRef option, uint16_t len) 85{ 86 net_uint16_set(option->len, len); 87 return; 88} 89 90INLINE int 91DHCPv6OptionGetCode(DHCPv6OptionRef option) 92{ 93 return (net_uint16_get(option->code)); 94} 95 96INLINE void 97DHCPv6OptionSetCode(DHCPv6OptionRef option, uint16_t code) 98{ 99 net_uint16_set(option->code, code); 100} 101 102INLINE const uint8_t * 103DHCPv6OptionGetData(DHCPv6OptionRef option) 104{ 105 return (option->data); 106} 107 108const char * 109DHCPv6OptionCodeGetName(int option_code); 110 111enum { 112 kDHCPv6OptionTypeNone = 0, 113 kDHCPv6OptionTypeUnknown = 1, 114 kDHCPv6OptionTypeDUID = 2, 115 kDHCPv6OptionTypeUInt16 = 3, 116 kDHCPv6OptionTypeUInt32 = 4, 117 kDHCPv6OptionTypeIPv6Address = 5, 118 kDHCPv6OptionTypeDNSNameList = 6, 119 kDHCPv6OptionTypeIA_NA = 7, 120 kDHCPv6OptionTypeIAADDR = 8, 121 kDHCPv6OptionTypeStatusCode = 9, 122}; 123 124typedef int DHCPv6OptionType; 125 126DHCPv6OptionType 127DHCPv6OptionCodeGetType(int option_code); 128 129typedef struct { 130 char str[256]; 131} DHCPv6OptionErrorString, *DHCPv6OptionErrorStringRef; 132 133/** 134 ** DHCPv6OptionArea 135 **/ 136typedef struct { 137 uint8_t * buf; 138 int size; 139 int used; 140} DHCPv6OptionArea, * DHCPv6OptionAreaRef; 141 142void 143DHCPv6OptionAreaInit(DHCPv6OptionAreaRef oa_p, uint8_t * buf, int size); 144 145int 146DHCPv6OptionAreaGetUsedLength(DHCPv6OptionAreaRef oa_p); 147 148bool 149DHCPv6OptionAreaAddOption(DHCPv6OptionAreaRef oa_p, int option_code, 150 int option_len, const void * option_data, 151 DHCPv6OptionErrorStringRef err_p); 152bool 153DHCPv6OptionAreaAddOptionRequestOption(DHCPv6OptionAreaRef oa_p, 154 const uint16_t * requested_options, 155 int count, 156 DHCPv6OptionErrorStringRef err_p); 157/** 158 ** DHCPv6OptionList 159 **/ 160typedef struct DHCPv6OptionList * DHCPv6OptionListRef; 161 162DHCPv6OptionListRef 163DHCPv6OptionListCreate(const uint8_t * buf, int buf_size, 164 DHCPv6OptionErrorStringRef err_p); 165 166DHCPv6OptionListRef 167DHCPv6OptionListCreateWithPacket(const DHCPv6PacketRef pkt, int pkt_len, 168 DHCPv6OptionErrorStringRef err_p); 169 170void 171DHCPv6OptionListRelease(DHCPv6OptionListRef * dhcpol_p); 172 173const uint8_t * 174DHCPv6OptionListGetOptionDataAndLength(DHCPv6OptionListRef options, 175 int option_code, int * ret_length, 176 int * start_index); 177void 178DHCPv6OptionListFPrint(FILE * file, DHCPv6OptionListRef options); 179 180void 181DHCPv6OptionListPrintToString(CFMutableStringRef str, 182 DHCPv6OptionListRef options); 183 184 185int 186DHCPv6OptionListGetCount(DHCPv6OptionListRef options); 187 188DHCPv6OptionRef 189DHCPv6OptionListGetOptionAtIndex(DHCPv6OptionListRef options, int i); 190 191/** 192 ** IA_NA option 193 **/ 194typedef struct { 195 uint8_t iaid[4]; 196 uint8_t t1[4]; 197 uint8_t t2[4]; 198 uint8_t options[1]; /* variable length */ 199} DHCPv6OptionIA_NA, * DHCPv6OptionIA_NARef; 200 201#define DHCPv6OptionIA_NA_MIN_LENGTH ((int)offsetof(DHCPv6OptionIA_NA, options)) 202 203INLINE uint32_t 204DHCPv6OptionIA_NAGetIAID(DHCPv6OptionIA_NARef ia_na) 205{ 206 return (net_uint32_get(ia_na->iaid)); 207} 208 209INLINE void 210DHCPv6OptionIA_NASetIAID(DHCPv6OptionIA_NARef ia_na, uint32_t iaid) 211{ 212 net_uint32_set(ia_na->iaid, iaid); 213 return; 214} 215 216INLINE uint32_t 217DHCPv6OptionIA_NAGetT1(DHCPv6OptionIA_NARef ia_na) 218{ 219 return (net_uint32_get(ia_na->t1)); 220} 221 222INLINE void 223DHCPv6OptionIA_NASetT1(DHCPv6OptionIA_NARef ia_na, uint32_t t1) 224{ 225 net_uint32_set(ia_na->t1, t1); 226 return; 227} 228 229INLINE uint32_t 230DHCPv6OptionIA_NAGetT2(DHCPv6OptionIA_NARef ia_na) 231{ 232 return (net_uint32_get(ia_na->t2)); 233} 234 235INLINE void 236DHCPv6OptionIA_NASetT2(DHCPv6OptionIA_NARef ia_na, uint32_t t2) 237{ 238 net_uint32_set(ia_na->t2, t2); 239 return; 240} 241 242/** 243 ** IAADDR option 244 **/ 245typedef struct { 246 uint8_t address[16]; 247 uint8_t preferred_lifetime[4]; 248 uint8_t valid_lifetime[4]; 249 uint8_t options[1]; /* variable length */ 250} DHCPv6OptionIAADDR, * DHCPv6OptionIAADDRRef; 251 252#define DHCPv6OptionIAADDR_MIN_LENGTH ((int)offsetof(DHCPv6OptionIAADDR, options)) 253 254INLINE const uint8_t * 255DHCPv6OptionIAADDRGetAddress(DHCPv6OptionIAADDRRef ia_addr) 256{ 257 return ((const uint8_t *)ia_addr->address); 258} 259 260INLINE void 261DHCPv6OptionIAADDRSetAddress(DHCPv6OptionIAADDRRef ia_addr, 262 const void * addr_p) 263{ 264 bcopy(addr_p, ia_addr->address, sizeof(struct in6_addr)); 265 return; 266} 267 268INLINE uint32_t 269DHCPv6OptionIAADDRGetPreferredLifetime(DHCPv6OptionIAADDRRef ia_addr) 270{ 271 return (net_uint32_get(ia_addr->preferred_lifetime)); 272} 273 274INLINE void 275DHCPv6OptionIAADDRSetPreferredLifetime(DHCPv6OptionIAADDRRef ia_addr, 276 uint32_t preferred_lifetime) 277{ 278 net_uint32_set(ia_addr->preferred_lifetime, preferred_lifetime); 279 return; 280} 281 282INLINE uint32_t 283DHCPv6OptionIAADDRGetValidLifetime(DHCPv6OptionIAADDRRef ia_addr) 284{ 285 return (net_uint32_get(ia_addr->valid_lifetime)); 286} 287 288INLINE void 289DHCPv6OptionIAADDRSetValidLifetime(DHCPv6OptionIAADDRRef ia_addr, 290 uint32_t valid_lifetime) 291{ 292 net_uint32_set(ia_addr->valid_lifetime, valid_lifetime); 293 return; 294} 295 296void 297DHCPv6OptionIAADDRPrintToString(CFMutableStringRef str, 298 DHCPv6OptionIAADDRRef ia_addr, 299 int ia_addr_len); 300 301/** 302 ** Status Code option 303 **/ 304typedef struct { 305 uint8_t code[2]; 306 uint8_t message[1]; /* variable length */ 307} DHCPv6OptionSTATUS_CODE, * DHCPv6OptionSTATUS_CODERef; 308 309#define DHCPv6OptionSTATUS_CODE_MIN_LENGTH ((int)offsetof(DHCPv6OptionSTATUS_CODE, message)) 310 311enum { 312 kDHCPv6StatusCodeSuccess = 0, 313 kDHCPv6StatusCodeFailure = 1, 314 kDHCPv6StatusCodeNoAddrsAvail = 2, 315 kDHCPv6StatusCodeNoBinding = 3, 316 kDHCPv6StatusCodeNotOnLink = 4, 317 kDHCPv6StatusCodeUseMulticast = 5 318}; 319typedef int DHCPv6StatusCode; 320 321const char * 322DHCPv6StatusCodeGetName(int option_code); 323 324INLINE uint16_t 325DHCPv6OptionSTATUS_CODEGetCode(DHCPv6OptionSTATUS_CODERef status_p) 326{ 327 return (net_uint16_get(status_p->code)); 328} 329 330INLINE void 331DHCPv6OptionSTATUS_CODESetCode(DHCPv6OptionSTATUS_CODERef status_p, 332 uint16_t code) 333{ 334 net_uint16_set(status_p->code, code); 335 return; 336} 337 338void 339DHCPv6OptionSTATUS_CODEFPrint(FILE * f, DHCPv6OptionSTATUS_CODERef status_p, 340 int status_len); 341 342/** 343 ** PREFERENCE option 344 **/ 345typedef struct { 346 uint8_t value; 347} DHCPv6OptionPREFERENCE, * DHCPv6OptionPREFERENCERef; 348 349#define DHCPv6OptionPREFERENCE_MIN_LENGTH 1 350#define kDHCPv6OptionPREFERENCEMinValue 0 351#define kDHCPv6OptionPREFERENCEMaxValue 255 352 353#endif /* _S_DHCPV6OPTIONS_H */ 354