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 2001-2003 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/*
30 * mkdstore: fast datastore creation program.
31 *
32 * mkdstore <table> <nrecords> <cid> <flags> <cip> <sip> <lease> <comment>
33 */
34
35#include <stdio.h>
36#include <netdb.h>
37
38#include <string.h>
39#include <stdlib.h>
40#include <rpcsvc/nis.h>
41
42#include <sys/types.h>
43#include <sys/socket.h>
44#include <netinet/in.h>
45#include <arpa/inet.h>
46
47#include <stdio.h>
48#include <stdlib.h>
49#include <unistd.h>
50#include <sys/types.h>
51#include <errno.h>
52#include <assert.h>
53#include <string.h>
54#include <syslog.h>
55#include <sys/socket.h>
56#include <net/if.h>
57#include <netinet/in.h>
58#include <netinet/if_ether.h>
59#include <arpa/inet.h>
60#include <netinet/dhcp.h>
61#include <netdb.h>
62#include <locale.h>
63#include <signal.h>
64#include <tnf/probe.h>
65
66#include <dhcp_svc_confopt.h>
67#include <dhcp_svc_private.h>
68#include <dhcp_impl.h>
69
70dsvc_handle_t	dh;		/* data handle */
71dsvc_datastore_t	datastore;	/* Datastore for container access */
72uint_t		nrecords;
73char		network[INET_ADDRSTRLEN];
74struct in_addr	net;
75
76/*
77 * mkdstore <table> <nrecords> <cid> <flags> <cip> <sip> <lease> <macro>
78 * <comment>
79 */
80main(int c, char **v)
81{
82	long long	cid;
83	uchar_t	flags;
84	struct in_addr	cip;
85	struct in_addr	sip;
86	int		i, j;
87	char		**entries;
88	uint_t		lease;
89	char		*network = v[1];
90	int		ct = strtol(v[2], 0L, 0L);
91	char		*server;
92	char		*macro;
93	int		err;
94	uint32_t	query;
95	dn_rec_t	dn;
96	dn_rec_list_t	*dncp = NULL;
97	dhcp_confopt_t	*dsp = NULL;
98
99#ifdef	DEBUG
100	mallocctl(MTDEBUGPATTERN, 1);
101	mallocctl(MTINITBUFFER, 1);
102#endif				/* DEBUG */
103
104	if (c == 1) {
105		(void) fprintf(stderr, "/*\n * mkdstore <table> <nrecords> "
106		    "<cid> <flags> <cip> <sip> <lease> <comment>\n*/");
107		return (0);
108	}
109
110	cid = (c > 3) ? strtoul(v[3], 0L, 0L) : 0;
111	flags = (c > 4) ? (char)strtol(v[4], 0L, 0L) : 0;
112	cip.s_addr = (c > 5) ? strtoul(v[5], 0L, 0L) : 0;
113	sip.s_addr = (c > 6) ? strtoul(v[6], 0L, 0L) : 0;
114	lease = (c > 7) ? strtoul(v[7], 0L, 0L) : 0;
115	macro = (c > 8) ? v[8] : 0;
116	server = (c > 9) ? v[9] : "unknown";
117
118	entries = (char **) malloc(ct * (sizeof (char *) * 8 + 4));
119
120	/* Load current datastore. */
121	(void) read_dsvc_conf(&dsp);
122	if ((i = confopt_to_datastore(dsp, &datastore)) != DSVC_SUCCESS) {
123		(void) fprintf(stderr, "Invalid datastore: %s\n",
124		    dhcpsvc_errmsg(i));
125		return (EINVAL);
126	}
127	err = open_dd(&dh, &datastore, DSVC_DHCPNETWORK, network,
128	    DSVC_READ | DSVC_WRITE);
129
130	if (err != DSVC_SUCCESS) {
131		(void) fprintf(stderr, "Invalid network: %s trying create...\n",
132		    dhcpsvc_errmsg(err));
133
134		err = open_dd(&dh, &datastore, DSVC_DHCPNETWORK, network,
135		    DSVC_READ | DSVC_WRITE | DSVC_CREATE);
136		if (err != DSVC_SUCCESS) {
137			(void) fprintf(stderr, "Can't create network: %s\n",
138			    dhcpsvc_errmsg(err));
139			return (err);
140		}
141	}
142	/* XXXX: bug: currently can't get the count as advertised */
143	(void) memset(&dn, '\0', sizeof (dn));
144	DSVC_QINIT(query);
145	err = lookup_dd(dh, B_FALSE, query, -1,
146		    (const void *) &dn, (void **) &dncp, &nrecords);
147	if (dncp)
148		free_dd_list(dh, dncp);
149
150	if (err != DSVC_SUCCESS) {
151		(void) fprintf(stderr, "Bad nrecords: %s [%d]\n",
152		    dhcpsvc_errmsg(err), nrecords);
153		return (err);
154	}
155
156	for (i = 0, j = 0; i < ct; i++) {
157		TNF_PROBE_1(main, "main",
158			    "main%debug 'in function main'",
159			    tnf_ulong, record, i);
160		if (cid) {
161			(void) memcpy(dn.dn_cid, &cid, sizeof (long long));
162			dn.dn_cid_len = 7;
163		} else {
164			(void) memset(dn.dn_cid, '\0', sizeof (long long));
165			dn.dn_cid_len = 1;
166		}
167		dn.dn_sig = 0;
168		dn.dn_flags = flags;
169		dn.dn_cip.s_addr = cip.s_addr;
170		dn.dn_sip.s_addr = sip.s_addr;
171		dn.dn_lease = lease;
172		strcpy(dn.dn_macro, macro);
173		strcpy(dn.dn_comment, server);
174		(void) add_dd_entry(dh, &dn);
175		if (cid)
176			cid += 0x100;
177		cip.s_addr++;
178
179		TNF_PROBE_0(main_end, "main", "");
180	}
181	(void) close_dd(&dh);
182
183	return (0);
184}
185