1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 package com.sun.dhcpmgr.server; 26 27 import java.util.*; 28 import java.net.InetAddress; 29 30 import com.sun.dhcpmgr.bridge.*; 31 import com.sun.dhcpmgr.data.*; 32 33 /** 34 * This class provides methods to manage the contents of the dhcptab. 35 */ 36 37 public class DhcptabMgrImpl implements DhcptabMgr { 38 private Bridge bridge; 39 40 /** 41 * Create a new DhcptabMgr using the provided native bridge. 42 * @param bridge the native bridge class which actually does the work. 43 */ 44 public DhcptabMgrImpl(Bridge bridge) { 45 this.bridge = bridge; 46 } 47 48 /** 49 * Create an option. 50 * @param name the name of the option. 51 * @param value the value for the option in dhcptab(4) format. 52 * @return the Option. 53 */ 54 public Option createOption(String name, String value) 55 throws BridgeException { 56 return bridge.createOption(name, value); 57 } 58 59 /** 60 * Retrieve all options currently defined in the dhcptab. 61 * @return an array of Options 62 */ 63 public Option [] getOptions() throws BridgeException { 64 return getOptions(null); 65 } 66 67 /** 68 * Retrieve all options currently defined in the dhcptab. 69 * @param datastore user-supplied datastore attributes 70 * @return an array of Options 71 */ 72 public Option [] getOptions(DhcpDatastore datastore) 73 throws BridgeException { 74 return bridge.getOptions(datastore); 75 } 76 77 /** 78 * Retrieve all the macros currently defined in the dhcptab. 79 * @return an array of Macros 80 */ 81 public Macro [] getMacros() throws BridgeException { 82 return getMacros(null); 83 } 84 85 /** 86 * Retrieve all the macros currently defined in the dhcptab. 87 * @param datastore user-supplied datastore attributes 88 * @return an array of Macros 89 */ 90 public Macro [] getMacros(DhcpDatastore datastore) 91 throws BridgeException { 92 /* 93 * Load the vendor and site options before loading the macros 94 * so we can validate correctly, adding them to the standard options 95 * table. 96 */ 97 OptionsTable optionsTable = OptionsTable.getTable(); 98 optionsTable.add(bridge.getOptions(datastore)); 99 return bridge.getMacros(datastore); 100 } 101 102 /** 103 * Create a given record in the dhcptab, and signal the server to 104 * reload the dhcptab if so requested. 105 * @param rec the record to add to the table 106 * @param signalServer true if the server is to be sent a SIGHUP 107 */ 108 public void createRecord(DhcptabRecord rec, boolean signalServer) 109 throws BridgeException { 110 createRecord(rec, signalServer, null); 111 } 112 113 /** 114 * Create a given record in the dhcptab, and signal the server to 115 * reload the dhcptab if so requested. 116 * @param rec the record to add to the table 117 * @param signalServer true if the server is to be sent a SIGHUP 118 * @param datastore user-supplied datastore attributes 119 */ 120 public void createRecord(DhcptabRecord rec, boolean signalServer, 121 DhcpDatastore datastore) throws BridgeException { 122 bridge.createDhcptabRecord(rec, datastore); 123 if (signalServer) { 124 bridge.reload(); 125 } 126 } 127 128 /** 129 * Modify a given record in the dhcptab, and signal the server to reload 130 * the dhcptab if so requested 131 * @param oldRec the current record to modify 132 * @param newRec the new record to be placed in the table 133 * @param signalServer true if the server is to be sent a SIGHUP 134 */ 135 public void modifyRecord(DhcptabRecord oldRec, DhcptabRecord newRec, 136 boolean signalServer) throws BridgeException { 137 modifyRecord(oldRec, newRec, signalServer, null); 138 } 139 140 /** 141 * Modify a given record in the dhcptab, and signal the server to reload 142 * the dhcptab if so requested 143 * @param oldRec the current record to modify 144 * @param newRec the new record to be placed in the table 145 * @param signalServer true if the server is to be sent a SIGHUP 146 * @param datastore user-supplied datastore attributes 147 */ 148 public void modifyRecord(DhcptabRecord oldRec, DhcptabRecord newRec, 149 boolean signalServer, DhcpDatastore datastore) 150 throws BridgeException { 151 bridge.modifyDhcptabRecord(oldRec, newRec, datastore); 152 if (signalServer) { 153 bridge.reload(); 154 } 155 } 156 157 /** 158 * Delete a given record from the dhcptab, and signal the server to reload 159 * the dhcptab if so requested 160 * @param rec the record to delete 161 * @param signalServer true if the server is to be sent a SIGHUP 162 */ 163 public void deleteRecord(DhcptabRecord rec, boolean signalServer) 164 throws BridgeException { 165 deleteRecord(rec, signalServer, null); 166 } 167 168 /** 169 * Delete a given record from the dhcptab, and signal the server to reload 170 * the dhcptab if so requested 171 * @param rec the record to delete 172 * @param signalServer true if the server is to be sent a SIGHUP 173 * @param datastore user-supplied datastore attributes 174 */ 175 public void deleteRecord(DhcptabRecord rec, boolean signalServer, 176 DhcpDatastore datastore) throws BridgeException { 177 bridge.deleteDhcptabRecord(rec, datastore); 178 if (signalServer) { 179 bridge.reload(); 180 } 181 } 182 183 /** 184 * Delete a record by name and type 185 * @param key The key for the record 186 * @param type The type of record; either MACRO or OPTION 187 */ 188 private void deleteRecord(String name, String type) throws BridgeException { 189 DhcptabRecord rec = null; 190 if (type.equals(DhcptabRecord.MACRO)) { 191 rec = getMacro(name); 192 } else { 193 rec = getOption(name); 194 } 195 deleteRecord(rec, false); 196 } 197 198 /** 199 * Delete a set of records. 200 * @return An array of ActionError, one error for each record not deleted 201 */ 202 private ActionError [] deleteRecords(DhcptabRecord [] recs) { 203 ArrayList errorList = new ArrayList(); 204 205 for (int i = 0; i < recs.length; ++i) { 206 try { 207 deleteRecord(recs[i], false); 208 } catch (BridgeException e) { 209 errorList.add(new ActionError(recs[i].getKey(), e)); 210 } 211 } 212 213 return (ActionError[])errorList.toArray(new ActionError[0]); 214 } 215 216 private ActionError [] deleteAllRecords(String type) 217 throws BridgeException { 218 DhcptabRecord [] recs; 219 if (type.equals(DhcptabRecord.MACRO)) { 220 recs = getMacros(); 221 } else { 222 recs = getOptions(); 223 } 224 return deleteRecords(recs); 225 } 226 227 /** 228 * Delete all macros 229 * @return An array of ActionError, one error for each macro not deleted 230 */ 231 public ActionError [] deleteAllMacros() throws BridgeException { 232 return deleteAllRecords(DhcptabRecord.MACRO); 233 } 234 235 /** 236 * Delete all options 237 * @return An array of ActionError, one error for each option not deleted 238 */ 239 public ActionError [] deleteAllOptions() throws BridgeException { 240 return deleteAllRecords(DhcptabRecord.OPTION); 241 } 242 243 /** 244 * Delete a list of macros identified by name 245 * @param macroNames Names of the macros to delete 246 * @return An array of ActionError, one element per macro not deleted 247 */ 248 public ActionError [] deleteMacros(String [] macroNames) { 249 ArrayList errorList = new ArrayList(); 250 251 for (int i = 0; i < macroNames.length; ++i) { 252 try { 253 deleteRecord(macroNames[i], DhcptabRecord.MACRO); 254 } catch (BridgeException e) { 255 errorList.add(new ActionError(macroNames[i], e)); 256 } 257 } 258 259 return (ActionError [])errorList.toArray(new ActionError[0]); 260 } 261 262 /** 263 * Delete a list of options identified by name 264 * @param optionNames Names of options to delete 265 * @return An array of ActionError, one element per option not deleted 266 */ 267 public ActionError [] deleteOptions(String [] optionNames) { 268 ArrayList errorList = new ArrayList(); 269 270 for (int i = 0; i < optionNames.length; ++i) { 271 try { 272 deleteRecord(optionNames[i], DhcptabRecord.OPTION); 273 } catch (BridgeException e) { 274 errorList.add(new ActionError(optionNames[i], e)); 275 } 276 } 277 278 return (ActionError [])errorList.toArray(new ActionError[0]); 279 } 280 281 /** 282 * Retrieve a given macro from the dhcptab. 283 * @param key the key of the record to retrieve 284 * @return the Macro for the given key 285 */ 286 public Macro getMacro(String key) 287 throws BridgeException { 288 return getMacro(key, null); 289 } 290 291 /** 292 * Retrieve a given macro from the dhcptab. 293 * @param key the key of the record to retrieve 294 * @param datastore user-supplied datastore attributes 295 * @return the Macro for the given key 296 */ 297 public Macro getMacro(String key, DhcpDatastore datastore) 298 throws BridgeException { 299 OptionsTable optionsTable = OptionsTable.getTable(); 300 optionsTable.add(bridge.getOptions(datastore)); 301 return bridge.getMacro(key, datastore); 302 } 303 304 /** 305 * Retrieve a given option from the dhcptab. 306 * @param key the key of the record to retrieve 307 * @return the Option for the given key 308 */ 309 public Option getOption(String key) 310 throws BridgeException { 311 return getOption(key, null); 312 } 313 314 /** 315 * Retrieve a given option from the dhcptab. 316 * @param key the key of the record to retrieve 317 * @param datastore user-supplied datastore attributes 318 * @return the Option for the given key 319 */ 320 public Option getOption(String key, DhcpDatastore datastore) 321 throws BridgeException { 322 return bridge.getOption(key, datastore); 323 } 324 325 /** 326 * Create a new dhcptab converting the one in the server's data store, 327 * into a new data store. 328 * @param datastore user-supplied datastore attributes 329 */ 330 public void cvtDhcptab(DhcpDatastore datastore) 331 throws BridgeException { 332 bridge.cvtDhcptab(datastore); 333 } 334 335 /** 336 * Create a new empty dhcptab in the server's data store, which must 337 * already be configured. 338 */ 339 public void createDhcptab() throws BridgeException { 340 createDhcptab(null); 341 } 342 343 /** 344 * Create a new empty dhcptab in the server's data store, which must 345 * already be configured. 346 * @param datastore user-supplied datastore attributes 347 */ 348 public void createDhcptab(DhcpDatastore datastore) 349 throws BridgeException { 350 bridge.createDhcptab(datastore); 351 } 352 353 /** 354 * Delete the server's dhcptab in the current data store. 355 */ 356 public void deleteDhcptab() throws BridgeException { 357 deleteDhcptab(null); 358 } 359 360 /** 361 * Delete the server's dhcptab in the current data store. 362 * @param datastore user-supplied datastore attributes 363 */ 364 public void deleteDhcptab(DhcpDatastore datastore) 365 throws BridgeException { 366 bridge.deleteDhcptab(datastore); 367 } 368 369 public void createLocaleMacro() 370 throws BridgeException, ValidationException { 371 createLocaleMacro(null); 372 } 373 374 public void createLocaleMacro(DhcpDatastore datastore) 375 throws BridgeException, ValidationException { 376 377 Macro macro = new Macro(); 378 macro.setKey("Locale"); 379 macro.storeOption(StandardOptions.CD_TIMEOFFSET, 380 String.valueOf(TimeZone.getDefault().getRawOffset()/1000)); 381 382 createRecord(macro, false); 383 } 384 385 public void createServerMacro(String svrName, 386 InetAddress svrAddress, int leaseLength, 387 boolean leaseNegotiable, String dnsDomain, Vector dnsServs) 388 throws BridgeException, ValidationException { 389 390 createServerMacro(svrName, svrAddress, leaseLength, leaseNegotiable, 391 dnsDomain, dnsServs, null); 392 } 393 394 public void createServerMacro(String svrName, 395 InetAddress svrAddress, int leaseLength, 396 boolean leaseNegotiable, String dnsDomain, Vector dnsServs, 397 DhcpDatastore datastore) 398 throws BridgeException, ValidationException { 399 400 Macro macro = new Macro(); 401 macro.setKey(svrName); 402 macro.storeOption("Include", "Locale"); 403 macro.storeOption(StandardOptions.CD_TIMESERV, svrAddress); 404 macro.storeOption(StandardOptions.CD_LEASE_TIME, 405 String.valueOf(leaseLength)); 406 if (leaseNegotiable) { 407 macro.storeOption(StandardOptions.CD_BOOL_LEASENEG, null); 408 } 409 if (dnsDomain != null && dnsDomain.length() != 0 && 410 dnsServs != null && dnsServs.size() != 0) { 411 macro.storeOption(StandardOptions.CD_DNSDOMAIN, dnsDomain); 412 macro.storeOption(StandardOptions.CD_DNSSERV, dnsServs); 413 } 414 // First delete it in case it's already there 415 try { 416 deleteRecord(macro, false); 417 } catch (Throwable e) { 418 // Ignore any error 419 } 420 421 createRecord(macro, false); 422 } 423 424 public synchronized void createNetworkMacro(Network network, 425 IPAddress [] routers, boolean isLan, String nisDomain, Vector nisServs) 426 throws BridgeException, ValidationException { 427 428 createNetworkMacro(network, routers, isLan, nisDomain, nisServs, 429 null); 430 } 431 432 public void createNetworkMacro(Network network, 433 IPAddress [] routers, boolean isLan, String nisDomain, Vector nisServs, 434 DhcpDatastore datastore) throws BridgeException, ValidationException { 435 436 Macro macro = new Macro(); 437 macro.setKey(network.toString()); 438 macro.storeOption(StandardOptions.CD_SUBNETMASK, network.getMask()); 439 if (routers == null) { 440 macro.storeOption(StandardOptions.CD_ROUTER_DISCVRY_ON, "1"); 441 } else { 442 for (int i = 0; i < routers.length; i++) { 443 macro.storeOption(StandardOptions.CD_ROUTER, routers[i]); 444 } 445 } 446 447 if (isLan) { 448 macro.storeOption(StandardOptions.CD_BROADCASTADDR, 449 network.getBroadcastAddress()); 450 } 451 452 // NIS config 453 if (nisDomain != null && nisDomain.length() != 0 && 454 nisServs != null && nisServs.size() != 0) { 455 macro.storeOption(StandardOptions.CD_NIS_DOMAIN, nisDomain); 456 macro.storeOption(StandardOptions.CD_NIS_SERV, nisServs); 457 } 458 459 createRecord(macro, false); 460 } 461 }