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