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