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