1/* 2 * Copyright (c) 1999 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 * netinfo.c - Routines for dealing with the NetInfo database. 25 * 26 ********************************************************************** 27 * HISTORY 28 * 10-Jun-89 Peter King 29 * Created. 30 * 23-Feb-98 Dieter Siegmund (dieter@apple.com) 31 * Removed all of the promiscous-related stuff, 32 * left with routines to do host creation/lookup. 33 * 11-Sep-06 Dieter Siegmund (dieter@apple.com) 34 * Imported netinfo code from Libinfo 35 ********************************************************************** 36 */ 37 38/* 39 * Include Files 40 */ 41#include <ctype.h> 42#include <pwd.h> 43#include <netdb.h> 44#include <string.h> 45#include <syslog.h> 46#include <sys/types.h> 47#include <sys/socket.h> 48#include <net/if.h> 49#include <netinet/in.h> 50#include <netinet/if_ether.h> 51#include <arpa/inet.h> 52#include <string.h> 53#include <unistd.h> 54#include <stdlib.h> 55#include <stdio.h> 56#include "host_identifier.h" 57#include "netinfo.h" 58 59/* 60 * Imported from Libinfo START ---v 61 */ 62#define mm_used() mstats() 63 64#define MM_ALLOC(obj) obj = ((void *)malloc(sizeof(*(obj)))) 65 66#define MM_FREE(obj) free((void *)(obj)) 67 68#define MM_ZERO(obj) bzero((void *)(obj), sizeof(*(obj))) 69 70#define MM_BCOPY(b1, b2, size) bcopy((void *)(b1), (void *)(b2), \ 71 (unsigned)(size)) 72 73#define MM_BEQ(b1, b2, size) (bcmp((void *)(b1), (void *)(b2), \ 74 (unsigned)(size)) == 0) 75 76#define MM_ALLOC_ARRAY(obj, len) \ 77 obj = ((void *)malloc(sizeof(*(obj)) * (len))) 78 79#define MM_ZERO_ARRAY(obj, len) bzero((void *)(obj), sizeof(*obj) * len) 80 81#define MM_FREE_ARRAY(obj, len) free((void *)(obj)) 82 83#define MM_GROW_ARRAY(obj, len) \ 84 ((obj == NULL) ? (MM_ALLOC_ARRAY((obj), (len) + 1)) : \ 85 (obj = (void *)realloc((void *)(obj), \ 86 sizeof(*(obj)) * ((len) + 1)))) 87 88#define MM_SHRINK_ARRAY(obj, len) \ 89 obj = (void *)realloc((void *)(obj), \ 90 sizeof(*(obj)) * ((len) - 1)) 91 92void 93ni_proplist_insert( 94 ni_proplist *pl, 95 const ni_property prop, 96 ni_index where 97 ) 98{ 99 ni_index i; 100 101 MM_GROW_ARRAY(pl->nipl_val, pl->nipl_len); 102 for (i = pl->nipl_len; i > where; i--) { 103 pl->nipl_val[i] = pl->nipl_val[i - 1]; 104 } 105 pl->nipl_val[i] = ni_prop_dup(prop); 106 pl->nipl_len++; 107} 108 109void 110ni_proplist_delete( 111 ni_proplist *pl, 112 ni_index which 113 ) 114{ 115 int i; 116 117 ni_prop_free(&pl->nipl_val[which]); 118 for (i = which + 1; i < pl->nipl_len; i++) { 119 pl->nipl_val[i - 1] = pl->nipl_val[i]; 120 } 121 MM_SHRINK_ARRAY(pl->nipl_val, pl->nipl_len--); 122} 123 124void 125ni_proplist_free( 126 ni_proplist *pl 127 ) 128{ 129 ni_index i; 130 131 if (pl->nipl_val == NULL) { 132 return; 133 } 134 for (i = 0; i < pl->nipl_len; i++) { 135 ni_prop_free(&pl->nipl_val[i]); 136 } 137 MM_FREE_ARRAY(pl->nipl_val, pl->nipl_len); 138 NI_INIT(pl); 139} 140 141ni_proplist 142ni_proplist_dup( 143 const ni_proplist pl 144 ) 145{ 146 ni_proplist newlist; 147 ni_index i; 148 149 newlist.nipl_len = pl.nipl_len; 150 MM_ALLOC_ARRAY(newlist.nipl_val, pl.nipl_len); 151 for (i = 0; i < pl.nipl_len; i++) { 152 newlist.nipl_val[i].nip_name = ni_name_dup(pl.nipl_val[i].nip_name); 153 newlist.nipl_val[i].nip_val = ni_namelist_dup(pl.nipl_val[i].nip_val); 154 } 155 return (newlist); 156} 157 158ni_index 159ni_proplist_match( 160 const ni_proplist pl, 161 ni_name_const pname, 162 ni_name_const pval 163 ) 164{ 165 ni_index i; 166 ni_index j; 167 ni_namelist nl; 168 169 for (i = 0; i < pl.nipl_len; i++) { 170 if (ni_name_match(pname, pl.nipl_val[i].nip_name)) { 171 if (pval == NULL) { 172 return (i); 173 } 174 nl = pl.nipl_val[i].nip_val; 175 for (j = 0; j < nl.ninl_len; j++) { 176 if (ni_name_match(pval, nl.ninl_val[j])) { 177 return (i); 178 } 179 } 180 break; 181 } 182 } 183 return (NI_INDEX_NULL); 184} 185 186 187ni_property 188ni_prop_dup( 189 const ni_property prop 190 ) 191{ 192 ni_property newprop; 193 194 newprop.nip_name = ni_name_dup(prop.nip_name); 195 newprop.nip_val = ni_namelist_dup(prop.nip_val); 196 return (newprop); 197} 198 199void 200ni_prop_free( 201 ni_property *prop 202 ) 203{ 204 ni_name_free(&prop->nip_name); 205 ni_namelist_free(&prop->nip_val); 206} 207 208int 209ni_name_match( 210 ni_name_const nm1, 211 ni_name_const nm2 212 ) 213{ 214 return (strcmp(nm1, nm2) == 0); 215} 216 217ni_name 218ni_name_dup( 219 ni_name_const nm 220 ) 221{ 222 return (strcpy(malloc(strlen(nm) + 1), nm)); 223} 224 225 226void 227ni_name_free( 228 ni_name *nm 229 ) 230{ 231 if (*nm != NULL) { 232 free(*nm); 233 *nm = NULL; 234 } 235} 236 237ni_namelist 238ni_namelist_dup( 239 const ni_namelist nl 240 ) 241{ 242 ni_namelist newlist; 243 ni_index i; 244 245 newlist.ninl_len = nl.ninl_len; 246 MM_ALLOC_ARRAY(newlist.ninl_val, newlist.ninl_len); 247 for (i = 0; i < nl.ninl_len; i++) { 248 newlist.ninl_val[i] = ni_name_dup(nl.ninl_val[i]); 249 } 250 return (newlist); 251} 252 253void 254ni_namelist_free( 255 ni_namelist *nl 256 ) 257{ 258 ni_index i; 259 260 if (nl->ninl_val == NULL) { 261 return; 262 } 263 for (i = 0; i < nl->ninl_len; i++) { 264 ni_name_free(&nl->ninl_val[i]); 265 } 266 MM_FREE_ARRAY(nl->ninl_val, nl->ninl_len); 267 NI_INIT(nl); 268} 269 270void 271ni_namelist_insert( 272 ni_namelist *nl, 273 ni_name_const nm, 274 ni_index where 275 ) 276{ 277 ni_index i; 278 279 MM_GROW_ARRAY(nl->ninl_val, nl->ninl_len); 280 for (i = nl->ninl_len; i > where; i--) { 281 nl->ninl_val[i] = nl->ninl_val[i - 1]; 282 } 283 nl->ninl_val[i] = ni_name_dup(nm); 284 nl->ninl_len++; 285} 286 287void 288ni_namelist_delete( 289 ni_namelist *nl, 290 ni_index which 291 ) 292{ 293 int i; 294 295 ni_name_free(&nl->ninl_val[which]); 296 for (i = which + 1; i < nl-> ninl_len; i++) { 297 nl->ninl_val[i - 1] = nl->ninl_val[i]; 298 } 299 MM_SHRINK_ARRAY(nl->ninl_val, nl->ninl_len--); 300} 301 302ni_index 303ni_namelist_match( 304 const ni_namelist nl, 305 ni_name_const nm 306 ) 307{ 308 ni_index i; 309 310 for (i = 0; i < nl.ninl_len; i++) { 311 if (ni_name_match(nl.ninl_val[i], nm)) { 312 return (i); 313 } 314 } 315 return (NI_INDEX_NULL); 316} 317 318/* 319 * Imported from Libinfo END ---^ 320 */ 321 322/* 323 * Exported routines 324 */ 325 326void 327ni_proplist_dump(ni_proplist * pl) 328{ 329 int i, j; 330 331 for (i = 0; i < pl->nipl_len; i++) { 332 ni_property * prop = &(pl->nipl_val[i]); 333 ni_namelist * nl_p = &prop->nip_val; 334 if (nl_p->ninl_len == 0) { 335 printf("\"%s\"\n", prop->nip_name); 336 } 337 else { 338 printf("\"%s\" = ", prop->nip_name); 339 for (j = 0; j < nl_p->ninl_len; j++) 340 printf("%s\"%s\"", (j == 0) ? "" : ", ", nl_p->ninl_val[j]); 341 printf("\n"); 342 } 343 } 344} 345 346void 347ni_set_prop(ni_proplist * pl_p, ni_name prop, ni_name value, 348 boolean_t * modified) 349{ 350 ni_index where; 351 352 where = ni_proplist_match(*pl_p, prop, NULL); 353 if (where != NI_INDEX_NULL) { 354 if (value != NULL && where == ni_proplist_match(*pl_p, prop, value)) { 355 return; /* already set */ 356 } 357 ni_proplist_delete(pl_p, where); 358 } 359 ni_proplist_insertprop(pl_p, prop, value, where); 360 if (modified) 361 *modified = TRUE; 362 return; 363} 364 365void 366ni_delete_prop(ni_proplist * pl_p, ni_name prop, boolean_t * modified) 367{ 368 int where; 369 370 where = ni_proplist_match(*pl_p, prop, NULL); 371 if (where != NI_INDEX_NULL) { 372 ni_proplist_delete(pl_p, where); 373 if (modified) 374 *modified = TRUE; 375 } 376 return; 377} 378 379