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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
28 #include <sys/contract/process.h>
29 #include <sys/socket.h>
33 #include <libcontract.h>
34 #include <libcontract_priv.h>
40 #include "dhcpagent_ipc.h"
41 #include "dhcpagent_util.h"
44 * Strings returned by dhcp_status_hdr_string() and
45 * dhcp_status_reply_to_string(). The first define is the header line, and
46 * the second defines line printed underneath.
47 * The spacing of fields must match.
49 #define DHCP_STATUS_HDR "Interface State Sent Recv Declined Flags\n"
50 #define DHCP_STATUS_STR "%-10s %-12s %5d %5d %9d "
52 static const char *time_to_string(time_t abs_time
);
55 * dhcp_state_to_string(): given a state, provides the state's name
57 * input: DHCPSTATE: the state to get the name of
58 * output: const char *: the state's name
62 dhcp_state_to_string(DHCPSTATE state
)
64 const char *states
[] = {
80 if (state
< 0 || state
>= DHCP_NSTATES
)
83 return (states
[state
]);
92 fd
= open64(CTFS_ROOT
"/process/template", O_RDWR
);
97 * Deliver no events, don't inherit, and allow it to be orphaned.
99 err
|= ct_tmpl_set_critical(fd
, 0);
100 err
|= ct_tmpl_set_informative(fd
, 0);
101 err
|= ct_pr_tmpl_set_fatal(fd
, CT_PR_EV_HWERR
);
102 err
|= ct_pr_tmpl_set_param(fd
, CT_PR_PGRPONLY
| CT_PR_REGENT
);
103 if (err
!= 0 || ct_tmpl_activate(fd
) != 0) {
112 * dhcp_start_agent(): starts the agent if not already running
114 * input: int: number of seconds to wait for agent to start (-1 is forever)
115 * output: int: 0 on success, -1 on failure
119 dhcp_start_agent(int timeout
)
122 time_t start_time
= time(NULL
);
123 dhcp_ipc_request_t
*request
;
124 dhcp_ipc_reply_t
*reply
;
130 * just send a dummy request to the agent to find out if it's
131 * up. we do this instead of directly connecting to it since
132 * we want to make sure we follow its IPC conventions
133 * (otherwise, it will log warnings to syslog).
136 request
= dhcp_ipc_alloc_request(DHCP_PING
, "", NULL
, 0,
141 error
= dhcp_ipc_make_request(request
, &reply
, 0);
147 if (error
!= DHCP_IPC_E_CONNECT
)
150 if ((ctfd
= init_template()) == -1)
155 (void) ct_tmpl_clear(ctfd
);
163 (void) execl(DHCP_AGENT_PATH
, DHCP_AGENT_PATH
, (char *)0);
170 /* wait for the daemon to run and then abandon the contract */
171 (void) waitpid(childpid
, NULL
, 0);
173 if (contract_latest(&ct
) != -1)
174 (void) contract_abandon_id(ct
);
176 while ((timeout
!= -1) && (time(NULL
) - start_time
< timeout
)) {
177 error
= dhcp_ipc_make_request(request
, &reply
, 0);
182 } else if (error
!= DHCP_IPC_E_CONNECT
)
193 * dhcp_status_hdr_string(): Return a string suitable to use as the header
194 * when printing DHCP_STATUS reply.
195 * output: const char *: newline terminated printable string
198 dhcp_status_hdr_string(void)
200 return (DHCP_STATUS_HDR
);
204 * time_to_string(): Utility routine for printing time
206 * input: time_t *: time_t to stringify
207 * output: const char *: printable time
210 time_to_string(time_t abs_time
)
212 static char time_buf
[24];
213 time_t tm
= abs_time
;
218 if (strftime(time_buf
, sizeof (time_buf
), "%m/%d/%Y %R",
219 localtime(&tm
)) == 0)
220 return ("<unknown>");
226 * dhcp_status_reply_to_string(): Return DHCP IPC reply of type DHCP_STATUS
227 * as a printable string
229 * input: dhcp_reply_t *: contains the status structure to print
230 * output: const char *: newline terminated printable string
233 dhcp_status_reply_to_string(dhcp_ipc_reply_t
*reply
)
235 static char str
[1024];
237 dhcp_status_t
*status
;
239 status
= dhcp_ipc_get_data(reply
, &reply_size
, NULL
);
240 if (reply_size
< DHCP_STATUS_VER1_SIZE
)
241 return ("<Internal error: status msg size>\n");
243 (void) snprintf(str
, sizeof (str
), DHCP_STATUS_STR
,
244 status
->if_name
, dhcp_state_to_string(status
->if_state
),
245 status
->if_sent
, status
->if_recv
, status
->if_bad_offers
);
247 if (status
->if_dflags
& DHCP_IF_PRIMARY
)
248 (void) strlcat(str
, "[PRIMARY] ", sizeof (str
));
250 if (status
->if_dflags
& DHCP_IF_BOOTP
)
251 (void) strlcat(str
, "[BOOTP] ", sizeof (str
));
253 if (status
->if_dflags
& DHCP_IF_FAILED
)
254 (void) strlcat(str
, "[FAILED] ", sizeof (str
));
256 if (status
->if_dflags
& DHCP_IF_BUSY
)
257 (void) strlcat(str
, "[BUSY] ", sizeof (str
));
259 if (status
->if_dflags
& DHCP_IF_V6
)
260 (void) strlcat(str
, "[V6] ", sizeof (str
));
262 (void) strlcat(str
, "\n", sizeof (str
));
264 switch (status
->if_state
) {
273 (void) strlcat(str
, "(Began, Expires, Renew) = (", sizeof (str
));
274 (void) strlcat(str
, time_to_string(status
->if_began
), sizeof (str
));
275 (void) strlcat(str
, ", ", sizeof (str
));
276 (void) strlcat(str
, time_to_string(status
->if_lease
), sizeof (str
));
277 (void) strlcat(str
, ", ", sizeof (str
));
278 (void) strlcat(str
, time_to_string(status
->if_t1
), sizeof (str
));
279 (void) strlcat(str
, ")\n", sizeof (str
));