xref: /netbsd-src/external/mpl/dhcp/dist/dhcpctl/cltest.c (revision 3f351f34c6d827cf017cdcff3543f6ec0c88b420)
1 /*	$NetBSD: cltest.c,v 1.3 2022/04/03 01:10:58 christos Exp $	*/
2 
3 /* cltest.c
4 
5    Example program that uses the dhcpctl library. */
6 
7 /*
8  * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC")
9  * Copyright (c) 2000-2003 by Internet Software Consortium
10  *
11  * This Source Code Form is subject to the terms of the Mozilla Public
12  * License, v. 2.0. If a copy of the MPL was not distributed with this
13  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
18  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  *   Internet Systems Consortium, Inc.
24  *   PO Box 360
25  *   Newmarket, NH 03857 USA
26  *   <info@isc.org>
27  *   https://www.isc.org/
28  *
29  * This software was contributed to Internet Systems Consortium
30  * by Brian Murrell.
31  */
32 
33 #include <sys/cdefs.h>
34 __RCSID("$NetBSD: cltest.c,v 1.3 2022/04/03 01:10:58 christos Exp $");
35 
36 #include "config.h"
37 
38 #include <time.h>
39 #include <sys/time.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <stdarg.h>
44 #include "omapip/result.h"
45 #include "dhcpctl.h"
46 #include "dhcpd.h"
47 
48 /* Fixups */
49 isc_result_t find_class (struct class **c, const char *n, const char *f, int l)
50 {
51 	return 0;
52 }
53 int parse_allow_deny (struct option_cache **oc, struct parse *cfile, int flag)
54 {
55 	return 0;
56 }
57 void dhcp (struct packet *packet) { }
58 void bootp (struct packet *packet) { }
59 
60 #ifdef DHCPv6
61 /* XXX: should we warn or something here? */
62 void dhcpv6(struct packet *packet) { }
63 #ifdef DHCP4o6
64 isc_result_t dhcpv4o6_handler(omapi_object_t *h)
65 {
66 	return ISC_R_NOTIMPLEMENTED;
67 }
68 #endif /* DHCP4o6 */
69 #endif /* DHCPv6 */
70 
71 int check_collection (struct packet *p, struct lease *l, struct collection *c)
72 {
73 	return 0;
74 }
75 void classify (struct packet *packet, struct class *class) { }
76 
77 isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
78 				     control_object_state_t newstate)
79 {
80 	return ISC_R_SUCCESS;
81 }
82 
83 uint16_t local_port = 0;
84 uint16_t remote_port = 0;
85 libdhcp_callbacks_t cltest_callbacks = {
86 	&local_port,
87 	&remote_port,
88 	classify,
89 	check_collection,
90 	dhcp,
91 #ifdef DHCPv6
92 	dhcpv6,
93 #endif /* DHCPv6 */
94 	bootp,
95 	find_class,
96 	parse_allow_deny,
97 	dhcp_set_control_state,
98 };
99 
100 int main (int, char **);
101 
102 enum modes { up, down, undefined };
103 
104 static void usage (char *s) {
105 	fprintf (stderr,
106 		 "Usage: %s [-n <username>] [-p <password>] [-a <algorithm>]"
107 		 "(-u | -d) <if>\n", s);
108 	exit (1);
109 }
110 
111 int main (argc, argv)
112 	int argc;
113 	char **argv;
114 {
115 	isc_result_t status, waitstatus;
116 	dhcpctl_handle authenticator;
117 	dhcpctl_handle connection;
118 	dhcpctl_handle interface_handle;
119 	dhcpctl_data_string result;
120 	int i;
121 	int mode = undefined;
122 	const char *interface = 0;
123 	const char *action;
124 
125 	libdhcp_callbacks_register(&cltest_callbacks);
126 
127 	for (i = 1; i < argc; i++) {
128 		if (!strcmp (argv[i], "-u")) {
129 			mode = up;
130 		} else if (!strcmp (argv [i], "-d")) {
131 			mode = down;
132 		} else if (argv[i][0] == '-') {
133 			usage(argv[0]);
134 		} else {
135 			interface = argv[i];
136 		}
137 	}
138 
139 	if (!interface)
140 		usage(argv[0]);
141 	if (mode == undefined)
142 		usage(argv[0]);
143 
144 	status = dhcpctl_initialize ();
145 	if (status != ISC_R_SUCCESS) {
146 		fprintf (stderr, "dhcpctl_initialize: %s\n",
147 			 isc_result_totext (status));
148 		exit (1);
149 	}
150 
151 	authenticator = dhcpctl_null_handle;
152 	connection = dhcpctl_null_handle;
153 
154 	status = dhcpctl_connect (&connection, "127.0.0.1", 7911,
155 				  authenticator);
156 	if (status != ISC_R_SUCCESS) {
157 		fprintf (stderr, "dhcpctl_connect: %s\n",
158 			 isc_result_totext (status));
159 		exit (1);
160 	}
161 
162 	interface_handle = dhcpctl_null_handle;
163 	status = dhcpctl_new_object (&interface_handle,
164 				     connection, "interface");
165 	if (status != ISC_R_SUCCESS) {
166 		fprintf (stderr, "dhcpctl_new_object: %s\n",
167 			 isc_result_totext (status));
168 		exit (1);
169 	}
170 
171 	status = dhcpctl_set_string_value (interface_handle,
172 					   interface, "name");
173 	if (status != ISC_R_SUCCESS) {
174 		fprintf (stderr, "dhcpctl_set_value: %s\n",
175 			 isc_result_totext (status));
176 		exit (1);
177 	}
178 
179 	if (mode == up) {
180 		/* "up" the interface */
181 		printf ("upping interface %s\n", interface);
182 		action = "create";
183 		status = dhcpctl_open_object (interface_handle, connection,
184 					      DHCPCTL_CREATE | DHCPCTL_EXCL);
185 		if (status != ISC_R_SUCCESS) {
186 			fprintf (stderr, "dhcpctl_open_object: %s\n",
187 				 isc_result_totext (status));
188 			exit (1);
189 		}
190 	} else {
191 		/* down the interface */
192 		printf ("downing interface %s\n", interface);
193 		action = "remove";
194 		status = dhcpctl_open_object (interface_handle, connection, 0);
195 		if (status != ISC_R_SUCCESS) {
196 			fprintf (stderr, "dhcpctl_open_object: %s\n",
197 				 isc_result_totext (status));
198 			exit (1);
199 		}
200 		status = dhcpctl_wait_for_completion (interface_handle,
201 						      &waitstatus);
202 		if (status != ISC_R_SUCCESS) {
203 			fprintf (stderr, "dhcpctl_wait_for_completion: %s\n",
204 				 isc_result_totext (status));
205 			exit (1);
206 		}
207 		if (waitstatus != ISC_R_SUCCESS) {
208 			fprintf (stderr, "dhcpctl_wait_for_completion: %s\n",
209 				 isc_result_totext (waitstatus));
210 			exit (1);
211 		}
212 		status = dhcpctl_object_remove (connection, interface_handle);
213 		if (status != ISC_R_SUCCESS) {
214 			fprintf (stderr, "dhcpctl_open_object: %s\n",
215 				 isc_result_totext (status));
216 			exit (1);
217 		}
218 	}
219 
220 	status = dhcpctl_wait_for_completion (interface_handle, &waitstatus);
221 	if (status != ISC_R_SUCCESS) {
222 		fprintf (stderr, "dhcpctl_wait_for_completion: %s\n",
223 			 isc_result_totext (status));
224 		exit (1);
225 	}
226 	if (waitstatus != ISC_R_SUCCESS) {
227 		fprintf (stderr, "interface object %s: %s\n", action,
228 			 isc_result_totext (waitstatus));
229 		exit (1);
230 	}
231 
232 	memset (&result, 0, sizeof result);
233 	status = dhcpctl_get_value (&result, interface_handle, "state");
234 	if (status != ISC_R_SUCCESS) {
235 		fprintf (stderr, "dhcpctl_get_value: %s\n",
236 			 isc_result_totext (status));
237 		exit (1);
238 	}
239 
240 	exit (0);
241 }
242