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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * Copyright (c) 2013, 2015 by Delphix. All rights reserved. 27 * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. 28 */ 29 30 #ifndef _DHCPAGENT_IPC_H 31 #define _DHCPAGENT_IPC_H 32 33 #include <sys/socket.h> 34 #include <net/if.h> /* LIFNAMSIZ */ 35 #include <stddef.h> 36 #include <sys/types.h> 37 #include <sys/time.h> 38 #include <netinet/dhcp.h> 39 #include <dhcp_impl.h> 40 41 /* 42 * dhcpagent_ipc.[ch] comprise the interface used to perform 43 * interprocess communication with the agent. see dhcpagent_ipc.c for 44 * documentation on how to use the exported functions. 45 */ 46 47 #ifdef __cplusplus 48 extern "C" { 49 #endif 50 51 #define DHCP_AGENT_PATH "/sbin/dhcpagent" 52 #define DHCP_IPC_LISTEN_BACKLOG 30 53 #define IPPORT_DHCPAGENT 4999 54 #define DHCP_IPC_MAX_WAIT 15 /* max seconds to wait to start agent */ 55 56 /* 57 * return values which should be used by programs which talk to the 58 * agent (for uniformity). 59 */ 60 61 #define DHCP_EXIT_SUCCESS 0 62 #define DHCP_EXIT_FAILURE 2 63 #define DHCP_EXIT_BADARGS 3 64 #define DHCP_EXIT_TIMEOUT 4 65 #define DHCP_EXIT_SYSTEM 6 66 67 /* 68 * opaque types for requests and replies. users of this api do not 69 * need to understand their contents. 70 */ 71 72 typedef struct dhcp_ipc_request dhcp_ipc_request_t; 73 typedef struct dhcp_ipc_reply dhcp_ipc_reply_t; 74 75 /* payloads that can be passed in a request or reply */ 76 77 typedef enum { 78 DHCP_TYPE_OPTION, 79 DHCP_TYPE_STATUS, 80 DHCP_TYPE_OPTNUM, 81 DHCP_TYPE_NONE 82 } dhcp_data_type_t; 83 84 /* 85 * requests that can be sent to the agent 86 * 87 * code in dhcpagent relies on the numeric values of these 88 * requests -- but there's no sane reason to change them anyway. 89 * 90 * If any commands are changed, added, or removed, see the ipc_typestr[] 91 * array in dhcpagent_ipc.c. 92 */ 93 94 typedef enum { 95 DHCP_DROP, DHCP_EXTEND, DHCP_PING, DHCP_RELEASE, 96 DHCP_START, DHCP_STATUS, DHCP_INFORM, DHCP_GET_TAG, 97 DHCP_NIPC, /* number of supported requests */ 98 DHCP_PRIMARY = 0x100, 99 DHCP_V6 = 0x200 100 } dhcp_ipc_type_t; 101 102 /* structure passed with the DHCP_GET_TAG request */ 103 104 typedef struct { 105 uint_t category; 106 uint_t code; 107 uint_t size; 108 } dhcp_optnum_t; 109 110 #define DHCP_IPC_CMD(type) ((type) & 0x00ff) 111 #define DHCP_IPC_FLAGS(type) ((type) & 0xff00) 112 113 /* special timeout values for dhcp_ipc_make_request() */ 114 115 #define DHCP_IPC_WAIT_FOREVER (-1) 116 #define DHCP_IPC_WAIT_DEFAULT (-2) 117 118 /* 119 * errors that can be returned from the provided functions. 120 * note: keep in sync with dhcp_ipc_strerror() 121 */ 122 123 enum { 124 /* System call errors must be kept contiguous */ 125 DHCP_IPC_SUCCESS, DHCP_IPC_E_SOCKET, DHCP_IPC_E_FCNTL, 126 DHCP_IPC_E_READ, DHCP_IPC_E_ACCEPT, DHCP_IPC_E_CLOSE, 127 DHCP_IPC_E_BIND, DHCP_IPC_E_LISTEN, DHCP_IPC_E_MEMORY, 128 DHCP_IPC_E_CONNECT, DHCP_IPC_E_WRITEV, DHCP_IPC_E_POLL, 129 130 /* All others follow */ 131 DHCP_IPC_E_TIMEOUT, DHCP_IPC_E_SRVFAILED, DHCP_IPC_E_EOF, 132 DHCP_IPC_E_INVIF, DHCP_IPC_E_INT, DHCP_IPC_E_PERM, 133 DHCP_IPC_E_OUTSTATE, DHCP_IPC_E_PEND, DHCP_IPC_E_BOOTP, 134 DHCP_IPC_E_CMD_UNKNOWN, DHCP_IPC_E_UNKIF, DHCP_IPC_E_PROTO, 135 DHCP_IPC_E_FAILEDIF, DHCP_IPC_E_NOPRIMARY, DHCP_IPC_E_DOWNIF, 136 DHCP_IPC_E_NOIPIF, DHCP_IPC_E_NOVALUE, DHCP_IPC_E_RUNNING 137 }; 138 139 /* 140 * low-level public dhcpagent ipc functions -- these are for use by 141 * programs that need to communicate with the dhcpagent. these will 142 * remain relatively stable. 143 */ 144 145 extern const char *dhcp_ipc_strerror(int); 146 extern dhcp_ipc_request_t *dhcp_ipc_alloc_request(dhcp_ipc_type_t, const char *, 147 const void *, uint32_t, dhcp_data_type_t); 148 extern void *dhcp_ipc_get_data(dhcp_ipc_reply_t *, size_t *, 149 dhcp_data_type_t *); 150 extern int dhcp_ipc_make_request(dhcp_ipc_request_t *, 151 dhcp_ipc_reply_t **, int32_t); 152 extern const char *dhcp_ipc_type_to_string(dhcp_ipc_type_t); 153 154 /* 155 * high-level public dhcpagent ipc functions 156 */ 157 158 extern int dhcp_ipc_getinfo(dhcp_optnum_t *, DHCP_OPT **, int32_t); 159 160 /* 161 * private dhcpagent ipc "server side" functions -- these are only for 162 * use by dhcpagent(8) and are subject to change. 163 */ 164 165 extern int dhcp_ipc_init(int *); 166 extern int dhcp_ipc_accept(int, int *, int *); 167 extern int dhcp_ipc_recv_request(int, dhcp_ipc_request_t **, int); 168 extern dhcp_ipc_reply_t *dhcp_ipc_alloc_reply(dhcp_ipc_request_t *, int, 169 const void *, uint32_t, dhcp_data_type_t); 170 extern int dhcp_ipc_send_reply(int, dhcp_ipc_reply_t *); 171 extern int dhcp_ipc_close(int); 172 173 /* 174 * values for if_state in the dhcp_status_t 175 * 176 * code in this library and dhcpagent rely on the numeric values of these 177 * requests -- but there's no sane reason to change them anyway. 178 */ 179 180 typedef enum { 181 INIT, /* nothing done yet */ 182 SELECTING, /* sent DISCOVER, waiting for OFFERs */ 183 REQUESTING, /* sent REQUEST, waiting for ACK/NAK */ 184 PRE_BOUND, /* have ACK, setting up interface */ 185 BOUND, /* have a valid lease */ 186 RENEWING, /* have lease, but trying to renew */ 187 REBINDING, /* have lease, but trying to rebind */ 188 INFORMATION, /* sent INFORM, received ACK */ 189 INIT_REBOOT, /* attempt to use cached ACK/Reply */ 190 ADOPTING, /* attempting to adopt */ 191 INFORM_SENT, /* sent INFORM, awaiting ACK */ 192 DECLINING, /* sent v6 Decline, awaiting Reply */ 193 RELEASING, /* sent v6 Release, awaiting Reply */ 194 DHCP_NSTATES /* total number of states */ 195 } DHCPSTATE; 196 197 /* values for if_dflags in the dhcp_status_t */ 198 199 #define DHCP_IF_PRIMARY 0x0100 /* interface is primary interface */ 200 #define DHCP_IF_BUSY 0x0200 /* asynchronous command pending */ 201 #define DHCP_IF_BOOTP 0x0400 /* interface is using bootp */ 202 #define DHCP_IF_REMOVED 0x0800 /* interface is going away */ 203 #define DHCP_IF_FAILED 0x1000 /* interface configuration problem */ 204 #define DHCP_IF_V6 0x2000 /* DHCPv6 interface */ 205 206 /* 207 * structure passed with the DHCP_STATUS replies 208 * 209 * when parsing a dhcp_status_t, `version' should always be checked 210 * if there is a need to access any fields which were not defined in 211 * version 1 of this structure. 212 * 213 * as new fields are added to the dhcp_status_t, they should be 214 * appended to the structure and the version number incremented. 215 */ 216 217 typedef struct dhcp_status { 218 uint8_t version; /* version of this structure */ 219 220 char if_name[LIFNAMSIZ]; 221 DHCPSTATE if_state; /* state of interface; see above */ 222 223 /* 224 * We use int64_t here so that the structure is the same in both 225 * 32 and 64-bit, since it is passed via IPC. 226 * Once everything that uses this is 64-bit, these could be changed 227 * to time_t. 228 */ 229 int64_t if_began; /* time lease began (absolute) */ 230 int64_t if_t1; /* renewing time (absolute) */ 231 int64_t if_t2; /* rebinding time (absolute) */ 232 int64_t if_lease; /* lease expiration time (absolute) */ 233 234 uint16_t if_dflags; /* DHCP flags on this if; see above */ 235 236 /* 237 * these three fields are initially zero, and get incremented 238 * as if_state goes from INIT -> BOUND (or INIT -> 239 * INFORMATION). if and when the interface moves to the 240 * RENEWING state, these fields are reset, so they always 241 * either indicate the number of packets sent, received, and 242 * declined while obtaining the current lease (if BOUND), or 243 * the number of packets sent, received, and declined while 244 * attempting to obtain a future lease (if any other state). 245 */ 246 247 uint32_t if_sent; 248 uint32_t if_recv; 249 uint32_t if_bad_offers; 250 } dhcp_status_t; 251 252 #define DHCP_STATUS_VER 1 /* current version of dhcp_status_t */ 253 #define DHCP_STATUS_VER1_SIZE (offsetof(dhcp_status_t, if_bad_offers) + \ 254 sizeof (uint32_t)) 255 256 /* 257 * the remainder of this file contains implementation-specific 258 * artifacts which may change. note that a `dhcp_ipc_request_t' and a 259 * `dhcp_ipc_reply_t' are incomplete types as far as consumers of this 260 * api are concerned. use these details at your own risk. 261 */ 262 263 typedef hrtime_t dhcp_ipc_id_t; 264 265 /* 266 * note: the first 4 fields of the dhcp_ipc_request_t and dhcp_ipc_reply_t 267 * are intentionally identical; code in dhcpagent_ipc.c counts on it! 268 * 269 * we pack these structs to ensure that their lengths will be identical between 270 * 32-bit and 64-bit executables. 271 */ 272 273 #pragma pack(4) 274 275 struct dhcp_ipc_request { 276 dhcp_ipc_type_t message_type; /* type of request */ 277 dhcp_ipc_id_t ipc_id; /* per-socket unique request id */ 278 dhcp_data_type_t data_type; /* type of payload */ 279 uint32_t data_length; /* size of actual data in the buffer */ 280 char ifname[LIFNAMSIZ]; 281 int32_t timeout; /* timeout in seconds */ 282 uchar_t buffer[1]; /* dynamically extended */ 283 }; 284 285 struct dhcp_ipc_reply { 286 dhcp_ipc_type_t message_type; /* same message type as request */ 287 dhcp_ipc_id_t ipc_id; /* same id as request */ 288 dhcp_data_type_t data_type; /* type of payload */ 289 uint32_t data_length; /* size of actual data in the buffer */ 290 uint32_t return_code; /* did the request succeed? */ 291 uchar_t buffer[1]; /* dynamically extended */ 292 }; 293 294 #pragma pack() 295 296 #define DHCP_IPC_REPLY_SIZE offsetof(dhcp_ipc_reply_t, buffer) 297 #define DHCP_IPC_REQUEST_SIZE offsetof(dhcp_ipc_request_t, buffer) 298 299 #define DHCP_IPC_DEFAULT_WAIT 120 /* seconds */ 300 301 #ifdef __cplusplus 302 } 303 #endif 304 305 #endif /* _DHCPAGENT_IPC_H */ 306