xref: /onnv-gate/usr/src/lib/libdhcpagent/common/dhcpagent_ipc.h (revision 8562:62283013cc53)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52546Scarlsonj  * Common Development and Distribution License (the "License").
62546Scarlsonj  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*8562SPeter.Memishian@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #ifndef	_DHCPAGENT_IPC_H
270Sstevel@tonic-gate #define	_DHCPAGENT_IPC_H
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/socket.h>
30*8562SPeter.Memishian@Sun.COM #include <net/if.h>		/* LIFNAMSIZ */
310Sstevel@tonic-gate #include <stddef.h>
320Sstevel@tonic-gate #include <sys/types.h>
330Sstevel@tonic-gate #include <sys/time.h>
340Sstevel@tonic-gate #include <netinet/dhcp.h>
350Sstevel@tonic-gate #include <dhcp_impl.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate /*
380Sstevel@tonic-gate  * dhcpagent_ipc.[ch] comprise the interface used to perform
390Sstevel@tonic-gate  * interprocess communication with the agent.  see dhcpagent_ipc.c for
400Sstevel@tonic-gate  * documentation on how to use the exported functions.
410Sstevel@tonic-gate  */
420Sstevel@tonic-gate 
430Sstevel@tonic-gate #ifdef	__cplusplus
440Sstevel@tonic-gate extern "C" {
450Sstevel@tonic-gate #endif
460Sstevel@tonic-gate 
470Sstevel@tonic-gate #define	DHCP_AGENT_PATH		"/sbin/dhcpagent"
480Sstevel@tonic-gate #define	DHCP_IPC_LISTEN_BACKLOG	30
490Sstevel@tonic-gate #define	IPPORT_DHCPAGENT	4999
503431Scarlsonj #define	DHCP_IPC_MAX_WAIT	15	/* max seconds to wait to start agent */
510Sstevel@tonic-gate 
520Sstevel@tonic-gate /*
530Sstevel@tonic-gate  * return values which should be used by programs which talk to the
540Sstevel@tonic-gate  * agent (for uniformity).
550Sstevel@tonic-gate  */
560Sstevel@tonic-gate 
570Sstevel@tonic-gate #define	DHCP_EXIT_SUCCESS	0
580Sstevel@tonic-gate #define	DHCP_EXIT_FAILURE	2
590Sstevel@tonic-gate #define	DHCP_EXIT_BADARGS	3
600Sstevel@tonic-gate #define	DHCP_EXIT_TIMEOUT	4
610Sstevel@tonic-gate #define	DHCP_EXIT_SYSTEM	6
620Sstevel@tonic-gate 
630Sstevel@tonic-gate /*
640Sstevel@tonic-gate  * opaque types for requests and replies.  users of this api do not
650Sstevel@tonic-gate  * need to understand their contents.
660Sstevel@tonic-gate  */
670Sstevel@tonic-gate 
680Sstevel@tonic-gate typedef struct dhcp_ipc_request dhcp_ipc_request_t;
690Sstevel@tonic-gate typedef struct dhcp_ipc_reply   dhcp_ipc_reply_t;
700Sstevel@tonic-gate 
710Sstevel@tonic-gate /* payloads that can be passed in a request or reply */
720Sstevel@tonic-gate 
730Sstevel@tonic-gate typedef enum {
740Sstevel@tonic-gate 	DHCP_TYPE_OPTION,
750Sstevel@tonic-gate 	DHCP_TYPE_STATUS,
760Sstevel@tonic-gate 	DHCP_TYPE_OPTNUM,
770Sstevel@tonic-gate 	DHCP_TYPE_NONE
780Sstevel@tonic-gate } dhcp_data_type_t;
790Sstevel@tonic-gate 
800Sstevel@tonic-gate /*
810Sstevel@tonic-gate  * requests that can be sent to the agent
820Sstevel@tonic-gate  *
830Sstevel@tonic-gate  * code in dhcpagent relies on the numeric values of these
840Sstevel@tonic-gate  * requests -- but there's no sane reason to change them anyway.
853431Scarlsonj  *
864106Scarlsonj  * If any commands are changed, added, or removed, see the ipc_typestr[]
873431Scarlsonj  * array in dhcpagent_ipc.c.
880Sstevel@tonic-gate  */
890Sstevel@tonic-gate 
900Sstevel@tonic-gate typedef enum {
910Sstevel@tonic-gate 	DHCP_DROP,	DHCP_EXTEND,  DHCP_PING,    DHCP_RELEASE,
920Sstevel@tonic-gate 	DHCP_START,  	DHCP_STATUS,  DHCP_INFORM,  DHCP_GET_TAG,
930Sstevel@tonic-gate 	DHCP_NIPC,	/* number of supported requests */
943431Scarlsonj 	DHCP_PRIMARY = 0x100,
953431Scarlsonj 	DHCP_V6 = 0x200
960Sstevel@tonic-gate } dhcp_ipc_type_t;
970Sstevel@tonic-gate 
980Sstevel@tonic-gate /* structure passed with the DHCP_GET_TAG request */
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate typedef struct {
1013431Scarlsonj 	uint_t		category;
1023431Scarlsonj 	uint_t		code;
1033431Scarlsonj 	uint_t		size;
1040Sstevel@tonic-gate } dhcp_optnum_t;
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate #define	DHCP_IPC_CMD(type)	((type) & 0x00ff)
1070Sstevel@tonic-gate #define	DHCP_IPC_FLAGS(type)	((type) & 0xff00)
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate /* special timeout values for dhcp_ipc_make_request() */
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate #define	DHCP_IPC_WAIT_FOREVER	(-1)
1120Sstevel@tonic-gate #define	DHCP_IPC_WAIT_DEFAULT	(-2)
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate /*
1150Sstevel@tonic-gate  * errors that can be returned from the provided functions.
1160Sstevel@tonic-gate  * note: keep in sync with dhcp_ipc_strerror()
1170Sstevel@tonic-gate  */
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate enum {
1203431Scarlsonj 	/* System call errors must be kept contiguous */
1210Sstevel@tonic-gate 	DHCP_IPC_SUCCESS,	DHCP_IPC_E_SOCKET,	DHCP_IPC_E_FCNTL,
1220Sstevel@tonic-gate 	DHCP_IPC_E_READ,	DHCP_IPC_E_ACCEPT,	DHCP_IPC_E_CLOSE,
1230Sstevel@tonic-gate 	DHCP_IPC_E_BIND,	DHCP_IPC_E_LISTEN,	DHCP_IPC_E_MEMORY,
1243431Scarlsonj 	DHCP_IPC_E_CONNECT,	DHCP_IPC_E_WRITEV,	DHCP_IPC_E_POLL,
1253431Scarlsonj 
1263431Scarlsonj 	/* All others follow */
1273431Scarlsonj 	DHCP_IPC_E_TIMEOUT,	DHCP_IPC_E_SRVFAILED,	DHCP_IPC_E_EOF,
1280Sstevel@tonic-gate 	DHCP_IPC_E_INVIF,	DHCP_IPC_E_INT,		DHCP_IPC_E_PERM,
1290Sstevel@tonic-gate 	DHCP_IPC_E_OUTSTATE,	DHCP_IPC_E_PEND,	DHCP_IPC_E_BOOTP,
1300Sstevel@tonic-gate 	DHCP_IPC_E_CMD_UNKNOWN, DHCP_IPC_E_UNKIF,	DHCP_IPC_E_PROTO,
1310Sstevel@tonic-gate 	DHCP_IPC_E_FAILEDIF,	DHCP_IPC_E_NOPRIMARY,	DHCP_IPC_E_DOWNIF,
1323431Scarlsonj 	DHCP_IPC_E_NOIPIF,	DHCP_IPC_E_NOVALUE,	DHCP_IPC_E_RUNNING
1330Sstevel@tonic-gate };
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate /*
1360Sstevel@tonic-gate  * low-level public dhcpagent ipc functions -- these are for use by
1370Sstevel@tonic-gate  * programs that need to communicate with the dhcpagent.  these will
1380Sstevel@tonic-gate  * remain relatively stable.
1390Sstevel@tonic-gate  */
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate extern const char	*dhcp_ipc_strerror(int);
1420Sstevel@tonic-gate extern dhcp_ipc_request_t *dhcp_ipc_alloc_request(dhcp_ipc_type_t, const char *,
1433431Scarlsonj 			    const void *, uint32_t, dhcp_data_type_t);
1440Sstevel@tonic-gate extern void		*dhcp_ipc_get_data(dhcp_ipc_reply_t *, size_t *,
1450Sstevel@tonic-gate 			    dhcp_data_type_t *);
1460Sstevel@tonic-gate extern int		dhcp_ipc_make_request(dhcp_ipc_request_t *,
1470Sstevel@tonic-gate 			    dhcp_ipc_reply_t **, int32_t);
1483431Scarlsonj extern const char	*dhcp_ipc_type_to_string(dhcp_ipc_type_t);
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate /*
1510Sstevel@tonic-gate  * high-level public dhcpagent ipc functions
1520Sstevel@tonic-gate  */
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate extern int		dhcp_ipc_getinfo(dhcp_optnum_t *, DHCP_OPT **, int32_t);
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate /*
1570Sstevel@tonic-gate  * private dhcpagent ipc "server side" functions -- these are only for
1580Sstevel@tonic-gate  * use by dhcpagent(1M) and are subject to change.
1590Sstevel@tonic-gate  */
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate extern int		dhcp_ipc_init(int *);
1620Sstevel@tonic-gate extern int		dhcp_ipc_accept(int, int *, int *);
1630Sstevel@tonic-gate extern int		dhcp_ipc_recv_request(int, dhcp_ipc_request_t **, int);
1643431Scarlsonj extern dhcp_ipc_reply_t	*dhcp_ipc_alloc_reply(dhcp_ipc_request_t *, int,
1653431Scarlsonj 			    const void *, uint32_t, dhcp_data_type_t);
1660Sstevel@tonic-gate extern int		dhcp_ipc_send_reply(int, dhcp_ipc_reply_t *);
1670Sstevel@tonic-gate extern int		dhcp_ipc_close(int);
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate /*
1700Sstevel@tonic-gate  * values for if_state in the dhcp_status_t
1710Sstevel@tonic-gate  *
1720Sstevel@tonic-gate  * code in this library and dhcpagent rely on the numeric values of these
1730Sstevel@tonic-gate  * requests -- but there's no sane reason to change them anyway.
1740Sstevel@tonic-gate  */
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate typedef enum {
1770Sstevel@tonic-gate 	INIT,				/* nothing done yet */
1780Sstevel@tonic-gate 	SELECTING,			/* sent DISCOVER, waiting for OFFERs */
1790Sstevel@tonic-gate 	REQUESTING,			/* sent REQUEST, waiting for ACK/NAK */
1802546Scarlsonj 	PRE_BOUND,			/* have ACK, setting up interface */
1810Sstevel@tonic-gate 	BOUND,				/* have a valid lease */
1820Sstevel@tonic-gate 	RENEWING,			/* have lease, but trying to renew */
1830Sstevel@tonic-gate 	REBINDING,			/* have lease, but trying to rebind */
1840Sstevel@tonic-gate 	INFORMATION,			/* sent INFORM, received ACK */
1853431Scarlsonj 	INIT_REBOOT,			/* attempt to use cached ACK/Reply */
1860Sstevel@tonic-gate 	ADOPTING,			/* attempting to adopt */
1870Sstevel@tonic-gate 	INFORM_SENT,			/* sent INFORM, awaiting ACK */
1883431Scarlsonj 	DECLINING,			/* sent v6 Decline, awaiting Reply */
1893431Scarlsonj 	RELEASING,			/* sent v6 Release, awaiting Reply */
1900Sstevel@tonic-gate 	DHCP_NSTATES			/* total number of states */
1910Sstevel@tonic-gate } DHCPSTATE;
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate /* values for if_dflags in the dhcp_status_t */
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate #define	DHCP_IF_PRIMARY		0x0100	/* interface is primary interface */
1960Sstevel@tonic-gate #define	DHCP_IF_BUSY		0x0200	/* asynchronous command pending */
1970Sstevel@tonic-gate #define	DHCP_IF_BOOTP		0x0400	/* interface is using bootp */
1980Sstevel@tonic-gate #define	DHCP_IF_REMOVED		0x0800	/* interface is going away */
1990Sstevel@tonic-gate #define	DHCP_IF_FAILED		0x1000	/* interface configuration problem */
2003431Scarlsonj #define	DHCP_IF_V6		0x2000	/* DHCPv6 interface */
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate /*
2030Sstevel@tonic-gate  * structure passed with the DHCP_STATUS replies
2040Sstevel@tonic-gate  *
2050Sstevel@tonic-gate  * when parsing a dhcp_status_t, `version' should always be checked
2060Sstevel@tonic-gate  * if there is a need to access any fields which were not defined in
2070Sstevel@tonic-gate  * version 1 of this structure.
2080Sstevel@tonic-gate  *
2090Sstevel@tonic-gate  * as new fields are added to the dhcp_status_t, they should be
2100Sstevel@tonic-gate  * appended to the structure and the version number incremented.
2110Sstevel@tonic-gate  */
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate typedef struct dhcp_status {
2140Sstevel@tonic-gate 	uint8_t		version;	/* version of this structure */
2150Sstevel@tonic-gate 
216*8562SPeter.Memishian@Sun.COM 	char		if_name[LIFNAMSIZ];
2170Sstevel@tonic-gate 	DHCPSTATE	if_state;	/* state of interface; see above */
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate 	time_t		if_began;	/* time lease began (absolute) */
2200Sstevel@tonic-gate 	time_t		if_t1;		/* renewing time (absolute) */
2210Sstevel@tonic-gate 	time_t		if_t2;		/* rebinding time (absolute) */
2220Sstevel@tonic-gate 	time_t		if_lease;	/* lease expiration time (absolute) */
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate 	uint16_t	if_dflags;	/* DHCP flags on this if; see above */
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate 	/*
2270Sstevel@tonic-gate 	 * these three fields are initially zero, and get incremented
2280Sstevel@tonic-gate 	 * as if_state goes from INIT -> BOUND (or INIT ->
2290Sstevel@tonic-gate 	 * INFORMATION).  if and when the interface moves to the
2300Sstevel@tonic-gate 	 * RENEWING state, these fields are reset, so they always
2310Sstevel@tonic-gate 	 * either indicate the number of packets sent, received, and
2320Sstevel@tonic-gate 	 * declined while obtaining the current lease (if BOUND), or
2330Sstevel@tonic-gate 	 * the number of packets sent, received, and declined while
2340Sstevel@tonic-gate 	 * attempting to obtain a future lease (if any other state).
2350Sstevel@tonic-gate 	 */
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate 	uint32_t	if_sent;
2380Sstevel@tonic-gate 	uint32_t	if_recv;
2390Sstevel@tonic-gate 	uint32_t	if_bad_offers;
2400Sstevel@tonic-gate } dhcp_status_t;
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate #define	DHCP_STATUS_VER		1	/* current version of dhcp_status_t */
2430Sstevel@tonic-gate #define	DHCP_STATUS_VER1_SIZE	(offsetof(dhcp_status_t, if_bad_offers) + \
2440Sstevel@tonic-gate 				    sizeof (uint32_t))
2450Sstevel@tonic-gate 
2460Sstevel@tonic-gate /*
2470Sstevel@tonic-gate  * the remainder of this file contains implementation-specific
2480Sstevel@tonic-gate  * artifacts which may change. note that a `dhcp_ipc_request_t' and a
2490Sstevel@tonic-gate  * `dhcp_ipc_reply_t' are incomplete types as far as consumers of this
2500Sstevel@tonic-gate  * api are concerned.  use these details at your own risk.
2510Sstevel@tonic-gate  */
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate typedef hrtime_t dhcp_ipc_id_t;
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate /*
2560Sstevel@tonic-gate  * note: the first 4 fields of the dhcp_ipc_request_t and dhcp_ipc_reply_t
2570Sstevel@tonic-gate  *	 are intentionally identical; code in dhcpagent_ipc.c counts on it!
2580Sstevel@tonic-gate  */
2590Sstevel@tonic-gate 
2600Sstevel@tonic-gate struct	dhcp_ipc_request {
2610Sstevel@tonic-gate 	dhcp_ipc_type_t  message_type;	/* type of request */
2620Sstevel@tonic-gate 	dhcp_ipc_id_t	 ipc_id;	/* per-socket unique request id */
2630Sstevel@tonic-gate 	dhcp_data_type_t data_type;	/* type of payload */
2640Sstevel@tonic-gate 	uint32_t	 data_length;	/* size of actual data in the buffer */
265*8562SPeter.Memishian@Sun.COM 	char		 ifname[LIFNAMSIZ];
2660Sstevel@tonic-gate 	int32_t		 timeout;	/* timeout in seconds */
2670Sstevel@tonic-gate 	uchar_t		 buffer[1];	/* dynamically extended */
2680Sstevel@tonic-gate };
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate struct	dhcp_ipc_reply {
2710Sstevel@tonic-gate 	dhcp_ipc_type_t	 message_type;	/* same message type as request */
2720Sstevel@tonic-gate 	dhcp_ipc_id_t	 ipc_id;	/* same id as request */
2730Sstevel@tonic-gate 	dhcp_data_type_t data_type;	/* type of payload */
2740Sstevel@tonic-gate 	uint32_t	 data_length;	/* size of actual data in the buffer */
2750Sstevel@tonic-gate 	uint32_t	 return_code;	/* did the request succeed? */
2760Sstevel@tonic-gate 	uchar_t		 buffer[1];	/* dynamically extended */
2770Sstevel@tonic-gate };
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate /*
2800Sstevel@tonic-gate  * since ansi c won't let us define arrays with 0 elements, the
2810Sstevel@tonic-gate  * size of the ipc request/reply structures is off-by-1; use macros.
2820Sstevel@tonic-gate  */
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate #define	DHCP_IPC_REPLY_SIZE	(sizeof (dhcp_ipc_reply_t) - 1)
2850Sstevel@tonic-gate #define	DHCP_IPC_REQUEST_SIZE	(sizeof (dhcp_ipc_request_t) - 1)
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate #define	DHCP_IPC_DEFAULT_WAIT	120	/* seconds */
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate #ifdef	__cplusplus
2900Sstevel@tonic-gate }
2910Sstevel@tonic-gate #endif
2920Sstevel@tonic-gate 
2930Sstevel@tonic-gate #endif	/* _DHCPAGENT_IPC_H */
294