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, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <libintl.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <malloc.h>
33 #include <jni.h>
34 #include <dhcp_svc_private.h>
35 #include <dhcp_svc_confkey.h>
36 #include <dhcp_symbol.h>
37 #include <com_sun_dhcpmgr_bridge_Bridge.h>
38
39 #include "exception.h"
40 #include "dd_misc.h"
41 #include "class_cache.h"
42
43 /*
44 * Validate that a symbol definition in dhcptab(4) format is valid.
45 */
46 static boolean_t
47 validate_OptionValue(JNIEnv *env,
48 const char *key,
49 const char *value) {
50
51 dhcp_symbol_t sym;
52 char **fields;
53 int last = 0;
54 dsym_errcode_t dsymret;
55
56 dsymret = dsym_init_parser(key, value, &fields, &sym);
57 if (dsymret != DSYM_SUCCESS) {
58 throw_dsym_parser_init_exception(env, key, dsymret);
59 return (B_FALSE);
60 }
61
62 dsymret = dsym_parser(fields, &sym, &last, B_FALSE);
63 if (dsymret != DSYM_SUCCESS) {
64 throw_dsym_parser_exception(env, key, fields, last,
65 dsymret);
66 }
67
68 dsym_close_parser(fields, &sym);
69 return (dsymret == DSYM_SUCCESS);
70 }
71
72 /*
73 * Create a dt_rec from a DhcptabRecord.
74 */
75 static dt_rec_t *
76 create_dtrec(
77 JNIEnv *env,
78 jobject dhcptabRecord,
79 boolean_t validate)
80 {
81 jclass dtr_class;
82 dt_rec_t *dtrec;
83 char *str;
84
85 /* Locate the class we need */
86 dtr_class = find_class(env, DTR_CLASS);
87 if (dtr_class == NULL) {
88 /* exception thrown */
89 return (NULL);
90 }
91
92 dtrec = malloc(sizeof (dt_rec_t));
93 if (dtrec == NULL) {
94 throw_memory_exception(env);
95 return (NULL);
96 }
97
98 if (!dd_get_str_attr(env, dtr_class, DTR_GETKEY, dhcptabRecord,
99 &str)) {
100 /* exception thrown */
101 free_dtrec(dtrec);
102 return (NULL);
103 }
104 (void) strlcpy(dtrec->dt_key, str, sizeof (dtrec->dt_key));
105 free(str);
106
107 if (!dd_get_str_attr(env, dtr_class, DTR_GETFLAG, dhcptabRecord,
108 &str)) {
109 /* exception thrown */
110 free_dtrec(dtrec);
111 return (NULL);
112 }
113 dtrec->dt_type = str[0];
114 free(str);
115
116 if (!dd_get_str_attr(env, dtr_class, DTR_GETSIG, dhcptabRecord,
117 &str)) {
118 /* exception thrown */
119 free_dtrec(dtrec);
120 return (NULL);
121 }
122 dtrec->dt_sig = atoll(str);
123 free(str);
124
125 if (!dd_get_str_attr(env, dtr_class, DTR_GETVAL, dhcptabRecord,
126 &dtrec->dt_value)) {
127 /* exception thrown */
128 free_dtrec(dtrec);
129 return (NULL);
130 }
131
132 if (validate) {
133 if (dtrec->dt_type == DT_SYMBOL) {
134 if (!validate_OptionValue(env, dtrec->dt_key,
135 dtrec->dt_value)) {
136 /* exception thrown */
137 free_dtrec(dtrec);
138 return (NULL);
139 }
140 }
141 }
142 return (dtrec);
143 }
144
145 /*
146 * Create a Macro from a dt_rec.
147 */
148 static jobject
149 create_Macro(
150 JNIEnv *env,
151 const dt_rec_t *dtrec)
152 {
153 jobject dhcptabRecord;
154 jclass class;
155 jmethodID cons;
156
157 char ascii_sig[UINT64_MAX_CHAR + 1];
158
159 /* Find the class we need */
160 class = find_class(env, MAC_CLASS);
161 if (class == NULL) {
162 /* exception thrown */
163 return (NULL);
164 }
165
166 /* Locate the class constructor we need */
167 cons = get_methodID(env, class, MAC_CONS);
168 if (cons == NULL) {
169 /* exception thrown */
170 return (NULL);
171 }
172
173 (void) sprintf(ascii_sig, "%lld", dtrec->dt_sig);
174 dhcptabRecord = (*env)->NewObject(env, class, cons,
175 (*env)->NewStringUTF(env, dtrec->dt_key),
176 (*env)->NewStringUTF(env, dtrec->dt_value),
177 (*env)->NewStringUTF(env, ascii_sig));
178
179 if ((*env)->ExceptionOccurred(env) != NULL) {
180 dhcptabRecord = NULL;
181 }
182
183 return (dhcptabRecord);
184 }
185
186 /*
187 * Create an Array of vendor classes.
188 */
189 static jobjectArray
190 create_vendors(JNIEnv *env,
191 dhcp_classes_t *classes) {
192
193 jclass class;
194 jobjectArray jlist = NULL;
195 int i;
196
197 class = (*env)->FindClass(env, "java/lang/String");
198 if (class == NULL) {
199 /* exception thrown */
200 return (NULL);
201 }
202
203 /* Construct the array */
204 jlist = (*env)->NewObjectArray(env, classes->dc_cnt, class, NULL);
205 if (jlist == NULL) {
206 /* exception thrown */
207 return (NULL);
208 }
209
210 /* For each vendor, create an object and add it to the array */
211 for (i = 0; i < classes->dc_cnt; i++) {
212 (*env)->SetObjectArrayElement(env, jlist, i,
213 (*env)->NewStringUTF(env, classes->dc_names[i]));
214 if ((*env)->ExceptionOccurred(env) != NULL) {
215 jlist = NULL;
216 break;
217 }
218 }
219 return (jlist);
220 }
221
222 /*
223 * Create an Option from a dt_rec.
224 */
225 static jobject
226 create_Option(
227 JNIEnv *env,
228 const char *key,
229 const char *value,
230 uint64_t sig,
231 boolean_t force)
232 {
233 jobject dhcptabRecord = NULL;
234 jclass class;
235 jmethodID cons;
236
237 char ascii_sig[UINT64_MAX_CHAR + 1];
238
239 dhcp_symbol_t sym;
240 char **fields;
241 int last = 0;
242 dsym_errcode_t ret = DSYM_SUCCESS;
243
244 /* Find the class we need */
245 class = find_class(env, OPT_CLASS);
246 if (class == NULL) {
247 /* exception thrown */
248 return (NULL);
249 }
250
251 /* Locate the class constructor we need */
252 cons = get_methodID(env, class, OPT_CONS);
253 if (cons == NULL) {
254 /* exception thrown */
255 return (NULL);
256 }
257
258 (void) sprintf(ascii_sig, "%lld", sig);
259
260 ret = dsym_init_parser(key, value, &fields, &sym);
261 if (ret != DSYM_SUCCESS) {
262 /* throw exception */
263 throw_dsym_parser_init_exception(env, key, ret);
264 return (NULL);
265 }
266
267 ret = dsym_parser(fields, &sym, &last, force);
268 if (ret == DSYM_SUCCESS || force) {
269 jboolean isValid = (ret == DSYM_SUCCESS) ? JNI_TRUE : JNI_FALSE;
270 dhcptabRecord = (*env)->NewObject(env, class, cons,
271 (*env)->NewStringUTF(env, sym.ds_name),
272 (jbyte)sym.ds_category,
273 create_vendors(env, &sym.ds_classes),
274 (jshort)sym.ds_code,
275 (jbyte)sym.ds_type,
276 (jint)sym.ds_gran,
277 (jint)sym.ds_max,
278 (*env)->NewStringUTF(env, ascii_sig), isValid);
279
280 if ((*env)->ExceptionOccurred(env) != NULL) {
281 dhcptabRecord = NULL;
282 }
283 } else {
284 /* throw exception */
285 throw_dsym_parser_exception(env, key, fields, last, ret);
286 }
287
288 dsym_close_parser(fields, &sym);
289 return (dhcptabRecord);
290 }
291
292 /*
293 * Retrieve an option from the dhcptab. Returns
294 * the record as a new instance of a Option
295 */
296 /*ARGSUSED*/
297 JNIEXPORT jobject JNICALL
298 Java_com_sun_dhcpmgr_bridge_Bridge_getOption(
299 JNIEnv *env,
300 jobject obj,
301 jstring jkey,
302 jobject jdatastore)
303 {
304 dsvc_datastore_t datastore;
305 dsvc_handle_t handle;
306
307 dt_rec_t record;
308 dt_rec_list_t *recordList;
309 uint32_t query;
310 uint32_t count = 0;
311
312 char *key;
313 int rcode;
314
315 jobject dhcptabRecord;
316
317 /* Create a dsvc_datastore_t using args and DHCP config settings */
318 if (!dd_make_datastore_t(env, &datastore, jdatastore)) {
319 /* exception thrown */
320 return (NULL);
321 }
322
323 /* Retrieve the key argument */
324 if (!dd_jstring_to_UTF(env, jkey, &key)) {
325 /* exception thrown */
326 dd_free_datastore_t(&datastore);
327 return (NULL);
328 }
329
330 /* Open the dhcptab */
331 rcode = open_dd(&handle, &datastore, DSVC_DHCPTAB,
332 DT_DHCPTAB, DSVC_READ);
333
334 dd_free_datastore_t(&datastore);
335 if (rcode != DSVC_SUCCESS) {
336 throw_open_dd_exception(env, rcode, DT_DHCPTAB);
337 free(key);
338 return (NULL);
339 }
340
341 /* Get the records */
342 DSVC_QINIT(query);
343 DSVC_QEQ(query, DT_QTYPE | DT_QKEY);
344 (void) strlcpy(record.dt_key, key, sizeof (record.dt_key));
345 record.dt_type = DT_SYMBOL;
346
347 rcode = lookup_dd(handle, B_FALSE, query, 1, &record,
348 (void**)&recordList, &count);
349
350 (void) close_dd(&handle);
351 if (rcode == DSVC_SUCCESS) {
352 if (count == 1) {
353 dhcptabRecord = create_Option(env,
354 recordList->dtl_rec->dt_key,
355 recordList->dtl_rec->dt_value,
356 recordList->dtl_rec->dt_sig, B_TRUE);
357 free_dtrec_list(recordList);
358 } else {
359 throw_noent_exception(env, key);
360 }
361 } else {
362 throw_libdhcpsvc_exception(env, rcode);
363 }
364
365 free(key);
366
367 return (dhcptabRecord);
368 }
369
370 /*
371 * Use the current datastore to create a dhcptab table in a new datastore.
372 */
373 /*ARGSUSED*/
374 JNIEXPORT void JNICALL
375 Java_com_sun_dhcpmgr_bridge_Bridge_cvtDhcptab(
376 JNIEnv *env,
377 jobject obj,
378 jobject jdatastore)
379 {
380
381 dt_rec_t record;
382 dt_rec_list_t *recordList;
383 dt_rec_list_t *originalList = NULL;
384 uint32_t query;
385 uint32_t count = 0;
386
387 dsvc_handle_t curHandle;
388 dsvc_handle_t newHandle;
389 dsvc_datastore_t curDatastore;
390 dsvc_datastore_t newDatastore;
391
392 int rcode;
393 int i;
394
395 /* Get the current data store configuration */
396 if (!dd_get_conf_datastore_t(env, &curDatastore)) {
397 /* exception thrown */
398 return;
399 }
400
401 /* Make a "new" dsvc_datastore_t */
402 if (!dd_make_datastore_t(env, &newDatastore, jdatastore)) {
403 /* exception thrown */
404 dd_free_datastore_t(&curDatastore);
405 return;
406 }
407
408 /* Open the current dhcptab */
409 rcode = open_dd(&curHandle, &curDatastore, DSVC_DHCPTAB,
410 DT_DHCPTAB, DSVC_READ);
411
412 dd_free_datastore_t(&curDatastore);
413 if (rcode != DSVC_SUCCESS) {
414 throw_open_dd_exception(env, rcode, DT_DHCPTAB);
415 dd_free_datastore_t(&newDatastore);
416 return;
417 }
418
419 /* Open the new dhcptab */
420 rcode = open_dd(&newHandle, &newDatastore, DSVC_DHCPTAB, DT_DHCPTAB,
421 DSVC_CREATE | DSVC_READ | DSVC_WRITE);
422
423 dd_free_datastore_t(&newDatastore);
424 if (rcode != DSVC_SUCCESS) {
425 throw_open_dd_exception(env, rcode, DT_DHCPTAB);
426 (void) close_dd(&curHandle);
427 return;
428 }
429
430 /* Get the records */
431 DSVC_QINIT(query);
432 rcode = lookup_dd(curHandle, B_FALSE, query, -1, &record,
433 (void**)&recordList, &count);
434
435 (void) close_dd(&curHandle);
436 if (rcode != DSVC_SUCCESS) {
437 throw_libdhcpsvc_exception(env, rcode);
438 (void) close_dd(&newHandle);
439 return;
440 }
441
442 if (count != 0) {
443 originalList = recordList;
444 }
445
446 /* For each row, write client record to new table */
447 for (i = 0; i < count; i++) {
448 /* Now add the record */
449 rcode = add_dd_entry(newHandle, recordList->dtl_rec);
450
451 if (rcode != DSVC_SUCCESS) {
452 throw_add_dd_entry_exception(env, rcode,
453 recordList->dtl_rec->dt_key);
454 break;
455 }
456
457 recordList = recordList->dtl_next;
458 }
459
460 (void) close_dd(&newHandle);
461
462 if (originalList != NULL) {
463 free_dtrec_list(originalList);
464 }
465
466 }
467
468 /*
469 * Return all options (aka symbols) currently defined in the dhcptab.
470 * The options are returned as an array of Options.
471 */
472 /*ARGSUSED*/
473 JNIEXPORT jobjectArray JNICALL
474 Java_com_sun_dhcpmgr_bridge_Bridge_getOptions(
475 JNIEnv *env,
476 jobject obj,
477 jobject jdatastore)
478 {
479 dsvc_datastore_t datastore;
480 dsvc_handle_t handle;
481
482 dt_rec_t record;
483 dt_rec_list_t *recordList;
484 dt_rec_list_t *originalList = NULL;
485 uint32_t query;
486 uint32_t count = 0;
487 int rcode;
488
489 jclass opt_class;
490 jobjectArray jlist = NULL;
491 jobject dhcptabRecord;
492 int i;
493
494 /* Find the Option class and its constructor */
495 opt_class = find_class(env, OPT_CLASS);
496 if (opt_class == NULL) {
497 /* exception thrown */
498 return (NULL);
499 }
500
501 /* Create a dsvc_datastore_t using args and DHCP config settings */
502 if (!dd_make_datastore_t(env, &datastore, jdatastore)) {
503 /* exception thrown */
504 return (NULL);
505 }
506
507 /* Open the dhcptab */
508 rcode = open_dd(&handle, &datastore, DSVC_DHCPTAB,
509 DT_DHCPTAB, DSVC_READ);
510
511 dd_free_datastore_t(&datastore);
512 if (rcode != DSVC_SUCCESS) {
513 throw_open_dd_exception(env, rcode, DT_DHCPTAB);
514 return (NULL);
515 }
516
517 /* Get the records */
518 DSVC_QINIT(query);
519 DSVC_QEQ(query, DT_QTYPE);
520 record.dt_type = DT_SYMBOL;
521
522 rcode = lookup_dd(handle, B_FALSE, query, -1, &record,
523 (void**)&recordList, &count);
524
525 (void) close_dd(&handle);
526 if (rcode != DSVC_SUCCESS) {
527 throw_libdhcpsvc_exception(env, rcode);
528 return (NULL);
529 }
530
531 if (count != 0) {
532 originalList = recordList;
533 }
534
535 /* Construct the array */
536 jlist = (*env)->NewObjectArray(env, count, opt_class, NULL);
537 if (jlist == NULL) {
538 /* exception thrown */
539 if (originalList != NULL) {
540 free_dtrec_list(originalList);
541 }
542 return (NULL);
543 }
544
545 /* For each option, create an object and add it to the array */
546 for (i = 0; i < count; i++) {
547 dhcptabRecord = create_Option(env,
548 recordList->dtl_rec->dt_key,
549 recordList->dtl_rec->dt_value,
550 recordList->dtl_rec->dt_sig, B_TRUE);
551 if (dhcptabRecord == NULL) {
552 /* exception thrown */
553 break;
554 }
555
556 (*env)->SetObjectArrayElement(env, jlist, i, dhcptabRecord);
557 if ((*env)->ExceptionOccurred(env) != NULL) {
558 break;
559 }
560
561 recordList = recordList->dtl_next;
562 }
563
564 if (originalList != NULL) {
565 free_dtrec_list(originalList);
566 }
567
568 return (jlist);
569 }
570
571 /*
572 * Retrieve a macro from the dhcptab. Returns
573 * the record as a new instance of a Macro
574 */
575 /*ARGSUSED*/
576 JNIEXPORT jobject JNICALL
577 Java_com_sun_dhcpmgr_bridge_Bridge_getMacro(
578 JNIEnv *env,
579 jobject obj,
580 jstring jkey,
581 jobject jdatastore)
582 {
583 dsvc_datastore_t datastore;
584 dsvc_handle_t handle;
585
586 dt_rec_t record;
587 dt_rec_list_t *recordList;
588 uint32_t query;
589 uint32_t count = 0;
590
591 char *key;
592 int rcode;
593
594 jobject dhcptabRecord;
595
596 /* Create a dsvc_datastore_t using args and DHCP config settings */
597 if (!dd_make_datastore_t(env, &datastore, jdatastore)) {
598 /* exception thrown */
599 return (NULL);
600 }
601
602 /* Retrieve the key argument */
603 if (!dd_jstring_to_UTF(env, jkey, &key)) {
604 /* exception thrown */
605 dd_free_datastore_t(&datastore);
606 return (NULL);
607 }
608
609 /* Open the dhcptab */
610 rcode = open_dd(&handle, &datastore, DSVC_DHCPTAB,
611 DT_DHCPTAB, DSVC_READ);
612
613 dd_free_datastore_t(&datastore);
614 if (rcode != DSVC_SUCCESS) {
615 throw_open_dd_exception(env, rcode, DT_DHCPTAB);
616 free(key);
617 return (NULL);
618 }
619
620 /* Get the records */
621 DSVC_QINIT(query);
622 DSVC_QEQ(query, DT_QTYPE | DT_QKEY);
623 (void) strlcpy(record.dt_key, key, sizeof (record.dt_key));
624 record.dt_type = DT_MACRO;
625
626 rcode = lookup_dd(handle, B_FALSE, query, 1, &record,
627 (void**)&recordList, &count);
628
629 (void) close_dd(&handle);
630 if (rcode == DSVC_SUCCESS) {
631 if (count == 1) {
632 dhcptabRecord = create_Macro(env, recordList->dtl_rec);
633 free_dtrec_list(recordList);
634 } else {
635 throw_noent_exception(env, key);
636 }
637 } else {
638 throw_libdhcpsvc_exception(env, rcode);
639 }
640
641 free(key);
642
643 return (dhcptabRecord);
644 }
645
646 /*
647 * Return all macros defined in the dhcptab. Returned as an array of
648 * Macro objects.
649 */
650 /*ARGSUSED*/
651 JNIEXPORT jobjectArray JNICALL
652 Java_com_sun_dhcpmgr_bridge_Bridge_getMacros(
653 JNIEnv *env,
654 jobject obj,
655 jobject jdatastore)
656 {
657 dsvc_datastore_t datastore;
658 dsvc_handle_t handle;
659
660 dt_rec_t record;
661 dt_rec_list_t *recordList;
662 dt_rec_list_t *originalList = NULL;
663 uint32_t query;
664 uint32_t count = 0;
665 int rcode;
666
667 jclass mac_class;
668 jobjectArray jlist = NULL;
669 jobject dhcptabRecord;
670 int i;
671
672 /* Locate the Macro class and its constructor */
673 mac_class = find_class(env, MAC_CLASS);
674 if (mac_class == NULL) {
675 /* exception thrown */
676 return (NULL);
677 }
678
679 /* Create a dsvc_datastore_t using args and DHCP config settings */
680 if (!dd_make_datastore_t(env, &datastore, jdatastore)) {
681 /* exception thrown */
682 return (NULL);
683 }
684
685 /* Open the dhcptab */
686 rcode = open_dd(&handle, &datastore, DSVC_DHCPTAB,
687 DT_DHCPTAB, DSVC_READ);
688
689 dd_free_datastore_t(&datastore);
690 if (rcode != DSVC_SUCCESS) {
691 throw_open_dd_exception(env, rcode, DT_DHCPTAB);
692 return (NULL);
693 }
694
695 /* Get the records */
696 DSVC_QINIT(query);
697 DSVC_QEQ(query, DT_QTYPE);
698 record.dt_type = DT_MACRO;
699
700 rcode = lookup_dd(handle, B_FALSE, query, -1, &record,
701 (void**)&recordList, &count);
702
703 (void) close_dd(&handle);
704 if (rcode != DSVC_SUCCESS) {
705 throw_libdhcpsvc_exception(env, rcode);
706 return (NULL);
707 }
708
709 if (count != 0) {
710 originalList = recordList;
711 }
712
713 /* Construct the array */
714 jlist = (*env)->NewObjectArray(env, count, mac_class, NULL);
715 if (jlist == NULL) {
716 /* exception thrown */
717 if (originalList != NULL) {
718 free_dtrec_list(originalList);
719 }
720 return (NULL);
721 }
722
723 /* For each macro, create an object and add it to the array */
724 for (i = 0; i < count; i++) {
725 dhcptabRecord = create_Macro(env, recordList->dtl_rec);
726 if (dhcptabRecord == NULL) {
727 /* exception thrown */
728 break;
729 }
730
731 (*env)->SetObjectArrayElement(env, jlist, i, dhcptabRecord);
732 if ((*env)->ExceptionOccurred(env) != NULL) {
733 break;
734 }
735
736 recordList = recordList->dtl_next;
737 }
738
739 if (originalList != NULL) {
740 free_dtrec_list(originalList);
741 }
742
743 return (jlist);
744 }
745
746 /*
747 * Function to create an Option object
748 */
749 /*ARGSUSED*/
750 JNIEXPORT jobject JNICALL
751 Java_com_sun_dhcpmgr_bridge_Bridge_createOption(
752 JNIEnv *env,
753 jobject obj,
754 jstring jkey,
755 jstring jvalue)
756 {
757
758 jobject option;
759 char *key;
760 char *value;
761
762 /* Retrieve the key argument */
763 if (!dd_jstring_to_UTF(env, jkey, &key)) {
764 /* exception thrown */
765 return (NULL);
766 }
767
768 /* Retrieve the value argument */
769 if (!dd_jstring_to_UTF(env, jvalue, &value)) {
770 /* exception thrown */
771 free(key);
772 return (NULL);
773 }
774
775 option = create_Option(env, key, value, 0, B_FALSE);
776
777 free(key);
778 free(value);
779
780 return (option);
781 }
782
783 /*
784 * Function to create a new dhcptab record.
785 */
786 /*ARGSUSED*/
787 JNIEXPORT void JNICALL
788 Java_com_sun_dhcpmgr_bridge_Bridge_createDhcptabRecord(
789 JNIEnv *env,
790 jobject obj,
791 jobject jrec,
792 jobject jdatastore)
793 {
794 dsvc_handle_t handle;
795 dsvc_datastore_t datastore;
796 dt_rec_t *dtrec;
797 int rcode;
798
799 /* Create a dsvc_datastore_t using args and DHCP config settings */
800 if (!dd_make_datastore_t(env, &datastore, jdatastore)) {
801 /* exception thrown */
802 return;
803 }
804
805 dtrec = create_dtrec(env, jrec, B_TRUE);
806 if (dtrec == NULL) {
807 /* exception thrown */
808 dd_free_datastore_t(&datastore);
809 return;
810 }
811
812 /* Open the dhcptab */
813 rcode = open_dd(&handle, &datastore, DSVC_DHCPTAB,
814 DT_DHCPTAB, DSVC_WRITE);
815
816 dd_free_datastore_t(&datastore);
817 if (rcode != DSVC_SUCCESS) {
818 throw_open_dd_exception(env, rcode, DT_DHCPTAB);
819 free_dtrec(dtrec);
820 return;
821 }
822
823 /* Now add the record */
824 rcode = add_dd_entry(handle, dtrec);
825
826 (void) close_dd(&handle);
827 if (rcode != DSVC_SUCCESS) {
828 throw_add_dd_entry_exception(env, rcode, dtrec->dt_key);
829 }
830
831 free_dtrec(dtrec);
832
833 }
834
835 /*
836 * Modify a dhcptab record.
837 */
838 /*ARGSUSED*/
839 JNIEXPORT void JNICALL
840 Java_com_sun_dhcpmgr_bridge_Bridge_modifyDhcptabRecord(
841 JNIEnv *env,
842 jobject obj,
843 jobject joldrec,
844 jobject jnewrec,
845 jobject jdatastore)
846 {
847 dsvc_handle_t handle;
848 dsvc_datastore_t datastore;
849 dt_rec_t *dtoldrec;
850 dt_rec_t *dtnewrec;
851 int rcode;
852
853 /* Create a dsvc_datastore_t using args and DHCP config settings */
854 if (!dd_make_datastore_t(env, &datastore, jdatastore)) {
855 /* exception thrown */
856 return;
857 }
858
859 dtoldrec = create_dtrec(env, joldrec, B_FALSE);
860 if (dtoldrec == NULL) {
861 /* exception thrown */
862 dd_free_datastore_t(&datastore);
863 return;
864 }
865
866 dtnewrec = create_dtrec(env, jnewrec, B_TRUE);
867 if (dtnewrec == NULL) {
868 /* exception thrown */
869 dd_free_datastore_t(&datastore);
870 free_dtrec(dtoldrec);
871 return;
872 }
873
874 /* Open the dhcptab */
875 rcode = open_dd(&handle, &datastore, DSVC_DHCPTAB,
876 DT_DHCPTAB, DSVC_WRITE);
877
878 dd_free_datastore_t(&datastore);
879 if (rcode != DSVC_SUCCESS) {
880 throw_open_dd_exception(env, rcode, DT_DHCPTAB);
881 free_dtrec(dtoldrec);
882 free_dtrec(dtnewrec);
883 return;
884 }
885
886 /* Modify the record */
887 rcode = modify_dd_entry(handle, dtoldrec, dtnewrec);
888
889 (void) close_dd(&handle);
890 if (rcode != DSVC_SUCCESS) {
891 throw_modify_dd_entry_exception(env, rcode, dtoldrec->dt_key,
892 dtnewrec->dt_key);
893 }
894
895 free_dtrec(dtnewrec);
896 free_dtrec(dtoldrec);
897
898 }
899
900 /*
901 * Delete a record from the dhcptab
902 */
903 /*ARGSUSED*/
904 JNIEXPORT void JNICALL
905 Java_com_sun_dhcpmgr_bridge_Bridge_deleteDhcptabRecord(
906 JNIEnv *env,
907 jobject obj,
908 jobject jrec,
909 jobject jdatastore)
910 {
911 dsvc_handle_t handle;
912 dsvc_datastore_t datastore;
913 dt_rec_t *dtrec;
914 int rcode;
915
916 /* Create a dsvc_datastore_t using args and DHCP config settings */
917 if (!dd_make_datastore_t(env, &datastore, jdatastore)) {
918 /* exception thrown */
919 return;
920 }
921
922 dtrec = create_dtrec(env, jrec, B_FALSE);
923 if (dtrec == NULL) {
924 /* exception thrown */
925 dd_free_datastore_t(&datastore);
926 return;
927 }
928
929 /* Open the dhcptab */
930 rcode = open_dd(&handle, &datastore, DSVC_DHCPTAB,
931 DT_DHCPTAB, DSVC_WRITE);
932
933 dd_free_datastore_t(&datastore);
934 if (rcode != DSVC_SUCCESS) {
935 throw_open_dd_exception(env, rcode, DT_DHCPTAB);
936 free_dtrec(dtrec);
937 return;
938 }
939
940 /* Delete the record */
941 rcode = delete_dd_entry(handle, dtrec);
942
943 (void) close_dd(&handle);
944 if (rcode != DSVC_SUCCESS) {
945 throw_delete_dd_entry_exception(env, rcode, dtrec->dt_key);
946 }
947
948 free_dtrec(dtrec);
949 }
950
951 /*
952 * Create the dhcptab.
953 */
954 /*ARGSUSED*/
955 JNIEXPORT void JNICALL
956 Java_com_sun_dhcpmgr_bridge_Bridge_createDhcptab(
957 JNIEnv *env,
958 jobject obj,
959 jobject jdatastore)
960 {
961 dsvc_handle_t handle;
962 dsvc_datastore_t datastore;
963 int rcode;
964
965 /* Create a dsvc_datastore_t using args and DHCP config settings */
966 if (!dd_make_datastore_t(env, &datastore, jdatastore)) {
967 /* exception thrown */
968 return;
969 }
970
971 /* Open the dhcptab and in the process create it */
972 rcode = open_dd(&handle, &datastore, DSVC_DHCPTAB, DT_DHCPTAB,
973 DSVC_CREATE | DSVC_READ | DSVC_WRITE);
974
975 dd_free_datastore_t(&datastore);
976
977 /*
978 * If open was successful, then close. Otherwise, if unsuccessful
979 * opening table, then map error to exception.
980 */
981 if (rcode == DSVC_SUCCESS) {
982 (void) close_dd(&handle);
983 } else {
984 throw_open_dd_exception(env, rcode, DT_DHCPTAB);
985 }
986 }
987
988 /*
989 * Delete the dhcptab.
990 */
991 /*ARGSUSED*/
992 JNIEXPORT void JNICALL
993 Java_com_sun_dhcpmgr_bridge_Bridge_deleteDhcptab(
994 JNIEnv *env,
995 jobject obj,
996 jobject jdatastore)
997 {
998 dsvc_datastore_t datastore;
999 int rcode;
1000
1001 /* Create a dsvc_datastore_t using args and DHCP config settings */
1002 if (!dd_make_datastore_t(env, &datastore, jdatastore)) {
1003 /* exception thrown */
1004 return;
1005 }
1006
1007 rcode = remove_dd(&datastore, DSVC_DHCPTAB, DT_DHCPTAB);
1008
1009 if (rcode != DSVC_SUCCESS) {
1010 throw_remove_dd_exception(env, rcode, DT_DHCPTAB);
1011 }
1012
1013 dd_free_datastore_t(&datastore);
1014 }