tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[RFC] dhcp and crunchgen(1)



Hello

Binaries from src/external/bsd/dhcp cannot be easily folded into a 
crunchgen(1) binary, because libdhcp.a uses callbacks with the same
function names for dhclient, dhcrealy, dhcpd, and omshell. 

The offending symbols are classify, check_collection, dhcp, dhcpv6, bootp,
find_class, parse_allow_deny, and dhcp_set_control_state,

Below is a patch that change each program to define and register an 
array of callbacks at main() start, that lets libdhcp.a to callback
using registered pointers, and the programs can now go through crunchgen(1).

I know DHCP is 3rd party software. I would appreciate opinions on the
approach before submitting upsream.


Index: external/bsd/dhcp/dist/client/dhclient.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/client/dhclient.c,v
retrieving revision 1.9
diff -U 4 -r1.9 dhclient.c
--- external/bsd/dhcp/dist/client/dhclient.c	12 Jul 2014 12:09:37 -0000	1.9
+++ external/bsd/dhcp/dist/client/dhclient.c	31 May 2017 09:13:17 -0000
@@ -93,8 +93,21 @@
 int wanted_ia_ta = 0;
 int wanted_ia_pd = 0;
 char *mockup_relay = NULL;
 
+libdhcp_callbacks_t dhclient_callbacks = {
+	classify,
+	check_collection,
+	dhcp,
+#ifdef DHCPv6
+	dhcpv6,
+#endif /* DHCPv6 */
+	bootp,
+	find_class,
+	parse_allow_deny,
+	dhcp_set_control_state,
+};
+
 void run_stateless(int exit_mode);
 
 static void usage(void);
 
@@ -179,8 +192,10 @@
 #endif /* DHCPv6 */
 	char *s;
 	char **ifaces;
 
+	libdhcp_callbacks_register(&dhclient_callbacks);
+
 	/* Initialize client globals. */
 	memset(&default_duid, 0, sizeof(default_duid));
 
 	/* Make sure that file descriptors 0 (stdin), 1, (stdout), and
Index: external/bsd/dhcp/dist/common/comapi.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/common/comapi.c,v
retrieving revision 1.1.1.3
diff -U 4 -r1.1.1.3 comapi.c
--- external/bsd/dhcp/dist/common/comapi.c	12 Jul 2014 11:57:39 -0000	1.1.1.3
+++ external/bsd/dhcp/dist/common/comapi.c	31 May 2017 09:13:17 -0000
@@ -453,9 +453,10 @@
 	if (!omapi_ds_strcmp (name, "state")) {
 		status = omapi_get_int_value (&newstate, value);
 		if (status != ISC_R_SUCCESS)
 			return status;
-		status = dhcp_set_control_state (control -> state, newstate);
+		status = libdhcp_callbacks.dhcp_set_control_state 
+				(control -> state, newstate);
 		if (status == ISC_R_SUCCESS)
 			control -> state = value -> u.integer;
 		return status;
 	}
Index: external/bsd/dhcp/dist/common/dispatch.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/common/dispatch.c,v
retrieving revision 1.4
diff -U 4 -r1.4 dispatch.c
--- external/bsd/dhcp/dist/common/dispatch.c	12 Jul 2014 12:09:37 -0000	1.4
+++ external/bsd/dhcp/dist/common/dispatch.c	31 May 2017 09:13:18 -0000
@@ -36,8 +36,10 @@
 
 struct timeout *timeouts;
 static struct timeout *free_timeouts;
 
+libdhcp_callbacks_t libdhcp_callbacks;
+
 void set_time(TIME t)
 {
 	/* Do any outstanding timeouts. */
 	if (cur_tv . tv_sec != t) {
@@ -127,10 +129,10 @@
 			/*
 			 * dhcp_set_control_state() will do the job.
 			 * Note its first argument is ignored.
 			 */
-			status = dhcp_set_control_state(server_shutdown,
-							server_shutdown);
+			status = libdhcp_callbacks.dhcp_set_control_state
+					(server_shutdown, server_shutdown);
 			if (status == ISC_R_SUCCESS)
 				status = ISC_R_RELOAD;
 		}
 	} while (status == ISC_R_RELOAD);
@@ -436,4 +438,11 @@
 		dfree(t, MDL);
 	}
 }
 #endif
+
+void libdhcp_callbacks_register(cb)
+	libdhcp_callbacks_t *cb;
+{
+	memcpy(&libdhcp_callbacks, cb, sizeof(libdhcp_callbacks));
+	return;
+}
Index: external/bsd/dhcp/dist/common/execute.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/common/execute.c,v
retrieving revision 1.1.1.3
diff -U 4 -r1.1.1.3 execute.c
--- external/bsd/dhcp/dist/common/execute.c	12 Jul 2014 11:57:44 -0000	1.1.1.3
+++ external/bsd/dhcp/dist/common/execute.c	31 May 2017 09:13:18 -0000
@@ -294,9 +294,9 @@
 			log_debug ("exec: add %s", (r->data.add->name
 					       ? r->data.add->name
 					       : "<unnamed class>"));
 #endif
-			classify (packet, r->data.add);
+			libdhcp_callbacks.classify (packet, r->data.add);
 			break;
 
 		      case break_statement:
 #if defined (DEBUG_EXPRESSIONS)
Index: external/bsd/dhcp/dist/common/options.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/common/options.c,v
retrieving revision 1.1.1.3
diff -U 4 -r1.1.1.3 options.c
--- external/bsd/dhcp/dist/common/options.c	12 Jul 2014 11:57:46 -0000	1.1.1.3
+++ external/bsd/dhcp/dist/common/options.c	31 May 2017 09:13:19 -0000
@@ -3807,11 +3807,11 @@
 	}
 
 	if (validate_packet(decoded_packet) != 0) {
 		if (decoded_packet->packet_type)
-			dhcp(decoded_packet);
+			libdhcp_callbacks.dhcp(decoded_packet);
 		else
-			bootp(decoded_packet);
+			libdhcp_callbacks.bootp(decoded_packet);
 	}
 
 	/* If the caller kept the packet, they'll have upped the refcnt. */
 	packet_dereference(&decoded_packet, MDL);
@@ -3937,9 +3937,9 @@
 			return;
 		}
 	}
 
-	dhcpv6(decoded_packet);
+	libdhcp_callbacks.dhcpv6(decoded_packet);
 
 	packet_dereference(&decoded_packet, MDL);
 
 #if defined (DEBUG_MEMORY_LEAKAGE)
Index: external/bsd/dhcp/dist/common/parse.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/common/parse.c,v
retrieving revision 1.1.1.3
diff -U 4 -r1.1.1.3 parse.c
--- external/bsd/dhcp/dist/common/parse.c	12 Jul 2014 11:57:41 -0000	1.1.1.3
+++ external/bsd/dhcp/dist/common/parse.c	31 May 2017 09:13:22 -0000
@@ -2140,9 +2140,9 @@
 			*lose = 1;
 			return 0;
 		}
 		cta = (struct class *)0;
-		status = find_class (&cta, val, MDL);
+		status = libdhcp_callbacks.find_class (&cta, val, MDL);
 		if (status != ISC_R_SUCCESS) {
 			parse_warn (cfile, "class %s: %s",
 				    val, isc_result_totext (status));
 			skip_to_semi (cfile);
@@ -2207,9 +2207,9 @@
 		flag = 2;
 	      pad:
 		skip_token(&val, (unsigned *)0, cfile);
 		cache = (struct option_cache *)0;
-		if (!parse_allow_deny (&cache, cfile, flag))
+		if (!libdhcp_callbacks.parse_allow_deny (&cache, cfile, flag))
 			return 0;
 		if (!executable_statement_allocate (result, MDL))
 			log_fatal ("no memory for new statement.");
 		(*result) -> op = supersede_option_statement;
Index: external/bsd/dhcp/dist/common/tree.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/common/tree.c,v
retrieving revision 1.1.1.3
diff -U 4 -r1.1.1.3 tree.c
--- external/bsd/dhcp/dist/common/tree.c	12 Jul 2014 11:57:48 -0000	1.1.1.3
+++ external/bsd/dhcp/dist/common/tree.c	31 May 2017 09:13:23 -0000
@@ -718,10 +718,10 @@
 #endif
 
 	switch (expr -> op) {
 	      case expr_check:
-		*result = check_collection (packet, lease,
-					    expr -> data.check);
+		*result = libdhcp_callbacks.check_collection (packet, lease,
+				expr -> data.check);
 #if defined (DEBUG_EXPRESSIONS)
 		log_debug ("bool: check (%s) returns %s",
 			   expr -> data.check -> name,
 			   *result ? "true" : "false");
Index: external/bsd/dhcp/dist/dhcpctl/cltest.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/dhcpctl/cltest.c,v
retrieving revision 1.1.1.3
diff -U 4 -r1.1.1.3 cltest.c
--- external/bsd/dhcp/dist/dhcpctl/cltest.c	12 Jul 2014 11:57:51 -0000	1.1.1.3
+++ external/bsd/dhcp/dist/dhcpctl/cltest.c	31 May 2017 09:13:23 -0000
@@ -42,8 +42,21 @@
 #include <stdarg.h>
 #include "omapip/result.h"
 #include "dhcpctl.h"
 
+libdhcp_callbacks_t cltest_callbacks = {
+	classify,
+	check_collection,
+	dhcp,
+#ifdef DHCPv6
+	dhcpv6,
+#endif /* DHCPv6 */
+	bootp,
+	find_class,
+	parse_allow_deny,
+	dhcp_set_control_state,
+};
+
 int main (int, char **);
 
 enum modes { up, down, undefined };
 
@@ -66,8 +79,10 @@
 	int i;
 	int mode = undefined;
 	const char *interface = 0;
 	const char *action;
+
+	libdhcp_callback_register(&cltest_callbacks);
 	
 	for (i = 1; i < argc; i++) {
 		if (!strcmp (argv[i], "-u")) {
 			mode = up;
Index: external/bsd/dhcp/dist/dhcpctl/omshell.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/dhcpctl/omshell.c,v
retrieving revision 1.1.1.2
diff -U 4 -r1.1.1.2 omshell.c
--- external/bsd/dhcp/dist/dhcpctl/omshell.c	12 Jul 2014 11:57:52 -0000	1.1.1.2
+++ external/bsd/dhcp/dist/dhcpctl/omshell.c	31 May 2017 09:13:23 -0000
@@ -43,8 +43,21 @@
 #include <syslog.h>
 #include "dhcpctl.h"
 #include "dhcpd.h"
 
+libdhcp_callbacks_t omshell_callbacks = {
+	classify,
+	check_collection,
+	dhcp,
+#ifdef DHCPv6
+	dhcpv6,
+#endif /* DHCPv6 */
+	bootp,
+	find_class,
+	parse_allow_deny,
+	dhcp_set_control_state,
+};
+
 /* Fixups */
 isc_result_t find_class (struct class **c, const char *n, const char *f, int l)
 {
 	return 0;
@@ -98,8 +111,10 @@
 	char s1[1024];
 	int connected = 0;
 	char hex_buf[1025];
 
+	libdhcp_callbacks_register(&omshell_callbacks);
+
 	for (i = 1; i < argc; i++) {
 		usage(argv[0]);
 	}
 
Index: external/bsd/dhcp/dist/includes/dhcpd.h
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/includes/dhcpd.h,v
retrieving revision 1.6
diff -U 4 -r1.6 dhcpd.h
--- external/bsd/dhcp/dist/includes/dhcpd.h	12 Jul 2014 12:09:37 -0000	1.6
+++ external/bsd/dhcp/dist/includes/dhcpd.h	31 May 2017 09:13:24 -0000
@@ -3609,4 +3609,24 @@
 void mark_interfaces_unavailable(void);
 
 #define MAX_ADDRESS_STRING_LEN \
    (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))
+
+typedef struct libdhcp_callbacks {
+	void (*classify) (struct packet *, struct class *);
+	int (*check_collection) (struct packet *, struct lease *,
+				 struct collection *);
+	void (*dhcp) (struct packet *);
+#ifdef DHCPv6
+	void (*dhcpv6) (struct packet *);
+#endif /* DHCPv6 */
+	void (*bootp) (struct packet *);
+	isc_result_t (*find_class) (struct class **, const char *,
+				    const char *, int);
+	int (*parse_allow_deny) (struct option_cache **, struct parse *, int);
+	isc_result_t (*dhcp_set_control_state) (control_object_state_t,
+						control_object_state_t);
+} libdhcp_callbacks_t;
+
+extern libdhcp_callbacks_t libdhcp_callbacks;
+
+void libdhcp_callbacks_register(libdhcp_callbacks_t *);
Index: external/bsd/dhcp/dist/relay/dhcrelay.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/relay/dhcrelay.c,v
retrieving revision 1.5
diff -U 4 -r1.5 dhcrelay.c
--- external/bsd/dhcp/dist/relay/dhcrelay.c	12 Jul 2014 12:09:37 -0000	1.5
+++ external/bsd/dhcp/dist/relay/dhcrelay.c	31 May 2017 09:13:24 -0000
@@ -123,8 +123,21 @@
  */
 char *dhcrelay_sub_id = NULL;
 #endif
 
+libdhcp_callbacks_t dhcrelay_callbacks = {
+	classify,
+	check_collection,
+	dhcp,
+#ifdef DHCPv6
+	dhcpv6,
+#endif /* DHCPv6 */
+	bootp,
+	find_class,
+	parse_allow_deny,
+	dhcp_set_control_state,
+};
+
 static void do_relay4(struct interface_info *, struct dhcp_packet *,
 	              unsigned int, unsigned int, struct iaddr,
 		      struct hardware *);
 static int add_relay_agent_options(struct interface_info *,
@@ -187,8 +200,10 @@
 	struct stream_list *sl = NULL;
 	int local_family_set = 0;
 #endif
 
+	libdhcp_callbacks_register(&dhcrelay_callbacks);
+
 	/* Make sure that file descriptors 0(stdin), 1,(stdout), and
 	   2(stderr) are open. To do this, we assume that when we
 	   open a file the lowest available file descriptor is used. */
 	fd = open("/dev/null", O_RDWR);
Index: external/bsd/dhcp/dist/server/dhcpd.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/server/dhcpd.c,v
retrieving revision 1.4
diff -U 4 -r1.4 dhcpd.c
--- external/bsd/dhcp/dist/server/dhcpd.c	12 Jul 2014 12:09:38 -0000	1.4
+++ external/bsd/dhcp/dist/server/dhcpd.c	31 May 2017 09:13:27 -0000
@@ -92,8 +92,21 @@
 #if defined (TRACING)
 trace_type_t *trace_srandom;
 #endif
 
+libdhcp_callbacks_t dhcpd_callbacks = {
+	classify,
+	check_collection,
+	dhcp,
+#ifdef DHCPv6
+	dhcpv6,
+#endif /* DHCPv6 */
+	bootp,
+	find_class,
+	parse_allow_deny,
+	dhcp_set_control_state,
+};
+
 static isc_result_t verify_addr (omapi_object_t *l, omapi_addr_t *addr) {
 	return ISC_R_SUCCESS;
 }
 
@@ -187,8 +200,10 @@
 	uid_t set_uid = 0;
 	gid_t set_gid = 0;
 #endif /* PARANOIA */
 
+	libdhcp_callbacks_register(&dhcpd_callbacks);
+
         /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
            2 (stderr) are open. To do this, we assume that when we
            open a file the lowest available file descriptor is used. */
         fd = open("/dev/null", O_RDWR);
Index: external/bsd/dhcp/dist/tests/t_api.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/tests/t_api.c,v
retrieving revision 1.1.1.3
diff -U 4 -r1.1.1.3 t_api.c
--- external/bsd/dhcp/dist/tests/t_api.c	12 Jul 2014 11:58:01 -0000	1.1.1.3
+++ external/bsd/dhcp/dist/tests/t_api.c	31 May 2017 09:13:28 -0000
@@ -124,8 +124,21 @@
 printusage(void);
 
 static int	T_int;
 
+libdhcp_callbacks_t t_api_callbacks = {
+	classify,
+	check_collection,
+	dhcp,
+#ifdef DHCPv6
+	dhcpv6,
+#endif /* DHCPv6 */
+	bootp,
+	find_class,
+	parse_allow_deny,
+	dhcp_set_control_state,
+};
+
 static void
 t_sighandler(int sig) {
 	T_int = sig;
 }
@@ -148,8 +161,10 @@
 	first = ISC_TRUE;
 	subprocs = 1;
 	T_timeout = T_TCTOUT;
 
+	libdhcp_callbacks_register(&t_api_callbacks);
+
 	/*
 	 * -a option is now default.
 	 */
 	memset(T_tvec, 0xffff, sizeof(T_tvec));

-- 
Emmanuel Dreyfus
manu%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index